if (task == null) {
return;
}
+ if (mUserController.shouldConfirmCredentials(task.userId)) {
+ mActivityStarter.showConfirmDeviceCredential(task.userId);
+ if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+ mStackSupervisor.moveTaskToStackLocked(task.taskId,
+ FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
+ "setFocusedTask", ANIMATE);
+ }
+ return;
+ }
final ActivityRecord r = task.topRunningActivityLocked();
if (setFocusedActivityLocked(r, "setFocusedTask")) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
final long ident = Binder.clearCallingIdentity();
try {
final int currentUserId = mUserController.getCurrentUserIdLocked();
+
+ // Drop locked freeform tasks out into the fullscreen stack.
+ // TODO: Redact the tasks in place. It's much better to keep them on the screen
+ // where they were before, but in an obscured state.
+ mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
+
if (mUserController.isLockScreenDisabled(currentUserId)) {
// If there is no device lock, we will show the profile's credential page.
mActivityStarter.showConfirmDeviceCredential(userId);
if (!mService.mUserController.shouldConfirmCredentials(userId)) {
return false;
}
- final ActivityStack fullScreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack dockedStack = getStack(DOCKED_STACK_ID);
- final ActivityStack[] activityStacks = new ActivityStack[] {fullScreenStack, dockedStack};
+ final ActivityStack[] activityStacks = {
+ getStack(DOCKED_STACK_ID),
+ getStack(FREEFORM_WORKSPACE_STACK_ID),
+ getStack(FULLSCREEN_WORKSPACE_STACK_ID),
+ };
for (final ActivityStack activityStack : activityStacks) {
if (activityStack == null) {
continue;
if (activityStack.isDockedStack() && mIsDockMinimized) {
continue;
}
- final TaskRecord topTask = activityStack.topTask();
- if (topTask == null) {
- continue;
- }
- // To handle the case that work app is in the task but just is not the top one.
- for (int i = topTask.mActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord activityRecord = topTask.mActivities.get(i);
- if (activityRecord.userId == userId) {
+ if (activityStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+ // TODO: Only the topmost task should trigger credential confirmation. But first,
+ // there needs to be a way to block out locked task window surfaces.
+ final List<TaskRecord> tasks = activityStack.getAllTasks();
+ final int size = tasks.size();
+ for (int i = 0; i < size; i++) {
+ if (taskContainsActivityFromUser(tasks.get(i), userId)) {
+ return true;
+ }
+ }
+ } else {
+ final TaskRecord topTask = activityStack.topTask();
+ if (topTask == null) {
+ continue;
+ }
+ if (taskContainsActivityFromUser(topTask, userId)) {
return true;
}
}
return false;
}
+ private boolean taskContainsActivityFromUser(TaskRecord task, @UserIdInt int userId) {
+ // To handle the case that work app is in the task but just is not the top one.
+ for (int i = task.mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord activityRecord = task.mActivities.get(i);
+ if (activityRecord.userId == userId) {
+ return true;
+ }
+ }
+ return false;
+ }
+
void setNextTaskIdForUserLocked(int taskId, int userId) {
final int currentTaskId = mCurTaskIdForUser.get(userId, -1);
if (taskId > currentTaskId) {
}
}
+ /**
+ * TODO: remove the need for this method. (b/30693465)
+ *
+ * @param userId user handle for the locked managed profile. Freeform tasks for this user will
+ * be moved to another stack, so they are not shown in the background.
+ */
+ void moveProfileTasksFromFreeformToFullscreenStackLocked(@UserIdInt int userId) {
+ final ActivityStack stack = getStack(FREEFORM_WORKSPACE_STACK_ID);
+ if (stack == null) {
+ return;
+ }
+ mWindowManager.deferSurfaceLayout();
+ try {
+ final ArrayList<TaskRecord> tasks = stack.getAllTasks();
+ final int size = tasks.size();
+ for (int i = size - 1; i >= 0; i--) {
+ if (taskContainsActivityFromUser(tasks.get(i), userId)) {
+ positionTaskInStackLocked(tasks.get(i).taskId, FULLSCREEN_WORKSPACE_STACK_ID,
+ /* position */ 0);
+ }
+ }
+ } finally {
+ mWindowManager.continueSurfaceLayout();
+ }
+ }
+
void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
Rect tempDockedTaskInsetBounds,
Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds, boolean preserveWindows) {
// Preferred stack is the docked stack, but the task can't go in the docked stack.
// Put it in the fullscreen stack.
stackId = FULLSCREEN_WORKSPACE_STACK_ID;
+ } else if (stackId == FREEFORM_WORKSPACE_STACK_ID
+ && mService.mUserController.shouldConfirmCredentials(task.userId)) {
+ // Task is barred from the freeform stack. Put it in the fullscreen stack.
+ stackId = FULLSCREEN_WORKSPACE_STACK_ID;
}
if (task.stack != null) {
Slog.w(TAG, "Can not move unresizeable task=" + task
+ " to docked stack. Moving to stackId=" + stackId + " instead.");
}
+ if (stackId == FREEFORM_WORKSPACE_STACK_ID
+ && mService.mUserController.shouldConfirmCredentials(task.userId)) {
+ stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
+ Slog.w(TAG, "Can not move locked profile task=" + task
+ + " to freeform stack. Moving to stackId=" + stackId + " instead.");
+ }
// Temporarily disable resizeablility of task we are moving. We don't want it to be resized
// if a docked stack is created below which will lead to the stack we are moving from and
import android.app.admin.SecurityLog.SecurityEvent;
import android.app.admin.SystemUpdatePolicy;
import android.app.backup.IBackupManager;
+import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
return TelephonyManager.from(mContext);
}
+ TrustManager getTrustManager() {
+ return (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+ }
+
IWindowManager getIWindowManager() {
return IWindowManager.Stub
.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
mInjector.powerManagerGoToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
mInjector.getIWindowManager().lockNow(null);
+ } else {
+ mInjector.getTrustManager().setDeviceLockedForUser(userToLock, true);
}
} catch (RemoteException e) {
} finally {