Move task to the bottom when force hidden
Move a task to the bottom when the task was hidden to prevent the top focused activity unable to enter pip (while pausing) due to a invisible task remained on top. Move the task to top once being visible again Bug: 180405672 Test: atest TaskTests PinnedStackTests Change-Id: I038076c58cd41cc90039c9db5a295da5d5ee2cde
This commit is contained in:
@@ -5245,17 +5245,29 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
if (mForceHiddenFlags == newFlags) {
|
if (mForceHiddenFlags == newFlags) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean wasHidden = isForceHidden();
|
final boolean wasHidden = isForceHidden();
|
||||||
|
final boolean wasVisible = isVisible();
|
||||||
mForceHiddenFlags = newFlags;
|
mForceHiddenFlags = newFlags;
|
||||||
if (wasHidden != isForceHidden() && isTopActivityFocusable()) {
|
final boolean nowHidden = isForceHidden();
|
||||||
// The change in force-hidden state will change visibility without triggering a root
|
if (wasHidden != nowHidden) {
|
||||||
// task order change, so we should reset the preferred top focusable root task to ensure
|
final String reason = "setForceHidden";
|
||||||
// it's not used if a new activity is started from this task.
|
if (wasVisible && nowHidden) {
|
||||||
getDisplayArea().resetPreferredTopFocusableRootTaskIfNeeded(this);
|
// Move this visible task to back when the task is forced hidden
|
||||||
|
moveToBack(reason, null);
|
||||||
|
} else if (isAlwaysOnTop()) {
|
||||||
|
// Move this always-on-top task to front when no longer hidden
|
||||||
|
moveToFront(reason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAlwaysOnTop() {
|
||||||
|
return !isForceHidden() && super.isAlwaysOnTop();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this task is currently forced to be hidden for any reason.
|
* Returns whether this task is currently forced to be hidden for any reason.
|
||||||
*/
|
*/
|
||||||
@@ -7482,17 +7494,22 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setAlwaysOnTop(boolean alwaysOnTop) {
|
public void setAlwaysOnTop(boolean alwaysOnTop) {
|
||||||
if (isAlwaysOnTop() == alwaysOnTop) {
|
// {@link #isAwaysonTop} overrides the original behavior which also evaluates if this
|
||||||
|
// task is force hidden, so super.isAlwaysOnTop() is used here to see whether the
|
||||||
|
// alwaysOnTop attributes should be updated.
|
||||||
|
if (super.isAlwaysOnTop() == alwaysOnTop) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super.setAlwaysOnTop(alwaysOnTop);
|
super.setAlwaysOnTop(alwaysOnTop);
|
||||||
final TaskDisplayArea taskDisplayArea = getDisplayArea();
|
|
||||||
// positionChildAtTop() must be called even when always on top gets turned off because we
|
// positionChildAtTop() must be called even when always on top gets turned off because we
|
||||||
// need to make sure that the root task is moved from among always on top windows to
|
// need to make sure that the root task is moved from among always on top windows to
|
||||||
// below other always on top windows. Since the position the root task should be inserted
|
// below other always on top windows. Since the position the root task should be inserted
|
||||||
// into is calculated properly in {@link DisplayContent#getTopInsertPosition()} in both
|
// into is calculated properly in {@link DisplayContent#getTopInsertPosition()} in both
|
||||||
// cases, we can just request that the root task is put at top here.
|
// cases, we can just request that the root task is put at top here.
|
||||||
taskDisplayArea.positionChildAt(POSITION_TOP, this, false /* includingParents */);
|
// Don't bother moving task to top if this task is force hidden and invisible to user.
|
||||||
|
if (!isForceHidden()) {
|
||||||
|
getDisplayArea().positionChildAt(POSITION_TOP, this, false /* includingParents */);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dismissPip() {
|
void dismissPip() {
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
|
|||||||
final boolean moveToBottom = position <= 0;
|
final boolean moveToBottom = position <= 0;
|
||||||
|
|
||||||
final int oldPosition = mChildren.indexOf(child);
|
final int oldPosition = mChildren.indexOf(child);
|
||||||
if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
|
if (child.isAlwaysOnTop() && !moveToTop) {
|
||||||
// This root task is always-on-top, override the default behavior.
|
// This root task is always-on-top, override the default behavior.
|
||||||
Slog.w(TAG_WM, "Ignoring move of always-on-top root task=" + this + " to bottom");
|
Slog.w(TAG_WM, "Ignoring move of always-on-top root task=" + this + " to bottom");
|
||||||
|
|
||||||
@@ -974,14 +974,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
|
|||||||
onRootTaskOrderChanged(rootTask);
|
onRootTaskOrderChanged(rootTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reset the mPreferredTopFocusableRootTask if it is or below the given task. */
|
|
||||||
void resetPreferredTopFocusableRootTaskIfNeeded(Task task) {
|
|
||||||
if (mPreferredTopFocusableRootTask != null
|
|
||||||
&& mPreferredTopFocusableRootTask.compareTo(task) <= 0) {
|
|
||||||
mPreferredTopFocusableRootTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves/reparents `task` to the back of whatever container the root home task is in. This is
|
* Moves/reparents `task` to the back of whatever container the root home task is in. This is
|
||||||
* for when we just want to move a task to "the back" vs. a specific place. The primary use-case
|
* for when we just want to move a task to "the back" vs. a specific place. The primary use-case
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
|||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||||
|
import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -277,4 +278,15 @@ public class TaskTests extends WindowTestsBase {
|
|||||||
// Orientation request from standard activity in multi window will not be handled.
|
// Orientation request from standard activity in multi window will not be handled.
|
||||||
assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
|
assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlwaysOnTop() {
|
||||||
|
final Task task = createTaskStackOnDisplay(mDisplayContent);
|
||||||
|
task.setAlwaysOnTop(true);
|
||||||
|
task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
|
||||||
|
assertTrue(task.isAlwaysOnTop());
|
||||||
|
|
||||||
|
task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
|
||||||
|
assertFalse(task.isAlwaysOnTop());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user