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

Commit 9e76e357 authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Forward the TaskFragment info in IntentSender" into tm-qpr-dev

parents 4c542314 f2c23a11
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());
    }