Merge "Do not ignore home activity focus change on multi TaskDisplayArea device" into rvc-dev

This commit is contained in:
Chris Li
2020-05-01 00:00:38 +00:00
committed by Android (Google) Code Review
5 changed files with 138 additions and 5 deletions

View File

@@ -280,7 +280,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private final DisplayArea.Root mRootDisplayArea = new DisplayArea.Root(mWmService);
private final DisplayAreaPolicy mDisplayAreaPolicy;
@VisibleForTesting
final DisplayAreaPolicy mDisplayAreaPolicy;
private WindowState mTmpWindow;
private WindowState mTmpWindow2;

View File

@@ -7970,17 +7970,24 @@ public class WindowManagerService extends IWindowManager.Stub
handleTaskFocusChange(touchedWindow.getTask());
}
private void handleTaskFocusChange(Task task) {
@VisibleForTesting
void handleTaskFocusChange(Task task) {
if (task == null) {
return;
}
final ActivityStack stack = task.getStack();
// We ignore home stack since we don't want home stack to move to front when touched.
// Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
// behind home. See b/117376413
if (stack.isActivityTypeHome()) {
return;
if (task.isActivityTypeHome()) {
// Only ignore home stack if the requested focus home Task is in the same
// TaskDisplayArea as the current focus Task.
TaskDisplayArea homeTda = task.getDisplayArea();
WindowState curFocusedWindow = getFocusedWindow();
if (curFocusedWindow != null && homeTda != null
&& curFocusedWindow.isDescendantOf(homeTda)) {
return;
}
}
try {

View File

@@ -23,6 +23,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat;
@@ -35,6 +36,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.DisplayArea.Type.ANY;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
@@ -839,6 +841,36 @@ public class WindowContainerTests extends WindowTestsBase {
verifyWindowContainerApplyAnimation(stack, activity);
}
@Test
public void testGetDisplayArea() {
// WindowContainer
final WindowContainer windowContainer = new WindowContainer(mWm);
assertNull(windowContainer.getDisplayArea());
// ActivityStack > WindowContainer
final ActivityStack activityStack = createTaskStackOnDisplay(mDisplayContent);
activityStack.addChild(windowContainer, 0);
activityStack.setParent(null);
assertNull(windowContainer.getDisplayArea());
assertNull(activityStack.getDisplayArea());
// TaskDisplayArea > ActivityStack > WindowContainer
final TaskDisplayArea taskDisplayArea = new TaskDisplayArea(
mDisplayContent, mWm, "TaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
taskDisplayArea.addChild(activityStack, 0);
assertEquals(taskDisplayArea, windowContainer.getDisplayArea());
assertEquals(taskDisplayArea, activityStack.getDisplayArea());
assertEquals(taskDisplayArea, taskDisplayArea.getDisplayArea());
// DisplayArea
final DisplayArea displayArea = new DisplayArea(mWm, ANY, "DisplayArea");
assertEquals(displayArea, displayArea.getDisplayArea());
}
private void verifyWindowContainerApplyAnimation(WindowContainer wc, ActivityRecord act) {
// Initial remote animation for app transition.
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(

View File

@@ -16,21 +16,30 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Process.INVALID_UID;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -40,6 +49,10 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
/**
* Build/Install/Run:
* atest WmTests:WindowManagerServiceTests
*/
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
@@ -105,4 +118,70 @@ public class WindowManagerServiceTests extends WindowTestsBase {
mWm.removeWindowToken(token, mDisplayContent.getDisplayId());
}
@Test
public void testTaskFocusChange_stackNotHomeType_focusChanges() throws RemoteException {
DisplayContent display = createNewDisplay();
// Current focused window
ActivityStack focusedStack = createTaskStackOnDisplay(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
mDisplayContent.mCurrentFocus = focusedWindow;
// Tapped task
ActivityStack tappedStack = createTaskStackOnDisplay(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, display);
Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
spyOn(mWm.mActivityTaskManager);
mWm.handleTaskFocusChange(tappedTask);
verify(mWm.mActivityTaskManager).setFocusedTask(tappedTask.mTaskId);
}
@Test
public void testTaskFocusChange_stackHomeTypeWithSameTaskDisplayArea_focusDoesNotChange()
throws RemoteException {
DisplayContent display = createNewDisplay();
// Current focused window
ActivityStack focusedStack = createTaskStackOnDisplay(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
mDisplayContent.mCurrentFocus = focusedWindow;
// Tapped home task
ActivityStack tappedStack = createTaskStackOnDisplay(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, display);
Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
spyOn(mWm.mActivityTaskManager);
mWm.handleTaskFocusChange(tappedTask);
verify(mWm.mActivityTaskManager, never()).setFocusedTask(tappedTask.mTaskId);
}
@Test
public void testTaskFocusChange_stackHomeTypeWithDifferentTaskDisplayArea_focusChanges()
throws RemoteException {
DisplayContent display = createNewDisplay();
TaskDisplayArea secondTda =
new TaskDisplayArea(display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST);
display.mDisplayAreaPolicy.mRoot.addChild(secondTda, 1);
display.mDisplayAreaPolicy.mTaskDisplayAreas.add(secondTda);
// Current focused window
ActivityStack focusedStack = createTaskStackOnDisplay(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
Task focusedTask = createTaskInStack(focusedStack, 0 /* userId */);
WindowState focusedWindow = createAppWindow(focusedTask, TYPE_APPLICATION, "App Window");
mDisplayContent.mCurrentFocus = focusedWindow;
// Tapped home task on another task display area
ActivityStack tappedStack = createTaskStackOnTaskDisplayArea(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, secondTda);
Task tappedTask = createTaskInStack(tappedStack, 0 /* userId */);
spyOn(mWm.mActivityTaskManager);
mWm.handleTaskFocusChange(tappedTask);
verify(mWm.mActivityTaskManager).setFocusedTask(tappedTask.mTaskId);
}
}

View File

@@ -304,6 +304,20 @@ class WindowTestsBase extends SystemServiceTestsBase {
}
}
ActivityStack createTaskStackOnTaskDisplayArea(
int windowingMode, int activityType, TaskDisplayArea tda) {
synchronized (mWm.mGlobalLock) {
return new ActivityTestsBase.StackBuilder(
tda.mDisplayContent.mWmService.mAtmService.mRootWindowContainer)
.setTaskDisplayArea(tda)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
.setCreateActivity(false)
.setIntent(new Intent())
.build();
}
}
/** Creates a {@link Task} and adds it to the specified {@link ActivityStack}. */
Task createTaskInStack(ActivityStack stack, int userId) {
return WindowTestUtils.createTaskInStack(mWm, stack, userId);