Merge "Forward the TaskFragment info in IntentSender" into tm-qpr-dev
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user