androidandroid-cameraandroid-camera2android-11foreground-service

Start camera from foreground service if START_ACTIVITIES_FROM_BACKGROUND granted for the app (Android 11+)


My app process starts a foreground service when it receives BOOT_COMPLETED action

That service is for video recording (dashboard camera app) which uses camera and microphone.

To start a camera from a foreground service on Android 11+ one of the conditions must be met (Exemptions from the restrictions to starting a camera/micro from a foreground service) https://developer.android.com/guide/components/foreground-services#bg-access-restriction-exemptions

The only exception I can use is:

The service is started by an app that has the START_ACTIVITIES_FROM_BACKGROUND privileged permission.

This one doesn't require any interactions from a user, a user just wants a video recording to be started automatically when he starts driving his car, he doesn't want manually make app visible or start recording from a notification, he doesn't care about all of this, which is ok, it's 2021 and such things can be done automatically, but thanks Google for such restrictions in 2021, yes, we should care about safety of private personal data of a user, but they just could add BACKGROUND_CAMERA, BACKGROUND_RECORD_AUDIO permissions with manual review on Google Play Console like they did with ACCESS_BACKGROUND_LOCATION

If I understood correctly to get START_ACTIVITIES_FROM_BACKGROUND permission I must have one of the conditions be met (Exemptions from the restrictions to starting activities from the background) https://developer.android.com/guide/components/activities/background-starts#exceptions

So I chose SYSTEM_ALERT_WINDOW permission, because if it was granted by a user before then no interactions from the user is required and app can start an activity from background. This one can be granted with Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)

So do I have now START_ACTIVITIES_FROM_BACKGROUND permission granted or not? I don't understand...

If yes then I can use a camera in foreground service which was started from some background action

But still

fun isCameraAllowedForPackage(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val manager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val res = manager.unsafeCheckOpNoThrow(
            AppOpsManager.OPSTR_CAMERA,
            Process.myUid(),
            context.packageName
        )
         res == AppOpsManager.MODE_ALLOWED
    } else {
        true
    }
}

returns false for my Samsung S10 (Android 11) in foreground service before I try to use the camera

Why?

If I make app visible at least once (start an activity f the app) then foreground service can start the camera (this method returns true) even if the screen of the phone is turned off

I also tried to use Pixel Emulator (Android 11) and there is different behavour for this one - app can start using the camera by the foreground service which was started in background even without SYSTEM_ALERT_WINDOW permission. So I don't need any of that https://developer.android.com/guide/components/activities/background-starts#exceptions

I don't get it. Basically an Emulator doesn't follow those rules.

More about problems with my dashcam app

Recently I was receving reports from users of my app with the next message

android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1426: Caller "MY_APP_PACKAGE_NAME" (PID 10300, UID 29860) cannot open camera "0" when sensor privacy is enabled

or

Error happened during using Camera. android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): connectHelper:2198: Camera "2" disabled by policy

or

android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1416: Caller "MY_APP_PACKAGE_NAME" (PID 10376, UID 25653) cannot open camera "0" from background (calling UID 10376 proc state 8) App catches such errors when it tries to open the camera

A user can start recording manually from activity/notification/widget/floating window or recording can started automatically based on charging/Bluetooth/etc events (registered broadcast events within the foreground service for recording)

The foreground service WON'T start the recording if isCameraAllowedForPackage() returns false, no way, so it returns true in such cases and then app fails to open camera with CAMERA_DISABLED error, I don't get it.

I asked users about this issue, they answered it may happen some times (NOT ALWAYS, THEY DON'T SET ANY POLICY FOR THE CAMERA) when recording automatically starts/stops on charging/Bluetooth events. So of course the app on their phones can usually open the camera, it's allowed to be used, by seems sometimes the stupid operation system prevents app from using the camera, and I don't understand why, there is no any info about this case in restrictions I mentioned before. So for users app was working for a while without issues, they opened the activity of the app at least once (on Samsung Android 11+ they have to do it), so the foreground service 100% had the permission to use the camera but still then after some time this error happened for them.

It's a different issue. If it wasn't allowed for my app process then I would get such error

enter image description here

https://developer.android.com/guide/components/foreground-services#test-restrictions

Anyway I as I mentioned before I have a method to check if the camera is allowed to be used for my app process before I open it

There are so many problems with that. Phones (of different manufactures) behave differently. Some unexpected exceptions during using camera.

So basically even if everything was taken into account, for example, a user started the launch activity of the app, which starts the foreground service, in this case foreground is now allowed to use the camera, but still some issues with opening camera can happen while the same foreground service was running for some time


Solution

  • So do I have now START_ACTIVITIES_FROM_BACKGROUND permission granted or not?

    No. That permission is defined in the framework as:

        <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
            android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" />
    

    To hold it, you need to request it in the manifest of your app, and your app needs to be part of the firmware build (or be installed on the privileged partition by a user of a rooted device).

    If I understood correctly to get START_ACTIVITIES_FROM_BACKGROUND permission I must have one of the conditions must be met (Exemptions from the restrictions to starting activities from the background) https://developer.android.com/guide/components/activities/background-starts#exceptions

    That page does not refer to that permission.