Loading core/java/android/hardware/display/DisplayManagerGlobal.java +54 −23 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.display; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; Loading Loading @@ -99,6 +100,20 @@ public final class DisplayManagerGlobal { } } private PropertyInvalidatedCache<Integer, DisplayInfo> mDisplayCache = new PropertyInvalidatedCache<Integer, DisplayInfo>( 8, // size of display cache CACHE_KEY_DISPLAY_INFO_PROPERTY) { @Override protected DisplayInfo recompute(Integer id) { try { return mDm.getDisplayInfo(id); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } }; /** * Gets an instance of the display manager global singleton. * Loading Loading @@ -127,24 +142,21 @@ public final class DisplayManagerGlobal { */ @UnsupportedAppUsage public DisplayInfo getDisplayInfo(int displayId) { try { synchronized (mLock) { DisplayInfo info; if (USE_CACHE) { info = mDisplayInfoCache.get(displayId); if (info != null) { return info; DisplayInfo info = null; if (mDisplayCache != null) { info = mDisplayCache.query(displayId); } else { try { info = mDm.getDisplayInfo(displayId); } catch (RemoteException ex) { ex.rethrowFromSystemServer(); } } info = mDm.getDisplayInfo(displayId); if (info == null) { return null; } if (USE_CACHE) { mDisplayInfoCache.put(displayId, info); } registerCallbackIfNeededLocked(); if (DEBUG) { Loading @@ -152,9 +164,6 @@ public final class DisplayManagerGlobal { } return info; } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** Loading Loading @@ -777,4 +786,26 @@ public final class DisplayManagerGlobal { } } } /** * Name of the property containing a unique token which changes every time we update the * system's display configuration. */ public static final String CACHE_KEY_DISPLAY_INFO_PROPERTY = "cache_key.display_info"; /** * Invalidates the contents of the display info cache for all applications. Can only * be called by system_server. */ public static void invalidateLocalDisplayInfoCaches() { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DISPLAY_INFO_PROPERTY); } /** * Disables the binder call cache. */ public void disableLocalDisplayInfoCaches() { mDisplayCache = null; } } services/core/java/com/android/server/display/DisplayInfoProxy.java 0 → 100644 +57 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; import android.annotation.Nullable; import android.hardware.display.DisplayManagerGlobal; import android.view.DisplayInfo; /** * Class for wrapping access of DisplayInfo objects by LogicalDisplay so that we can appropriately * invalidate caches when they change. */ public class DisplayInfoProxy { private DisplayInfo mInfo; public DisplayInfoProxy(@Nullable DisplayInfo info) { mInfo = info; } /** * Set the current {@link DisplayInfo}. * * The also automatically invalidates the display info caches across the entire system. * @param info the new {@link DisplayInfo}. */ public void set(@Nullable DisplayInfo info) { mInfo = info; DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); } /** * Returns the current {@link DisplayInfo}. * * This info <b>must</b> be treated as immutable. Modifying the returned object is undefined * behavior that <b>will</b> result in inconsistent states across the system. * * @return the current {@link DisplayInfo} */ @Nullable public DisplayInfo get() { return mInfo; } } services/core/java/com/android/server/display/DisplayManagerService.java +15 −1 Original line number Diff line number Diff line Loading @@ -215,6 +215,7 @@ public final class DisplayManagerService extends SystemService { private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>(); // List of all logical displays indexed by logical display id. // Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache. private final SparseArray<LogicalDisplay> mLogicalDisplays = new SparseArray<LogicalDisplay>(); private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; Loading Loading @@ -373,6 +374,10 @@ public final class DisplayManagerService extends SystemService { } mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); // If there was a runtime restart then we may have stale caches left around, so we need to // make sure to invalidate them upon every start. DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), true /*allowIsolated*/); publishLocalService(DisplayManagerInternal.class, new LocalService()); Loading Loading @@ -1005,9 +1010,17 @@ public final class DisplayManagerService extends SystemService { if (displayId == Display.DEFAULT_DISPLAY) { recordTopInsetLocked(display); } // We don't bother invalidating the display info caches here because any changes to the // display info will trigger a cache invalidation inside of LogicalDisplay before we hit // this point. sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); } private void handleLogicalDisplayRemoved(int displayId) { DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); } private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { Loading Loading @@ -1066,6 +1079,7 @@ public final class DisplayManagerService extends SystemService { } mLogicalDisplays.put(displayId, display); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); // Wake up waitForDefaultDisplay. if (isDefault) { Loading Loading @@ -1206,7 +1220,7 @@ public final class DisplayManagerService extends SystemService { display.updateLocked(mDisplayDevices); if (!display.isValidLocked()) { mLogicalDisplays.removeAt(i); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); handleLogicalDisplayRemoved(displayId); changed = true; } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { handleLogicalDisplayChanged(displayId, display); Loading services/core/java/com/android/server/display/LogicalDisplay.java +25 −24 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ final class LogicalDisplay { * needs to be updated. * @see #getDisplayInfoLocked() */ private DisplayInfo mInfo; private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null); // The display device that this logical display is based on and which // determines the base metrics that it uses. Loading Loading @@ -141,26 +141,27 @@ final class LogicalDisplay { * the data changes. */ public DisplayInfo getDisplayInfoLocked() { if (mInfo == null) { mInfo = new DisplayInfo(); mInfo.copyFrom(mBaseDisplayInfo); if (mInfo.get() == null) { DisplayInfo info = new DisplayInfo(); info.copyFrom(mBaseDisplayInfo); if (mOverrideDisplayInfo != null) { mInfo.appWidth = mOverrideDisplayInfo.appWidth; mInfo.appHeight = mOverrideDisplayInfo.appHeight; mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth; mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight; mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth; mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight; mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth; mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight; mInfo.rotation = mOverrideDisplayInfo.rotation; mInfo.displayCutout = mOverrideDisplayInfo.displayCutout; mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; info.appWidth = mOverrideDisplayInfo.appWidth; info.appHeight = mOverrideDisplayInfo.appHeight; info.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth; info.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight; info.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth; info.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight; info.logicalWidth = mOverrideDisplayInfo.logicalWidth; info.logicalHeight = mOverrideDisplayInfo.logicalHeight; info.rotation = mOverrideDisplayInfo.rotation; info.displayCutout = mOverrideDisplayInfo.displayCutout; info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; info.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; info.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; } mInfo.set(info); } return mInfo; return mInfo.get(); } /** Loading @@ -181,17 +182,16 @@ final class LogicalDisplay { if (info != null) { if (mOverrideDisplayInfo == null) { mOverrideDisplayInfo = new DisplayInfo(info); mInfo = null; mInfo.set(null); return true; } if (!mOverrideDisplayInfo.equals(info)) { } else if (!mOverrideDisplayInfo.equals(info)) { mOverrideDisplayInfo.copyFrom(info); mInfo = null; mInfo.set(null); return true; } } else if (mOverrideDisplayInfo != null) { mOverrideDisplayInfo = null; mInfo = null; mInfo.set(null); return true; } return false; Loading Loading @@ -306,7 +306,7 @@ final class LogicalDisplay { mBaseDisplayInfo.displayId = mDisplayId; mPrimaryDisplayDeviceInfo = deviceInfo; mInfo = null; mInfo.set(null); } } Loading @@ -327,6 +327,7 @@ final class LogicalDisplay { private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) { boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; if (maskCutout && deviceInfo.displayCutout != null) { // getSafeInsets is fixed at creation time and cannot change return deviceInfo.displayCutout.getSafeInsets(); } else { return new Rect(); Loading Loading
core/java/android/hardware/display/DisplayManagerGlobal.java +54 −23 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.display; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PropertyInvalidatedCache; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ParceledListSlice; Loading Loading @@ -99,6 +100,20 @@ public final class DisplayManagerGlobal { } } private PropertyInvalidatedCache<Integer, DisplayInfo> mDisplayCache = new PropertyInvalidatedCache<Integer, DisplayInfo>( 8, // size of display cache CACHE_KEY_DISPLAY_INFO_PROPERTY) { @Override protected DisplayInfo recompute(Integer id) { try { return mDm.getDisplayInfo(id); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } }; /** * Gets an instance of the display manager global singleton. * Loading Loading @@ -127,24 +142,21 @@ public final class DisplayManagerGlobal { */ @UnsupportedAppUsage public DisplayInfo getDisplayInfo(int displayId) { try { synchronized (mLock) { DisplayInfo info; if (USE_CACHE) { info = mDisplayInfoCache.get(displayId); if (info != null) { return info; DisplayInfo info = null; if (mDisplayCache != null) { info = mDisplayCache.query(displayId); } else { try { info = mDm.getDisplayInfo(displayId); } catch (RemoteException ex) { ex.rethrowFromSystemServer(); } } info = mDm.getDisplayInfo(displayId); if (info == null) { return null; } if (USE_CACHE) { mDisplayInfoCache.put(displayId, info); } registerCallbackIfNeededLocked(); if (DEBUG) { Loading @@ -152,9 +164,6 @@ public final class DisplayManagerGlobal { } return info; } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** Loading Loading @@ -777,4 +786,26 @@ public final class DisplayManagerGlobal { } } } /** * Name of the property containing a unique token which changes every time we update the * system's display configuration. */ public static final String CACHE_KEY_DISPLAY_INFO_PROPERTY = "cache_key.display_info"; /** * Invalidates the contents of the display info cache for all applications. Can only * be called by system_server. */ public static void invalidateLocalDisplayInfoCaches() { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DISPLAY_INFO_PROPERTY); } /** * Disables the binder call cache. */ public void disableLocalDisplayInfoCaches() { mDisplayCache = null; } }
services/core/java/com/android/server/display/DisplayInfoProxy.java 0 → 100644 +57 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; import android.annotation.Nullable; import android.hardware.display.DisplayManagerGlobal; import android.view.DisplayInfo; /** * Class for wrapping access of DisplayInfo objects by LogicalDisplay so that we can appropriately * invalidate caches when they change. */ public class DisplayInfoProxy { private DisplayInfo mInfo; public DisplayInfoProxy(@Nullable DisplayInfo info) { mInfo = info; } /** * Set the current {@link DisplayInfo}. * * The also automatically invalidates the display info caches across the entire system. * @param info the new {@link DisplayInfo}. */ public void set(@Nullable DisplayInfo info) { mInfo = info; DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); } /** * Returns the current {@link DisplayInfo}. * * This info <b>must</b> be treated as immutable. Modifying the returned object is undefined * behavior that <b>will</b> result in inconsistent states across the system. * * @return the current {@link DisplayInfo} */ @Nullable public DisplayInfo get() { return mInfo; } }
services/core/java/com/android/server/display/DisplayManagerService.java +15 −1 Original line number Diff line number Diff line Loading @@ -215,6 +215,7 @@ public final class DisplayManagerService extends SystemService { private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>(); // List of all logical displays indexed by logical display id. // Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache. private final SparseArray<LogicalDisplay> mLogicalDisplays = new SparseArray<LogicalDisplay>(); private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; Loading Loading @@ -373,6 +374,10 @@ public final class DisplayManagerService extends SystemService { } mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); // If there was a runtime restart then we may have stale caches left around, so we need to // make sure to invalidate them upon every start. DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), true /*allowIsolated*/); publishLocalService(DisplayManagerInternal.class, new LocalService()); Loading Loading @@ -1005,9 +1010,17 @@ public final class DisplayManagerService extends SystemService { if (displayId == Display.DEFAULT_DISPLAY) { recordTopInsetLocked(display); } // We don't bother invalidating the display info caches here because any changes to the // display info will trigger a cache invalidation inside of LogicalDisplay before we hit // this point. sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); } private void handleLogicalDisplayRemoved(int displayId) { DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); } private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { Loading Loading @@ -1066,6 +1079,7 @@ public final class DisplayManagerService extends SystemService { } mLogicalDisplays.put(displayId, display); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); // Wake up waitForDefaultDisplay. if (isDefault) { Loading Loading @@ -1206,7 +1220,7 @@ public final class DisplayManagerService extends SystemService { display.updateLocked(mDisplayDevices); if (!display.isValidLocked()) { mLogicalDisplays.removeAt(i); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); handleLogicalDisplayRemoved(displayId); changed = true; } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { handleLogicalDisplayChanged(displayId, display); Loading
services/core/java/com/android/server/display/LogicalDisplay.java +25 −24 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ final class LogicalDisplay { * needs to be updated. * @see #getDisplayInfoLocked() */ private DisplayInfo mInfo; private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null); // The display device that this logical display is based on and which // determines the base metrics that it uses. Loading Loading @@ -141,26 +141,27 @@ final class LogicalDisplay { * the data changes. */ public DisplayInfo getDisplayInfoLocked() { if (mInfo == null) { mInfo = new DisplayInfo(); mInfo.copyFrom(mBaseDisplayInfo); if (mInfo.get() == null) { DisplayInfo info = new DisplayInfo(); info.copyFrom(mBaseDisplayInfo); if (mOverrideDisplayInfo != null) { mInfo.appWidth = mOverrideDisplayInfo.appWidth; mInfo.appHeight = mOverrideDisplayInfo.appHeight; mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth; mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight; mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth; mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight; mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth; mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight; mInfo.rotation = mOverrideDisplayInfo.rotation; mInfo.displayCutout = mOverrideDisplayInfo.displayCutout; mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; info.appWidth = mOverrideDisplayInfo.appWidth; info.appHeight = mOverrideDisplayInfo.appHeight; info.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth; info.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight; info.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth; info.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight; info.logicalWidth = mOverrideDisplayInfo.logicalWidth; info.logicalHeight = mOverrideDisplayInfo.logicalHeight; info.rotation = mOverrideDisplayInfo.rotation; info.displayCutout = mOverrideDisplayInfo.displayCutout; info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; info.physicalXDpi = mOverrideDisplayInfo.physicalXDpi; info.physicalYDpi = mOverrideDisplayInfo.physicalYDpi; } mInfo.set(info); } return mInfo; return mInfo.get(); } /** Loading @@ -181,17 +182,16 @@ final class LogicalDisplay { if (info != null) { if (mOverrideDisplayInfo == null) { mOverrideDisplayInfo = new DisplayInfo(info); mInfo = null; mInfo.set(null); return true; } if (!mOverrideDisplayInfo.equals(info)) { } else if (!mOverrideDisplayInfo.equals(info)) { mOverrideDisplayInfo.copyFrom(info); mInfo = null; mInfo.set(null); return true; } } else if (mOverrideDisplayInfo != null) { mOverrideDisplayInfo = null; mInfo = null; mInfo.set(null); return true; } return false; Loading Loading @@ -306,7 +306,7 @@ final class LogicalDisplay { mBaseDisplayInfo.displayId = mDisplayId; mPrimaryDisplayDeviceInfo = deviceInfo; mInfo = null; mInfo.set(null); } } Loading @@ -327,6 +327,7 @@ final class LogicalDisplay { private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) { boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; if (maskCutout && deviceInfo.displayCutout != null) { // getSafeInsets is fixed at creation time and cannot change return deviceInfo.displayCutout.getSafeInsets(); } else { return new Rect(); Loading