Pass profile userId to notifyLockedProfile
When the stack originates in the primary user and then a profile activity is added on top, RunningTaskInfo.userId will reflect the primary user, but this is not the user for which WorkLockActivity should be launched. With this CL profile userId is passed along the RunningTaskInfo into onTaskProfileLocked, so that WorkLockActivity is started for the right user. Bug: 279024529 Test: atest WmTests:RootWindowContainerTests SystemUITests WMShellUnitTests WMShellTest Change-Id: I7755243edf73546dc840d0107d0a6bdb695eb45d
This commit is contained in:
@@ -137,7 +137,7 @@ oneway interface ITaskStackListener {
|
||||
* activities inside it belong to a managed profile user, and that user has just
|
||||
* been locked.
|
||||
*/
|
||||
void onTaskProfileLocked(in ActivityManager.RunningTaskInfo taskInfo);
|
||||
void onTaskProfileLocked(in ActivityManager.RunningTaskInfo taskInfo, int userId);
|
||||
|
||||
/**
|
||||
* Called when a task snapshot got updated.
|
||||
|
||||
@@ -154,8 +154,18 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId)
|
||||
throws RemoteException {
|
||||
onTaskProfileLocked(taskInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated see {@link #onTaskProfileLocked(RunningTaskInfo, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
public void onTaskProfileLocked(RunningTaskInfo taskInfo) throws RemoteException {
|
||||
public void onTaskProfileLocked(RunningTaskInfo taskInfo)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,7 +38,7 @@ public interface TaskStackListenerCallback {
|
||||
|
||||
default void onTaskStackChanged() { }
|
||||
|
||||
default void onTaskProfileLocked(RunningTaskInfo taskInfo) { }
|
||||
default void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) { }
|
||||
|
||||
default void onTaskDisplayChanged(int taskId, int newDisplayId) { }
|
||||
|
||||
|
||||
@@ -150,8 +150,8 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
mMainHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskInfo).sendToTarget();
|
||||
public void onTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo, int userId) {
|
||||
mMainHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, userId, 0, taskInfo).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,8 +348,9 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler.
|
||||
case ON_TASK_PROFILE_LOCKED: {
|
||||
final ActivityManager.RunningTaskInfo
|
||||
info = (ActivityManager.RunningTaskInfo) msg.obj;
|
||||
final int userId = msg.arg1;
|
||||
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
|
||||
mTaskStackListeners.get(i).onTaskProfileLocked(info);
|
||||
mTaskStackListeners.get(i).onTaskProfileLocked(info, userId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -112,9 +112,9 @@ public class TaskStackListenerImplTest extends ShellTestCase {
|
||||
@Test
|
||||
public void testOnTaskProfileLocked() {
|
||||
ActivityManager.RunningTaskInfo info = mock(ActivityManager.RunningTaskInfo.class);
|
||||
mImpl.onTaskProfileLocked(info);
|
||||
verify(mCallback).onTaskProfileLocked(eq(info));
|
||||
verify(mOtherCallback).onTaskProfileLocked(eq(info));
|
||||
mImpl.onTaskProfileLocked(info, 0);
|
||||
verify(mCallback).onTaskProfileLocked(eq(info), eq(0));
|
||||
verify(mOtherCallback).onTaskProfileLocked(eq(info), eq(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -68,7 +68,7 @@ public interface TaskStackChangeListener {
|
||||
onActivityLaunchOnSecondaryDisplayRerouted();
|
||||
}
|
||||
|
||||
default void onTaskProfileLocked(RunningTaskInfo taskInfo) { }
|
||||
default void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) { }
|
||||
default void onTaskCreated(int taskId, ComponentName componentName) { }
|
||||
default void onTaskRemoved(int taskId) { }
|
||||
default void onTaskMovedToFront(int taskId) { }
|
||||
|
||||
@@ -262,8 +262,8 @@ public class TaskStackChangeListeners {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskProfileLocked(RunningTaskInfo taskInfo) {
|
||||
mHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, taskInfo).sendToTarget();
|
||||
public void onTaskProfileLocked(RunningTaskInfo taskInfo, int userId) {
|
||||
mHandler.obtainMessage(ON_TASK_PROFILE_LOCKED, userId, 0, taskInfo).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -418,8 +418,9 @@ public class TaskStackChangeListeners {
|
||||
}
|
||||
case ON_TASK_PROFILE_LOCKED: {
|
||||
final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
|
||||
final int userId = msg.arg1;
|
||||
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
|
||||
mTaskStackListeners.get(i).onTaskProfileLocked(info);
|
||||
mTaskStackListeners.get(i).onTaskProfileLocked(info, userId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -56,11 +56,11 @@ public class WorkLockActivityController {
|
||||
tscl.registerTaskStackListener(mLockListener);
|
||||
}
|
||||
|
||||
private void startWorkChallengeInTask(ActivityManager.RunningTaskInfo info) {
|
||||
private void startWorkChallengeInTask(ActivityManager.RunningTaskInfo info, int userId) {
|
||||
String packageName = info.baseActivity != null ? info.baseActivity.getPackageName() : "";
|
||||
Intent intent = new Intent(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER)
|
||||
.setComponent(new ComponentName(mContext, WorkLockActivity.class))
|
||||
.putExtra(Intent.EXTRA_USER_ID, info.userId)
|
||||
.putExtra(Intent.EXTRA_USER_ID, userId)
|
||||
.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
@@ -76,10 +76,11 @@ public class WorkLockActivityController {
|
||||
} else {
|
||||
// Starting the activity inside the task failed. We can't be sure why, so to be
|
||||
// safe just remove the whole task if it still exists.
|
||||
Log.w(TAG, "Failed to start work lock activity, will remove task=" + info.taskId);
|
||||
try {
|
||||
mIatm.removeTask(info.taskId);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed to get description for task=" + info.taskId);
|
||||
Log.e(TAG, "Failed to remove task=" + info.taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,8 +113,8 @@ public class WorkLockActivityController {
|
||||
|
||||
private final TaskStackChangeListener mLockListener = new TaskStackChangeListener() {
|
||||
@Override
|
||||
public void onTaskProfileLocked(ActivityManager.RunningTaskInfo info) {
|
||||
startWorkChallengeInTask(info);
|
||||
public void onTaskProfileLocked(ActivityManager.RunningTaskInfo info, int userId) {
|
||||
startWorkChallengeInTask(info, userId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,13 +25,11 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.IActivityTaskManager;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.ProfilerInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -59,13 +57,14 @@ import org.mockito.MockitoAnnotations;
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class WorkLockActivityControllerTest extends SysuiTestCase {
|
||||
private static final int USER_ID = 333;
|
||||
private static final int TASK_USER_ID = 333;
|
||||
private static final int PROFILE_USER_ID = 555;
|
||||
private static final int TASK_ID = 444;
|
||||
private static final ActivityManager.RunningTaskInfo TASK_INFO =
|
||||
new ActivityManager.RunningTaskInfo();
|
||||
|
||||
static {
|
||||
TASK_INFO.userId = USER_ID;
|
||||
TASK_INFO.userId = TASK_USER_ID;
|
||||
TASK_INFO.taskId = TASK_ID;
|
||||
}
|
||||
|
||||
@@ -101,10 +100,10 @@ public class WorkLockActivityControllerTest extends SysuiTestCase {
|
||||
setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_SUCCESS);
|
||||
|
||||
// And the controller receives a message saying the profile is locked,
|
||||
mTaskStackListener.onTaskProfileLocked(TASK_INFO);
|
||||
mTaskStackListener.onTaskProfileLocked(TASK_INFO, PROFILE_USER_ID);
|
||||
|
||||
// The overlay should start and the task the activity started in should not be removed.
|
||||
verifyStartActivity(TASK_ID, true /*taskOverlay*/);
|
||||
verifyStartActivity(TASK_ID, true /*taskOverlay*/, PROFILE_USER_ID);
|
||||
verify(mIActivityTaskManager, never()).removeTask(anyInt() /*taskId*/);
|
||||
}
|
||||
|
||||
@@ -114,11 +113,11 @@ public class WorkLockActivityControllerTest extends SysuiTestCase {
|
||||
setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_CLASS_NOT_FOUND);
|
||||
|
||||
// And the controller receives a message saying the profile is locked,
|
||||
mTaskStackListener.onTaskProfileLocked(TASK_INFO);
|
||||
mTaskStackListener.onTaskProfileLocked(TASK_INFO, PROFILE_USER_ID);
|
||||
|
||||
// The task the activity started in should be removed to prevent the locked task from
|
||||
// being shown.
|
||||
verifyStartActivity(TASK_ID, true /*taskOverlay*/);
|
||||
verifyStartActivity(TASK_ID, true /*taskOverlay*/, PROFILE_USER_ID);
|
||||
verify(mIActivityTaskManager).removeTask(TASK_ID);
|
||||
}
|
||||
|
||||
@@ -141,12 +140,13 @@ public class WorkLockActivityControllerTest extends SysuiTestCase {
|
||||
eq(ActivityManager.getCurrentUser()));
|
||||
}
|
||||
|
||||
private void verifyStartActivity(int taskId, boolean taskOverlay) throws Exception {
|
||||
private void verifyStartActivity(int taskId, boolean taskOverlay, int profileUserId)
|
||||
throws Exception {
|
||||
verify(mIActivityTaskManager).startActivityAsUser(
|
||||
eq((IApplicationThread) null),
|
||||
eq((String) null),
|
||||
eq((String) null),
|
||||
any(Intent.class),
|
||||
argThat(hasUserId(profileUserId)),
|
||||
eq((String) null),
|
||||
eq((IBinder) null),
|
||||
eq((String) null),
|
||||
@@ -157,24 +157,15 @@ public class WorkLockActivityControllerTest extends SysuiTestCase {
|
||||
eq(ActivityManager.getCurrentUser()));
|
||||
}
|
||||
|
||||
private static ArgumentMatcher<Intent> hasComponent(final Context context,
|
||||
final Class<? extends Activity> activityClass) {
|
||||
return new ArgumentMatcher<Intent>() {
|
||||
@Override
|
||||
public boolean matches(Intent intent) {
|
||||
return new ComponentName(context, activityClass).equals(intent.getComponent());
|
||||
}
|
||||
};
|
||||
private static ArgumentMatcher<Intent> hasUserId(int userId) {
|
||||
return intent -> intent.getIntExtra(Intent.EXTRA_USER_ID, -1) == userId;
|
||||
}
|
||||
|
||||
private static ArgumentMatcher<Bundle> hasOptions(final int taskId, final boolean overlay) {
|
||||
return new ArgumentMatcher<Bundle>() {
|
||||
@Override
|
||||
public boolean matches(Bundle item) {
|
||||
final ActivityOptions options = ActivityOptions.fromBundle(item);
|
||||
return (options.getLaunchTaskId() == taskId)
|
||||
&& (options.getTaskOverlay() == overlay);
|
||||
}
|
||||
return item -> {
|
||||
final ActivityOptions options = ActivityOptions.fromBundle(item);
|
||||
return (options.getLaunchTaskId() == taskId)
|
||||
&& (options.getTaskOverlay() == overlay);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3239,7 +3239,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
||||
if (task.getActivity(activity -> !activity.finishing && activity.mUserId == userId)
|
||||
!= null) {
|
||||
mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
|
||||
task.getTaskInfo());
|
||||
task.getTaskInfo(), userId);
|
||||
}
|
||||
}, true /* traverseTopToBottom */);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ class TaskChangeNotificationController {
|
||||
};
|
||||
|
||||
private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
|
||||
l.onTaskProfileLocked((RunningTaskInfo) m.obj);
|
||||
l.onTaskProfileLocked((RunningTaskInfo) m.obj, m.arg1);
|
||||
};
|
||||
|
||||
private final TaskStackConsumer mNotifyTaskSnapshotChanged = (l, m) -> {
|
||||
@@ -467,9 +467,9 @@ class TaskChangeNotificationController {
|
||||
* Notify listeners that the task has been put in a locked state because one or more of the
|
||||
* activities inside it belong to a managed profile user that has been locked.
|
||||
*/
|
||||
void notifyTaskProfileLocked(ActivityManager.RunningTaskInfo taskInfo) {
|
||||
void notifyTaskProfileLocked(RunningTaskInfo taskInfo, int userId) {
|
||||
final Message msg = mHandler.obtainMessage(NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG,
|
||||
taskInfo);
|
||||
userId, 0, taskInfo);
|
||||
forAllLocalListeners(mNotifyTaskProfileLocked, msg);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
|
||||
@@ -1134,7 +1134,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
|
||||
TaskChangeNotificationController controller = mAtm.getTaskChangeNotificationController();
|
||||
spyOn(controller);
|
||||
mWm.mRoot.lockAllProfileTasks(profileUserId);
|
||||
verify(controller).notifyTaskProfileLocked(any());
|
||||
verify(controller).notifyTaskProfileLocked(any(), eq(profileUserId));
|
||||
|
||||
// Create the work lock activity on top of the task
|
||||
final ActivityRecord workLockActivity = new ActivityBuilder(mAtm).setTask(task).build();
|
||||
@@ -1144,7 +1144,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
|
||||
// Make sure the listener won't be notified again.
|
||||
clearInvocations(controller);
|
||||
mWm.mRoot.lockAllProfileTasks(profileUserId);
|
||||
verify(controller, never()).notifyTaskProfileLocked(any());
|
||||
verify(controller, never()).notifyTaskProfileLocked(any(), anyInt());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user