Merge "Request power state updates for individual DisplayGroups" into sc-dev
This commit is contained in:
@@ -66,12 +66,6 @@ public abstract class DisplayManagerInternal {
|
||||
*/
|
||||
public abstract boolean isProximitySensorAvailable();
|
||||
|
||||
/**
|
||||
* Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided
|
||||
* display belongs.
|
||||
*/
|
||||
public abstract int getDisplayGroupId(int displayId);
|
||||
|
||||
/**
|
||||
* Registers a display group listener which will be informed of the addition, removal, or change
|
||||
* of display groups.
|
||||
@@ -469,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();
|
||||
|
||||
@@ -354,6 +354,10 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
setLightSensorEnabled(false);
|
||||
}
|
||||
|
||||
public boolean hasUserDataPoints() {
|
||||
return mBrightnessMapper.hasUserDataPoints();
|
||||
}
|
||||
|
||||
@@ -243,7 +243,6 @@ public class BrightnessTracker {
|
||||
}
|
||||
|
||||
/** Stop listening for events */
|
||||
@VisibleForTesting
|
||||
void stop() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Stop");
|
||||
|
||||
@@ -817,6 +817,12 @@ final class ColorFade {
|
||||
}
|
||||
|
||||
DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(mDisplayId);
|
||||
if (displayInfo == null) {
|
||||
// displayInfo can be null if the associated display has been removed. There
|
||||
// is a delay between the display being removed and ColorFade being dismissed.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (displayInfo.rotation) {
|
||||
case Surface.ROTATION_0:
|
||||
t.setPosition(mSurfaceControl, 0, 0);
|
||||
|
||||
@@ -249,30 +249,48 @@ public final class DisplayManagerService extends SystemService {
|
||||
|
||||
/** {@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);
|
||||
if (index > -1) {
|
||||
final int currentState = mDisplayStates.valueAt(index);
|
||||
stateChanged = state != currentState;
|
||||
if (stateChanged) {
|
||||
final int size = mDisplayStates.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int displayState = i == index ? state : mDisplayStates.valueAt(i);
|
||||
if (displayState != Display.STATE_OFF) {
|
||||
allOff = false;
|
||||
}
|
||||
if (Display.isActiveState(displayState)) {
|
||||
allInactive = false;
|
||||
}
|
||||
if (!allOff && !allInactive) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stateChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1160,7 +1178,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();
|
||||
@@ -2758,8 +2776,22 @@ public final class DisplayManagerService extends SystemService {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2771,13 +2803,6 @@ public final class DisplayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayGroupId(int displayId) {
|
||||
synchronized (mSyncRoot) {
|
||||
return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDisplayGroupListener(DisplayGroupListener listener) {
|
||||
mDisplayGroupListeners.add(listener);
|
||||
|
||||
@@ -121,6 +121,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 6;
|
||||
private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 7;
|
||||
private static final int MSG_IGNORE_PROXIMITY = 8;
|
||||
private static final int MSG_STOP = 9;
|
||||
|
||||
private static final int PROXIMITY_UNKNOWN = -1;
|
||||
private static final int PROXIMITY_NEGATIVE = 0;
|
||||
@@ -351,6 +352,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
@Nullable
|
||||
private final DisplayWhiteBalanceController mDisplayWhiteBalanceController;
|
||||
|
||||
@Nullable
|
||||
private final ColorDisplayServiceInternal mCdsi;
|
||||
private final float[] mNitsRange;
|
||||
|
||||
@@ -409,6 +411,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
private ObjectAnimator mColorFadeOffAnimator;
|
||||
private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
|
||||
|
||||
// True if this DisplayPowerController has been stopped and should no longer be running.
|
||||
private boolean mStopped;
|
||||
|
||||
/**
|
||||
* Creates the display power controller.
|
||||
*/
|
||||
@@ -583,14 +588,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
DisplayWhiteBalanceSettings displayWhiteBalanceSettings = null;
|
||||
DisplayWhiteBalanceController displayWhiteBalanceController = null;
|
||||
try {
|
||||
displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler);
|
||||
displayWhiteBalanceController = DisplayWhiteBalanceFactory.create(mHandler,
|
||||
mSensorManager, resources);
|
||||
displayWhiteBalanceSettings.setCallbacks(this);
|
||||
displayWhiteBalanceController.setCallbacks(this);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "failed to set up display white-balance: " + e);
|
||||
if (mDisplayId == Display.DEFAULT_DISPLAY) {
|
||||
try {
|
||||
displayWhiteBalanceSettings = new DisplayWhiteBalanceSettings(mContext, mHandler);
|
||||
displayWhiteBalanceController = DisplayWhiteBalanceFactory.create(mHandler,
|
||||
mSensorManager, resources);
|
||||
displayWhiteBalanceSettings.setCallbacks(this);
|
||||
displayWhiteBalanceController.setCallbacks(this);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "failed to set up display white-balance: " + e);
|
||||
}
|
||||
}
|
||||
mDisplayWhiteBalanceSettings = displayWhiteBalanceSettings;
|
||||
mDisplayWhiteBalanceController = displayWhiteBalanceController;
|
||||
@@ -602,20 +609,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mNitsRange = BrightnessMappingStrategy.getFloatArray(context.getResources()
|
||||
.obtainTypedArray(com.android.internal.R.array.config_screenBrightnessNits));
|
||||
}
|
||||
mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
|
||||
boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() {
|
||||
@Override
|
||||
public void onReduceBrightColorsActivationChanged(boolean activated) {
|
||||
applyReduceBrightColorsSplineAdjustment();
|
||||
}
|
||||
if (mDisplayId == Display.DEFAULT_DISPLAY) {
|
||||
mCdsi = LocalServices.getService(ColorDisplayServiceInternal.class);
|
||||
boolean active = mCdsi.setReduceBrightColorsListener(new ReduceBrightColorsListener() {
|
||||
@Override
|
||||
public void onReduceBrightColorsActivationChanged(boolean activated) {
|
||||
applyReduceBrightColorsSplineAdjustment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReduceBrightColorsStrengthChanged(int strength) {
|
||||
@Override
|
||||
public void onReduceBrightColorsStrengthChanged(int strength) {
|
||||
applyReduceBrightColorsSplineAdjustment();
|
||||
}
|
||||
});
|
||||
if (active) {
|
||||
applyReduceBrightColorsSplineAdjustment();
|
||||
}
|
||||
});
|
||||
if (active) {
|
||||
applyReduceBrightColorsSplineAdjustment();
|
||||
} else {
|
||||
mCdsi = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,6 +724,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mStopped) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (waitForNegativeProximity
|
||||
@@ -731,11 +746,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
if (changed) {
|
||||
mDisplayReadyLocked = false;
|
||||
}
|
||||
|
||||
if (changed && !mPendingRequestChangedLocked) {
|
||||
mPendingRequestChangedLocked = true;
|
||||
sendUpdatePowerStateLocked();
|
||||
if (!mPendingRequestChangedLocked) {
|
||||
mPendingRequestChangedLocked = true;
|
||||
sendUpdatePowerStateLocked();
|
||||
}
|
||||
}
|
||||
|
||||
return mDisplayReadyLocked;
|
||||
@@ -758,6 +772,34 @@ 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() {
|
||||
synchronized (mLock) {
|
||||
mStopped = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_STOP);
|
||||
mHandler.sendMessage(msg);
|
||||
|
||||
if (mDisplayWhiteBalanceController != null) {
|
||||
mDisplayWhiteBalanceController.setEnabled(false);
|
||||
}
|
||||
|
||||
if (mAutomaticBrightnessController != null) {
|
||||
mAutomaticBrightnessController.stop();
|
||||
}
|
||||
|
||||
if (mBrightnessTracker != null) {
|
||||
mBrightnessTracker.stop();
|
||||
}
|
||||
|
||||
mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUpdatePowerState() {
|
||||
synchronized (mLock) {
|
||||
sendUpdatePowerStateLocked();
|
||||
@@ -765,7 +807,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
|
||||
private void sendUpdatePowerStateLocked() {
|
||||
if (!mPendingUpdatePowerStateLocked) {
|
||||
if (!mStopped && !mPendingUpdatePowerStateLocked) {
|
||||
mPendingUpdatePowerStateLocked = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
|
||||
mHandler.sendMessage(msg);
|
||||
@@ -788,7 +830,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mColorFadeOffAnimator.addListener(mAnimatorListener);
|
||||
}
|
||||
|
||||
mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
|
||||
mScreenBrightnessRampAnimator = new RampAnimator<>(
|
||||
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT);
|
||||
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
|
||||
|
||||
@@ -829,12 +871,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
};
|
||||
|
||||
private final RampAnimator.Listener mRampAnimatorListener = new RampAnimator.Listener() {
|
||||
@Override
|
||||
public void onAnimationEnd() {
|
||||
sendUpdatePowerState();
|
||||
}
|
||||
};
|
||||
private final RampAnimator.Listener mRampAnimatorListener = this::sendUpdatePowerState;
|
||||
|
||||
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
|
||||
private void cleanupHandlerThreadAfterStop() {
|
||||
setProximitySensorEnabled(false);
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
mPowerState.stop();
|
||||
mPowerState = null;
|
||||
}
|
||||
|
||||
private void updatePowerState() {
|
||||
// Update the power state request.
|
||||
@@ -844,6 +889,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
int brightnessAdjustmentFlags = 0;
|
||||
mBrightnessReasonTemp.set(null);
|
||||
synchronized (mLock) {
|
||||
if (mStopped) {
|
||||
return;
|
||||
}
|
||||
mPendingUpdatePowerStateLocked = false;
|
||||
if (mPendingRequestLocked == null) {
|
||||
return; // wait until first actual power request
|
||||
@@ -2144,6 +2192,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
case MSG_IGNORE_PROXIMITY:
|
||||
ignoreProximitySensorUntilChangedInternal();
|
||||
break;
|
||||
|
||||
case MSG_STOP:
|
||||
cleanupHandlerThreadAfterStop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ final class DisplayPowerState {
|
||||
|
||||
private Runnable mCleanListener;
|
||||
|
||||
private volatile boolean mStopped;
|
||||
|
||||
DisplayPowerState(
|
||||
DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) {
|
||||
mHandler = new Handler(true /*async*/);
|
||||
@@ -264,9 +266,24 @@ final class DisplayPowerState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts all running threads; halting future work.
|
||||
*
|
||||
* This method should be called when the DisplayPowerState is no longer in use; i.e. when
|
||||
* the {@link #mDisplayId display} has been removed.
|
||||
*/
|
||||
public void stop() {
|
||||
mStopped = true;
|
||||
mPhotonicModulator.interrupt();
|
||||
dismissColorFade();
|
||||
mCleanListener = null;
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("Display Power State:");
|
||||
pw.println(" mStopped=" + mStopped);
|
||||
pw.println(" mScreenState=" + Display.stateToString(mScreenState));
|
||||
pw.println(" mScreenBrightness=" + mScreenBrightness);
|
||||
pw.println(" mScreenReady=" + mScreenReady);
|
||||
@@ -428,7 +445,11 @@ final class DisplayPowerState {
|
||||
if (!stateChanged && !backlightChanged) {
|
||||
try {
|
||||
mLock.wait();
|
||||
} catch (InterruptedException ex) { }
|
||||
} catch (InterruptedException ex) {
|
||||
if (mStopped) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
mActualState = state;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.display;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Process;
|
||||
import android.os.SystemProperties;
|
||||
import android.text.TextUtils;
|
||||
import android.util.IndentingPrintWriter;
|
||||
@@ -143,10 +142,6 @@ 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];
|
||||
@@ -171,15 +166,6 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public int getDisplayGroupIdLocked(int displayId) {
|
||||
final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
|
||||
if (displayGroup != null) {
|
||||
return displayGroup.getGroupId();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public DisplayGroup getDisplayGroupLocked(int groupId) {
|
||||
final int size = mDisplayIdToGroupMap.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.power;
|
||||
|
||||
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
|
||||
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
|
||||
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
|
||||
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
|
||||
|
||||
import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_ADDED;
|
||||
import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_CHANGED;
|
||||
import static com.android.server.power.DisplayGroupPowerStateMapper.DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED;
|
||||
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.PowerManagerInternal;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.display.DisplayGroup;
|
||||
|
||||
/**
|
||||
* Responsible for creating {@link DisplayPowerRequest}s and associating them with
|
||||
* {@link com.android.server.display.DisplayGroup}s.
|
||||
*
|
||||
* Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
|
||||
* which is used to request power state changes to every display in the group.
|
||||
*/
|
||||
public class DisplayGroupPowerStateMapper {
|
||||
|
||||
private static final String TAG = "DisplayPowerRequestMapper";
|
||||
|
||||
/** Lock obtained from {@link PowerManagerService}. */
|
||||
private final Object mLock;
|
||||
|
||||
/** Listener to inform of changes to display groups. */
|
||||
private final DisplayGroupPowerChangeListener mListener;
|
||||
|
||||
/** A mapping from DisplayGroup Id to DisplayGroup information. */
|
||||
@GuardedBy("mLock")
|
||||
private final SparseArray<DisplayGroupInfo> mDisplayGroupInfos = new SparseArray<>();
|
||||
|
||||
/** A cached array of DisplayGroup Ids. */
|
||||
@GuardedBy("mLock")
|
||||
private int[] mDisplayGroupIds;
|
||||
|
||||
private final DisplayManagerInternal.DisplayGroupListener mDisplayGroupListener =
|
||||
new DisplayManagerInternal.DisplayGroupListener() {
|
||||
@Override
|
||||
public void onDisplayGroupAdded(int groupId) {
|
||||
synchronized (mLock) {
|
||||
if (mDisplayGroupInfos.contains(groupId)) {
|
||||
Slog.e(TAG, "Tried to add already existing group:" + groupId);
|
||||
return;
|
||||
}
|
||||
// For now, only the default group supports sandman (dream/AOD).
|
||||
final boolean supportsSandman = groupId == Display.DEFAULT_DISPLAY_GROUP;
|
||||
final DisplayGroupInfo displayGroupInfo = new DisplayGroupInfo(
|
||||
new DisplayPowerRequest(),
|
||||
getGlobalWakefulnessLocked(),
|
||||
/* ready= */ false,
|
||||
supportsSandman);
|
||||
mDisplayGroupInfos.append(groupId, displayGroupInfo);
|
||||
mDisplayGroupIds = ArrayUtils.appendInt(mDisplayGroupIds, groupId);
|
||||
mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_ADDED, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayGroupRemoved(int groupId) {
|
||||
synchronized (mLock) {
|
||||
if (!mDisplayGroupInfos.contains(groupId)) {
|
||||
Slog.e(TAG, "Tried to remove non-existent group:" + groupId);
|
||||
return;
|
||||
}
|
||||
mDisplayGroupInfos.delete(groupId);
|
||||
mDisplayGroupIds = ArrayUtils.removeInt(mDisplayGroupIds, groupId);
|
||||
mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_REMOVED, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayGroupChanged(int groupId) {
|
||||
synchronized (mLock) {
|
||||
mListener.onDisplayGroupEventLocked(DISPLAY_GROUP_CHANGED, groupId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DisplayGroupPowerStateMapper(Object lock, DisplayManagerInternal displayManagerInternal,
|
||||
DisplayGroupPowerChangeListener listener) {
|
||||
mLock = lock;
|
||||
mListener = listener;
|
||||
displayManagerInternal.registerDisplayGroupListener(mDisplayGroupListener);
|
||||
|
||||
final DisplayGroupInfo displayGroupInfo = new DisplayGroupInfo(
|
||||
new DisplayPowerRequest(), WAKEFULNESS_AWAKE, /* ready= */
|
||||
false, /* supportsSandman= */ true);
|
||||
mDisplayGroupInfos.append(Display.DEFAULT_DISPLAY_GROUP, displayGroupInfo);
|
||||
mDisplayGroupIds = new int[]{Display.DEFAULT_DISPLAY_GROUP};
|
||||
}
|
||||
|
||||
DisplayPowerRequest getPowerRequestLocked(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).displayPowerRequest;
|
||||
}
|
||||
|
||||
int[] getDisplayGroupIdsLocked() {
|
||||
return mDisplayGroupIds;
|
||||
}
|
||||
|
||||
int getWakefulnessLocked(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).wakefulness;
|
||||
}
|
||||
|
||||
void setLastPowerOnTimeLocked(int groupId, long eventTime) {
|
||||
mDisplayGroupInfos.get(groupId).lastPowerOnTime = eventTime;
|
||||
}
|
||||
|
||||
long getLastPowerOnTimeLocked(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).lastPowerOnTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amalgamated wakefulness of all {@link DisplayGroup DisplayGroups}.
|
||||
*
|
||||
* <p>This will be the highest wakeful state of all {@link DisplayGroup DisplayGroups}; ordered
|
||||
* from highest to lowest:
|
||||
* <ol>
|
||||
* <li>{@link PowerManagerInternal#WAKEFULNESS_AWAKE}
|
||||
* <li>{@link PowerManagerInternal#WAKEFULNESS_DREAMING}
|
||||
* <li>{@link PowerManagerInternal#WAKEFULNESS_DOZING}
|
||||
* <li>{@link PowerManagerInternal#WAKEFULNESS_ASLEEP}
|
||||
* </ol>
|
||||
*/
|
||||
int getGlobalWakefulnessLocked() {
|
||||
final int size = mDisplayGroupInfos.size();
|
||||
int deviceWakefulness = WAKEFULNESS_ASLEEP;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int wakefulness = mDisplayGroupInfos.valueAt(i).wakefulness;
|
||||
if (wakefulness == WAKEFULNESS_AWAKE) {
|
||||
return WAKEFULNESS_AWAKE;
|
||||
} else if (wakefulness == WAKEFULNESS_DREAMING
|
||||
&& (deviceWakefulness == WAKEFULNESS_ASLEEP
|
||||
|| deviceWakefulness == WAKEFULNESS_DOZING)) {
|
||||
deviceWakefulness = WAKEFULNESS_DREAMING;
|
||||
} else if (wakefulness == WAKEFULNESS_DOZING
|
||||
&& deviceWakefulness == WAKEFULNESS_ASLEEP) {
|
||||
deviceWakefulness = WAKEFULNESS_DOZING;
|
||||
}
|
||||
}
|
||||
|
||||
return deviceWakefulness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code wakefulness} value for the {@link DisplayGroup} specified by the provided
|
||||
* {@code groupId}.
|
||||
*
|
||||
* @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
|
||||
*/
|
||||
boolean setWakefulnessLocked(int groupId, int wakefulness) {
|
||||
final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
|
||||
if (displayGroupInfo.wakefulness != wakefulness) {
|
||||
displayGroupInfo.wakefulness = wakefulness;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isSandmanSummoned(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).sandmanSummoned;
|
||||
}
|
||||
|
||||
boolean isSandmanSupported(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).supportsSandman;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not the sandman is summoned for the given {@code groupId}.
|
||||
*
|
||||
* @param groupId Signifies the DisplayGroup for which to summon or unsummon the
|
||||
* sandman.
|
||||
* @param sandmanSummoned {@code true} to summon the sandman; {@code false} to unsummon.
|
||||
*/
|
||||
void setSandmanSummoned(int groupId, boolean sandmanSummoned) {
|
||||
final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
|
||||
displayGroupInfo.sandmanSummoned = displayGroupInfo.supportsSandman && sandmanSummoned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if every display in the specified group has its requested state matching
|
||||
* its actual state.
|
||||
*
|
||||
* @param groupId The identifier for the display group to check for readiness.
|
||||
*/
|
||||
boolean isReady(int groupId) {
|
||||
return mDisplayGroupInfos.get(groupId).ready;
|
||||
}
|
||||
|
||||
/** Returns {@code true} if every display has its requested state matching its actual state. */
|
||||
boolean areAllDisplaysReadyLocked() {
|
||||
final int size = mDisplayGroupInfos.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (!mDisplayGroupInfos.valueAt(i).ready) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the displays specified by the provided {@code groupId} are all ready.
|
||||
*
|
||||
* <p>A display is ready if its reported
|
||||
* {@link DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() actual state} matches
|
||||
* its {@link DisplayManagerInternal#requestPowerState requested state}.
|
||||
*
|
||||
* @param groupId The identifier for the display group.
|
||||
* @param ready {@code true} if every display in the group is ready; otherwise {@code false}.
|
||||
* @return {@code true} if the ready state changed; otherwise {@code false}.
|
||||
*/
|
||||
boolean setDisplayGroupReadyLocked(int groupId, boolean ready) {
|
||||
final DisplayGroupInfo displayGroupInfo = mDisplayGroupInfos.get(groupId);
|
||||
if (displayGroupInfo.ready != ready) {
|
||||
displayGroupInfo.ready = ready;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface through which an interested party may be informed of {@link DisplayGroup} events.
|
||||
*/
|
||||
interface DisplayGroupPowerChangeListener {
|
||||
int DISPLAY_GROUP_ADDED = 0;
|
||||
int DISPLAY_GROUP_REMOVED = 1;
|
||||
int DISPLAY_GROUP_CHANGED = 2;
|
||||
|
||||
void onDisplayGroupEventLocked(int event, int groupId);
|
||||
}
|
||||
|
||||
private static final class DisplayGroupInfo {
|
||||
public final DisplayPowerRequest displayPowerRequest;
|
||||
public int wakefulness;
|
||||
public boolean ready;
|
||||
public long lastPowerOnTime;
|
||||
public boolean sandmanSummoned;
|
||||
|
||||
/** {@code true} if this DisplayGroup supports dreaming; otherwise {@code false}. */
|
||||
public boolean supportsSandman;
|
||||
|
||||
DisplayGroupInfo(DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
|
||||
boolean supportsSandman) {
|
||||
this.displayPowerRequest = displayPowerRequest;
|
||||
this.wakefulness = wakefulness;
|
||||
this.ready = ready;
|
||||
this.supportsSandman = supportsSandman;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* 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.power;
|
||||
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.Handler;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
/**
|
||||
* Responsible for creating {@link DisplayPowerRequest}s and associating them with
|
||||
* {@link com.android.server.display.DisplayGroup}s.
|
||||
*
|
||||
* Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
|
||||
* which is used to request power state changes to every display in the group.
|
||||
*/
|
||||
class DisplayPowerRequestMapper {
|
||||
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/** A mapping from LogicalDisplay Id to DisplayGroup Id. */
|
||||
@GuardedBy("mLock")
|
||||
private final SparseIntArray mDisplayGroupIds = new SparseIntArray();
|
||||
|
||||
/** A mapping from DisplayGroup Id to DisplayPowerRequest. */
|
||||
@GuardedBy("mLock")
|
||||
private final SparseArray<DisplayPowerRequest> mDisplayPowerRequests = new SparseArray<>();
|
||||
|
||||
private final DisplayManagerInternal mDisplayManagerInternal;
|
||||
|
||||
private final DisplayManager.DisplayListener mDisplayListener =
|
||||
new DisplayManager.DisplayListener() {
|
||||
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
synchronized (mLock) {
|
||||
if (mDisplayGroupIds.indexOfKey(displayId) >= 0) {
|
||||
return;
|
||||
}
|
||||
final int displayGroupId = mDisplayManagerInternal.getDisplayGroupId(
|
||||
displayId);
|
||||
if (!mDisplayPowerRequests.contains(displayGroupId)) {
|
||||
// A new DisplayGroup was created; create a new DisplayPowerRequest.
|
||||
mDisplayPowerRequests.append(displayGroupId, new DisplayPowerRequest());
|
||||
}
|
||||
mDisplayGroupIds.append(displayId, displayGroupId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final int index = mDisplayGroupIds.indexOfKey(displayId);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
final int displayGroupId = mDisplayGroupIds.valueAt(index);
|
||||
mDisplayGroupIds.removeAt(index);
|
||||
|
||||
if (mDisplayGroupIds.indexOfValue(displayGroupId) < 0) {
|
||||
// The DisplayGroup no longer exists; delete the DisplayPowerRequest.
|
||||
mDisplayPowerRequests.delete(displayGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final int newDisplayGroupId = mDisplayManagerInternal.getDisplayGroupId(
|
||||
displayId);
|
||||
final int oldDisplayGroupId = mDisplayGroupIds.get(displayId);
|
||||
|
||||
if (!mDisplayPowerRequests.contains(newDisplayGroupId)) {
|
||||
// A new DisplayGroup was created; create a new DisplayPowerRequest.
|
||||
mDisplayPowerRequests.append(newDisplayGroupId,
|
||||
new DisplayPowerRequest());
|
||||
}
|
||||
mDisplayGroupIds.put(displayId, newDisplayGroupId);
|
||||
|
||||
if (mDisplayGroupIds.indexOfValue(oldDisplayGroupId) < 0) {
|
||||
// The DisplayGroup no longer exists; delete the DisplayPowerRequest.
|
||||
mDisplayPowerRequests.delete(oldDisplayGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DisplayPowerRequestMapper(DisplayManager displayManager,
|
||||
DisplayManagerInternal displayManagerInternal, Handler handler) {
|
||||
mDisplayManagerInternal = displayManagerInternal;
|
||||
displayManager.registerDisplayListener(mDisplayListener, handler);
|
||||
mDisplayPowerRequests.append(Display.DEFAULT_DISPLAY_GROUP, new DisplayPowerRequest());
|
||||
mDisplayGroupIds.append(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY_GROUP);
|
||||
}
|
||||
|
||||
DisplayPowerRequest get(int displayId) {
|
||||
synchronized (mLock) {
|
||||
return mDisplayPowerRequests.get(mDisplayGroupIds.get(displayId));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -98,9 +98,11 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Tests for {@link com.android.server.power.PowerManagerService}.
|
||||
@@ -402,30 +404,33 @@ public class PowerManagerServiceTest {
|
||||
@Test
|
||||
public void testGetDesiredScreenPolicy_WithVR() throws Exception {
|
||||
createService();
|
||||
mService.systemReady(null);
|
||||
// Brighten up the screen
|
||||
mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_BRIGHT);
|
||||
|
||||
// Move to VR
|
||||
mService.setVrModeEnabled(true);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_VR);
|
||||
|
||||
// Then take a nap
|
||||
mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
|
||||
0);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_OFF);
|
||||
|
||||
// Wake up to VR
|
||||
mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_VR);
|
||||
|
||||
// And back to normal
|
||||
mService.setVrModeEnabled(false);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_BRIGHT);
|
||||
}
|
||||
|
||||
@@ -676,8 +681,9 @@ public class PowerManagerServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForceSuspend_forceSuspendFailurePropogated() {
|
||||
public void testForceSuspend_forceSuspendFailurePropagated() throws Exception {
|
||||
createService();
|
||||
startSystem();
|
||||
when(mNativeWrapperMock.nativeForceSuspend()).thenReturn(false);
|
||||
assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();
|
||||
}
|
||||
@@ -841,7 +847,7 @@ public class PowerManagerServiceTest {
|
||||
createService();
|
||||
startSystem();
|
||||
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_BRIGHT);
|
||||
}
|
||||
|
||||
@@ -860,11 +866,8 @@ public class PowerManagerServiceTest {
|
||||
public void testQuiescentBoot_DesiredScreenPolicyShouldBeOff() throws Exception {
|
||||
when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), any())).thenReturn("1");
|
||||
createService();
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_OFF);
|
||||
|
||||
startSystem();
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_OFF);
|
||||
}
|
||||
|
||||
@@ -874,7 +877,7 @@ public class PowerManagerServiceTest {
|
||||
createService();
|
||||
startSystem();
|
||||
forceAwake();
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_BRIGHT);
|
||||
}
|
||||
|
||||
@@ -890,7 +893,7 @@ public class PowerManagerServiceTest {
|
||||
|
||||
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
|
||||
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
|
||||
DisplayPowerRequest.POLICY_BRIGHT);
|
||||
}
|
||||
|
||||
@@ -1163,6 +1166,87 @@ public class PowerManagerServiceTest {
|
||||
mService.getBinderServiceInstance().setPowerModeChecked(Mode.INTERACTIVE, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiDisplay_wakefulnessUpdates() throws Exception {
|
||||
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||
new AtomicReference<>();
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
listener.set(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||
|
||||
createService();
|
||||
startSystem();
|
||||
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiDisplay_addDisplayGroup_preservesWakefulness() throws Exception {
|
||||
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||
new AtomicReference<>();
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
listener.set(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||
|
||||
createService();
|
||||
startSystem();
|
||||
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
|
||||
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiDisplay_removeDisplayGroup_updatesWakefulness() throws Exception {
|
||||
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
|
||||
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
|
||||
new AtomicReference<>();
|
||||
doAnswer((Answer<Void>) invocation -> {
|
||||
listener.set(invocation.getArgument(0));
|
||||
return null;
|
||||
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
|
||||
|
||||
createService();
|
||||
startSystem();
|
||||
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
|
||||
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
|
||||
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
|
||||
null, null);
|
||||
assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFullPowerSavePolicy_returnsStateMachineResult() {
|
||||
createService();
|
||||
|
||||
Reference in New Issue
Block a user