Home > Mobile >  Implementing STILL_IMAGE_CAPTURE_SECURE on Android 12
Implementing STILL_IMAGE_CAPTURE_SECURE on Android 12

Time:11-05

I'm currently trying to implement STILL_IMAGE_CAPTURE_SECURE intent for my camera app. (A intent that gets triggered when the power button is double tapped in secure mode)

I have added WAKE_LOCK and DISABLE_KEYGUARD permissions in the manifest file and set showOnLockScreen and showOnLockScreen to true for that activity.

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

<!-- [...] -->

<activity
            android:name=".ui.activities.SecureMainActivity"
            android:taskAffinity=".ui.activities.SecureMainActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
            android:screenOrientation="nosensor"
            android:showWhenLocked="true"
            android:showOnLockScreen="true"
            android:excludeFromRecents="true"
            android:exported="true">

            <intent-filter>
                <action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </activity>

We have tested our app on Android 11 (AOSP) and double tapping to open camera in lock screen works fine/as expected there (our app is visible along with other apps that implement this intent such as Google Camera in an Intent Chooser) but however in Android 12 (AOSP) Google Camera directly gets triggered (which implicitly means that our app isn't being considered for the intent).

If Google Camera isn't installed, nothing really gets triggered.

What could possibly could possibly cause this unexpected behavior?

CodePudding user response:

As per the 'How double-click power launches the camera' guide:

  • Note that starting in Android 12, as required by some OEMs, if the special string resource config_cameraGesturePackage is nonempty, this will be treated as a package name to be added to the insecure camera intent, constraining the invocation to that single app and typically preventing implicit intent resolution. This package must be on the device or the camera gesture will no longer work properly.

As explained in the commit that added this code:

Using an implicit intent at the moment of picture-taking usually goes unnoticed. But immediately after installing a new camera, this behavior becomes incredibly frustrating to users as they are presented with a puzzling resolver dialog (or in the case of the secure camera, the authenticator). And if, at this moment, the user chooses to make one of the options a default, it's almost impossible to figure out how to change this setting.

As a result, many OEMs simply hardcode the camera gesture to launch a specific preinstalled camera, but this is poorly supported by AOSP, leading to duplicate implementations and bugs. This patch routes all camera intents in System UI through a single utility class, creating a convenient spot to insert a resource that contains the OEM's default preinstalled camera app.

It goes on to explain how to determine what intents are fired when this action is performed:

Bugreport/dumpsys output to look for:

$ adb shell dumpsys activity service com.android.systemui | grep -C3 'Camera gesture' | tail -3
    Camera gesture intents:
      Insecure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA }
      Secure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA_SECURE flg=0x800000 }
      Override package: null

By looking at the "Override package", you can see if a particular camera package, such as the one associated with the Google Camera app, is defined as the only camera that can handle this intent. If that is the case, then it is expected that your app will never be able to handle that intent on that particular device.

Of course, if you are an OEM and controlling the resource overlay on your own device, you would want to update the config_cameraGesturePackage string resource to point to your custom camera app or leave it blank if you want to allow any camera app to handle this action.

  • Related