AsteroidOS / AsteroidOSSync

Android application to synchronize a phone with a watch running asteroid-btsyncd.
GNU General Public License v3.0
100 stars 37 forks source link

Add Support for Work Profiles #121

Open jrtberlin opened 3 years ago

jrtberlin commented 3 years ago

User feedback via IRC indicates that currently, notifications from apps in work profiles are not synced (this includes solutions like Shelter).

Investigation

The Android Developer documentation seems to back that up:

When your app runs in the personal profile, you might not get notifications for apps running in the work profile. By default, all personal profile apps receive callbacks but an IT admin can allowlist one or more personal profile apps that they allow to listen for notification changes. The system then blocks non-allowlisted apps. In Android 8.0 (API level 26) or later, a device policy controller (DPC) that manages a work profile might block your app from listening to the work profile's notifications using the DevicePolicyManager method setPermittedCrossProfileNotificationListeners(). Your app still receives callbacks about notifications posted in the personal profile.

From my very short read into the docs, one could assume that Shelters device policy blocks the listener. That seems to be not the case since the policy file is empty and I have not found any use of setPermittedCrossProfileNotificationListeners().

Possible options could be:

Going forward

The next steps would be:

  1. to reproduce the issue
  2. use dumpsys to get the notification flags to find possible differences between work-profile-installed app notifications and normal ones.
jrtberlin commented 3 years ago

Reproducing the issue

To reproduce the issue I installed a Gotify server and the app in a work profile with shelter.

When I push a notification with the following command:

curl "http://gotify-server-ip:gotify-port:/message?token=<apptoken>" \
-F "title=my title" \
-F "message=my message" \
-F "priority=5"

I get the following results on the phone: gotify_notification_phone

And I also get a notification on the watch: notification_watch

I also did a test with the same setup in the main user profile and in the work profile to see differences in the NotificationRecord.

Work Profile NotificationRecord:

NotificationRecord(0x0ea3bcdd: pkg=com.github.gotify user=UserHandle{10} id=-5 tag=null importance=4 key=10|com.github.gotify|-5|null|1010400appImportanceLocked=false: Notification(channel=gotify_messages_high_importance pri=0 contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x210 color=0xff3f51b5 groupKey=GOTIFY_GROUP_MESSAGES vis=PRIVATE))
      uid=1010400 userId=10
      opPkg=com.github.gotify
      icon=Icon(typ=RESOURCE pkg=com.github.gotify id=0x7f080075)
      flags=0x210
      pri=0
      key=10|com.github.gotify|-5|null|1010400
      seen=false
      groupKey=10|com.github.gotify|g:GOTIFY_GROUP_MESSAGES
      fullscreenIntent=null
      contentIntent=PendingIntent{f30f052: PendingIntentRecord{3e2a6e3 com.github.gotify startActivity (whitelist: 9e0cfe6:+30s0ms)}}
      deleteIntent=null
      number=0
      groupAlertBehavior=2
      tickerText=...
      contentView=null
      bigContentView=null
      headsUpContentView=null
      color=0xff3f51b5
      timeout=unknown
      extras={
          android.title=String
          android.reduced.images=Boolean (true)
          android.subText=null
          android.showChronometer=Boolean (false)
          android.text=String
          android.progress=Integer (0)
          android.progressMax=Integer (0)
          android.appInfo=ApplicationInfo (ApplicationInfo{27b7f23 com.github.gotify})
          android.showWhen=Boolean (true)
          android.largeIcon=null
          android.infoText=null
          android.progressIndeterminate=Boolean (false)
          android.remoteInputHistory=null
      }

Main User NotificationRecord:

NotificationRecord(0x0f86aa95: pkg=com.github.gotify user=UserHandle{0} id=-5 tag=null importance=4 key=0|com.github.gotify|-5|null|10400appImportanceLocked=false: Notification(channel=gotify_messages_high_importance pri=0 contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x210 color=0xff3f51b5 groupKey=GOTIFY_GROUP_MESSAGES vis=PRIVATE))
      uid=10400 userId=0
      opPkg=com.github.gotify
      icon=Icon(typ=RESOURCE pkg=com.github.gotify id=0x7f080075)
      flags=0x210
      pri=0
      key=0|com.github.gotify|-5|null|10400
      seen=false
      groupKey=0|com.github.gotify|g:GOTIFY_GROUP_MESSAGES
      fullscreenIntent=null
      contentIntent=PendingIntent{88e37aa: PendingIntentRecord{290be0a com.github.gotify startActivity (whitelist: 9e0cfe6:+30s0ms)}}
      deleteIntent=null
      number=0
      groupAlertBehavior=2
      tickerText=...
      contentView=null
      bigContentView=null
      headsUpContentView=null
      color=0xff3f51b5      
      timeout=unknown
      extras={
          android.title=String
          android.reduced.images=Boolean (true)
          android.subText=null
          android.showChronometer=Boolean (false)
          android.text=String
          android.progress=Integer (0)
          android.progressMax=Integer (0)
          android.appInfo=ApplicationInfo (ApplicationInfo{ffaf9b com.github.gotify})
          android.showWhen=Boolean (true)
          android.largeIcon=null
          android.infoText=null
          android.progressIndeterminate=Boolean (false)
          android.remoteInputHistory=null
      }

Looking at the flags and extras I can not see a real difference other than the userId (0 is the main user, 10 is the work profile).

This indicates in conjunction with the following statement from the Android documentation that there is no additional work on our side to support work profiles.

By default, all personal profile apps receive callbacks but an IT admin can allowlist one or more personal profile apps that they allow to listen for notification changes. The system then blocks non-allowlisted apps.

The two remaining possibilities are that:

  1. The ROM does not follow the behavior described in the Android documentation (Since the ROM of the user on IRC is LineageOS 16, this is unlikely)
  2. There is a Device Policy that prohibits NotificationListeners from seeing the notifications from work profile apps. The only non-root workaround would be to get whitelisted in the policy.

I think it is more likely that there is an issue with notifications from the specific app in general (e.g. #34 , #54 ,...) that is unrelated to work profiles.

T-vK commented 3 years ago

Thank you for all the testing! The app that is problematic for me is WhatsApp (installed inside of Shelter). It doesn't even show up in the Notification Settings of the Asteroid Sync app. Is there a way to see the Device Policies?

jrtberlin commented 3 years ago

@T-vK There is dumpsys device_policy and dpm to get info about profiles, users and their set policies.

vanitasvitae commented 3 years ago

In my experience notifications are delivered as vibrations, but they are not delivered as watch notifications.

Unb0rn commented 2 years ago

Yep, would be nice to have this implemented. It seems it's impossible to control media players running in work profile with Asteroid Music app...