Detects all activities for whether showing work challenge

Work challenge did not show when a work activity is not on top, but
still visible after screen turns on.

Also show work challenge even if the work activity is behind a top
fullscreen activity of another profile because the user can still
navigate back to the work activity when top activity finishes.

Bug: 177457096
Test: ActivityStackSupervisorTests

Change-Id: I5e09b09be547d04fdfd709cb9cd4bcd4a94bbf21
Merged-In: I5e09b09be547d04fdfd709cb9cd4bcd4a94bbf21
This commit is contained in:
Louis Chang
2021-04-15 12:11:07 +08:00
parent d17b979843
commit fe5e1432cf
2 changed files with 41 additions and 30 deletions

View File

@@ -860,27 +860,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
/**
* Detects whether we should show a lock screen in front of this task for a locked user.
* <p>
* We'll do this if either of the following holds:
* <ul>
* <li>The top activity explicitly belongs to {@param userId}.</li>
* <li>The top activity returns a result to an activity belonging to {@param userId}.</li>
* </ul>
*
* @return {@code true} if the top activity looks like it belongs to {@param userId}.
*/
private boolean taskTopActivityIsUser(TaskRecord task, @UserIdInt int userId) {
// To handle the case that work app is in the task but just is not the top one.
final ActivityRecord activityRecord = task.getTopActivity();
final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
return (activityRecord != null && activityRecord.userId == userId)
|| (resultTo != null && resultTo.userId == userId);
}
/**
* Find all visible task stacks containing {@param userId} and intercept them with an activity
* Find all task stacks containing {@param userId} and intercept them with an activity
* to block out the contents and possibly start a credential-confirming intent.
*
* @param userId user handle for the locked managed profile.
@@ -895,13 +875,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final List<TaskRecord> tasks = stack.getAllTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
final TaskRecord task = tasks.get(taskNdx);
// Check the task for a top activity belonging to userId, or returning a
// result to an activity belonging to userId. Example case: a document
// picker for personal files, opened by a work app, should still get locked.
if (taskTopActivityIsUser(task, userId)) {
mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
task.taskId, userId);
for (int activityNdx = task.mActivities.size() - 1; activityNdx >= 0;
activityNdx--) {
final ActivityRecord activity = task.mActivities.get(activityNdx);
if (!activity.finishing && activity.userId == userId) {
mService.mTaskChangeNotificationController.notifyTaskProfileLocked(
task.taskId, userId);
break;
}
}
}
}

View File

@@ -27,8 +27,7 @@ import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor
.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -46,6 +45,8 @@ import static org.mockito.Mockito.verify;
import android.app.ActivityOptions;
import android.app.WaitResult;
import android.graphics.Rect;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
@@ -407,4 +408,33 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
// Assert that the primary stack is returned.
assertEquals(primaryStack, result);
}
@Test
public void testLockAllProfileTasks() throws Exception {
// Make an activity visible with the user id set to 1
final TaskRecord task = new TaskBuilder(mSupervisor).setStack(mFullscreenStack).build();
final ActivityRecord activity = new ActivityBuilder(mService).setTask(task)
.setUid(UserHandle.PER_USER_RANGE + 1).build();
// Create another activity on top and the user id is 2
final ActivityRecord topActivity = new ActivityBuilder(mService)
.setTask(task).setUid(UserHandle.PER_USER_RANGE + 2).build();
// Make sure the listeners will be notified for putting the task to locked state
LocalTaskStackListener listener = new LocalTaskStackListener();
mService.registerTaskStackListener(listener);
mService.mStackSupervisor.lockAllProfileTasks(1);
assertTrue(listener.mTaskProfileLocked);
mService.unregisterTaskStackListener(listener);
}
private class LocalTaskStackListener extends android.app.TaskStackListener {
boolean mTaskProfileLocked;
@Override
public void onTaskProfileLocked(int taskId, int userId) throws RemoteException {
super.onTaskProfileLocked(taskId, userId);
mTaskProfileLocked = true;
}
}
}