OSDN Git Service

Compute the focused window in display focus order
authorDavid Stevens <stevensd@google.com>
Fri, 24 Mar 2017 20:04:00 +0000 (13:04 -0700)
committerDavid Stevens <stevensd@google.com>
Mon, 27 Mar 2017 18:07:22 +0000 (11:07 -0700)
A WindowContainer's children are sorted so the focused child is at the
end of the list, so RootWindowContainer needs to iterate from end to
start when looking for the focused window.

Bug: 36590788
Test: DisplayContentTests#testFocusedWindowMultipleDisplays
Change-Id: I56e6b7d2054bc1e74b54a4f99706a08d278fa2e1

services/core/java/com/android/server/wm/RootWindowContainer.java
services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java

index 68d0f24..b0e3e32 100644 (file)
@@ -152,8 +152,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
     }
 
     WindowState computeFocusedWindow() {
-        final int count = mChildren.size();
-        for (int i = 0; i < count; i++) {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
             final DisplayContent dc = mChildren.get(i);
             final WindowState win = dc.findFocusedWindow();
             if (win != null) {
index 3868242..dd94a21 100644 (file)
@@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -233,6 +234,26 @@ public class DisplayContentTests extends WindowTestsBase {
         assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
     }
 
+    @Test
+    public void testFocusedWindowMultipleDisplays() throws Exception {
+        // Create a focusable window and check that focus is calcualted correctly
+        final WindowState window1 =
+                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1");
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+        // Check that a new display doesn't affect focus
+        final DisplayContent dc = createNewDisplay();
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+        // Add a window to the second display, and it should be focused
+        final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
+        assertEquals(window2, sWm.mRoot.computeFocusedWindow());
+
+        // Move the first window to the to including parents, and make sure focus is updated
+        window1.getParent().positionChildAt(POSITION_TOP, window1, true);
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+    }
+
     private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
         final LinkedList<WindowState> actualWindows = new LinkedList();
 
index 65efd9c..b67080d 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.view.View.VISIBLE;
+
 import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -226,7 +228,7 @@ class WindowTestsBase {
         attrs.setTitle(name);
 
         final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
+                0, attrs, VISIBLE, 0, ownerCanAddInternalSystemWindow);
         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
         // adding it to the token...
         token.addWindow(w);