Loading services/core/java/com/android/server/display/DisplayManagerService.java +81 −57 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.util.IntArray; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.Spline; import android.view.Display; import android.view.DisplayInfo; Loading @@ -96,6 +97,7 @@ import android.view.IDisplayFoldListener; import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.BrightnessSynchronizer; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; Loading @@ -112,7 +114,6 @@ import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; Loading Loading @@ -235,15 +236,28 @@ public final class DisplayManagerService extends SystemService { private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { @Override public void requestDisplayState(int displayId, int state, float brightness) { // TODO (b/168210494): Stop applying default display state to all displays. if (displayId != Display.DEFAULT_DISPLAY) { return; } final int[] displayIds; synchronized (mSyncRoot) { displayIds = mLogicalDisplayMapper.getDisplayIdsLocked(); } // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } } mDisplayPowerCallbacks.onDisplayStateChange(state); if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } } } }; Loading @@ -257,13 +271,16 @@ public final class DisplayManagerService extends SystemService { /** The {@link Handler} used by all {@link DisplayPowerController}s. */ private Handler mPowerHandler; // The overall display state, independent of changes that might influence one // display or another in particular. private int mGlobalDisplayState = Display.STATE_ON; // A map from LogicalDisplay ID to display power state. @GuardedBy("mSyncRoot") private final SparseIntArray mDisplayStates = new SparseIntArray(); // A map from LogicalDisplay ID to display brightness. @GuardedBy("mSyncRoot") private final SparseArray<Float> mDisplayBrightnesses = new SparseArray<>(); // The overall display brightness. // For now, this only applies to the default display but we may split it up eventually. private float mGlobalDisplayBrightness; // The default brightness. private final float mDisplayDefaultBrightness; // Set to true when there are pending display changes that have yet to be applied // to the surface flinger state. Loading Loading @@ -317,11 +334,6 @@ public final class DisplayManagerService extends SystemService { // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. private final int mDefaultDisplayDefaultColorMode; // Temporary list of deferred work to perform when setting the display state. // Only used by requestDisplayState. The field is self-synchronized and only // intended for use inside of the requestGlobalDisplayStateInternal function. private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>(); // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); Loading Loading @@ -372,7 +384,7 @@ public final class DisplayManagerService extends SystemService { mMinimumBrightnessSpline = Spline.createSpline(lux, nits); PowerManager pm = mContext.getSystemService(PowerManager.class); mGlobalDisplayBrightness = pm.getBrightnessConstraint( mDisplayDefaultBrightness = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); mCurrentUserId = UserHandle.USER_SYSTEM; ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); Loading Loading @@ -589,7 +601,7 @@ public final class DisplayManagerService extends SystemService { } } private void requestGlobalDisplayStateInternal(int state, float brightnessState) { private void requestDisplayStateInternal(int displayId, int state, float brightnessState) { if (state == Display.STATE_UNKNOWN) { state = Display.STATE_ON; } Loading @@ -602,38 +614,40 @@ public final class DisplayManagerService extends SystemService { brightnessState = PowerManager.BRIGHTNESS_MAX; } synchronized (mTempDisplayStateWorkQueue) { try { // Update the display state within the lock. // Note that we do not need to schedule traversals here although it // may happen as a side-effect of displays changing state. final Runnable runnable; final String traceMessage; synchronized (mSyncRoot) { if (mGlobalDisplayState == state && mGlobalDisplayBrightness == brightnessState) { return; // no change final int index = mDisplayStates.indexOfKey(displayId); if (index < 0 || (mDisplayStates.valueAt(index) == state && BrightnessSynchronizer.floatEquals(mDisplayBrightnesses.valueAt(index), brightnessState))) { return; // Display no longer exists or no change. } Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" traceMessage = "requestDisplayStateInternal(" + displayId + ", " + Display.stateToString(state) + ", brightness=" + brightnessState + ")"); + ", brightness=" + brightnessState + ")"; Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId); mGlobalDisplayState = state; mGlobalDisplayBrightness = brightnessState; applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); mDisplayStates.setValueAt(index, state); mDisplayBrightnesses.setValueAt(index, brightnessState); runnable = updateDisplayStateLocked( mLogicalDisplayMapper.getLocked(displayId).getPrimaryDisplayDeviceLocked()); } // Setting the display power state can take hundreds of milliseconds // to complete so we defer the most expensive part of the work until // after we have exited the critical section to avoid blocking other // threads for a long time. for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) { mTempDisplayStateWorkQueue.get(i).run(); } Trace.traceEnd(Trace.TRACE_TAG_POWER); } finally { mTempDisplayStateWorkQueue.clear(); } if (runnable != null) { runnable.run(); } Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, traceMessage, displayId); } private class SettingsObserver extends ContentObserver { Loading Loading @@ -987,6 +1001,8 @@ public final class DisplayManagerService extends SystemService { recordTopInsetLocked(display); } addDisplayPowerControllerLocked(displayId); mDisplayStates.append(displayId, Display.STATE_OFF); mDisplayBrightnesses.append(displayId, mDisplayDefaultBrightness); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); Loading Loading @@ -1021,6 +1037,8 @@ public final class DisplayManagerService extends SystemService { private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { final int displayId = display.getDisplayIdLocked(); mDisplayPowerControllers.delete(displayId); mDisplayStates.delete(displayId); mDisplayBrightnesses.delete(displayId); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); scheduleTraversalLocked(false); Loading @@ -1035,15 +1053,6 @@ public final class DisplayManagerService extends SystemService { handleLogicalDisplayChangedLocked(display); } private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> { Runnable runnable = updateDisplayStateLocked(device); if (runnable != null) { workQueue.add(runnable); } }); } private Runnable updateDisplayStateLocked(DisplayDevice device) { // Blank or unblank the display immediately to match the state requested // by the display power controller (if known). Loading @@ -1052,12 +1061,16 @@ public final class DisplayManagerService extends SystemService { // TODO - b/170498827 The rules regarding what display state to apply to each // display will depend on the configuration/mapping of logical displays. // Clean up LogicalDisplay.isEnabled() mechanism once this is fixed. int state = mGlobalDisplayState; final LogicalDisplay display = mLogicalDisplayMapper.getLocked(device); if (display != null && !display.isEnabled()) { final int state; final int displayId = display.getDisplayIdLocked(); if (display.isEnabled()) { state = mDisplayStates.get(displayId); } else { state = Display.STATE_OFF; } return device.requestDisplayStateLocked(state, mGlobalDisplayBrightness); final float brightness = mDisplayBrightnesses.get(displayId); return device.requestDisplayStateLocked(state, brightness); } return null; } Loading Loading @@ -1587,13 +1600,24 @@ public final class DisplayManagerService extends SystemService { pw.println(" mOnlyCode=" + mOnlyCore); pw.println(" mSafeMode=" + mSafeMode); pw.println(" mPendingTraversal=" + mPendingTraversal); pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); pw.println(" mViewports=" + mViewports); pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); pw.println(" mStableDisplaySize=" + mStableDisplaySize); pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); pw.println(); final int displayStateCount = mDisplayStates.size(); pw.println("Display States: size=" + displayStateCount); for (int i = 0; i < displayStateCount; i++) { final int displayId = mDisplayStates.keyAt(i); final int displayState = mDisplayStates.valueAt(i); final float brightness = mDisplayBrightnesses.valueAt(i); pw.println(" Display Id=" + displayId); pw.println(" Display State=" + Display.stateToString(displayState)); pw.println(" Display Brightness=" + brightness); } IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); Loading services/core/java/com/android/server/display/DisplayPowerController.java +0 −2 Original line number Diff line number Diff line Loading @@ -685,8 +685,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void initialize() { // Initialize the power state object for the default display. // In the future, we might manage multiple displays independently. mPowerState = new DisplayPowerState(mBlanker, mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId); Loading services/core/java/com/android/server/display/LogicalDisplay.java +1 −1 Original line number Diff line number Diff line Loading @@ -588,7 +588,7 @@ final class LogicalDisplay { } /** * Swap the underlying {@link DisplayDevice} with the specificed LogicalDisplay. * Swap the underlying {@link DisplayDevice} with the specified LogicalDisplay. * * @param targetDisplay The display with which to swap display-devices. * @return {@code true} if the displays were swapped, {@code false} otherwise. Loading services/core/java/com/android/server/display/LogicalDisplayMapper.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display; import android.content.Context; import android.os.Process; import android.os.SystemProperties; import android.text.TextUtils; import android.util.Slog; Loading Loading @@ -149,6 +150,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return null; } public int[] getDisplayIdsLocked() { return getDisplayIdsLocked(Process.SYSTEM_UID); } public int[] getDisplayIdsLocked(int callingUid) { final int count = mLogicalDisplays.size(); int[] displayIds = new int[count]; Loading Loading
services/core/java/com/android/server/display/DisplayManagerService.java +81 −57 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import android.util.IntArray; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.Spline; import android.view.Display; import android.view.DisplayInfo; Loading @@ -96,6 +97,7 @@ import android.view.IDisplayFoldListener; import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.BrightnessSynchronizer; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; Loading @@ -112,7 +114,6 @@ import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; Loading Loading @@ -235,15 +236,28 @@ public final class DisplayManagerService extends SystemService { private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { @Override public void requestDisplayState(int displayId, int state, float brightness) { // TODO (b/168210494): Stop applying default display state to all displays. if (displayId != Display.DEFAULT_DISPLAY) { return; } final int[] displayIds; synchronized (mSyncRoot) { displayIds = mLogicalDisplayMapper.getDisplayIdsLocked(); } // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } } mDisplayPowerCallbacks.onDisplayStateChange(state); if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } } } }; Loading @@ -257,13 +271,16 @@ public final class DisplayManagerService extends SystemService { /** The {@link Handler} used by all {@link DisplayPowerController}s. */ private Handler mPowerHandler; // The overall display state, independent of changes that might influence one // display or another in particular. private int mGlobalDisplayState = Display.STATE_ON; // A map from LogicalDisplay ID to display power state. @GuardedBy("mSyncRoot") private final SparseIntArray mDisplayStates = new SparseIntArray(); // A map from LogicalDisplay ID to display brightness. @GuardedBy("mSyncRoot") private final SparseArray<Float> mDisplayBrightnesses = new SparseArray<>(); // The overall display brightness. // For now, this only applies to the default display but we may split it up eventually. private float mGlobalDisplayBrightness; // The default brightness. private final float mDisplayDefaultBrightness; // Set to true when there are pending display changes that have yet to be applied // to the surface flinger state. Loading Loading @@ -317,11 +334,6 @@ public final class DisplayManagerService extends SystemService { // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. private final int mDefaultDisplayDefaultColorMode; // Temporary list of deferred work to perform when setting the display state. // Only used by requestDisplayState. The field is self-synchronized and only // intended for use inside of the requestGlobalDisplayStateInternal function. private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>(); // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); Loading Loading @@ -372,7 +384,7 @@ public final class DisplayManagerService extends SystemService { mMinimumBrightnessSpline = Spline.createSpline(lux, nits); PowerManager pm = mContext.getSystemService(PowerManager.class); mGlobalDisplayBrightness = pm.getBrightnessConstraint( mDisplayDefaultBrightness = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); mCurrentUserId = UserHandle.USER_SYSTEM; ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); Loading Loading @@ -589,7 +601,7 @@ public final class DisplayManagerService extends SystemService { } } private void requestGlobalDisplayStateInternal(int state, float brightnessState) { private void requestDisplayStateInternal(int displayId, int state, float brightnessState) { if (state == Display.STATE_UNKNOWN) { state = Display.STATE_ON; } Loading @@ -602,38 +614,40 @@ public final class DisplayManagerService extends SystemService { brightnessState = PowerManager.BRIGHTNESS_MAX; } synchronized (mTempDisplayStateWorkQueue) { try { // Update the display state within the lock. // Note that we do not need to schedule traversals here although it // may happen as a side-effect of displays changing state. final Runnable runnable; final String traceMessage; synchronized (mSyncRoot) { if (mGlobalDisplayState == state && mGlobalDisplayBrightness == brightnessState) { return; // no change final int index = mDisplayStates.indexOfKey(displayId); if (index < 0 || (mDisplayStates.valueAt(index) == state && BrightnessSynchronizer.floatEquals(mDisplayBrightnesses.valueAt(index), brightnessState))) { return; // Display no longer exists or no change. } Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" traceMessage = "requestDisplayStateInternal(" + displayId + ", " + Display.stateToString(state) + ", brightness=" + brightnessState + ")"); + ", brightness=" + brightnessState + ")"; Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId); mGlobalDisplayState = state; mGlobalDisplayBrightness = brightnessState; applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); mDisplayStates.setValueAt(index, state); mDisplayBrightnesses.setValueAt(index, brightnessState); runnable = updateDisplayStateLocked( mLogicalDisplayMapper.getLocked(displayId).getPrimaryDisplayDeviceLocked()); } // Setting the display power state can take hundreds of milliseconds // to complete so we defer the most expensive part of the work until // after we have exited the critical section to avoid blocking other // threads for a long time. for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) { mTempDisplayStateWorkQueue.get(i).run(); } Trace.traceEnd(Trace.TRACE_TAG_POWER); } finally { mTempDisplayStateWorkQueue.clear(); } if (runnable != null) { runnable.run(); } Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, traceMessage, displayId); } private class SettingsObserver extends ContentObserver { Loading Loading @@ -987,6 +1001,8 @@ public final class DisplayManagerService extends SystemService { recordTopInsetLocked(display); } addDisplayPowerControllerLocked(displayId); mDisplayStates.append(displayId, Display.STATE_OFF); mDisplayBrightnesses.append(displayId, mDisplayDefaultBrightness); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); Loading Loading @@ -1021,6 +1037,8 @@ public final class DisplayManagerService extends SystemService { private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { final int displayId = display.getDisplayIdLocked(); mDisplayPowerControllers.delete(displayId); mDisplayStates.delete(displayId); mDisplayBrightnesses.delete(displayId); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); scheduleTraversalLocked(false); Loading @@ -1035,15 +1053,6 @@ public final class DisplayManagerService extends SystemService { handleLogicalDisplayChangedLocked(display); } private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> { Runnable runnable = updateDisplayStateLocked(device); if (runnable != null) { workQueue.add(runnable); } }); } private Runnable updateDisplayStateLocked(DisplayDevice device) { // Blank or unblank the display immediately to match the state requested // by the display power controller (if known). Loading @@ -1052,12 +1061,16 @@ public final class DisplayManagerService extends SystemService { // TODO - b/170498827 The rules regarding what display state to apply to each // display will depend on the configuration/mapping of logical displays. // Clean up LogicalDisplay.isEnabled() mechanism once this is fixed. int state = mGlobalDisplayState; final LogicalDisplay display = mLogicalDisplayMapper.getLocked(device); if (display != null && !display.isEnabled()) { final int state; final int displayId = display.getDisplayIdLocked(); if (display.isEnabled()) { state = mDisplayStates.get(displayId); } else { state = Display.STATE_OFF; } return device.requestDisplayStateLocked(state, mGlobalDisplayBrightness); final float brightness = mDisplayBrightnesses.get(displayId); return device.requestDisplayStateLocked(state, brightness); } return null; } Loading Loading @@ -1587,13 +1600,24 @@ public final class DisplayManagerService extends SystemService { pw.println(" mOnlyCode=" + mOnlyCore); pw.println(" mSafeMode=" + mSafeMode); pw.println(" mPendingTraversal=" + mPendingTraversal); pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); pw.println(" mViewports=" + mViewports); pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); pw.println(" mStableDisplaySize=" + mStableDisplaySize); pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); pw.println(); final int displayStateCount = mDisplayStates.size(); pw.println("Display States: size=" + displayStateCount); for (int i = 0; i < displayStateCount; i++) { final int displayId = mDisplayStates.keyAt(i); final int displayState = mDisplayStates.valueAt(i); final float brightness = mDisplayBrightnesses.valueAt(i); pw.println(" Display Id=" + displayId); pw.println(" Display State=" + Display.stateToString(displayState)); pw.println(" Display Brightness=" + brightness); } IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); Loading
services/core/java/com/android/server/display/DisplayPowerController.java +0 −2 Original line number Diff line number Diff line Loading @@ -685,8 +685,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void initialize() { // Initialize the power state object for the default display. // In the future, we might manage multiple displays independently. mPowerState = new DisplayPowerState(mBlanker, mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId); Loading
services/core/java/com/android/server/display/LogicalDisplay.java +1 −1 Original line number Diff line number Diff line Loading @@ -588,7 +588,7 @@ final class LogicalDisplay { } /** * Swap the underlying {@link DisplayDevice} with the specificed LogicalDisplay. * Swap the underlying {@link DisplayDevice} with the specified LogicalDisplay. * * @param targetDisplay The display with which to swap display-devices. * @return {@code true} if the displays were swapped, {@code false} otherwise. Loading
services/core/java/com/android/server/display/LogicalDisplayMapper.java +5 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.display; import android.content.Context; import android.os.Process; import android.os.SystemProperties; import android.text.TextUtils; import android.util.Slog; Loading Loading @@ -149,6 +150,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return null; } public int[] getDisplayIdsLocked() { return getDisplayIdsLocked(Process.SYSTEM_UID); } public int[] getDisplayIdsLocked(int callingUid) { final int count = mLogicalDisplays.size(); int[] displayIds = new int[count]; Loading