Merge "Forward the TaskFragment info in IntentSender" into tm-qpr-dev am: 9e76e35728
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19033640 Change-Id: I8167628bf18ef84e35d6f43eee019c21e7d1076d Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -49,6 +49,7 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.SuspendDialogInfo;
|
import android.content.pm.SuspendDialogInfo;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
@@ -64,7 +65,7 @@ import com.android.server.am.ActivityManagerService;
|
|||||||
import com.android.server.wm.ActivityInterceptorCallback.ActivityInterceptResult;
|
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.
|
* 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
|
* Note that this class is instantiated when {@link ActivityManagerService} gets created so there
|
||||||
@@ -104,6 +105,7 @@ class ActivityStartInterceptor {
|
|||||||
ActivityInfo mAInfo;
|
ActivityInfo mAInfo;
|
||||||
String mResolvedType;
|
String mResolvedType;
|
||||||
Task mInTask;
|
Task mInTask;
|
||||||
|
TaskFragment mInTaskFragment;
|
||||||
ActivityOptions mActivityOptions;
|
ActivityOptions mActivityOptions;
|
||||||
|
|
||||||
ActivityStartInterceptor(
|
ActivityStartInterceptor(
|
||||||
@@ -135,15 +137,46 @@ class ActivityStartInterceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IntentSender createIntentSenderForOriginalIntent(int callingUid, int flags) {
|
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(
|
final IIntentSender target = mService.getIntentSenderLocked(
|
||||||
INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId,
|
INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingFeatureId, callingUid, mUserId,
|
||||||
null /*token*/, null /*resultCode*/, 0 /*requestCode*/,
|
null /*token*/, null /*resultCode*/, 0 /*requestCode*/,
|
||||||
new Intent[] { mIntent }, new String[] { mResolvedType },
|
new Intent[] { mIntent }, new String[] { mResolvedType },
|
||||||
flags, activityOptions);
|
flags, bOptions);
|
||||||
return new IntentSender(target);
|
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
|
* 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.
|
* 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
|
* @return true if an interception occurred
|
||||||
*/
|
*/
|
||||||
boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType,
|
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);
|
mUserManager = UserManager.get(mServiceContext);
|
||||||
|
|
||||||
mIntent = intent;
|
mIntent = intent;
|
||||||
@@ -161,6 +195,7 @@ class ActivityStartInterceptor {
|
|||||||
mAInfo = aInfo;
|
mAInfo = aInfo;
|
||||||
mResolvedType = resolvedType;
|
mResolvedType = resolvedType;
|
||||||
mInTask = inTask;
|
mInTask = inTask;
|
||||||
|
mInTaskFragment = inTaskFragment;
|
||||||
mActivityOptions = activityOptions;
|
mActivityOptions = activityOptions;
|
||||||
|
|
||||||
if (interceptQuietProfileIfNeeded()) {
|
if (interceptQuietProfileIfNeeded()) {
|
||||||
@@ -332,12 +367,21 @@ class ActivityStartInterceptor {
|
|||||||
mCallingPid = mRealCallingPid;
|
mCallingPid = mRealCallingPid;
|
||||||
mCallingUid = mRealCallingUid;
|
mCallingUid = mRealCallingUid;
|
||||||
mResolvedType = null;
|
mResolvedType = null;
|
||||||
|
final TaskFragment taskFragment = getLaunchTaskFragment();
|
||||||
// If we are intercepting and there was a task, convert it into an extra for the
|
// 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
|
// ConfirmCredentials intent and unassign it, as otherwise the task will move to
|
||||||
// front even if ConfirmCredentials is cancelled.
|
// front even if ConfirmCredentials is cancelled.
|
||||||
if (mInTask != null) {
|
if (mInTask != null) {
|
||||||
mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId);
|
mIntent.putExtra(EXTRA_TASK_ID, mInTask.mTaskId);
|
||||||
mInTask = null;
|
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) {
|
if (mActivityOptions == null) {
|
||||||
mActivityOptions = ActivityOptions.makeBasic();
|
mActivityOptions = ActivityOptions.makeBasic();
|
||||||
|
|||||||
@@ -1060,8 +1060,8 @@ class ActivityStarter {
|
|||||||
|
|
||||||
mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
|
mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
|
||||||
callingFeatureId);
|
callingFeatureId);
|
||||||
if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid,
|
if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
|
||||||
callingUid, checkedOptions)) {
|
callingPid, callingUid, checkedOptions)) {
|
||||||
// activity start was intercepted, e.g. because the target user is currently in quiet
|
// activity start was intercepted, e.g. because the target user is currently in quiet
|
||||||
// mode (turn off work) or the target application is suspended
|
// mode (turn off work) or the target application is suspended
|
||||||
intent = mInterceptor.mIntent;
|
intent = mInterceptor.mIntent;
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
.thenReturn(PLATFORM_PACKAGE_NAME);
|
.thenReturn(PLATFORM_PACKAGE_NAME);
|
||||||
|
|
||||||
// THEN calling intercept returns 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 admin support intent
|
// THEN the returned intent is the admin support intent
|
||||||
assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent);
|
assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent);
|
||||||
@@ -203,7 +203,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
final String suspendingPackage = "com.test.suspending.package";
|
final String suspendingPackage = "com.test.suspending.package";
|
||||||
final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage);
|
final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage);
|
||||||
// THEN calling intercept returns 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));
|
||||||
|
|
||||||
// Check intent parameters
|
// Check intent parameters
|
||||||
assertEquals(dialogInfo,
|
assertEquals(dialogInfo,
|
||||||
@@ -234,7 +234,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT))
|
TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT))
|
||||||
.thenReturn(false);
|
.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)
|
assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME)
|
||||||
.filterEquals(mInterceptor.mIntent));
|
.filterEquals(mInterceptor.mIntent));
|
||||||
@@ -246,7 +246,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
|
when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
|
||||||
|
|
||||||
// THEN calling intercept returns 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
|
// THEN the returned intent is the quiet mode intent
|
||||||
assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
|
assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
|
||||||
@@ -260,7 +260,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
|
when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
|
||||||
|
|
||||||
// THEN calling intercept returns 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
|
// THEN the returned intent is the quiet mode intent
|
||||||
assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
|
assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
|
||||||
@@ -273,7 +273,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);
|
when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);
|
||||||
|
|
||||||
// THEN calling intercept returns 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
|
// THEN the returned intent is the quiet mode intent
|
||||||
assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent));
|
assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent));
|
||||||
@@ -286,7 +286,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
.thenReturn("This app is bad");
|
.thenReturn("This app is bad");
|
||||||
|
|
||||||
// THEN calling intercept returns 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 harmful app warning intent
|
// THEN the returned intent is the harmful app warning intent
|
||||||
assertEquals(HarmfulAppWarningActivity.class.getName(),
|
assertEquals(HarmfulAppWarningActivity.class.getName(),
|
||||||
@@ -298,7 +298,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
// GIVEN that none of the interception conditions are met
|
// GIVEN that none of the interception conditions are met
|
||||||
|
|
||||||
// THEN calling intercept returns false
|
// 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(
|
public void addMockInterceptorCallback(
|
||||||
@@ -323,7 +323,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
new Intent("android.test.foo"),
|
new Intent("android.test.foo"),
|
||||||
ActivityOptions.makeBasic().setLaunchDisplayId(3));
|
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("android.test.foo", mInterceptor.mIntent.getAction());
|
||||||
assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId());
|
assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId());
|
||||||
}
|
}
|
||||||
@@ -332,7 +332,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
public void testInterceptionCallback_singleCallbackReturnsNull() {
|
public void testInterceptionCallback_singleCallbackReturnsNull() {
|
||||||
addMockInterceptorCallback(null, null);
|
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
|
@Test
|
||||||
@@ -340,7 +340,7 @@ public class ActivityStartInterceptorTest {
|
|||||||
addMockInterceptorCallback(null, null);
|
addMockInterceptorCallback(null, null);
|
||||||
addMockInterceptorCallback(new Intent("android.test.second"), 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());
|
assertEquals("android.test.second", mInterceptor.mIntent.getAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user