From f7fea166d40842fc5b55b2169d41df88136ae2cc Mon Sep 17 00:00:00 2001 From: Clara Bayarri Date: Thu, 22 Oct 2015 16:09:52 +0100 Subject: [PATCH] Intercept activity start with ConfirmCredentials When the calling user is a work profile and the device has file based encryption enabled, show the work challenge via the Confirm Credentials APIs before launching the requested activity. A companion CL in Settings will add support to the Confirm Credentials flow to read the given intent extra and fire it when the authorization succeeds. This is part of the Separate Work Challenge feature. Note nobody will see this yet as the feature is conditioned by file based encryption. Change-Id: I303890095936b1fd1f6a99d645724dffba144345 --- core/java/android/content/Intent.java | 7 ++++ .../android/server/am/ActivityStackSupervisor.java | 46 ++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index d7e94d0c8811..68b77fe78673 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3458,6 +3458,13 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_INTENT = "android.intent.extra.INTENT"; /** + * An int representing the user id to be used. + * + * @hide + */ + public static final String EXTRA_USER_ID = "android.intent.extra.USER_ID"; + + /** * An Intent[] describing additional, alternate choices you would like shown with * {@link #ACTION_CHOOSER}. * diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index f262ec9a1702..9389056e6a94 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -58,6 +58,7 @@ import android.app.IActivityContainer; import android.app.IActivityContainerCallback; import android.app.IActivityManager; import android.app.IApplicationThread; +import android.app.KeyguardManager; import android.app.PendingIntent; import android.app.ProfilerInfo; import android.app.ActivityManager.RunningTaskInfo; @@ -75,6 +76,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; @@ -97,10 +99,13 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.Trace; import android.os.TransactionTooLargeException; import android.os.UserHandle; +import android.os.UserManager; import android.os.WorkSource; +import android.os.storage.StorageManager; import android.provider.MediaStore; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -1662,6 +1667,38 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + UserInfo user = getUserInfo(userId); + // TODO: Timeout for work challenge + if (user.isManagedProfile() + && mService.mContext.getSystemService(StorageManager.class) + .isPerUserEncryptionEnabled()) { + KeyguardManager km = (KeyguardManager) mService.mContext + .getSystemService(Context.KEYGUARD_SERVICE); + + IIntentSender target = mService.getIntentSenderLocked( + ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, + Binder.getCallingUid(), userId, null, null, 0, new Intent[]{ intent }, + new String[]{ resolvedType }, + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT + | PendingIntent.FLAG_IMMUTABLE, null); + int flags = intent.getFlags(); + intent = km.createConfirmDeviceCredentialIntent(null, null); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName); + intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target)); + intent.putExtra(Intent.EXTRA_USER_ID, userId); + intent.setFlags(flags); + + resolvedType = null; + callingUid = realCallingUid; + callingPid = realCallingPid; + + UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId); + aInfo = resolveActivity(intent, null, PackageManager.MATCH_DEFAULT_ONLY + | ActivityManagerService.STOCK_PM_FLAGS, null, parent.id); + } + if (abort) { if (resultRecord != null) { resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, @@ -1725,6 +1762,15 @@ public final class ActivityStackSupervisor implements DisplayListener { return err; } + private UserInfo getUserInfo(int userId) { + final long identity = Binder.clearCallingIdentity(); + try { + return UserManager.get(mService.mContext).getUserInfo(userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, -- 2.11.0