android / health-samples

Apache License 2.0
248 stars 142 forks source link

Missing permissions on targetSdk 33 #212

Open dharmraj2018 opened 6 months ago

dharmraj2018 commented 6 months ago

FATAL EXCEPTION: main Process: com.example.exercise, PID: 13281 java.lang.SecurityException: Missing permissions at androidx.health.services.client.impl.internal.StatusCallback.onFailure(StatusCallback.kt:43) at androidx.health.services.client.impl.internal.IStatusCallback$Stub.onTransact(IStatusCallback.java:74) at android.os.Binder.execTransactInternal(Binder.java:1285) at android.os.Binder.execTransact(Binder.java:1244) Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@d760ae4, Dispatchers.Main.immediate]

yschimke commented 6 months ago

I think I know how it's happening, but could you add some text to explain how to reproduce apart from the stacktrace.

dharmraj2018 commented 6 months ago

I have run this demo on a Samsung Watch 5, (Android OS version 13, and Wear OS version 4.0) and give all permissions after that just click on to Start button

yschimke commented 6 months ago

OK, it's working on emulator if you grant all permissions. But does fail if you deny.

So looks like a different issue than I guessed.

dharmraj2018 commented 6 months ago

Please see the video... I have given all permission but not working on actual watch

https://github.com/android/health-samples/assets/134904942/e5b4591d-9acf-4389-bc88-5c945d6a4a51

ithinkihaveacat commented 6 months ago

@dharmraj2018 Thanks for the video. I can't reproduce on Pixel Watch 2 or the API 33 emulator. I don't have access to GW4 at the moment. Can you share your Health Services version?

$ adb shell dumpsys package com.google.android.wearable.healthservices | grep versionCode
    versionCode=1443860 minSdk=30 targetSdk=33
    versionCode=1405199 minSdk=30 targetSdk=33
dharmraj2018 commented 6 months ago

Hi @ithinkihaveacat please check the version. let me know if anything needs to upgrade version. versionCode=1388651 minSdk=30 targetSdk=33

yschimke commented 6 months ago

@ithinkihaveacat I think there are multiple parts here

1) Why it's failing on GW 2) Catching the failure and showing an error 3) detecting/explaining which permissions are needed proactively

ithinkihaveacat commented 6 months ago

I'm having trouble reproducing the behavior shown in the video at https://github.com/android/health-samples/issues/212#issuecomment-1880880994.

Things I tried:

yschimke commented 6 months ago

Linking here the docs for which permissions are needed - https://developer.android.com/health-and-fitness/guides/health-services/permissions

dharmraj2018 commented 6 months ago

Hi @yschimke @ithinkihaveacat do you have any updates for me?

ithinkihaveacat commented 6 months ago

@dharmraj2018 I'm struggling to reproduce this :-(. Tried another GW device just now and it works just fine. (Granting all permissions for now, as in https://github.com/android/health-samples/issues/212#issuecomment-1880880994.) It also works on the emulator. Can you reproduce on a different device?

dharmraj2018 commented 6 months ago

Hi @ithinkihaveacat , I have been able to run the app on the simulator successfully. However, I'm encountering issues when trying to run it on actual Samsung Watch 4 and 5 devices with the latest software version. Previously, it was working fine, but after updating the watch to One UI 5.0 (System version: 13 and Wear OS version 4.0), the app is not functioning properly, and I'm experiencing the same crash. Please assist in resolving this issue.

amankhoza commented 6 months ago

@dharmraj2018 can you post the results of this command:

adb shell dumpsys package com.example.exercise | grep -i -C10 "permissions"

Double check that the package is actually com.example.exercise, change it if its different.

amankhoza commented 6 months ago

@dharmraj2018 I think this should solve your issue #223, looks like the exercise sample was missing the POST_NOTIFICATION permission, you only need to request this on Wear 4, which explains why you only say this after updating, see: https://developer.android.com/training/wearables/versions/4/changes#notification-permission

yschimke commented 6 months ago

I'm unclear how this manifest as

java.lang.SecurityException: Missing permissions
at androidx.health.services.client.impl.internal.StatusCallback.onFailure(StatusCallback.kt:43)

If really required, we should add to https://developer.android.com/health-and-fitness/guides/health-services/permissions

dharmraj2018 commented 6 months ago

Hi @amankhoza please check the results of this given command:

$ adb shell dumpsys package com.example.exercise | grep -i -C10 "permissions"
          Action: "androidx.work.impl.background.systemalarm.UpdateProxies"

Service Resolver Table:
  Non-Data Actions:
      hs.versionclient.BIND:
        4d29d7e com.example.exercise/androidx.health.services.client.VersionApiService filter 71da2df permission com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING
          Action: "hs.versionclient.BIND"

Domain verification status:

Permissions:
  Permission [com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION] (3e988d):
    sourcePackage=com.example.exercise
    uid=10040 gids=[] type=0 prot=signature
    perm=PermissionInfo{b7fa1cb com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION}

Registered ContentProviders:
  com.example.exercise/androidx.startup.InitializationProvider:
    Provider{6a5eda8 com.example.exercise/androidx.startup.InitializationProvider}

ContentProvider Authorities:
--
--
      com.google.android.wearable
    usesOptionalLibraries:
      androidx.window.extensions
      androidx.window.sidecar
    usesLibraryFiles:
      /system/framework/com.google.android.wearable.jar
    timeStamp=2024-01-15 17:11:36
    lastUpdateTime=2024-01-15 17:11:36
    packageSource=0
    signatures=PackageSignatures{a403c54 version:2, signatures:[fce376d4], past signatures:[]}
    installPermissionsFixed=true
    pkgFlags=[ TEST_ONLY ]
--
    pkgFlags=[ TEST_ONLY ]
    declared permissions:
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION: prot=signature, INSTALLED
--
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION: prot=signature, INSTALLED
    requested permissions:
      android.permission.BODY_SENSORS
      android.permission.ACCESS_FINE_LOCATION
      android.permission.ACTIVITY_RECOGNITION
      android.permission.WAKE_LOCK
      android.permission.FOREGROUND_SERVICE
      android.permission.ACCESS_NETWORK_STATE
      android.permission.RECEIVE_BOOT_COMPLETED
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
      android.permission.ACCESS_COARSE_LOCATION
--
      android.permission.BODY_SENSORS
      android.permission.ACCESS_FINE_LOCATION
      android.permission.ACTIVITY_RECOGNITION
      android.permission.WAKE_LOCK
      android.permission.FOREGROUND_SERVICE
      android.permission.ACCESS_NETWORK_STATE
      android.permission.RECEIVE_BOOT_COMPLETED
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
      android.permission.ACCESS_COARSE_LOCATION
    install permissions:
      android.permission.FOREGROUND_SERVICE: granted=true
      android.permission.RECEIVE_BOOT_COMPLETED: granted=true
      android.permission.ACCESS_NETWORK_STATE: granted=true
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION: granted=true
      android.permission.WAKE_LOCK: granted=true
    User 0: ceDataInode=17960 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
      installReason=0
      firstInstallTime=2024-01-15 17:11:36
      uninstallReason=0
--
      android.permission.FOREGROUND_SERVICE: granted=true
      android.permission.RECEIVE_BOOT_COMPLETED: granted=true
      android.permission.ACCESS_NETWORK_STATE: granted=true
      com.example.exercise.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION: granted=true
      android.permission.WAKE_LOCK: granted=true
    User 0: ceDataInode=17960 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
      installReason=0
      firstInstallTime=2024-01-15 17:11:36
      uninstallReason=0
      runtime permissions:
        android.permission.ACCESS_FINE_LOCATION: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED|524288]
        android.permission.BODY_SENSORS: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.ACCESS_COARSE_LOCATION: granted=true, flags=[ USER_SET|REVOKE_WHEN_REQUESTED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
        android.permission.ACTIVITY_RECOGNITION: granted=true, flags=[ USER_SET|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
      enabledComponents:
        androidx.work.impl.background.systemjob.SystemJobService

Queries:
  system apps queryable: false
  queries via forceQueryable:
yschimke commented 6 months ago

Is our sample missing BODY_SENSORS_BACKGROUND ?

Also discussed https://github.com/android/health-samples/issues/101 and https://github.com/android/health-samples/issues/190

amankhoza commented 6 months ago

@dharmraj2018 I was going to suggest the same as @yschimke, looking at the permissions you've mentioned in https://github.com/android/health-samples/issues/212#issuecomment-1916071696 the only one missing from https://developer.android.com/health-and-fitness/guides/health-services/permissions is BODY_SENSORS_BACKGROUND. This should only be necessary if you're using a PassiveMonitoring client or want to collect sensor data in the background, but regardless, try adding it to the REQUIRED_PERMISSIONS array in app/src/main/java/com/example/exercise/PrepareFragment.kt, and let's see if that works.

dharmraj2018 commented 6 months ago

Hi @amankhoza I already checked with having permission for BODY_SENSORS_BACKGROUND still crashing the same issue although Google Pixel Watch 2 is working fine without this permission. The problem is only with the Samsung watch One UI 5.0

amankhoza commented 6 months ago

Ok @dharmraj2018 a few more ideas:

1) Open the app, grant all permissions, but before clicking start, in a new terminal, run the following command:

adb logcat | grep -i WHS_PermissionPolicy

Now click start and see what is printed in the logcat, this might help us narrow down if the app is losing a permission at runtime. Paste the results back here.

2) Let's try updating Wear Health Services, to see if this is an issue that has already been fixed. Run the following command to open the playstore listing for WHS, since you're on an old version there should be an update available. Install it then run the following command to see the new version:

adb shell dumpsys package com.google.android.wearable.healthservices | grep versionCode

Report the new versionCode here, then repeat steps in 1)

3) Maybe there's a new system update available for your device in which this bug has been fixed. Check in your settings if this is the case, if there is an update, install it, rerun the steps in 1) and post the version from settings here.

4) I noticed in your video, GPS is unavailable so this might be the problem permission, to rule it out first open Google maps, ensure you get a GPS fix for the watch and then rerun the app but ensure the Prepare fragment shows that GPS has been acquired. Once GPS has been acquired rerun steps in 1)

dharmraj2018 commented 5 months ago

Thanks, @amankhoza! I've identified the issue; it seems that GPS was not enabled, leading to the crash on the Samsung watch. I resolved the problem by enabling the location before starting an exercise, and now the crash has been fixed.

yschimke commented 5 months ago

That sounds like a bug we could easily reproduce and fix.

monteiro-renato commented 5 months ago

Hello :wave: I had a similar issue today with a different setup. I'm running Wear OS 3.5 on a TicWatch Pro 3 Ultra. I was following the docs but instead of only trying out the HR functionality, I tried all the available options. i.e. instead of:

val passiveListenerConfig = PassiveListenerConfig.builder()
    .setDataTypes(setOf(DataType.HEART_RATE_BPM))
    .build()

I configured:

val passiveListenerConfig = PassiveListenerConfig.builder()
                .setDataTypes(
                    passiveMonitoringClient.getCapabilities()
                        .supportedDataTypesPassiveMonitoring
                )
                .build()

While running the app I ended up with:

FATAL EXCEPTION: main
Process: x.y.z, PID: 6446
java.lang.SecurityException: Missing permissions
at androidx.health.services.client.impl.internal.StatusCallback.onFailure(StatusCallback.kt:43)
at androidx.health.services.client.impl.internal.IStatusCallback$Stub.onTransact(IStatusCallback.java:74)
at android.os.Binder.execTransactInternal(Binder.java:1159)
at android.os.Binder.execTransact(Binder.java:1123)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@d8e3de1, Dispatchers.Main.immediate]

After looking into health-services permissions I noticed I was missing the ACTIVITY_RECOGNITION permission. It would be nice if the exception could drive the user towards the solution.

amankhoza commented 5 months ago

@monteiro-renato improving the exception has been raised internally, feel free to raise it as a public issue here if you want to keep track or get others to upvote etc. https://issuetracker.google.com/issues/new?component=1056301&template=1581114

In terms of the crash, I added a PR to prevent it for ExerciseSampleCompose in https://github.com/android/health-samples/pull/231, something similar can probably be done for ExerciseSample.