Bug 337276

Summary: fully-qualified audio notifications no longer play
Product: [Frameworks and Libraries] Phonon Reporter: Ramesh Kandukuri <rkanduku>
Component: generalAssignee: Harald Sitter <sitter>
Status: RESOLVED FIXED    
Severity: normal CC: dvratil, kaputtnik, kdelibs-bugs, mklapetek, myriam, orbmiser, raghu, rdieter, romain.perier
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Fedora RPMs   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Ramesh Kandukuri 2014-07-09 14:05:58 UTC
Notification sound will not play.
We have tried every format of sound file but none of them worked.
Using Fedora 19 with latest KDE update

Reproducible: Always

Steps to Reproduce:
1. Configured Notifications
2. Attached sound file
3. Attached the event 
Actual Results:  
No sound 

Expected Results:  
Sound need to be come with pop up
Comment 1 Rex Dieter 2014-07-10 23:17:59 UTC
Do other notification types work here?  Like "show message in a popup?"
Comment 2 Raghavendra kamath 2016-04-25 18:36:47 UTC
+1 i am experiencing this issue on arch linux too ,

Although I get notification only popups, there is no sounds and there is no konversation icon blinking in systray too.
Comment 3 Franky 2016-04-28 16:10:12 UTC
Beside konversation plays no event sounds, kmail does not too.

I am on arch linux.
Comment 4 Orbmiser 2016-04-28 17:40:05 UTC
Yep has to do with Path issue.

See my thread http://forums.netrunner.com/showthread.php?tid=23575

"Default points to sound example Network Connection deactivated works if you keep whatever default sounds.
Example device disconnected.ogg. But if you want to change sounds and end up with a path even a valid one. Will Not play

Like /usr/share/sounds/disconnect.ogg then it will not work till you erase the path and only have disconnect.ogg in the play sound path window. Cannot change sounds as soon as you select sound then it will insert path string /usr/sounds/disconnect.ogg and that will Not work.

Goes for path to any other including ones in my home directory no longer work. If i enter just the sound file. As doesn't know where to look? As not in default folder where it is looking?"
Comment 5 Rex Dieter 2016-04-28 17:44:44 UTC
Confirmed, triaging to frameworks-knotifications
Comment 6 Rex Dieter 2016-04-28 17:48:07 UTC
void NotifyByAudio::notify(KNotification *notification, KNotifyConfig *config)

contains:

    QUrl soundURL = QUrl(soundFilename); // this CTOR accepts both absolute paths (/usr/share/sounds/blabla.ogg and blabla.ogg) w/o screwing the scheme
    if (soundURL.isRelative() && !soundURL.toString().startsWith('/')) { // QUrl considers url.scheme.isEmpty() == url.isRelative()
        soundURL = QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("sounds/") + soundFilename));

So it seems only the "relative" cases is currently working (for whatever reason)
Comment 7 Rex Dieter 2016-04-28 18:44:41 UTC
Another datapoint:

audio file entries of the form:
/usr/share/sounds/KDE-Im-Cant-Connect.ogg
do not work, but:
file:///usr/share/sounds/KDE-Im-Cant-Connect.ogg
does play, so seems it has something to do with URL scheme, or lack thereof.
Comment 8 Franky 2016-04-28 22:27:18 UTC
With the file: prefix it works for "configure notifications", but this is not stored and notification sounds doesn't work at all.
Comment 9 Rex Dieter 2016-04-29 17:41:44 UTC
OK, starting to think at least part of what's going on here is a phonon regression from 4.8 => 4.9

With phonon-4.8 audio preview of /usr/share/sounds/KDE-Im-Cant-Connect.ogg works, after upgrading to phonon-4.9 it doesn't
Comment 10 Rex Dieter 2016-04-29 18:58:05 UTC
I think I've narrowed it down to the commit that fixes bug #356218 as the culprit behind this apparent regression:

http://commits.kde.org/phonon/621ffb823d45a88a02602fb4ee4b769dfbc0c16a

Reverting that fixes issues as reported here for me
Comment 11 Colin J Thomson 2016-04-29 23:23:01 UTC
Fixes it for me also - F23
Comment 12 Harald Sitter 2016-05-04 11:57:12 UTC
Ok, so. This is somewhat tricky business and I'd love some input on how to deal with it. Lot's of technobabble upcoming.

This was originally changed because of bug 356218 where having a '#' in a file name would fail to be encoded correctly because QUrl upon construction would internally safe-encode a path, so internally 'Foo#.mp4' is 'Foo%23.mp4'. QUrl.toString would then output the internal variant rather than fully decoded back to 'Foo#.mp4' which clashes with the encoding Phonon's Mrl applies later on. Resulting in 'Foo%2523.mp4' as output (that is literally a percent encoded percent character followed by 23).
So it was changed to toLocalString, since that always fully decodes.

The problem we are facing in this bug here is that toLocalString only outputs anything if the string is actually known to be local, which it isn't because it was constructed via QUrl() and didn't have a file:// scheme so it could be cat for all QUrl knows.

I am proposing that the bug is in fact in KNotifications and not in Phonon.

KNotifications in the case of an absolute path does the following:
>     QUrl soundURL = QUrl(soundFilename); // this CTOR accepts both absolute paths (/usr/share/sounds/blabla.ogg and blabla.ogg) w/o screwing the scheme
which looks innocent enough, except it is not. What this does is it assumes soundFilename is a URL, which is not wrong, it is however not a parsable URL.

The key difference is that in a parsable URL #?&= have meaning. In one that isn't, they don't. So, what that means is that if soundFilename is '/Foo#.mp3' this results in parsing leading to the path() being '/Foo' and the fragment() being '#.mp3', so unless Phonon were to manually concatenate all parts of the URL (scheme, host, path, query, fragment) in their fully decoded form we cannot get to the actual path. This is in particular true since we cannot toString(FullyDecode) because that would be ambiguous precisely because of cases like above where the path may contain a # but then the URL could also have a fragment.

The reason it worked previously is precisely because of bug 356218. As long as a local file path doesn't contain a reserved character all is fine since we'd always correctly decode with toString() and then apply our encoding rules on top. If the file path contained such a character it would still work for QUrl() constructed *parsed* paths (i.e. where for example #.mp3 is a fragment internally) but would then fail for QUrl::fromUserInput or QUrl::fromLocalFile as there toString would return the half-encoded internal variant to prevent ambiguity.

So. Can we fix this? Absolutely! We could toEncoded, then run that through the static fromPercentEncoding and should get the fully decoded string again.

BUT!

I'm going out on a limb here and say that the breakage in 4.9.0, while very unfortunate short-term, is a good thing. The way QUrl() is used in KNotifications is quite simply wrong. KNotifications should use fromLocalFile or fromUserInput (latter actually can replace the entire file name code there). The fact that it worked by "accident" earlier doesn't help make it behavior I would want to hold on to in Phonon.

On the other hand I do also dislike compatibility break, so I am torn on this.

Anyone got thoughts?

A middle-ground would perhaps be to reach for maximum compatibility when building with Qt4 and leave the breakage for Qt5 software using Qt4 probably won't be getting an update to adjust QUrl usage if needed.
Comment 13 Franky 2016-05-04 21:16:38 UTC
Do i understand it right, the main problem is compatibility with qt4?
Comment 14 Orbmiser 2016-05-04 21:57:47 UTC
(In reply to Franky from comment #13)
> Do i understand it right, the main problem is compatibility with qt4?

Nope recent breakage worked fine last month but updates last couple of weeks broke it.

KDE Plasma 5.6.3
KDE Frameworks 5.21.0
Qt version: 5.6.0
Comment 15 Rex Dieter 2016-05-06 01:28:25 UTC
See also:
knotifyconfig : https://git.reviewboard.kde.org/r/127829/
knotifications: https://git.reviewboard.kde.org/r/127830

Harald, may related kde4 components (like kdelibs/libknotifyconfig) need fixing too?
Comment 16 Rex Dieter 2016-05-06 01:35:52 UTC
Did test notifications from 'kcmshell4 kcmnotify' both relative and full path audio is fine, so nevermind
Comment 17 Harald Sitter 2016-05-09 07:29:03 UTC
Git commit 4832f7d9f2f3bd0fa8ab9b9162bf50e855efc448 by Harald Sitter.
Committed on 09/05/2016 at 07:27.
Pushed by sitter into branch 'master'.

use QUrl::fromUserInput to construct sound url

QUrl() would treats it as a parsable uri, but they aren't e.g. # in a uri
separates segments in a local file path it simply is a #.
This "accidentally" worked in Phonon < 4.9 as Phonon obtained string
representations in a way that would bypass internal QUrl checks for
fileyness and URI ambiguity. Since 4.9 Phonon expects scheme-less URLs to
be local files, but QUrl() would most of the time not do that since it
would honestly think the soundfilename is a random (i.e. not necessarily
local) uri.

To fix this use QUrl::fromUserInput which behaves exactly like what we
need to properly resolve relative names, urls, paths, full URIs.

This now works with input of the type:
- Oxygen-Sys-Special.ogg
- /usr/share/sounds/Oxygen-Sys-Special.ogg
- file:///usr/share/sounds/Oxygen-Sys-Special.ogg
- /usr/share/sounds/#KDE-Im-Cant-#Connect.ogg
- file:///usr/share/sounds/#KDE-Im-Cant-#Connect.ogg
- http://people.ubuntu.com/~apachelogger/sounds/sounds-3.5/KDE_Glass_Break.ogg
(yes, we can have http notifications!!!! https://xkcd.com/1172/)
REVIEW: 127829

M  +13   -8    src/knotifyconfigactionswidget.cpp

http://commits.kde.org/knotifyconfig/4832f7d9f2f3bd0fa8ab9b9162bf50e855efc448
Comment 18 Harald Sitter 2016-05-09 07:29:05 UTC
Git commit 9db06adc8114163f401417064b07772139bc36bc by Harald Sitter.
Committed on 09/05/2016 at 07:27.
Pushed by sitter into branch 'master'.

use QUrl::fromUserInput to construct sound url

QUrl() would treats it as a parsable uri, but they aren't e.g. # in a uri
separates segments in a local file path it simply is a #.
This "accidentally" worked in Phonon < 4.9 as Phonon obtained string
representations in a way that would bypass internal QUrl checks for
fileyness and URI ambiguity. Since 4.9 Phonon expects scheme-less URLs to
be local files, but QUrl() would most of the time not do that since it
would honestly think the soundfilename is a random (i.e. not necessarily
local) uri.

To fix this use QUrl::fromUserInput which behaves exactly like what we
need to properly resolve relative names, urls, paths, full URIs.

This now works with input of the type:
- Oxygen-Sys-Special.ogg
- /usr/share/sounds/Oxygen-Sys-Special.ogg
- file:///usr/share/sounds/Oxygen-Sys-Special.ogg
- /usr/share/sounds/#KDE-Im-Cant-#Connect.ogg
- file:///usr/share/sounds/#KDE-Im-Cant-#Connect.ogg
- http://people.ubuntu.com/~apachelogger/sounds/sounds-3.5/KDE_Glass_Break.ogg
(yes, we can have http notifications!!!! https://xkcd.com/1172/)
REVIEW: 127830

M  +16   -9    src/notifybyaudio.cpp

http://commits.kde.org/knotifications/9db06adc8114163f401417064b07772139bc36bc
Comment 19 Colin J Thomson 2016-05-14 23:09:05 UTC
With the new fixes all works fine for me - F24

kf5-knotifications-5.21.0-3.fc24.x86_64
kf5-knotifyconfig-5.21.0-2.fc24.x86_64
phonon-4.9.0-3.fc24.x86_64
Comment 20 Franky 2016-06-05 12:39:04 UTC
With which version should this be fixed? Here on arch-linux it is working only when i use the "file://" prefix. 
Installed Versions:

knotifications 5.22.0-1 (kf5)
knotifyconfig 5.22.0-1 (kf5)
phonon-qt4 4.9.0-1
Comment 21 Rex Dieter 2016-06-05 12:55:20 UTC
It was fixed in both knotifications and knotifyconfig after 5.22.0 release.  The fix will be included in kf5 5.23.0 release.
Comment 22 Franky 2016-06-05 13:21:02 UTC
Thanks :-)