summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Carmen Jackson <carmenjackson@google.com> 2018-07-20 16:43:09 -0700
committer Carmen Jackson <carmenjackson@google.com> 2018-07-24 15:50:44 -0700
commit879fb6886b1917179deda95a9f0ceff20ad82c8a (patch)
tree5f776a22ecca6049c682e8fec9622449bdd756f4
parentaa7766b4d4990bc80764f942ee49ad7ba8d6334b (diff)
Try harder to find a camera app to pin.
Currently, the pinner service pins whatever Camera app is being pointed to by MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA. This change updates that logic to try pinning whatever is in MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE if the first intent doesn't exist. If neither of those resolve to a single target, this change reviews the targets in MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA and pins the Camera app with the System flag, making the assumption that the System app is the one that we'd want to pin if the user hasn't resolved the intent manually. Bug: 111655213 Test: Results show from just after boot, with logging added to ensure all code paths are covered Two camera apps installed (Snapchat chosen by manually resolving the double-tap intent). Two launchers installed (Nova Launcher chosen by selecting it in Settings) 07-24 21:45:38.014 1158 6329 E carmen : getting application info for intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x100 } defaultToSystemApp false 07-24 21:45:38.014 1158 6329 E carmen : only one app for this intent: ResolveInfo{f871a08 com.teslacoilsw.launcher/.NovaLauncher m=0x108000} 07-24 21:45:38.014 1158 6329 E carmen : getting application info for intent: Intent { act=android.media.action.STILL_IMAGE_CAMERA } defaultToSystemApp false 07-24 21:45:38.014 1158 6329 E carmen : only one app for this intent: ResolveInfo{a4b5a1 com.snapchat.android/.LandingPageActivity m=0x108000} $ adb shell dumpsys pinner Camera uid=10162 active=false /data/app/com.snapchat.android-TXaPziuyDrKJhSP_OsPBhQ==/base.apk 76214272 /data/app/com.snapchat.android-TXaPziuyDrKJhSP_OsPBhQ==/oat/arm/base.vdex 57143296 /data/app/com.snapchat.android-TXaPziuyDrKJhSP_OsPBhQ==/oat/arm/base.odex 1462272 Home uid=10160 active=false /data/app/com.teslacoilsw.launcher-RxwR4RYHwo8fCUIe3yRTtA==/base.apk 6291456 /data/app/com.teslacoilsw.launcher-RxwR4RYHwo8fCUIe3yRTtA==/oat/arm64/base.vdex 5488640 /data/app/com.teslacoilsw.launcher-RxwR4RYHwo8fCUIe3yRTtA==/oat/arm64/base.odex 131072 Total size: 246603776 Two camera apps installed, neither resolved (double tapping power key shows disambiguation dialog). Two launchers installed (Pixel Launcher chosen by selecting it in Settings) Then reboot: 07-24 21:51:34.319 1186 6132 E carmen : getting application info for intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x100 } defaultToSystemApp false 07-24 21:51:34.319 1186 6132 E carmen : only one app for this intent: ResolveInfo{bb98d44 com.google.android.apps.nexuslauncher/.NexusLauncherActivity m=0x108000} 07-24 21:51:34.319 1186 6132 E carmen : getting application info for intent: Intent { act=android.media.action.STILL_IMAGE_CAMERA } defaultToSystemApp false 07-24 21:51:34.319 1186 6132 E carmen : returning null 07-24 21:51:34.319 1186 6132 E carmen : getting application info for intent: Intent { act=android.media.action.STILL_IMAGE_CAMERA_SECURE } defaultToSystemApp false 07-24 21:51:34.319 1186 6132 E carmen : only one app for this intent: ResolveInfo{da40e2d com.google.android.GoogleCamera/com.android.camera.SecureCameraActivity m=0x108000} $ adb shell dumpsys pinner Camera uid=10131 active=false /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/base.apk 70901760 /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/oat/arm64/base.vdex 12369920 /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/oat/arm64/base.odex 249856 Home uid=10059 active=false /system/priv-app/NexusLauncherPrebuilt/NexusLauncherPrebuilt.apk 5664768 /data/dalvik-cache/arm64/system@priv-app@NexusLauncherPrebuilt@NexusLauncherPrebuilt.apk@classes.vdex 36864 /data/dalvik-cache/arm64/system@priv-app@NexusLauncherPrebuilt@NexusLauncherPrebuilt.apk@classes.dex 90112 Total size: 189186048 Commenting out the _SECURE intent check, with two camera apps and neither one chosen: 07-24 22:18:31.314 1174 1198 E carmen : getting application info for intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x100 } defaultToSystemApp false 07-24 22:18:31.314 1174 1198 E carmen : only one app for this intent: ResolveInfo{e4399e1 com.google.android.apps.nexuslauncher/.NexusLauncherActivity m=0x108000} 07-24 22:18:31.350 1174 1198 E carmen : getting application info for intent: Intent { act=android.media.action.STILL_IMAGE_CAMERA } defaultToSystemApp false 07-24 22:18:31.351 1174 1198 E carmen : returning null 07-24 22:18:31.351 1174 1198 E carmen : getting application info for intent: Intent { act=android.media.action.STILL_IMAGE_CAMERA } defaultToSystemApp true 07-24 22:18:31.351 1174 1198 E carmen : multiple apps for this intent, choosing system app: ApplicationInfo{845c229 com.google.android.GoogleCamera} $ adb shell dumpsys pinner Camera uid=10131 active=false /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/base.apk 70901760 /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/oat/arm64/base.vdex 11657216 /data/app/com.google.android.GoogleCamera-03j4UhJ73NQ42OkVl_VgHw==/oat/arm64/base.odex 397312 Home uid=10059 active=true /system/priv-app/NexusLauncherPrebuilt/NexusLauncherPrebuilt.apk 5664768 /data/dalvik-cache/arm64/system@priv-app@NexusLauncherPrebuilt@NexusLauncherPrebuilt.apk@classes.vdex 36864 /data/dalvik-cache/arm64/system@priv-app@NexusLauncherPrebuilt@NexusLauncherPrebuilt.apk@classes.dex 90112 Total size: 188616704 Change-Id: Ib90c91ac394adf269aaa8d3603af84a9ad4375f9
-rw-r--r--services/core/java/com/android/server/PinnerService.java68
1 files changed, 57 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index f5b29e9b76b8..a05a3e767d12 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -69,6 +69,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
import java.util.ArrayList;
import java.util.zip.ZipFile;
@@ -345,31 +346,76 @@ public final class PinnerService extends SystemService {
}
private ApplicationInfo getCameraInfo(int userHandle) {
- // find the camera via an intent
- // use INTENT_ACTION_STILL_IMAGE_CAMERA instead of _SECURE. On a
- // device without a fbe enabled, the _SECURE intent will never get set.
Intent cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
- return getApplicationInfoForIntent(cameraIntent, userHandle);
+ ApplicationInfo info = getApplicationInfoForIntent(cameraIntent, userHandle,
+ false /* defaultToSystemApp */);
+
+ // If the STILL_IMAGE_CAMERA intent doesn't resolve, try the _SECURE intent.
+ // We don't use _SECURE first because it will never get set on a device
+ // without File-based Encryption. But if the user has only set the intent
+ // before unlocking their device, we may still be able to identify their
+ // preference using this intent.
+ if (info == null) {
+ cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
+ info = getApplicationInfoForIntent(cameraIntent, userHandle,
+ false /* defaultToSystemApp */);
+ }
+
+ // If the _SECURE intent doesn't resolve, try the original intent but request
+ // the system app for camera if there was more than one result.
+ if (info == null) {
+ cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ info = getApplicationInfoForIntent(cameraIntent, userHandle,
+ true /* defaultToSystemApp */);
+ }
+ return info;
}
private ApplicationInfo getHomeInfo(int userHandle) {
Intent intent = mAmInternal.getHomeIntent();
- return getApplicationInfoForIntent(intent, userHandle);
+ return getApplicationInfoForIntent(intent, userHandle, false);
}
- private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle) {
+ private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle,
+ boolean defaultToSystemApp) {
if (intent == null) {
return null;
}
- ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(intent,
+
+ ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivityAsUser(intent,
MATCH_FLAGS, userHandle);
- if (info == null) {
+
+ // If this intent can resolve to only one app, choose that one.
+ // Otherwise, if we've requested to default to the system app, return it;
+ // if we have not requested that default, return null if there's more than one option.
+ // If there's more than one system app, return null since we don't know which to pick.
+ if (resolveInfo == null) {
return null;
}
- if (isResolverActivity(info.activityInfo)) {
- return null;
+
+ if (!isResolverActivity(resolveInfo.activityInfo)) {
+ return resolveInfo.activityInfo.applicationInfo;
+ }
+
+ if (defaultToSystemApp) {
+ List<ResolveInfo> infoList = mContext.getPackageManager()
+ .queryIntentActivitiesAsUser(intent, MATCH_FLAGS, userHandle);
+ ApplicationInfo systemAppInfo = null;
+ for (ResolveInfo info : infoList) {
+ if ((info.activityInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if (systemAppInfo == null) {
+ systemAppInfo = info.activityInfo.applicationInfo;
+ } else {
+ // If there's more than one system app, return null due to ambiguity.
+ return null;
+ }
+ }
+ }
+ return systemAppInfo;
}
- return info.activityInfo.applicationInfo;
+
+ return null;
}
private void sendPinAppsMessage(int userHandle) {