Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7fea166 authored by Clara Bayarri's avatar Clara Bayarri
Browse files

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
parent 243336b3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3457,6 +3457,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}.
+46 −0
Original line number Diff line number Diff line
@@ -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,