Merge "Add caching for getDisplayInfo" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4753576dbf
@@ -18,6 +18,7 @@ package android.hardware.display;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.PropertyInvalidatedCache;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
@@ -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.
|
* Gets an instance of the display manager global singleton.
|
||||||
*
|
*
|
||||||
@@ -127,33 +142,27 @@ public final class DisplayManagerGlobal {
|
|||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
public DisplayInfo getDisplayInfo(int displayId) {
|
public DisplayInfo getDisplayInfo(int displayId) {
|
||||||
try {
|
synchronized (mLock) {
|
||||||
synchronized (mLock) {
|
DisplayInfo info = null;
|
||||||
DisplayInfo info;
|
if (mDisplayCache != null) {
|
||||||
if (USE_CACHE) {
|
info = mDisplayCache.query(displayId);
|
||||||
info = mDisplayInfoCache.get(displayId);
|
} else {
|
||||||
if (info != null) {
|
try {
|
||||||
return info;
|
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) {
|
|
||||||
Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
}
|
||||||
} catch (RemoteException ex) {
|
if (info == null) {
|
||||||
throw ex.rethrowFromSystemServer();
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCallbackIfNeededLocked();
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -215,6 +215,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
|
private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
|
||||||
|
|
||||||
// List of all logical displays indexed by logical display id.
|
// List of all logical displays indexed by logical display id.
|
||||||
|
// Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
|
||||||
private final SparseArray<LogicalDisplay> mLogicalDisplays =
|
private final SparseArray<LogicalDisplay> mLogicalDisplays =
|
||||||
new SparseArray<LogicalDisplay>();
|
new SparseArray<LogicalDisplay>();
|
||||||
private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
|
private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
|
||||||
@@ -373,6 +374,10 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
|
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(),
|
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
|
||||||
true /*allowIsolated*/);
|
true /*allowIsolated*/);
|
||||||
publishLocalService(DisplayManagerInternal.class, new LocalService());
|
publishLocalService(DisplayManagerInternal.class, new LocalService());
|
||||||
@@ -1005,9 +1010,17 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||||
recordTopInsetLocked(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);
|
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) {
|
private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
|
||||||
final int count = mDisplayDevices.size();
|
final int count = mDisplayDevices.size();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@@ -1066,6 +1079,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mLogicalDisplays.put(displayId, display);
|
mLogicalDisplays.put(displayId, display);
|
||||||
|
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
|
||||||
|
|
||||||
// Wake up waitForDefaultDisplay.
|
// Wake up waitForDefaultDisplay.
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
@@ -1206,7 +1220,7 @@ public final class DisplayManagerService extends SystemService {
|
|||||||
display.updateLocked(mDisplayDevices);
|
display.updateLocked(mDisplayDevices);
|
||||||
if (!display.isValidLocked()) {
|
if (!display.isValidLocked()) {
|
||||||
mLogicalDisplays.removeAt(i);
|
mLogicalDisplays.removeAt(i);
|
||||||
sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
|
handleLogicalDisplayRemoved(displayId);
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
|
} else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
|
||||||
handleLogicalDisplayChanged(displayId, display);
|
handleLogicalDisplayChanged(displayId, display);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ final class LogicalDisplay {
|
|||||||
* needs to be updated.
|
* needs to be updated.
|
||||||
* @see #getDisplayInfoLocked()
|
* @see #getDisplayInfoLocked()
|
||||||
*/
|
*/
|
||||||
private DisplayInfo mInfo;
|
private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null);
|
||||||
|
|
||||||
// The display device that this logical display is based on and which
|
// The display device that this logical display is based on and which
|
||||||
// determines the base metrics that it uses.
|
// determines the base metrics that it uses.
|
||||||
@@ -141,26 +141,27 @@ final class LogicalDisplay {
|
|||||||
* the data changes.
|
* the data changes.
|
||||||
*/
|
*/
|
||||||
public DisplayInfo getDisplayInfoLocked() {
|
public DisplayInfo getDisplayInfoLocked() {
|
||||||
if (mInfo == null) {
|
if (mInfo.get() == null) {
|
||||||
mInfo = new DisplayInfo();
|
DisplayInfo info = new DisplayInfo();
|
||||||
mInfo.copyFrom(mBaseDisplayInfo);
|
info.copyFrom(mBaseDisplayInfo);
|
||||||
if (mOverrideDisplayInfo != null) {
|
if (mOverrideDisplayInfo != null) {
|
||||||
mInfo.appWidth = mOverrideDisplayInfo.appWidth;
|
info.appWidth = mOverrideDisplayInfo.appWidth;
|
||||||
mInfo.appHeight = mOverrideDisplayInfo.appHeight;
|
info.appHeight = mOverrideDisplayInfo.appHeight;
|
||||||
mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
|
info.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
|
||||||
mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
|
info.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
|
||||||
mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
|
info.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
|
||||||
mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
|
info.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
|
||||||
mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth;
|
info.logicalWidth = mOverrideDisplayInfo.logicalWidth;
|
||||||
mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight;
|
info.logicalHeight = mOverrideDisplayInfo.logicalHeight;
|
||||||
mInfo.rotation = mOverrideDisplayInfo.rotation;
|
info.rotation = mOverrideDisplayInfo.rotation;
|
||||||
mInfo.displayCutout = mOverrideDisplayInfo.displayCutout;
|
info.displayCutout = mOverrideDisplayInfo.displayCutout;
|
||||||
mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
|
info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
|
||||||
mInfo.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
|
info.physicalXDpi = mOverrideDisplayInfo.physicalXDpi;
|
||||||
mInfo.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
|
info.physicalYDpi = mOverrideDisplayInfo.physicalYDpi;
|
||||||
}
|
}
|
||||||
|
mInfo.set(info);
|
||||||
}
|
}
|
||||||
return mInfo;
|
return mInfo.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,17 +182,16 @@ final class LogicalDisplay {
|
|||||||
if (info != null) {
|
if (info != null) {
|
||||||
if (mOverrideDisplayInfo == null) {
|
if (mOverrideDisplayInfo == null) {
|
||||||
mOverrideDisplayInfo = new DisplayInfo(info);
|
mOverrideDisplayInfo = new DisplayInfo(info);
|
||||||
mInfo = null;
|
mInfo.set(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if (!mOverrideDisplayInfo.equals(info)) {
|
||||||
if (!mOverrideDisplayInfo.equals(info)) {
|
|
||||||
mOverrideDisplayInfo.copyFrom(info);
|
mOverrideDisplayInfo.copyFrom(info);
|
||||||
mInfo = null;
|
mInfo.set(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (mOverrideDisplayInfo != null) {
|
} else if (mOverrideDisplayInfo != null) {
|
||||||
mOverrideDisplayInfo = null;
|
mOverrideDisplayInfo = null;
|
||||||
mInfo = null;
|
mInfo.set(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -306,7 +306,7 @@ final class LogicalDisplay {
|
|||||||
mBaseDisplayInfo.displayId = mDisplayId;
|
mBaseDisplayInfo.displayId = mDisplayId;
|
||||||
|
|
||||||
mPrimaryDisplayDeviceInfo = deviceInfo;
|
mPrimaryDisplayDeviceInfo = deviceInfo;
|
||||||
mInfo = null;
|
mInfo.set(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +327,7 @@ final class LogicalDisplay {
|
|||||||
private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
|
private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
|
||||||
boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
|
boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
|
||||||
if (maskCutout && deviceInfo.displayCutout != null) {
|
if (maskCutout && deviceInfo.displayCutout != null) {
|
||||||
|
// getSafeInsets is fixed at creation time and cannot change
|
||||||
return deviceInfo.displayCutout.getSafeInsets();
|
return deviceInfo.displayCutout.getSafeInsets();
|
||||||
} else {
|
} else {
|
||||||
return new Rect();
|
return new Rect();
|
||||||
|
|||||||
Reference in New Issue
Block a user