Adding Tests for SuspendBlocker.Display usage
Bug: 213407479 Test: atest DisplayPowerControllerTest Change-Id: I0ee03f704349729d3298e7b3cd26dd870d61935f
This commit is contained in:
committed by
Rupesh Bansal
parent
95fab76bcc
commit
d0894ea2ab
@@ -2583,8 +2583,8 @@ public final class DisplayManagerService extends SystemService {
|
||||
final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore,
|
||||
display, mSyncRoot);
|
||||
final DisplayPowerController displayPowerController = new DisplayPowerController(
|
||||
mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
|
||||
mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
|
||||
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
|
||||
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
|
||||
() -> handleBrightnessChange(display));
|
||||
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
import android.util.MutableFloat;
|
||||
@@ -58,6 +59,7 @@ import android.view.Display;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.display.BrightnessSynchronizer;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
@@ -97,7 +99,7 @@ import java.io.PrintWriter;
|
||||
* blocker as long as the display is not ready. So most of the work done here
|
||||
* does not need to worry about holding a suspend blocker unless it happens
|
||||
* independently of the display ready signal.
|
||||
*
|
||||
*
|
||||
* For debugging, you can make the color fade and brightness animations run
|
||||
* slower by changing the "animator duration scale" option in Development Settings.
|
||||
*/
|
||||
@@ -256,6 +258,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// to reach the final state.
|
||||
private final boolean mBrightnessBucketsInDozeConfig;
|
||||
|
||||
private final Clock mClock;
|
||||
private final Injector mInjector;
|
||||
|
||||
// Maximum time a ramp animation can take.
|
||||
private long mBrightnessRampIncreaseMaxTimeMillis;
|
||||
private long mBrightnessRampDecreaseMaxTimeMillis;
|
||||
@@ -495,20 +500,22 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
/**
|
||||
* Creates the display power controller.
|
||||
*/
|
||||
public DisplayPowerController(Context context,
|
||||
DisplayPowerController(Context context, Injector injector,
|
||||
DisplayPowerCallbacks callbacks, Handler handler,
|
||||
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
|
||||
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
|
||||
Runnable onBrightnessChangeRunnable) {
|
||||
|
||||
mInjector = injector != null ? injector : new Injector();
|
||||
mClock = mInjector.getClock();
|
||||
mLogicalDisplay = logicalDisplay;
|
||||
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
|
||||
final String displayIdStr = "[" + mDisplayId + "]";
|
||||
TAG = "DisplayPowerController" + displayIdStr;
|
||||
mSuspendBlockerIdUnfinishedBusiness = displayIdStr + "unfinished business";
|
||||
mSuspendBlockerIdOnStateChanged = displayIdStr + "on state changed";
|
||||
mSuspendBlockerIdProxPositive = displayIdStr + "prox positive";
|
||||
mSuspendBlockerIdProxNegative = displayIdStr + "prox negative";
|
||||
mSuspendBlockerIdProxDebounce = displayIdStr + "prox debounce";
|
||||
TAG = "DisplayPowerController[" + mDisplayId + "]";
|
||||
mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId);
|
||||
mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId);
|
||||
mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId);
|
||||
mSuspendBlockerIdProxNegative = getSuspendBlockerProxNegativeId(mDisplayId);
|
||||
mSuspendBlockerIdProxDebounce = getSuspendBlockerProxDebounceId(mDisplayId);
|
||||
|
||||
mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
|
||||
mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
|
||||
@@ -681,7 +688,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
|
||||
/**
|
||||
* Get the {@link BrightnessChangeEvent}s for the specified user.
|
||||
* @param userId userId to fetch data for
|
||||
*
|
||||
* @param userId userId to fetch data for
|
||||
* @param includePackage if false will null out the package name in events
|
||||
*/
|
||||
@Nullable
|
||||
@@ -723,10 +731,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
* The controller makes a copy of the provided object and then
|
||||
* begins adjusting the power state to match what was requested.
|
||||
*
|
||||
* @param request The requested power state.
|
||||
* @param request The requested power state.
|
||||
* @param waitForNegativeProximity If 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.
|
||||
* 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()}
|
||||
@@ -834,7 +843,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
synchronized (mLock) {
|
||||
mStopped = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_STOP);
|
||||
mHandler.sendMessage(msg);
|
||||
mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
|
||||
|
||||
if (mDisplayWhiteBalanceController != null) {
|
||||
mDisplayWhiteBalanceController.setEnabled(false);
|
||||
@@ -888,12 +897,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
if (!mStopped && !mPendingUpdatePowerStateLocked) {
|
||||
mPendingUpdatePowerStateLocked = true;
|
||||
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
|
||||
mHandler.sendMessage(msg);
|
||||
mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize(int displayState) {
|
||||
mPowerState = new DisplayPowerState(mBlanker,
|
||||
mPowerState = mInjector.getDisplayPowerState(mBlanker,
|
||||
mColorFadeEnabled ? new ColorFade(mDisplayId) : null, mDisplayId, displayState);
|
||||
|
||||
if (mColorFadeEnabled) {
|
||||
@@ -908,7 +917,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mColorFadeOffAnimator.addListener(mAnimatorListener);
|
||||
}
|
||||
|
||||
mScreenBrightnessRampAnimator = new DualRampAnimator<>(mPowerState,
|
||||
mScreenBrightnessRampAnimator = mInjector.getDualRampAnimator(mPowerState,
|
||||
DisplayPowerState.SCREEN_BRIGHTNESS_FLOAT,
|
||||
DisplayPowerState.SCREEN_SDR_BRIGHTNESS_FLOAT);
|
||||
mScreenBrightnessRampAnimator.setAnimationTimeLimits(
|
||||
@@ -1077,13 +1086,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
sendUpdatePowerState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
@@ -1124,8 +1136,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mOnProximityNegativeMessages = 0;
|
||||
|
||||
final float brightness = mPowerState != null
|
||||
? mPowerState.getScreenBrightness()
|
||||
: PowerManager.BRIGHTNESS_MIN;
|
||||
? mPowerState.getScreenBrightness()
|
||||
: PowerManager.BRIGHTNESS_MIN;
|
||||
reportStats(brightness);
|
||||
|
||||
if (mPowerState != null) {
|
||||
@@ -1203,7 +1215,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
state = Display.STATE_ON;
|
||||
break;
|
||||
}
|
||||
assert(state != Display.STATE_UNKNOWN);
|
||||
assert (state != Display.STATE_UNKNOWN);
|
||||
|
||||
// Apply the proximity sensor.
|
||||
if (mProximitySensor != null) {
|
||||
@@ -1290,16 +1302,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
final boolean autoBrightnessEnabledInDoze =
|
||||
mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
|
||||
final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
|
||||
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
|
||||
&& Float.isNaN(brightnessState)
|
||||
&& mAutomaticBrightnessController != null;
|
||||
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
|
||||
&& Float.isNaN(brightnessState)
|
||||
&& mAutomaticBrightnessController != null;
|
||||
final boolean autoBrightnessDisabledDueToDisplayOff = mPowerRequest.useAutoBrightness
|
||||
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
|
||||
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
|
||||
final int autoBrightnessState = autoBrightnessEnabled
|
||||
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
|
||||
: autoBrightnessDisabledDueToDisplayOff
|
||||
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
|
||||
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
|
||||
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
|
||||
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
|
||||
|
||||
final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
|
||||
|
||||
@@ -1589,9 +1601,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
// AND if we are not in idle screen brightness mode.
|
||||
if (!brightnessIsTemporary
|
||||
&& (mAutomaticBrightnessController != null
|
||||
&& !mAutomaticBrightnessController.isInIdleMode())) {
|
||||
&& !mAutomaticBrightnessController.isInIdleMode())) {
|
||||
if (userInitiatedChange && (mAutomaticBrightnessController == null
|
||||
|| !mAutomaticBrightnessController.hasValidAmbientLux())) {
|
||||
|| !mAutomaticBrightnessController.hasValidAmbientLux())) {
|
||||
// If we don't have a valid lux reading we can't report a valid
|
||||
// slider event so notify as if the system changed the brightness.
|
||||
userInitiatedChange = false;
|
||||
@@ -1781,26 +1793,26 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
boolean changed = false;
|
||||
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness,
|
||||
brightness);
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness,
|
||||
brightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness,
|
||||
adjustedBrightness);
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness,
|
||||
adjustedBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
|
||||
minBrightness);
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
|
||||
minBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
|
||||
maxBrightness);
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
|
||||
maxBrightness);
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
|
||||
mHbmController.getHighBrightnessMode());
|
||||
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
|
||||
mHbmController.getHighBrightnessMode());
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
|
||||
mHbmController.getTransitionPoint());
|
||||
mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
|
||||
mHbmController.getTransitionPoint());
|
||||
changed |=
|
||||
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
|
||||
mBrightnessThrottler.getBrightnessMaxReason());
|
||||
mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.brightnessMaxReason,
|
||||
mBrightnessThrottler.getBrightnessMaxReason());
|
||||
|
||||
return changed;
|
||||
}
|
||||
@@ -1942,7 +1954,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
if (!isOff
|
||||
&& (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF
|
||||
|| mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
|
||||
|| mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED)) {
|
||||
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_ON);
|
||||
if (mPowerState.getColorFadeLevel() == 0.0f) {
|
||||
blockScreenOn();
|
||||
@@ -2070,7 +2082,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
} else if (mPowerState.prepareColorFade(mContext,
|
||||
mColorFadeFadesConfig ?
|
||||
ColorFade.MODE_FADE :
|
||||
ColorFade.MODE_WARM_UP)) {
|
||||
ColorFade.MODE_WARM_UP)) {
|
||||
mColorFadeOnAnimator.start();
|
||||
} else {
|
||||
mColorFadeOnAnimator.end();
|
||||
@@ -2172,8 +2184,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
mPowerState.dismissColorFadeResources();
|
||||
} else if (performScreenOffTransition
|
||||
&& mPowerState.prepareColorFade(mContext,
|
||||
mColorFadeFadesConfig ?
|
||||
ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
|
||||
mColorFadeFadesConfig
|
||||
? ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
|
||||
&& mPowerState.getScreenState() != Display.STATE_OFF) {
|
||||
// Perform the screen off animation.
|
||||
mColorFadeOffAnimator.start();
|
||||
@@ -2244,7 +2256,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
if (mProximitySensorEnabled
|
||||
&& mPendingProximity != PROXIMITY_UNKNOWN
|
||||
&& mPendingProximityDebounceTime >= 0) {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
final long now = mClock.uptimeMillis();
|
||||
if (mPendingProximityDebounceTime <= now) {
|
||||
if (mProximity != mPendingProximity) {
|
||||
// if the status of the sensor changed, stop ignoring.
|
||||
@@ -2522,7 +2534,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
pw.println(" mCachedBrightnessInfo.hbmTransitionPoint=" +
|
||||
mCachedBrightnessInfo.hbmTransitionPoint.value);
|
||||
pw.println(" mCachedBrightnessInfo.brightnessMaxReason =" +
|
||||
mCachedBrightnessInfo.brightnessMaxReason .value);
|
||||
mCachedBrightnessInfo.brightnessMaxReason.value);
|
||||
}
|
||||
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
|
||||
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
|
||||
@@ -2705,7 +2717,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
|
||||
float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX;
|
||||
synchronized(mCachedBrightnessInfo) {
|
||||
synchronized (mCachedBrightnessInfo) {
|
||||
if (mCachedBrightnessInfo.hbmTransitionPoint == null) {
|
||||
return;
|
||||
}
|
||||
@@ -2739,8 +2751,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final class DisplayControllerHandler extends Handler {
|
||||
public DisplayControllerHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
@@ -2805,7 +2815,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
break;
|
||||
|
||||
case MSG_BRIGHTNESS_RAMP_DONE:
|
||||
if (mPowerState != null) {
|
||||
if (mPowerState != null) {
|
||||
final float brightness = mPowerState.getScreenBrightness();
|
||||
reportStats(brightness);
|
||||
}
|
||||
@@ -2822,7 +2832,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mProximitySensorEnabled) {
|
||||
final long time = SystemClock.uptimeMillis();
|
||||
final long time = mClock.uptimeMillis();
|
||||
final float distance = event.values[0];
|
||||
boolean positive = distance >= 0.0f && distance < mProximityThreshold;
|
||||
handleProximitySensorEvent(time, positive);
|
||||
@@ -2891,19 +2901,68 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getSuspendBlockerUnfinishedBusinessId(int displayId) {
|
||||
return "[" + displayId + "]unfinished business";
|
||||
}
|
||||
|
||||
String getSuspendBlockerOnStateChangedId(int displayId) {
|
||||
return "[" + displayId + "]on state changed";
|
||||
}
|
||||
|
||||
String getSuspendBlockerProxPositiveId(int displayId) {
|
||||
return "[" + displayId + "]prox positive";
|
||||
}
|
||||
|
||||
String getSuspendBlockerProxNegativeId(int displayId) {
|
||||
return "[" + displayId + "]prox negative";
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String getSuspendBlockerProxDebounceId(int displayId) {
|
||||
return "[" + displayId + "]prox debounce";
|
||||
}
|
||||
|
||||
/** Functional interface for providing time. */
|
||||
@VisibleForTesting
|
||||
interface Clock {
|
||||
/**
|
||||
* Returns current time in milliseconds since boot, not counting time spent in deep sleep.
|
||||
*/
|
||||
long uptimeMillis();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class Injector {
|
||||
Clock getClock() {
|
||||
return SystemClock::uptimeMillis;
|
||||
}
|
||||
|
||||
DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
|
||||
int displayId, int displayState) {
|
||||
return new DisplayPowerState(blanker, colorFade, displayId, displayState);
|
||||
}
|
||||
|
||||
DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
|
||||
FloatProperty<DisplayPowerState> firstProperty,
|
||||
FloatProperty<DisplayPowerState> secondProperty) {
|
||||
return new DualRampAnimator(dps, firstProperty, secondProperty);
|
||||
}
|
||||
}
|
||||
|
||||
static class CachedBrightnessInfo {
|
||||
public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
public MutableFloat adjustedBrightness =
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
public MutableFloat brightnessMin =
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
public MutableFloat brightnessMax =
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
|
||||
public MutableInt hbmMode = new MutableInt(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
|
||||
public MutableFloat hbmTransitionPoint =
|
||||
new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
|
||||
new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
|
||||
public MutableInt brightnessMaxReason =
|
||||
new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
|
||||
new MutableInt(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
|
||||
|
||||
public boolean checkAndSetFloat(MutableFloat mf, float f) {
|
||||
if (mf.value != f) {
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.test.TestLooper;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.display.RampAnimator.DualRampAnimator;
|
||||
import com.android.server.policy.WindowManagerPolicy;
|
||||
import com.android.server.testutils.OffsettableClock;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class DisplayPowerControllerTest {
|
||||
private static final String UNIQUE_DISPLAY_ID = "unique_id_test123";
|
||||
private static final int DISPLAY_ID = 42;
|
||||
|
||||
private OffsettableClock mClock;
|
||||
private TestLooper mTestLooper;
|
||||
private Handler mHandler;
|
||||
private DisplayPowerController.Injector mInjector;
|
||||
private Context mContextSpy;
|
||||
|
||||
@Mock
|
||||
private DisplayPowerCallbacks mDisplayPowerCallbacksMock;
|
||||
@Mock
|
||||
private SensorManager mSensorManagerMock;
|
||||
@Mock
|
||||
private DisplayBlanker mDisplayBlankerMock;
|
||||
@Mock
|
||||
private LogicalDisplay mLogicalDisplayMock;
|
||||
@Mock
|
||||
private DisplayDevice mDisplayDeviceMock;
|
||||
@Mock
|
||||
private BrightnessTracker mBrightnessTrackerMock;
|
||||
@Mock
|
||||
private BrightnessSetting mBrightnessSettingMock;
|
||||
@Mock
|
||||
private WindowManagerPolicy mWindowManagerPolicyMock;
|
||||
@Mock
|
||||
private PowerManager mPowerManagerMock;
|
||||
@Mock
|
||||
private Resources mResourcesMock;
|
||||
@Mock
|
||||
private DisplayDeviceConfig mDisplayDeviceConfigMock;
|
||||
@Mock
|
||||
private DisplayPowerState mDisplayPowerStateMock;
|
||||
@Mock
|
||||
private DualRampAnimator<DisplayPowerState> mDualRampAnimatorMock;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
|
||||
mClock = new OffsettableClock.Stopped();
|
||||
mTestLooper = new TestLooper(mClock::now);
|
||||
mHandler = new Handler(mTestLooper.getLooper());
|
||||
mInjector = new DisplayPowerController.Injector() {
|
||||
@Override
|
||||
DisplayPowerController.Clock getClock() {
|
||||
return mClock::now;
|
||||
}
|
||||
|
||||
@Override
|
||||
DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
|
||||
int displayId, int displayState) {
|
||||
return mDisplayPowerStateMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
|
||||
FloatProperty<DisplayPowerState> firstProperty,
|
||||
FloatProperty<DisplayPowerState> secondProperty) {
|
||||
return mDualRampAnimatorMock;
|
||||
}
|
||||
};
|
||||
|
||||
addLocalServiceMock(WindowManagerPolicy.class, mWindowManagerPolicyMock);
|
||||
|
||||
when(mContextSpy.getSystemService(eq(PowerManager.class))).thenReturn(mPowerManagerMock);
|
||||
when(mContextSpy.getResources()).thenReturn(mResourcesMock);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
LocalServices.removeServiceForTest(WindowManagerPolicy.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseProxSuspendBlockersOnExit() throws Exception {
|
||||
setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
|
||||
|
||||
Sensor proxSensor = setUpProxSensor();
|
||||
|
||||
DisplayPowerController dpc = new DisplayPowerController(
|
||||
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
|
||||
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
|
||||
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
|
||||
});
|
||||
|
||||
when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
|
||||
// send a display power request
|
||||
DisplayPowerRequest dpr = new DisplayPowerRequest();
|
||||
dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
|
||||
dpr.useProximitySensor = true;
|
||||
dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
|
||||
|
||||
// Run updatePowerState to start listener for the prox sensor
|
||||
advanceTime(1);
|
||||
|
||||
SensorEventListener listener = getSensorEventListener(proxSensor);
|
||||
assertNotNull(listener);
|
||||
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(proxSensor, 5 /* lux */));
|
||||
advanceTime(1);
|
||||
|
||||
// two times, one for unfinished business and one for proximity
|
||||
verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
|
||||
dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
|
||||
verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
|
||||
dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
|
||||
|
||||
dpc.stop();
|
||||
advanceTime(1);
|
||||
|
||||
// two times, one for unfinished business and one for proximity
|
||||
verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
|
||||
dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
|
||||
verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
|
||||
dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mock and registers it to {@link LocalServices}.
|
||||
*/
|
||||
private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
|
||||
LocalServices.removeServiceForTest(clazz);
|
||||
LocalServices.addService(clazz, mock);
|
||||
}
|
||||
|
||||
private void advanceTime(long timeMs) {
|
||||
mClock.fastForward(timeMs);
|
||||
mTestLooper.dispatchAll();
|
||||
}
|
||||
|
||||
private Sensor setUpProxSensor() throws Exception {
|
||||
Sensor proxSensor = TestUtils.createSensor(
|
||||
Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY);
|
||||
when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
|
||||
.thenReturn(List.of(proxSensor));
|
||||
return proxSensor;
|
||||
}
|
||||
|
||||
private SensorEventListener getSensorEventListener(Sensor sensor) {
|
||||
verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
|
||||
eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
|
||||
return mSensorEventListenerCaptor.getValue();
|
||||
}
|
||||
|
||||
private void setUpDisplay(int displayId, String uniqueId) {
|
||||
DisplayInfo info = new DisplayInfo();
|
||||
DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
|
||||
|
||||
when(mLogicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
|
||||
when(mLogicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(mDisplayDeviceMock);
|
||||
when(mLogicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
|
||||
when(mLogicalDisplayMock.isEnabled()).thenReturn(true);
|
||||
when(mLogicalDisplayMock.getPhase()).thenReturn(LogicalDisplay.DISPLAY_PHASE_ENABLED);
|
||||
when(mDisplayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
|
||||
when(mDisplayDeviceMock.getUniqueId()).thenReturn(uniqueId);
|
||||
when(mDisplayDeviceMock.getDisplayDeviceConfig()).thenReturn(mDisplayDeviceConfigMock);
|
||||
when(mDisplayDeviceConfigMock.getProximitySensor()).thenReturn(
|
||||
new DisplayDeviceConfig.SensorData() {
|
||||
{
|
||||
type = Sensor.STRING_TYPE_PROXIMITY;
|
||||
name = null;
|
||||
}
|
||||
});
|
||||
when(mDisplayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
|
||||
}
|
||||
}
|
||||
@@ -131,8 +131,9 @@ android_test {
|
||||
java_library {
|
||||
name: "servicestests-core-utils",
|
||||
srcs: [
|
||||
"src/com/android/server/pm/PackageSettingBuilder.java",
|
||||
"src/com/android/server/am/DeviceConfigSession.java",
|
||||
"src/com/android/server/display/TestUtils.java",
|
||||
"src/com/android/server/pm/PackageSettingBuilder.java",
|
||||
],
|
||||
static_libs: [
|
||||
"services.core",
|
||||
|
||||
Reference in New Issue
Block a user