Loading core/java/android/hardware/display/DisplayManagerInternal.java +52 −11 Original line number Diff line number Diff line Loading @@ -47,28 +47,40 @@ public abstract class DisplayManagerInternal { * begins adjusting the power state to match what was requested. * </p> * * @param groupId The identifier for the display group being requested to change power state * @param request The requested power state. * @param waitForNegativeProximity If true, issues a request to wait for * @param waitForNegativeProximity If {@code true}, issues a request to wait for * negative proximity before turning the screen back on, assuming the screen * was turned off by the proximity sensor. * @return True if display is ready, false if there are important changes that must * be made asynchronously (such as turning the screen on), in which case the caller * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} * then try the request again later until the state converges. * @return {@code true} if display group is ready, {@code false} if there are important * changes that must be made asynchronously (such as turning the screen on), in which case * the caller should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged} * then try the request again later until the state converges. If the provided {@code groupId} * cannot be found then {@code true} will be returned. */ public abstract boolean requestPowerState(DisplayPowerRequest request, public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request, boolean waitForNegativeProximity); /** * Returns true if the proximity sensor screen-off function is available. * Returns {@code true} if the proximity sensor screen-off function is available. */ public abstract boolean isProximitySensorAvailable(); /** * Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided * display belongs. * Registers a display group listener which will be informed of the addition, removal, or change * of display groups. * * @param listener The listener to register. */ public abstract int getDisplayGroupId(int displayId); public abstract void registerDisplayGroupListener(DisplayGroupListener listener); /** * Unregisters a display group listener which will be informed of the addition, removal, or * change of display groups. * * @param listener The listener to unregister. */ public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener); /** * Screenshot for internal system-only use such as rotation, etc. This method includes Loading Loading @@ -451,7 +463,7 @@ public abstract class DisplayManagerInternal { void onStateChanged(); void onProximityPositive(); void onProximityNegative(); void onDisplayStateChange(int state); // one of the Display state constants void onDisplayStateChange(boolean allInactive, boolean allOff); void acquireSuspendBlocker(); void releaseSuspendBlocker(); Loading @@ -465,4 +477,33 @@ public abstract class DisplayManagerInternal { public interface DisplayTransactionListener { void onDisplayTransaction(Transaction t); } /** * Called when there are changes to {@link com.android.server.display.DisplayGroup * DisplayGroups}. */ public interface DisplayGroupListener { /** * A new display group with the provided {@code groupId} was added. * This is guaranteed to be called <i>before</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupAdded(int groupId); /** * The display group with the provided {@code groupId} was removed. * * This is guaranteed to be called <i>after</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupRemoved(int groupId); /** * The display group with the provided {@code groupId} has changed. * * This is guaranteed to be called <i>after</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupChanged(int groupId); } } core/java/android/os/PowerManager.java +70 −10 Original line number Diff line number Diff line Loading @@ -416,9 +416,21 @@ public final class PowerManager { public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10; /** * Go to sleep reason code: The last powered on display group has been removed. * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_QUIESCENT; public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED = 11; /** * Go to sleep reason code: Every display group has been turned off. * @hide */ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF = 12; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF; /** * @hide Loading @@ -435,6 +447,8 @@ public final class PowerManager { case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility"; case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend"; case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive"; case GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED: return "display_group_removed"; case GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF: return "display_groups_turned_off"; default: return Integer.toString(sleepReason); } } Loading Loading @@ -521,6 +535,8 @@ public final class PowerManager { WAKE_REASON_WAKE_KEY, WAKE_REASON_WAKE_MOTION, WAKE_REASON_HDMI, WAKE_REASON_DISPLAY_GROUP_ADDED, WAKE_REASON_DISPLAY_GROUP_TURNED_ON, }) @Retention(RetentionPolicy.SOURCE) public @interface WakeReason{} Loading Loading @@ -607,6 +623,18 @@ public final class PowerManager { */ public static final int WAKE_REASON_LID = 9; /** * Wake up reason code: Waking due to display group being added. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10; /** * Wake up reason code: Waking due to display group being powered on. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11; /** * Convert the wake reason to a string for debugging purposes. * @hide Loading @@ -623,6 +651,8 @@ public final class PowerManager { case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION"; case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI"; case WAKE_REASON_LID: return "WAKE_REASON_LID"; case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED"; case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON"; default: return Integer.toString(wakeReason); } } Loading Loading @@ -1215,7 +1245,14 @@ public final class PowerManager { } /** * Forces the device to go to sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn off. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT * default display group} is already off then nothing will happen. * * <p> * Overrides all the wake locks that are held. * This is what happens when the power key is pressed to turn off the screen. Loading @@ -1238,7 +1275,14 @@ public final class PowerManager { } /** * Forces the device to go to sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn off. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT * default display group} is already off then nothing will happen. * * <p> * Overrides all the wake locks that are held. * This is what happens when the power key is pressed to turn off the screen. Loading Loading @@ -1268,9 +1312,15 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn on. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already * on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading @@ -1293,9 +1343,15 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn on. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already * on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading @@ -1322,9 +1378,13 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on. * * <p>If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading services/core/java/com/android/server/display/DisplayGroup.java +31 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ import java.util.List; /** * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and * operations. * operations; particularly display-state. * * @hide */ public class DisplayGroup { Loading @@ -35,17 +36,44 @@ public class DisplayGroup { mGroupId = groupId; } /** Returns the identifier for the Group. */ int getGroupId() { return mGroupId; } void addDisplay(LogicalDisplay display) { /** * Adds the provided {@code display} to the Group * * @param display the {@link LogicalDisplay} to add to the Group */ void addDisplayLocked(LogicalDisplay display) { if (!mDisplays.contains(display)) { mDisplays.add(display); } } boolean removeDisplay(LogicalDisplay display) { /** * Removes the provided {@code display} from the Group. * * @param display The {@link LogicalDisplay} to remove from the Group. * @return {@code true} if the {@code display} was removed; otherwise {@code false} */ boolean removeDisplayLocked(LogicalDisplay display) { return mDisplays.remove(display); } /** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */ boolean isEmptyLocked() { return mDisplays.isEmpty(); } /** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */ int getSizeLocked() { return mDisplays.size(); } /** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */ int getIdLocked(int index) { return mDisplays.get(index).getDisplayIdLocked(); } } services/core/java/com/android/server/display/DisplayManagerService.java +103 −22 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.hardware.display.Curve; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayedContentSample; Loading Loading @@ -190,6 +191,7 @@ public final class DisplayManagerService extends SystemService { private static final int MSG_UPDATE_VIEWPORT = 5; private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; private final Context mContext; private final DisplayManagerHandler mHandler; Loading Loading @@ -237,36 +239,54 @@ public final class DisplayManagerService extends SystemService { private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = new CopyOnWriteArrayList<DisplayTransactionListener>(); /** List of all display group listeners. */ private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners = new CopyOnWriteArrayList<>(); /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */ private final SparseArray<DisplayPowerController> mDisplayPowerControllers = new SparseArray<>(); /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */ private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { // Synchronized to avoid race conditions when updating multiple display states. @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; public synchronized void requestDisplayState(int displayId, int state, float brightness) { boolean allInactive = true; boolean allOff = true; final boolean stateChanged; synchronized (mSyncRoot) { displayIds = mLogicalDisplayMapper.getDisplayIdsLocked(); final int index = mDisplayStates.indexOfKey(displayId); final int newState = mDisplayStates.valueAt(index); stateChanged = index == -1 || state != newState; if (stateChanged) { final int size = mDisplayStates.size(); for (int i = 0; i < size; i++) { final int displayState = i == index ? newState : state; if (displayState != Display.STATE_OFF) { allOff = false; } if (Display.isActiveState(displayState)) { allInactive = false; } if (!allOff && !allInactive) { break; } } } } // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } requestDisplayStateInternal(displayId, state, brightness); } mDisplayPowerCallbacks.onDisplayStateChange(state); if (stateChanged) { mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff); } if (state != Display.STATE_OFF) { for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } requestDisplayStateInternal(displayId, state, brightness); } } }; Loading Loading @@ -1152,7 +1172,7 @@ public final class DisplayManagerService extends SystemService { private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { final int displayId = display.getDisplayIdLocked(); mDisplayPowerControllers.delete(displayId); mDisplayPowerControllers.removeReturnOld(displayId).stop(); mDisplayStates.delete(displayId); mDisplayBrightnesses.delete(displayId); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); Loading Loading @@ -1669,6 +1689,11 @@ public final class DisplayManagerService extends SystemService { mHandler.sendMessage(msg); } private void sendDisplayGroupEvent(int groupId, int event) { Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event); mHandler.sendMessage(msg); } private void sendDisplayEventFrameRateOverrideLocked(int displayId) { Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE, displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); Loading Loading @@ -1713,6 +1738,35 @@ public final class DisplayManagerService extends SystemService { mTempCallbacks.clear(); } // Runs on Handler thread. // Delivers display group event notifications to callbacks. private void deliverDisplayGroupEvent(int groupId, int event) { if (DEBUG) { Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event=" + event); } switch (event) { case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupAdded(groupId); } break; case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupChanged(groupId); } break; case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupRemoved(groupId); } break; } } private IMediaProjectionManager getProjectionService() { if (mProjectionService == null) { IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); Loading Loading @@ -1935,6 +1989,11 @@ public final class DisplayManagerService extends SystemService { } deliverDisplayEvent(msg.arg1, uids, msg.arg2); break; case MSG_DELIVER_DISPLAY_GROUP_EVENT: deliverDisplayGroupEvent(msg.arg1, msg.arg2); break; } } } Loading Loading @@ -1965,6 +2024,11 @@ public final class DisplayManagerService extends SystemService { } } @Override public void onDisplayGroupEventLocked(int groupId, int event) { sendDisplayGroupEvent(groupId, event); } @Override public void onTraversalRequested() { synchronized (mSyncRoot) { Loading Loading @@ -2700,11 +2764,25 @@ public final class DisplayManagerService extends SystemService { } @Override public boolean requestPowerState(DisplayPowerRequest request, public boolean requestPowerState(int groupId, DisplayPowerRequest request, boolean waitForNegativeProximity) { synchronized (mSyncRoot) { return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) .requestPowerState(request, waitForNegativeProximity); final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked( groupId); if (displayGroup == null) { return true; } final int size = displayGroup.getSizeLocked(); boolean ready = true; for (int i = 0; i < size; i++) { final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(displayGroup.getIdLocked(i)); ready &= displayPowerController.requestPowerState(request, waitForNegativeProximity); } return ready; } } Loading @@ -2717,10 +2795,13 @@ public final class DisplayManagerService extends SystemService { } @Override public int getDisplayGroupId(int displayId) { synchronized (mSyncRoot) { return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId); public void registerDisplayGroupListener(DisplayGroupListener listener) { mDisplayGroupListeners.add(listener); } @Override public void unregisterDisplayGroupListener(DisplayGroupListener listener) { mDisplayGroupListeners.remove(listener); } @Override Loading services/core/java/com/android/server/display/DisplayPowerController.java +11 −0 Original line number Diff line number Diff line Loading @@ -683,6 +683,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // TODO: b/175821789 - Support high brightness on multiple (folding) displays } /** * Unregisters all listeners and interrupts all running threads; halting future work. * * This method should be called when the DisplayPowerController is no longer in use; i.e. when * the {@link #mDisplayId display} has been removed. */ public void stop() { mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); mPowerState.stop(); } private void sendUpdatePowerState() { synchronized (mLock) { sendUpdatePowerStateLocked(); Loading Loading
core/java/android/hardware/display/DisplayManagerInternal.java +52 −11 Original line number Diff line number Diff line Loading @@ -47,28 +47,40 @@ public abstract class DisplayManagerInternal { * begins adjusting the power state to match what was requested. * </p> * * @param groupId The identifier for the display group being requested to change power state * @param request The requested power state. * @param waitForNegativeProximity If true, issues a request to wait for * @param waitForNegativeProximity If {@code true}, issues a request to wait for * negative proximity before turning the screen back on, assuming the screen * was turned off by the proximity sensor. * @return True if display is ready, false if there are important changes that must * be made asynchronously (such as turning the screen on), in which case the caller * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} * then try the request again later until the state converges. * @return {@code true} if display group is ready, {@code false} if there are important * changes that must be made asynchronously (such as turning the screen on), in which case * the caller should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged} * then try the request again later until the state converges. If the provided {@code groupId} * cannot be found then {@code true} will be returned. */ public abstract boolean requestPowerState(DisplayPowerRequest request, public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request, boolean waitForNegativeProximity); /** * Returns true if the proximity sensor screen-off function is available. * Returns {@code true} if the proximity sensor screen-off function is available. */ public abstract boolean isProximitySensorAvailable(); /** * Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided * display belongs. * Registers a display group listener which will be informed of the addition, removal, or change * of display groups. * * @param listener The listener to register. */ public abstract int getDisplayGroupId(int displayId); public abstract void registerDisplayGroupListener(DisplayGroupListener listener); /** * Unregisters a display group listener which will be informed of the addition, removal, or * change of display groups. * * @param listener The listener to unregister. */ public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener); /** * Screenshot for internal system-only use such as rotation, etc. This method includes Loading Loading @@ -451,7 +463,7 @@ public abstract class DisplayManagerInternal { void onStateChanged(); void onProximityPositive(); void onProximityNegative(); void onDisplayStateChange(int state); // one of the Display state constants void onDisplayStateChange(boolean allInactive, boolean allOff); void acquireSuspendBlocker(); void releaseSuspendBlocker(); Loading @@ -465,4 +477,33 @@ public abstract class DisplayManagerInternal { public interface DisplayTransactionListener { void onDisplayTransaction(Transaction t); } /** * Called when there are changes to {@link com.android.server.display.DisplayGroup * DisplayGroups}. */ public interface DisplayGroupListener { /** * A new display group with the provided {@code groupId} was added. * This is guaranteed to be called <i>before</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupAdded(int groupId); /** * The display group with the provided {@code groupId} was removed. * * This is guaranteed to be called <i>after</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupRemoved(int groupId); /** * The display group with the provided {@code groupId} has changed. * * This is guaranteed to be called <i>after</i> any corresponding calls to * {@link android.hardware.display.DisplayManager.DisplayListener} are made. */ void onDisplayGroupChanged(int groupId); } }
core/java/android/os/PowerManager.java +70 −10 Original line number Diff line number Diff line Loading @@ -416,9 +416,21 @@ public final class PowerManager { public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10; /** * Go to sleep reason code: The last powered on display group has been removed. * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_QUIESCENT; public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED = 11; /** * Go to sleep reason code: Every display group has been turned off. * @hide */ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF = 12; /** * @hide */ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF; /** * @hide Loading @@ -435,6 +447,8 @@ public final class PowerManager { case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility"; case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend"; case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive"; case GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED: return "display_group_removed"; case GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF: return "display_groups_turned_off"; default: return Integer.toString(sleepReason); } } Loading Loading @@ -521,6 +535,8 @@ public final class PowerManager { WAKE_REASON_WAKE_KEY, WAKE_REASON_WAKE_MOTION, WAKE_REASON_HDMI, WAKE_REASON_DISPLAY_GROUP_ADDED, WAKE_REASON_DISPLAY_GROUP_TURNED_ON, }) @Retention(RetentionPolicy.SOURCE) public @interface WakeReason{} Loading Loading @@ -607,6 +623,18 @@ public final class PowerManager { */ public static final int WAKE_REASON_LID = 9; /** * Wake up reason code: Waking due to display group being added. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10; /** * Wake up reason code: Waking due to display group being powered on. * @hide */ public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11; /** * Convert the wake reason to a string for debugging purposes. * @hide Loading @@ -623,6 +651,8 @@ public final class PowerManager { case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION"; case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI"; case WAKE_REASON_LID: return "WAKE_REASON_LID"; case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED"; case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON"; default: return Integer.toString(wakeReason); } } Loading Loading @@ -1215,7 +1245,14 @@ public final class PowerManager { } /** * Forces the device to go to sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn off. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT * default display group} is already off then nothing will happen. * * <p> * Overrides all the wake locks that are held. * This is what happens when the power key is pressed to turn off the screen. Loading @@ -1238,7 +1275,14 @@ public final class PowerManager { } /** * Forces the device to go to sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn off. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned on it will be turned off. If all displays are off as a result of this action the * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT * default display group} is already off then nothing will happen. * * <p> * Overrides all the wake locks that are held. * This is what happens when the power key is pressed to turn off the screen. Loading Loading @@ -1268,9 +1312,15 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn on. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already * on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading @@ -1293,9 +1343,15 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} * to turn on. * * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already * on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading @@ -1322,9 +1378,13 @@ public final class PowerManager { } /** * Forces the device to wake up from sleep. * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on. * * <p>If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen. * * <p> * If the device is currently asleep, wakes it up, otherwise does nothing. * This is what happens when the power key is pressed to turn on the screen. * </p><p> * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission. Loading
services/core/java/com/android/server/display/DisplayGroup.java +31 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ import java.util.List; /** * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and * operations. * operations; particularly display-state. * * @hide */ public class DisplayGroup { Loading @@ -35,17 +36,44 @@ public class DisplayGroup { mGroupId = groupId; } /** Returns the identifier for the Group. */ int getGroupId() { return mGroupId; } void addDisplay(LogicalDisplay display) { /** * Adds the provided {@code display} to the Group * * @param display the {@link LogicalDisplay} to add to the Group */ void addDisplayLocked(LogicalDisplay display) { if (!mDisplays.contains(display)) { mDisplays.add(display); } } boolean removeDisplay(LogicalDisplay display) { /** * Removes the provided {@code display} from the Group. * * @param display The {@link LogicalDisplay} to remove from the Group. * @return {@code true} if the {@code display} was removed; otherwise {@code false} */ boolean removeDisplayLocked(LogicalDisplay display) { return mDisplays.remove(display); } /** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */ boolean isEmptyLocked() { return mDisplays.isEmpty(); } /** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */ int getSizeLocked() { return mDisplays.size(); } /** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */ int getIdLocked(int index) { return mDisplays.get(index).getDisplayIdLocked(); } }
services/core/java/com/android/server/display/DisplayManagerService.java +103 −22 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ import android.hardware.display.Curve; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayedContentSample; Loading Loading @@ -190,6 +191,7 @@ public final class DisplayManagerService extends SystemService { private static final int MSG_UPDATE_VIEWPORT = 5; private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; private final Context mContext; private final DisplayManagerHandler mHandler; Loading Loading @@ -237,36 +239,54 @@ public final class DisplayManagerService extends SystemService { private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = new CopyOnWriteArrayList<DisplayTransactionListener>(); /** List of all display group listeners. */ private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners = new CopyOnWriteArrayList<>(); /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */ private final SparseArray<DisplayPowerController> mDisplayPowerControllers = new SparseArray<>(); /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */ private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { // Synchronized to avoid race conditions when updating multiple display states. @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; public synchronized void requestDisplayState(int displayId, int state, float brightness) { boolean allInactive = true; boolean allOff = true; final boolean stateChanged; synchronized (mSyncRoot) { displayIds = mLogicalDisplayMapper.getDisplayIdsLocked(); final int index = mDisplayStates.indexOfKey(displayId); final int newState = mDisplayStates.valueAt(index); stateChanged = index == -1 || state != newState; if (stateChanged) { final int size = mDisplayStates.size(); for (int i = 0; i < size; i++) { final int displayState = i == index ? newState : state; if (displayState != Display.STATE_OFF) { allOff = false; } if (Display.isActiveState(displayState)) { allInactive = false; } if (!allOff && !allInactive) { break; } } } } // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } requestDisplayStateInternal(displayId, state, brightness); } mDisplayPowerCallbacks.onDisplayStateChange(state); if (stateChanged) { mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff); } if (state != Display.STATE_OFF) { for (int id : displayIds) { requestDisplayStateInternal(id, state, brightness); } requestDisplayStateInternal(displayId, state, brightness); } } }; Loading Loading @@ -1152,7 +1172,7 @@ public final class DisplayManagerService extends SystemService { private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { final int displayId = display.getDisplayIdLocked(); mDisplayPowerControllers.delete(displayId); mDisplayPowerControllers.removeReturnOld(displayId).stop(); mDisplayStates.delete(displayId); mDisplayBrightnesses.delete(displayId); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); Loading Loading @@ -1669,6 +1689,11 @@ public final class DisplayManagerService extends SystemService { mHandler.sendMessage(msg); } private void sendDisplayGroupEvent(int groupId, int event) { Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event); mHandler.sendMessage(msg); } private void sendDisplayEventFrameRateOverrideLocked(int displayId) { Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE, displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); Loading Loading @@ -1713,6 +1738,35 @@ public final class DisplayManagerService extends SystemService { mTempCallbacks.clear(); } // Runs on Handler thread. // Delivers display group event notifications to callbacks. private void deliverDisplayGroupEvent(int groupId, int event) { if (DEBUG) { Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event=" + event); } switch (event) { case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupAdded(groupId); } break; case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupChanged(groupId); } break; case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED: for (DisplayGroupListener listener : mDisplayGroupListeners) { listener.onDisplayGroupRemoved(groupId); } break; } } private IMediaProjectionManager getProjectionService() { if (mProjectionService == null) { IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); Loading Loading @@ -1935,6 +1989,11 @@ public final class DisplayManagerService extends SystemService { } deliverDisplayEvent(msg.arg1, uids, msg.arg2); break; case MSG_DELIVER_DISPLAY_GROUP_EVENT: deliverDisplayGroupEvent(msg.arg1, msg.arg2); break; } } } Loading Loading @@ -1965,6 +2024,11 @@ public final class DisplayManagerService extends SystemService { } } @Override public void onDisplayGroupEventLocked(int groupId, int event) { sendDisplayGroupEvent(groupId, event); } @Override public void onTraversalRequested() { synchronized (mSyncRoot) { Loading Loading @@ -2700,11 +2764,25 @@ public final class DisplayManagerService extends SystemService { } @Override public boolean requestPowerState(DisplayPowerRequest request, public boolean requestPowerState(int groupId, DisplayPowerRequest request, boolean waitForNegativeProximity) { synchronized (mSyncRoot) { return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) .requestPowerState(request, waitForNegativeProximity); final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked( groupId); if (displayGroup == null) { return true; } final int size = displayGroup.getSizeLocked(); boolean ready = true; for (int i = 0; i < size; i++) { final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(displayGroup.getIdLocked(i)); ready &= displayPowerController.requestPowerState(request, waitForNegativeProximity); } return ready; } } Loading @@ -2717,10 +2795,13 @@ public final class DisplayManagerService extends SystemService { } @Override public int getDisplayGroupId(int displayId) { synchronized (mSyncRoot) { return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId); public void registerDisplayGroupListener(DisplayGroupListener listener) { mDisplayGroupListeners.add(listener); } @Override public void unregisterDisplayGroupListener(DisplayGroupListener listener) { mDisplayGroupListeners.remove(listener); } @Override Loading
services/core/java/com/android/server/display/DisplayPowerController.java +11 −0 Original line number Diff line number Diff line Loading @@ -683,6 +683,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // TODO: b/175821789 - Support high brightness on multiple (folding) displays } /** * Unregisters all listeners and interrupts all running threads; halting future work. * * This method should be called when the DisplayPowerController is no longer in use; i.e. when * the {@link #mDisplayId display} has been removed. */ public void stop() { mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); mPowerState.stop(); } private void sendUpdatePowerState() { synchronized (mLock) { sendUpdatePowerStateLocked(); Loading