Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -295,11 +295,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity, @NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity, @NonNull TaskFragmentContainer secondaryContainer, @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { @NonNull SplitRule splitRule) { SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, secondaryContainer, splitRule); // Remove container later to prevent pinning escaping toast showing in lock task mode. if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { removeExistingSecondaryContainers(wct, primaryContainer); removeExistingSecondaryContainers(wct, primaryContainer); } } SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, secondaryContainer, splitRule); mSplitContainers.add(splitContainer); mSplitContainers.add(splitContainer); } } Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +18 −6 Original line number Original line Diff line number Diff line Loading @@ -112,8 +112,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryContainer.setLastRequestedBounds(secondaryRectBounds); secondaryContainer.setLastRequestedBounds(secondaryRectBounds); // Set adjacent to each other so that the containers below will be invisible. // Set adjacent to each other so that the containers below will be invisible. setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); secondaryContainer.getTaskFragmentToken(), rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); Loading Loading @@ -149,8 +148,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryActivity, secondaryRectBounds, primaryContainer); secondaryActivity, secondaryRectBounds, primaryContainer); // Set adjacent to each other so that the containers below will be invisible. // Set adjacent to each other so that the containers below will be invisible. setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); secondaryContainer.getTaskFragmentToken(), rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); Loading Loading @@ -269,8 +267,22 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds); resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds); setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); } private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer primaryContainer, @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { final Rect parentBounds = getParentContainerBounds(primaryContainer); // Clear adjacent TaskFragments if the container is shown in fullscreen, or the // secondaryContainer could not be finished. if (!shouldShowSideBySide(parentBounds, splitRule)) { setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), rule); null /* secondary */, null /* splitRule */); } else { setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), splitRule); } } } /** /** Loading services/core/java/com/android/server/wm/LockTaskController.java +40 −8 Original line number Original line Diff line number Diff line Loading @@ -251,16 +251,48 @@ public class LockTaskController { */ */ boolean activityBlockedFromFinish(ActivityRecord activity) { boolean activityBlockedFromFinish(ActivityRecord activity) { final Task task = activity.getTask(); final Task task = activity.getTask(); if (activity == task.getRootActivity() if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || !isRootTask(task)) { && activity == task.getTopNonFinishingActivity() return false; && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV } && isRootTask(task)) { final ActivityRecord taskTop = task.getTopNonFinishingActivity(); final ActivityRecord taskRoot = task.getRootActivity(); // If task has more than one Activity, verify if there's only adjacent TaskFragments that // should be finish together in the Task. if (activity != taskRoot || activity != taskTop) { final TaskFragment taskFragment = activity.getTaskFragment(); final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (taskFragment.asTask() != null || !taskFragment.isDelayLastActivityRemoval() || adjacentTaskFragment == null) { // Don't block activity from finishing if the TaskFragment don't have any adjacent // TaskFragment, or it won't finish together with its adjacent TaskFragment. return false; } final boolean hasOtherActivityInTaskFragment = taskFragment.getActivity(a -> !a.finishing && a != activity) != null; if (hasOtherActivityInTaskFragment) { // Don't block activity from finishing if there's other Activity in the same // TaskFragment. return false; } final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing && a != activity && a.getTaskFragment() != adjacentTaskFragment) != null; if (hasOtherActivityInTask) { // Do not block activity from finishing if there are another running activities // after the current and adjacent TaskFragments are removed. Note that we don't // check activities in adjacent TaskFragment because it will be finished together // with TaskFragment regardless of numbers of activities. return false; } } Slog.i(TAG, "Not finishing task in lock task mode"); Slog.i(TAG, "Not finishing task in lock task mode"); showLockTaskToast(); showLockTaskToast(); return true; return true; } } return false; } /** /** * @return whether the given task can be moved to the back of the stack with * @return whether the given task can be moved to the back of the stack with Loading services/core/java/com/android/server/wm/TaskFragment.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -241,7 +241,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { /** /** * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * This should only be set on a embedded TaskFragment, where the organizer can have the * This should only be set on a embedded TaskFragment, where the organizer can have the * opportunity to perform other actions or animations. * opportunity to perform animations and finishing the adjacent TaskFragment. */ */ private boolean mDelayLastActivityRemoval; private boolean mDelayLastActivityRemoval; Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -295,11 +295,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity, @NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity, @NonNull TaskFragmentContainer secondaryContainer, @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { @NonNull SplitRule splitRule) { SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, secondaryContainer, splitRule); // Remove container later to prevent pinning escaping toast showing in lock task mode. if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { removeExistingSecondaryContainers(wct, primaryContainer); removeExistingSecondaryContainers(wct, primaryContainer); } } SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, secondaryContainer, splitRule); mSplitContainers.add(splitContainer); mSplitContainers.add(splitContainer); } } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +18 −6 Original line number Original line Diff line number Diff line Loading @@ -112,8 +112,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryContainer.setLastRequestedBounds(secondaryRectBounds); secondaryContainer.setLastRequestedBounds(secondaryRectBounds); // Set adjacent to each other so that the containers below will be invisible. // Set adjacent to each other so that the containers below will be invisible. setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); secondaryContainer.getTaskFragmentToken(), rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); Loading Loading @@ -149,8 +148,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryActivity, secondaryRectBounds, primaryContainer); secondaryActivity, secondaryRectBounds, primaryContainer); // Set adjacent to each other so that the containers below will be invisible. // Set adjacent to each other so that the containers below will be invisible. setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); secondaryContainer.getTaskFragmentToken(), rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); Loading Loading @@ -269,8 +267,22 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds); resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds); setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); } private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer primaryContainer, @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { final Rect parentBounds = getParentContainerBounds(primaryContainer); // Clear adjacent TaskFragments if the container is shown in fullscreen, or the // secondaryContainer could not be finished. if (!shouldShowSideBySide(parentBounds, splitRule)) { setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), rule); null /* secondary */, null /* splitRule */); } else { setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), secondaryContainer.getTaskFragmentToken(), splitRule); } } } /** /** Loading
services/core/java/com/android/server/wm/LockTaskController.java +40 −8 Original line number Original line Diff line number Diff line Loading @@ -251,16 +251,48 @@ public class LockTaskController { */ */ boolean activityBlockedFromFinish(ActivityRecord activity) { boolean activityBlockedFromFinish(ActivityRecord activity) { final Task task = activity.getTask(); final Task task = activity.getTask(); if (activity == task.getRootActivity() if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || !isRootTask(task)) { && activity == task.getTopNonFinishingActivity() return false; && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV } && isRootTask(task)) { final ActivityRecord taskTop = task.getTopNonFinishingActivity(); final ActivityRecord taskRoot = task.getRootActivity(); // If task has more than one Activity, verify if there's only adjacent TaskFragments that // should be finish together in the Task. if (activity != taskRoot || activity != taskTop) { final TaskFragment taskFragment = activity.getTaskFragment(); final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (taskFragment.asTask() != null || !taskFragment.isDelayLastActivityRemoval() || adjacentTaskFragment == null) { // Don't block activity from finishing if the TaskFragment don't have any adjacent // TaskFragment, or it won't finish together with its adjacent TaskFragment. return false; } final boolean hasOtherActivityInTaskFragment = taskFragment.getActivity(a -> !a.finishing && a != activity) != null; if (hasOtherActivityInTaskFragment) { // Don't block activity from finishing if there's other Activity in the same // TaskFragment. return false; } final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing && a != activity && a.getTaskFragment() != adjacentTaskFragment) != null; if (hasOtherActivityInTask) { // Do not block activity from finishing if there are another running activities // after the current and adjacent TaskFragments are removed. Note that we don't // check activities in adjacent TaskFragment because it will be finished together // with TaskFragment regardless of numbers of activities. return false; } } Slog.i(TAG, "Not finishing task in lock task mode"); Slog.i(TAG, "Not finishing task in lock task mode"); showLockTaskToast(); showLockTaskToast(); return true; return true; } } return false; } /** /** * @return whether the given task can be moved to the back of the stack with * @return whether the given task can be moved to the back of the stack with Loading
services/core/java/com/android/server/wm/TaskFragment.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -241,7 +241,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { /** /** * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * This should only be set on a embedded TaskFragment, where the organizer can have the * This should only be set on a embedded TaskFragment, where the organizer can have the * opportunity to perform other actions or animations. * opportunity to perform animations and finishing the adjacent TaskFragment. */ */ private boolean mDelayLastActivityRemoval; private boolean mDelayLastActivityRemoval; Loading