Block split Activity in lock task mode
Before this CL, Activity was only blocked from finishing if it is the last Activity in th Task to start lock task mode. However, it may make half of screen black if the finishing Activity is in one of adjacent TaskFragments. This CL considers the scenario that two adjacent TaskFragments side-by-side. If a finishing Activity leads to TaskFragment empty, and also make the adjacent TaskFragment finish, block the Activity from finishing. Bug: 205813709 Test: manual - use Settings in task pinning mode Change-Id: I6116d644aeccc13460d302fe3b40953fa67dca6c
This commit is contained in:
committed by
Charles Chen
parent
a5f83144a3
commit
0399d9c951
@@ -293,11 +293,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
@NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity,
|
||||
@NonNull TaskFragmentContainer secondaryContainer,
|
||||
@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()) {
|
||||
removeExistingSecondaryContainers(wct, primaryContainer);
|
||||
}
|
||||
SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity,
|
||||
secondaryContainer, splitRule);
|
||||
mSplitContainers.add(splitContainer);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,8 +112,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
secondaryContainer.setLastRequestedBounds(secondaryRectBounds);
|
||||
|
||||
// Set adjacent to each other so that the containers below will be invisible.
|
||||
setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
|
||||
secondaryContainer.getTaskFragmentToken(), rule);
|
||||
setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule);
|
||||
|
||||
mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule);
|
||||
|
||||
@@ -149,8 +148,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
secondaryActivity, secondaryRectBounds, primaryContainer);
|
||||
|
||||
// Set adjacent to each other so that the containers below will be invisible.
|
||||
setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
|
||||
secondaryContainer.getTaskFragmentToken(), rule);
|
||||
setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule);
|
||||
|
||||
mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule);
|
||||
|
||||
@@ -269,8 +267,22 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
|
||||
final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer();
|
||||
resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds);
|
||||
|
||||
setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
|
||||
secondaryContainer.getTaskFragmentToken(), rule);
|
||||
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(),
|
||||
null /* secondary */, null /* splitRule */);
|
||||
} else {
|
||||
setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
|
||||
secondaryContainer.getTaskFragmentToken(), splitRule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -251,15 +251,47 @@ public class LockTaskController {
|
||||
*/
|
||||
boolean activityBlockedFromFinish(ActivityRecord activity) {
|
||||
final Task task = activity.getTask();
|
||||
if (activity == task.getRootActivity()
|
||||
&& activity == task.getTopNonFinishingActivity()
|
||||
&& task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV
|
||||
&& isRootTask(task)) {
|
||||
Slog.i(TAG, "Not finishing task in lock task mode");
|
||||
showLockTaskToast();
|
||||
return true;
|
||||
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || !isRootTask(task)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
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");
|
||||
showLockTaskToast();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -232,7 +232,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
/**
|
||||
* 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
|
||||
* opportunity to perform other actions or animations.
|
||||
* opportunity to perform animations and finishing the adjacent TaskFragment.
|
||||
*/
|
||||
private boolean mDelayLastActivityRemoval;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user