Trouble to get electron app's systray icon working as a snap

Overview

I created a snap for an electron app qqmusic for linux. It’s already packed in .deb package, and works correctly if install the deb package directly. I snapped it, and most stuff work correctly, however, I cannot get the systray icon working properly. There should be a menu showed up if single-click on the systray icon, but nothing happened, the double-click to hide/show the main window of qqmusic does work correctly however.

here is the snapcraft.yaml (https://github.com/twang2218/qqmusic-snap):

name: qqmusic
base: core18
version: '1.1.1'
summary: QQ Music for Linux
description: |
  QQ Music provides massive high-quality music for you.

# grade: stable
grade: devel
confinement: strict
architectures:
  - build-on: amd64

parts:
  qqmusic:
    plugin: dump
    source: https://dldir1.qq.com/music/clntupate/linux/deb/qqmusic_1.1.1_amd64.deb
    source-type: deb
    override-pull: |
      snapcraftctl pull
      # Fix the name
      sed -i -e 's|Name=qqmusic|Name=QQ Music\nName[zh]=QQ音乐|g' usr/share/applications/qqmusic.desktop
      # Fix the executable's location
      sed -i -e 's|Exec=/opt/qqmusic/qqmusic %U|Exec=qqmusic %U|g' usr/share/applications/qqmusic.desktop
      # Point icon to the correct location
      sed -i -e 's|Icon=qqmusic|Icon=${SNAP}/usr/share/icons/hicolor/256x256/apps/qqmusic.png|g' usr/share/applications/qqmusic.desktop
    stage-packages:
      - libgtk-3-0
      - libnotify4
      - libnss3
      - libxss1
      - libxtst6
      - xdg-utils
      - libatspi2.0-0
      - libuuid1
      - libappindicator3-1
      - libsecret-1-0
      - libx11-xcb1
      - libasound2
      - dbus-x11
      # for /usr/bin/whereis
      - util-linux

apps:
  qqmusic:
    command: desktop-launch $SNAP/opt/qqmusic/qqmusic --no-sandbox
    environment:
      # Correct the TMPDIR path for Chromium Framework/Electron to ensure
      # libappindicator has readable resources.
      TMPDIR: $XDG_RUNTIME_DIR
    extensions:
      - gnome-3-34
    plugs:
# desktop
      - desktop
      - desktop-legacy
      - wayland
      - unity7
      - x11
      - opengl
# electron
      - browser-support
      - gsettings
      # - home
      - network
# audio
      - alsa
      - jack1
      - pulseaudio
      - audio-playback
      # - audio-record
# others
      - avahi-observe
      - screen-inhibit-control
      - upower-observe
      - bluez
    slots:
      - mpris

Compare the devmode vs strict mode

The systray works correctly in devmode, but cannot work properly in strict mode. here is what I tried.

Installed in devmode

sudo snap install --devmode ./qqmusic_1.1.1_amd64.snap

Verify the mode:

➜ snap info --verbose qqmusic                                                       
name:    qqmusic
summary: QQ Music for Linux
health:
  status:  unknown
  message: health has not been set
publisher: –
license:   unset
description: |
  QQ Music provides massive high-quality music for you.
commands:
  - qqmusic
notes:               
  private:           false
  confinement:       strict
  devmode:           true
  jailmode:          false
  trymode:           false
  enabled:           true
  broken:            false
  ignore-validation: false
base:         core18
refresh-date: yesterday at 20:10 AEST
installed:    1.1.1 (x1) 110MB devmode

Launch the qqmusic via cli

➜ qqmusic                                 
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Gtk-Message: 14:24:41.446: Failed to load module "canberra-gtk-module"
Gtk-Message: 14:24:41.465: Failed to load module "canberra-gtk-module"
(electron) The default value of app.allowRendererProcessReuse is deprecated, it is currently "false".  It will change to be "true" in Electron 9.  For more information please check https://github.com/electron/electron/issues/18397
(node:497255) UnhandledPromiseRejectionWarning: undefined
(node:497255) UnhandledPromiseRejectionWarning: undefined
(node:497255) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:497255) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:497255) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:497255) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
login refresh fail
(node:497255) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
(node:497255) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
(electron) 'setUserAgent function' is deprecated and will be removed. Please use 'userAgent property' instead.

At the same time, the /var/log/kern.log content is following:

Sep 17 14:24:42 purrbuntu kernel: [353140.318443] audit: type=1107 audit(1631852682.480:1015366): pid=1682 uid=103 auid=4294967295 ses=4294967295 msg='apparmor="ALLOWED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=497255 label="snap.qqmusic.qqmusic" peer_pid=1677 peer_label="unconfined"
Sep 17 14:24:42 purrbuntu kernel: [353140.318443]  exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'
Sep 17 14:24:43 purrbuntu kernel: [353141.066130] audit: type=1326 audit(1631852683.228:1015367): auid=1000 uid=1000 gid=1000 ses=3 pid=497255 comm="qqmusic" exe="/snap/qqmusic/x1/opt/qqmusic/qqmusic" sig=0 arch=c000003e syscall=92 compat=0 ip=0x7efc3aaa04b7 code=0x7ffc0000
Sep 17 14:24:43 purrbuntu kernel: [353141.126718] audit: type=1107 audit(1631852683.288:1015368): pid=1682 uid=103 auid=4294967295 ses=4294967295 msg='apparmor="ALLOWED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=497255 label="snap.qqmusic.qqmusic" peer_pid=1677 peer_label="unconfined"
Sep 17 14:24:43 purrbuntu kernel: [353141.126718]  exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'
Sep 17 14:24:45 purrbuntu kernel: [353143.008397] audit: type=1326 audit(1631852685.168:1015369): auid=1000 uid=1000 gid=1000 ses=3 pid=497400 comm="qqmusic" exe="/snap/qqmusic/x1/opt/qqmusic/qqmusic" sig=0 arch=c000003e syscall=92 compat=0 ip=0x7f7dfff764b7 code=0x7ffc0000

And the systray icon works correctly.

2021-09-17 14-25-11 的屏幕截图

Installed in strict/dangerous mode

sudo snap install --dangerous ./qqmusic_1.1.1_amd64.snap

The mode can be verified by CLI:

➜ snap info --verbose qqmusic                                                         
name:    qqmusic
summary: QQ Music for Linux
health:
  status:  unknown
  message: health has not been set
publisher: –
license:   unset
description: |
  QQ Music provides massive high-quality music for you.
commands:
  - qqmusic
notes:               
  private:           false
  confinement:       strict
  devmode:           false
  jailmode:          false
  trymode:           false
  enabled:           true
  broken:            false
  ignore-validation: false
base:         core18
refresh-date: today at 14:29 AEST
installed:    1.1.1 (x1) 110MB -

Launch the qqmusic from command line:

➜ qqmusic
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Gtk-Message: 14:32:50.482: Failed to load module "canberra-gtk-module"
Gtk-Message: 14:32:50.485: Failed to load module "canberra-gtk-module"
(electron) The default value of app.allowRendererProcessReuse is deprecated, it is currently "false".  It will change to be "true" in Electron 9.  For more information please check https://github.com/electron/electron/issues/18397
(node:501785) UnhandledPromiseRejectionWarning: undefined
(node:501785) UnhandledPromiseRejectionWarning: undefined
(node:501785) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:501785) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:501785) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:501785) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
login refresh fail
(node:501785) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
(node:501785) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
stderr: dbus-monitor: unable to enable new-style monitoring: org.freedesktop.DBus.Error.AccessDenied: "An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.18543" (uid=1000 pid=501935 comm="dbus-monitor --session type='signal',interface='or" label="snap.qqmusic.qqmusic (enforce)") interface="org.freedesktop.DBus.Monitoring" member="BecomeMonitor" error name="(unset)" requested_reply="0" destination="org.freedesktop.DBus" (bus)". Falling back to eavesdropping.

(electron) 'setUserAgent function' is deprecated and will be removed. Please use 'userAgent property' instead.

The /var/log/kern.log output for the launch is:

Sep 17 14:32:50 purrbuntu kernel: [353628.627303] audit: type=1107 audit(1631853170.758:1015479): pid=1682 uid=103 auid=4294967295 ses=4294967295 msg='apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=501785 label="snap.qqmusic.qqmusic" peer_pid=1677 peer_label="unconfined"
Sep 17 14:32:50 purrbuntu kernel: [353628.627303]  exe="/usr/bin/dbus-daemon" sauid=103 hostname=? addr=? terminal=?'
Sep 17 14:32:50 purrbuntu kernel: [353628.748537] audit: type=1326 audit(1631853170.882:1015480): auid=1000 uid=1000 gid=1000 ses=3 pid=501785 comm="qqmusic" exe="/snap/qqmusic/x1/opt/qqmusic/qqmusic" sig=0 arch=c000003e syscall=92 compat=0 ip=0x7f6d221ff4b7 code=0x50000
Sep 17 14:32:51 purrbuntu kernel: [353629.560219] audit: type=1326 audit(1631853171.694:1015481): auid=1000 uid=1000 gid=1000 ses=3 pid=501921 comm="qqmusic" exe="/snap/qqmusic/x1/opt/qqmusic/qqmusic" sig=0 arch=c000003e syscall=92 compat=0 ip=0x7f4e52b624b7 code=0x50000

And nothing happened if click on the qqmusic systray icon.

Potential Problem

The bluez error should not be the problem, I can overcome it by connecting it to bluez interface, and the result is the same.

The following error caught my eyes, and I’m not sure whether it’s the cause of the problem:

stderr: dbus-monitor: unable to enable new-style monitoring: org.freedesktop.DBus.Error.AccessDenied: "An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.18543" (uid=1000 pid=501935 comm="dbus-monitor --session type='signal',interface='or" label="snap.qqmusic.qqmusic (enforce)") interface="org.freedesktop.DBus.Monitoring" member="BecomeMonitor" error name="(unset)" requested_reply="0" destination="org.freedesktop.DBus" (bus)". Falling back to eavesdropping.

I cannot find any interface corresponding to dbus org.freedesktop.DBus.Monitoring, so can any one give me a help on how to solve the problem? Thanks.

This might be a long shot but the majority of the Electron 7 releases didn’t actually use libappindicator for the system tray icon, they used a DBus approach that only half worked with the snapd interfaces. This was reverted in Electron 8 and the latter end of the Electron 7 releases.

Whilst Electron 7 is an old release by Electrons new release cadence (They’re on Electron 14 now), it’s EOL’d only about a year ago. Is it possible this .deb is still using it?

Meanwhile, you could give snappy-debug a go for some possible extra feedback, try sudo snap install snappy-debug and then run snappy-debug in a terminal while launching your app, you might find it’s output insightful.

Thank James for your detailed explaination, I have better understanding of the Electron 7 parts. I agree that the Electron which qqmusic used should be upgraded to later version. I will try to contact the author of the software, but it’s out of my control.

I have installed snappy-debug as your advice, it does output much more stuff than I expected.

➜ sudo journalctl --output=short --follow --all | sudo snappy-debug
kernel.printk_ratelimit = 0
= AppArmor =
Time: Sep 18 15:05:20
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=593090 label="snap.qqmusic.qqmusic" peer_pid=1677 peer_label="unconfined"
DBus access

= AppArmor =
Time: Sep 18 15:05:20
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus.Monitoring" member="BecomeMonitor" mask="send" name="org.freedesktop.DBus" pid=593337 label="snap.qqmusic.qqmusic" peer_label="unconfined"
DBus access

= AppArmor =
Time: Sep 18 15:05:20
Log: apparmor="DENIED" operation="dbus_eavesdrop"  bus="session" mask="eavesdrop" pid=593337 label="snap.qqmusic.qqmusic"
DBus access

= AppArmor =
Time: Sep 18 15:05:21
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/com/canonical/dbusmenu" interface="com.canonical.dbusmenu" member="AboutToShow" name=":1.38" mask="receive" pid=593090 label="snap.qqmusic.qqmusic" peer_pid=523681 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'unity7' to 'plugs'

= AppArmor =
Time: Sep 18 15:05:21
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/com/canonical/dbusmenu" interface="com.canonical.dbusmenu" member="GetLayout" name=":1.38" mask="receive" pid=593090 label="snap.qqmusic.qqmusic" peer_pid=523681 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'unity7' to 'plugs'

= Seccomp =
Time: Sep 18 15:05:22
Log: auid=1000 uid=1000 gid=1000 ses=796 pid=593090 comm="qqmusic" exe="/snap/qqmusic/x3/opt/qqmusic/qqmusic" sig=0 arch=c000003e 92(chown) compat=0 ip=0x7ff6cbb374b7 code=0x50000
Syscall: chown
Suggestions:
* don't copy ownership of files (eg, use 'cp -r --preserve=mode' instead of 'cp -a')
* try the snapcraft preload plugin: https://github.com/sergiusens/snapcraft-preload
* adjust program to not use 'chown'
* ignore the denial if the program otherwise works correctly (unconditial chown is often just noise)

= Seccomp =
Time: Sep 18 15:05:22
Log: auid=1000 uid=1000 gid=1000 ses=796 pid=593333 comm="qqmusic" exe="/snap/qqmusic/x3/opt/qqmusic/qqmusic" sig=0 arch=c000003e 92(chown) compat=0 ip=0x7f2602ac14b7 code=0x50000
Syscall: chown
Suggestions:
* don't copy ownership of files (eg, use 'cp -r --preserve=mode' instead of 'cp -a')
* try the snapcraft preload plugin: https://github.com/sergiusens/snapcraft-preload
* adjust program to not use 'chown'
* ignore the denial if the program otherwise works correctly (unconditial chown is often just noise)



= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/opt/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /opt/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/share/man/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/share/man/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/src/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/src/ (read)
Suggestions:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON
* add one of 'system-source-code, system-trace' to 'plugs'
* add 'system-trace' to 'plugs'

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/sbin/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/bin/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /bin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/sbin/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/etc/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /etc/ (read)
Suggestions:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON
* adjust snap to use snap layouts (https://forum.snapcraft.io/t/snap-layouts/7207)

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/lib64/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /lib64/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/games/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/games/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/include/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/include/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/local/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/local/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/share/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/share/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:05:34
Log: apparmor="DENIED" operation="open" profile="snap.qqmusic.qqmusic" name="/usr/share/info/" pid=593432 comm="whereis" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /usr/share/info/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Sep 18 15:52:01
Log: apparmor="DENIED" operation="dbus_signal"  bus="session" path="/org/gnome/ScreenSaver" interface="org.gnome.ScreenSaver" member="WakeUpScreen" name=":1.38" mask="receive" pid=593337 label="snap.qqmusic.qqmusic" peer_pid=523681 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'screen-inhibit-control' to 'plugs'

I’m not sure why there are chown and many whereis in the electron app, however, it doesn’t seem to stop the app running, so I guess they can be ignored.

org.freedesktop.DBus.Monitoring and dbus_eavesdrop are denied by AppArmor. And following com.canonical.dbusmenu's AboutToShow and GetLayout are denied as well. The plug unity7 and screen-inhibit-control which suggested by snappy-debug have already been added and connected automatically. It can be verified by snap connections command:

➜ snap connections qqmusic                                
Interface                 Plug                            Slot                             Notes
alsa                      qqmusic:alsa                    -                                -
audio-playback            qqmusic:audio-playback          :audio-playback                  -
avahi-observe             qqmusic:avahi-observe           -                                -
bluez                     qqmusic:bluez                   -                                -
browser-support           qqmusic:browser-support         :browser-support                 -
content[gnome-3-34-1804]  qqmusic:gnome-3-34-1804         gnome-3-34-1804:gnome-3-34-1804  -
content[gtk-3-themes]     qqmusic:gtk-3-themes            gtk-common-themes:gtk-3-themes   -
content[icon-themes]      qqmusic:icon-themes             gtk-common-themes:icon-themes    -
content[sound-themes]     qqmusic:sound-themes            gtk-common-themes:sound-themes   -
desktop                   qqmusic:desktop                 :desktop                         -
desktop-legacy            qqmusic:desktop-legacy          :desktop-legacy                  -
gsettings                 qqmusic:gsettings               :gsettings                       -
jack1                     qqmusic:jack1                   -                                -
mpris                     -                               qqmusic:mpris                    -
network                   qqmusic:network                 :network                         -
opengl                    qqmusic:opengl                  :opengl                          -
pulseaudio                qqmusic:pulseaudio              -                                -
screen-inhibit-control    qqmusic:screen-inhibit-control  :screen-inhibit-control          -
unity7                    qqmusic:unity7                  :unity7                          -
upower-observe            qqmusic:upower-observe          :upower-observe                  -
wayland                   qqmusic:wayland                 :wayland                         -
x11                       qqmusic:x11                     :x11                             -

So, why those requests are denied even if the plugs have been connected? and is there a way to enable org.freedesktop.DBus.Monitoring dbus access for the snap?

After looking through the source code https://github.com/snapcore/snapd/blob/61b66aaa1beb861f308ea7dd75c2f0c042bf29a3/interfaces/builtin/unity7.go#L367-L379

dbus (receive)
    bus=session
    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*}
    interface="{com.canonical.dbusmenu,org.freedesktop.DBus.Properties}"
    member=Get*
    peer=(label=unconfined),
dbus (receive)
    bus=session
    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*}
    interface=com.canonical.dbusmenu
    member="{AboutTo*,Event*}"
    peer=(label=unconfined),

It might be the path problem, should com/canonical/menu in unity7.go become com/canonical/dbusmenu?

snappy-debug sometimes isn’t 100% accurate with it’s suggestions, I’m not confident the exact heuristics that are in play, but your snap connections does clearly show unity7 is connected as you’ve mentioned.

I’m not personally sure the exact DBus paths that would be needed to fix this. The concern from the snapd team would be whether those DBus calls could be used maliciously in any manner and that’s not something I could comment on. However based on the AppArmor denials you could possibly try resolving this locally and propose a patch if you get it to work.

The AppArmor policy for your snap should be located at /var/lib/snapd/apparmor/profiles/snap.qqmusic.qqmusic and if you edit them there and run sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.qqmusic.qqmusic to apply them, you can experiment with adding the DBus paths and seeing if they work. Once you’ve got the correct configuration, I’d try proposing it for review so it can be distributed in future snapd releases.

Wow, it works.

I modified the /var/lib/snapd/apparmor/profiles/snap.qqmusic.qqmusic by adding com/canonical/dbusmenu to dbusmenu section:

➜ diff -u snap.qqmusic.qqmusic.bak snap.qqmusic.qqmusic
--- snap.qqmusic.qqmusic.bak	2021-09-19 12:47:04.518276613 +1000
+++ snap.qqmusic.qqmusic	2021-09-19 12:44:02.897018611 +1000
@@ -973,21 +973,21 @@
 # dbusmenu
 dbus (send)
     bus=session
-    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*}
+    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*,com/canonical/dbusmenu}
     interface=com.canonical.dbusmenu
     member="{LayoutUpdated,ItemsPropertiesUpdated}"
     peer=(name=org.freedesktop.DBus, label=unconfined),
 
 dbus (receive)
     bus=session
-    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*}
+    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*,com/canonical/dbusmenu}
     interface="{com.canonical.dbusmenu,org.freedesktop.DBus.Properties}"
     member=Get*
     peer=(label=unconfined),
 
 dbus (receive)
     bus=session
-    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*}
+    path=/{MenuBar{,/[0-9A-F]*},com/canonical/menu/[0-9A-F]*,com/canonical/dbusmenu}
     interface=com.canonical.dbusmenu
     member="{AboutTo*,Event*}"
     peer=(label=unconfined),

After reload the file:

➜ sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.qqmusic.qqmusic

then restart the qqmusic,

➜ qqmusic
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Gtk-Message: 12:44:29.963: Failed to load module "canberra-gtk-module"
Gtk-Message: 12:44:29.968: Failed to load module "canberra-gtk-module"
(electron) The default value of app.allowRendererProcessReuse is deprecated, it is currently "false".  It will change to be "true" in Electron 9.  For more information please check https://github.com/electron/electron/issues/18397
WX login
cookie set success
stderr: dbus-monitor: unable to enable new-style monitoring: org.freedesktop.DBus.Error.AccessDenied: "An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.4280" (uid=1000 pid=677649 comm="dbus-monitor --session type='signal',interface='or" label="snap.qqmusic.qqmusic (enforce)") interface="org.freedesktop.DBus.Monitoring" member="BecomeMonitor" error name="(unset)" requested_reply="0" destination="org.freedesktop.DBus" (bus)". Falling back to eavesdropping.

(electron) 'setUserAgent function' is deprecated and will be removed. Please use 'userAgent property' instead.
cookie set success
Gtk-Message: 12:44:48.736: GtkDialog mapped without a transient parent. This is discouraged.

Although the org.freedesktop.DBus.Monitoring error is still there, the menu of tray icon menu works correctly this time.

And there is no any denial of com.canonical.dbusmenu in the snappy-debug log anymore:

➜ sudo journalctl --output=short --follow --all | sudo snappy-debug            
kernel.printk_ratelimit = 0
= AppArmor =
Time: Sep 19 12:44:30
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=677499 label="snap.qqmusic.qqmusic" peer_pid=1677 peer_label="unconfined"
DBus access

= AppArmor =
Time: Sep 19 12:44:30
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus.Monitoring" member="BecomeMonitor" mask="send" name="org.freedesktop.DBus" pid=677649 label="snap.qqmusic.qqmusic" peer_label="unconfined"
DBus access

= AppArmor =
Time: Sep 19 12:44:30
Log: apparmor="DENIED" operation="dbus_eavesdrop"  bus="session" mask="eavesdrop" pid=677649 label="snap.qqmusic.qqmusic"
DBus access

= Seccomp =
Time: Sep 19 12:44:31
Log: auid=1000 uid=1000 gid=1000 ses=796 pid=677634 comm="qqmusic" exe="/snap/qqmusic/x3/opt/qqmusic/qqmusic" sig=0 arch=c000003e 92(chown) compat=0 ip=0x7f611558c4b7 code=0x50000
Syscall: chown
Suggestions:
* don't copy ownership of files (eg, use 'cp -r --preserve=mode' instead of 'cp -a')
* try the snapcraft preload plugin: https://github.com/sergiusens/snapcraft-preload
* adjust program to not use 'chown'
* ignore the denial if the program otherwise works correctly (unconditial chown is often just noise)

= Seccomp =
Time: Sep 19 12:44:33
Log: auid=1000 uid=1000 gid=1000 ses=796 pid=677499 comm="qqmusic" exe="/snap/qqmusic/x3/opt/qqmusic/qqmusic" sig=0 arch=c000003e 92(chown) compat=0 ip=0x7f8f3866f4b7 code=0x50000
Syscall: chown
Suggestions:
* don't copy ownership of files (eg, use 'cp -r --preserve=mode' instead of 'cp -a')
* try the snapcraft preload plugin: https://github.com/sergiusens/snapcraft-preload
* adjust program to not use 'chown'
* ignore the denial if the program otherwise works correctly (unconditial chown is often just noise)

Hi, James, I have been testing the profile for the past week, there were multiple remove/install/patch operations over multiple computers, I think it fixed the systray problem. So, should I create a pull request to snapd somewhere to patch the unity7 interface?

In theory the Unity7 interface is deprecated, and was superseded by the desktop and desktop-legacy interfaces. My guess is that in addition to adding it to the unity7 interface, it should also be added to either desktop or desktop-legacy. Whether it gets into desktop depends on the relative safety of the DBus call, which I couldn’t personally answer.

But sure, consider sending a pull request :)! You should be aware you’d need to sign the contributor agreement in order for it to be accepted though. In short terms, and keep in mind I’m not a lawyer, this gives Canonical the right to relicense your work; without taking away your specific ownership (so you could submit it yourself elsewhere under other licenses too for example).

Aside from the CLA, I expect you’d find the process pretty standard.

@ijohnson Hopefully this is a pretty simple interface proposal from OP and afaik you’re one of the experts there, do you have any preliminary advice for OP here perhaps :slight_smile:

Seems a reasonable change to make, if you’re comfortable filing a PR that is definitely the next step, we try to prioritize getting small interface only changes to PR’s landed quickly and painlessly.

Thanks everyone, I created the PR #10873, and I’m signing the CLA, however, I don’t know any “Canonical Project Manager or contact”, may I ask who should I put in there?

You can just put “not applicable” in there :slight_smile: the forms read by a human and they’ll work out it doesn’t really make sense for an independent/singlular developer.

What I did forget to mention and might be required (I’m not entirely sure but it seems reasonable enough to bring up), is that people who have signed the CLA are added to a group on Launchpad, if you’re unfamiliar with Launchpad, it’s Canonical’s service used primarily for orchestrating Ubuntu and contains services like Git hosting, bug trackers, CI builds, etc. You can sign into it with the same account as you sign in with Snapcraft/Ubuntu SSO and if you haven’t ever signed into it before, I’d probably recommend you log in the one time just to make sure the service knows about your account and the CLA succeeds fully.

1 Like