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

Commit 04f6997c authored by Charles Chen's avatar Charles Chen Committed by Automerger Merge Worker
Browse files

Merge "Forward the TaskFragment info in IntentSender" into tm-qpr-dev am: 9e76e357 am: 439458f4

parents e2fdbeff 439458f4
Loading
Loading
Loading
Loading
+48 −4
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService;
import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult;

/**
 * A class that contains activity intercepting logic for {@link ActivityStarter#startActivityLocked}
 * A class that contains activity intercepting logic for {@link ActivityStarter#execute()}
 * It's initialized via setStates and interception occurs via the intercept method.
 *
 * Note that this class is instantiated when {@link ActivityManagerService} gets created so there
@@ -104,6 +105,7 @@ class ActivityStartInterceptor {
    ActivityInfo mAInfo;
    String mResolvedType;
    Task mInTask;
    TaskFragment mInTaskFragment;
    ActivityOptions mActivityOptions;

    ActivityStartInterceptor(
@@ -135,15 +137,46 @@ class ActivityStartInterceptor {
    }

    private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) {
        Bundle activityOptions = deferCrossProfileAppsAnimationIfNecessary();
        Bundle bOptions = deferCrossProfileAppsAnimationIfNecessary();
        final TaskFragment taskFragment = getLaunchTaskFragment();
        // If the original intent is going to be embedded, try to forward the embedding TaskFragment
        // and its task id to embed back the original intent.
        if (taskFragment != null) {
            ActivityOptions activityOptions = bOptions != null
                    ? ActivityOptions.fromBundle(bOptions)
                    : ActivityOptions.makeBasic();
            activityOptions.setLaunchTaskFragmentToken(taskFragment.getFragmentToken());
            bOptions = activityOptions.toBundle();
        }
        final IIntentSender target = mService.getIntentSenderLocked(
                INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId,
                null /*token*/, null /*resultCode*/, 0 /*requestCode*/,
                new Intent[] { mIntent }, new String[] { mResolvedType },
                flags, activityOptions);
                flags, bOptions);
        return new IntentSender(target);
    }


    /**
     * A helper function to obtain the targeted {@link TaskFragment} during
     * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int,
     * ActivityOptions)} if any.
     */
    @Nullable
    private TaskFragment getLaunchTaskFragment() {
        if (mInTaskFragment != null) {
            return mInTaskFragment;
        }
        if (mActivityOptions == null) {
            return null;
        }
        final IBinder taskFragToken = mActivityOptions.getLaunchTaskFragmentToken();
        if (taskFragToken == null) {
            return null;
        }
        return TaskFragment.fromTaskFragmentToken(taskFragToken, mService);
    }

    /**
     * Intercept the launch intent based on various signals. If an interception happened the
     * internal variables get assigned and need to be read explicitly by the caller.
@@ -151,7 +184,8 @@ class ActivityStartInterceptor {
     * @return true if an interception occurred
     */
    boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType,
            Task inTask, int callingPid, int callingUid, ActivityOptions activityOptions) {
            Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid,
            ActivityOptions activityOptions) {
        mUserManager = UserManager.get(mServiceContext);

        mIntent = intent;
@@ -161,6 +195,7 @@ class ActivityStartInterceptor {
        mAInfo = aInfo;
        mResolvedType = resolvedType;
        mInTask = inTask;
        mInTaskFragment = inTaskFragment;
        mActivityOptions = activityOptions;

        if (interceptQuietProfileIfNeeded()) {
@@ -332,12 +367,21 @@ class ActivityStartInterceptor {
        mCallingPid = mRealCallingPid;
        mCallingUid = mRealCallingUid;
        mResolvedType = null;
        final TaskFragment taskFragment = getLaunchTaskFragment();
        // If we are intercepting and there was a task, convert it into an extra for the
        // ConfirmCredentials intent and unassign it, as otherwise the task will move to
        // front even if ConfirmCredentials is cancelled.
        if (mInTask != null) {
            mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId);
            mInTask = null;
        } else if (taskFragment != null) {
            // If the original intent is started to an embedded TaskFragment, append its parent task
            // id to extra. It is to embed back the original intent to the TaskFragment with the
            // same task.
            final Task parentTask = taskFragment.getTask();
            if (parentTask != null) {
                mIntent.putExtra(EXTRA_TASK_ID, parentTask.mTaskId);
            }
        }
        if (mActivityOptions == null) {
            mActivityOptions = ActivityOptions.makeBasic();
+2 −2
Original line number Diff line number Diff line
@@ -1060,8 +1060,8 @@ class ActivityStarter {

        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
                callingFeatureId);
        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
                callingUid, checkedOptions)) {
        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
                callingPid, callingUid, checkedOptions)) {
            // activity start was intercepted, e.g. because the target user is currently in quiet
            // mode (turn off work) or the target application is suspended
            intent = mInterceptor.mIntent;
+11 −11
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest {
                .thenReturn(PLATFORM_PACKAGE_NAME);

        // THEN calling intercept returns true
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));

        // THEN the returned intent is the admin support intent
        assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent);
@@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest {
        final String suspendingPackage = "com.test.suspending.package";
        final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage);
        // THEN calling intercept returns true
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));

        // Check intent parameters
        assertEquals(dialogInfo,
@@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest {
                TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT))
                .thenReturn(false);

        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));

        assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME)
                .filterEquals(mInterceptor.mIntent));
@@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest {
        when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);

        // THEN calling intercept returns true
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null,  null, 0, 0, null));

        // THEN the returned intent is the quiet mode intent
        assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
@@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest {
        when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);

        // THEN calling intercept returns true
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));

        // THEN the returned intent is the quiet mode intent
        assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
@@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest {
        when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);

        // THEN calling intercept returns true
        mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null);
        mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null);

        // THEN the returned intent is the quiet mode intent
        assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent));
@@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest {
                .thenReturn("This app is bad");

        // THEN calling intercept returns true
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));

        // THEN the returned intent is the harmful app warning intent
        assertEquals(HarmfulAppWarningActivity.class.getName(),
@@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest {
        // GIVEN that none of the interception conditions are met

        // THEN calling intercept returns false
        assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));
    }

    public void addMockInterceptorCallback(
@@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest {
                new Intent("android.test.foo"),
                ActivityOptions.makeBasic().setLaunchDisplayId(3));

        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));
        assertEquals("android.test.foo", mInterceptor.mIntent.getAction());
        assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId());
    }
@@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest {
    public void testInterceptionCallback_singleCallbackReturnsNull() {
        addMockInterceptorCallback(null, null);

        assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));
    }

    @Test
@@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest {
        addMockInterceptorCallback(null, null);
        addMockInterceptorCallback(new Intent("android.test.second"), null);

        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null));
        assertEquals("android.test.second", mInterceptor.mIntent.getAction());
    }