OSDN Git Service

Fix propagation of display overscan information.
authorJeff Brown <jeffbrown@google.com>
Wed, 7 Aug 2013 21:13:37 +0000 (14:13 -0700)
committerJeff Brown <jeffbrown@google.com>
Wed, 7 Aug 2013 21:33:50 +0000 (14:33 -0700)
Fix several problems in the way that the overscan was plumbed in
which could result in information not being delivered to applications.
There was also a violation of certain invariants regarding the
immutability of returned DisplayInfo objects.

Bug: 10213771
Change-Id: I21184a14305e44278b5e81353bf95d511e8517fb

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
services/java/com/android/server/display/DisplayManagerService.java
services/java/com/android/server/display/LogicalDisplay.java
services/java/com/android/server/wm/WindowManagerService.java

index f83b017..ae7120f 100644 (file)
@@ -995,8 +995,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
 
     @Override
     public void setInitialDisplaySize(Display display, int width, int height, int density) {
-        if (display.getDisplayId() != Display.DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
+        // This method might be called before the policy has been fully initialized
+        // or for other displays we don't care about.
+        if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
+            return;
         }
         mDisplay = display;
 
index 20db4cd..4b3463c 100644 (file)
@@ -314,6 +314,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
      * to the display information synchronously so that applications will immediately
      * observe the new state.
      *
+     * NOTE: This method must be the only entry point by which the window manager
+     * influences the logical configuration of displays.
+     *
      * @param displayId The logical display id.
      * @param info The new data to be stored.
      */
@@ -322,9 +325,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
             if (display != null) {
-                mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
-                display.setDisplayInfoOverrideFromWindowManagerLocked(info);
-                if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
+                if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
                     sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
                     scheduleTraversalLocked(false);
                 }
@@ -333,18 +334,6 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
     }
 
     /**
-     * Sets the overscan insets for a particular display.
-     */
-    public void setOverscan(int displayId, int left, int top, int right, int bottom) {
-        synchronized (mSyncRoot) {
-            LogicalDisplay display = mLogicalDisplays.get(displayId);
-            if (display != null) {
-                display.setOverscan(left, top, right, bottom);
-            }
-        }
-    }
-
-    /**
      * Called by the window manager to perform traversals while holding a
      * surface flinger transaction.
      */
index b9839c2..7e357c0 100644 (file)
@@ -128,32 +128,24 @@ final class LogicalDisplay {
      *
      * @param info The logical display information, may be null.
      */
-    public void setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
+    public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
         if (info != null) {
             if (mOverrideDisplayInfo == null) {
                 mOverrideDisplayInfo = new DisplayInfo(info);
                 mInfo = null;
-            } else if (!mOverrideDisplayInfo.equals(info)) {
+                return true;
+            }
+            if (!mOverrideDisplayInfo.equals(info)) {
                 mOverrideDisplayInfo.copyFrom(info);
                 mInfo = null;
+                return true;
             }
         } else if (mOverrideDisplayInfo != null) {
             mOverrideDisplayInfo = null;
             mInfo = null;
+            return true;
         }
-    }
-
-    public void setOverscan(int left, int top, int right, int bottom) {
-        mInfo.overscanLeft = left;
-        mInfo.overscanTop = top;
-        mInfo.overscanRight = right;
-        mInfo.overscanBottom = bottom;
-        if (mOverrideDisplayInfo != null) {
-            mOverrideDisplayInfo.overscanLeft = left;
-            mOverrideDisplayInfo.overscanTop = top;
-            mOverrideDisplayInfo.overscanRight = right;
-            mOverrideDisplayInfo.overscanBottom = bottom;
-        }
+        return false;
     }
 
     /**
index 27177f9..364b854 100644 (file)
@@ -6961,12 +6961,7 @@ public class WindowManagerService extends IWindowManager.Stub
         synchronized(mWindowMap) {
             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_TOUCHSCREEN);
-
-            final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
-                    displayContent.mInitialDisplayWidth,
-                    displayContent.mInitialDisplayHeight,
-                    displayContent.mInitialDisplayDensity);
+            configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
         }
 
         try {
@@ -7793,11 +7788,7 @@ public class WindowManagerService extends IWindowManager.Stub
     // displayContent must not be null
     private void reconfigureDisplayLocked(DisplayContent displayContent) {
         // TODO: Multidisplay: for now only use with default display.
-        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
-                displayContent.mBaseDisplayWidth,
-                displayContent.mBaseDisplayHeight,
-                displayContent.mBaseDisplayDensity);
-
+        configureDisplayPolicyLocked(displayContent);
         displayContent.layoutNeeded = true;
 
         boolean configChanged = updateOrientationFromAppTokensLocked(false);
@@ -7818,6 +7809,18 @@ public class WindowManagerService extends IWindowManager.Stub
         performLayoutAndPlaceSurfacesLocked();
     }
 
+    private void configureDisplayPolicyLocked(DisplayContent displayContent) {
+        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+                displayContent.mBaseDisplayWidth,
+                displayContent.mBaseDisplayHeight,
+                displayContent.mBaseDisplayDensity);
+
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        mPolicy.setDisplayOverscan(displayContent.getDisplay(),
+                displayInfo.overscanLeft, displayInfo.overscanTop,
+                displayInfo.overscanRight, displayInfo.overscanBottom);
+    }
+
     @Override
     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
         if (mContext.checkCallingOrSelfPermission(
@@ -7829,23 +7832,27 @@ public class WindowManagerService extends IWindowManager.Stub
         synchronized(mWindowMap) {
             DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null) {
-                mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
-                final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-                synchronized(displayContent.mDisplaySizeLock) {
-                    displayInfo.overscanLeft = left;
-                    displayInfo.overscanTop = top;
-                    displayInfo.overscanRight = right;
-                    displayInfo.overscanBottom = bottom;
-                }
-                mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
-                displayContent.layoutNeeded = true;
-                mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
-                mDisplaySettings.writeSettingsLocked();
-                performLayoutAndPlaceSurfacesLocked();
+                setOverscanLocked(displayContent, left, top, right, bottom);
             }
         }
     }
 
+    private void setOverscanLocked(DisplayContent displayContent,
+            int left, int top, int right, int bottom) {
+        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        synchronized (displayContent.mDisplaySizeLock) {
+            displayInfo.overscanLeft = left;
+            displayInfo.overscanTop = top;
+            displayInfo.overscanRight = right;
+            displayInfo.overscanBottom = bottom;
+        }
+
+        mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
+        mDisplaySettings.writeSettingsLocked();
+
+        reconfigureDisplayLocked(displayContent);
+    }
+
     // -------------------------------------------------------------
     // Internals
     // -------------------------------------------------------------
@@ -10719,17 +10726,19 @@ public class WindowManagerService extends IWindowManager.Stub
         DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
         mDisplayContents.put(displayId, displayContent);
+
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final Rect rect = new Rect();
-        DisplayInfo info = displayContent.getDisplayInfo();
-        mDisplaySettings.getOverscanLocked(info.name, rect);
-        info.overscanLeft = rect.left;
-        info.overscanTop = rect.top;
-        info.overscanRight = rect.right;
-        info.overscanBottom = rect.bottom;
-        mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
-                rect.right, rect.bottom);
-        mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
-                rect.right, rect.bottom);
+        mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
+        synchronized (displayContent.mDisplaySizeLock) {
+            displayInfo.overscanLeft = rect.left;
+            displayInfo.overscanTop = rect.top;
+            displayInfo.overscanRight = rect.right;
+            displayInfo.overscanBottom = rect.bottom;
+            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
+                    displayId, displayInfo);
+        }
+        configureDisplayPolicyLocked(displayContent);
 
         // TODO: Create an input channel for each display with touch capability.
         if (displayId == Display.DEFAULT_DISPLAY) {