From ee82f8fa2d47fc1dbfc29582ae348b3c45ff8fe0 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Mon, 1 Oct 2012 16:26:18 -0700 Subject: [PATCH] Fix camera disambiguation in secure keyguard When there are multiple activities that respond to MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE we need to show the disambiguation dialog to the user. However the disambiguation "dialog" is actully an activity themed as a dialog. Hence, we can't show it in the secure keyguard. This works around the issue by prompting the user for their credentials directly when the intent needs disambiguation. This will take them out of keyguard and prompt them for which activity they want to use. We'll provide a more robust solution in a future release. Fixes bug 7109816 Change-Id: I94e643d3cb503e1ce6de24c82400b4d5fcbb9d95 --- .../internal/widget/LockPatternUtils.java | 10 +++--- .../impl/keyguard/KeyguardFaceUnlockView.java | 3 +- .../impl/keyguard/KeyguardSelectorView.java | 35 +++++++++++++++++-- .../impl/keyguard/KeyguardViewMediator.java | 2 ++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 84e1d95a9385d..f987fc55704db 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -125,7 +125,9 @@ public class LockPatternUtils { private final ContentResolver mContentResolver; private DevicePolicyManager mDevicePolicyManager; private ILockSettings mLockSettingsService; - private int mCurrentUserId = UserHandle.USER_NULL; + + // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils. + private static volatile int sCurrentUserId = UserHandle.USER_NULL; public DevicePolicyManager getDevicePolicyManager() { if (mDevicePolicyManager == null) { @@ -215,13 +217,13 @@ public class LockPatternUtils { } public void setCurrentUser(int userId) { - mCurrentUserId = userId; + sCurrentUserId = userId; } public int getCurrentUser() { - if (mCurrentUserId != UserHandle.USER_NULL) { + if (sCurrentUserId != UserHandle.USER_NULL) { // Someone is regularly updating using setCurrentUser() use that value. - return mCurrentUserId; + return sCurrentUserId; } try { return ActivityManagerNative.getDefault().getCurrentUser().id; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java index 592281086e111..8776a80c48f1d 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java @@ -153,7 +153,8 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu if (mBiometricUnlock != null) { mBiometricUnlock.stop(); } - mLockPatternUtils.setCurrentUser(userId); + // No longer required; static value set by KeyguardViewMediator + // mLockPatternUtils.setCurrentUser(userId); } }; diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java index 8714276b55419..6de65b0841cb7 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java @@ -23,6 +23,8 @@ import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.RemoteException; import android.os.UserHandle; import android.provider.MediaStore; @@ -38,6 +40,8 @@ import com.android.internal.widget.multiwaveview.GlowPadView; import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener; import com.android.internal.R; +import java.util.List; + public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView { private static final boolean DEBUG = KeyguardHostView.DEBUG; private static final String TAG = "SecuritySelectorView"; @@ -116,12 +120,39 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri this(context, null); } + private boolean wouldLaunchResolverActivity(Intent intent) { + PackageManager packageManager = mContext.getPackageManager(); + ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, + PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser()); + final List appList = packageManager.queryIntentActivitiesAsUser( + intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser()); + // If the list contains the above resolved activity, then it can't be + // ResolverActivity itself. + for (int i = 0; i < appList.size(); i++) { + ResolveInfo tmp = appList.get(i); + if (tmp.activityInfo.name.equals(resolved.activityInfo.name) + && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { + return false; + } + } + return true; + } + protected void launchCamera() { if (mLockPatternUtils.isSecure()) { // Launch the secure version of the camera - Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); + final Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - launchActivity(intent, true); + + if (wouldLaunchResolverActivity(intent)) { + // TODO: Show disambiguation dialog instead. + // For now, we'll treat this like launching any other app from secure keyguard. + // When they do, user sees the system's ResolverActivity which lets them choose + // which secure camera to use. + launchActivity(intent, false); + } else { + launchActivity(intent, true); + } } else { // Launch the normal camera launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA), false); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java index 212a6bb72f276..e4c1214b1961e 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java @@ -907,6 +907,8 @@ public class KeyguardViewMediator { /** * Update the newUserId. Call while holding WindowManagerService lock. + * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing. + * * @param newUserId The id of the incoming user. */ public void setCurrentUser(int newUserId) {