Introducing DisplayPowerProximityStateController
This is a part of restructuring the way display service updates the power state of the system. All the proximity related logic has been abstracted out to a new class. As an attempt to keep this simple and contained, no new logic has been added. Bug: 241308364 Test: atest com.android.server.display Change-Id: I45bb8cff3f6da805a816a9c3eef7428e7f7fbf7d
This commit is contained in:
@@ -26,8 +26,6 @@ import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.AmbientBrightnessDayStats;
|
||||
import android.hardware.display.BrightnessChangeEvent;
|
||||
@@ -54,7 +52,6 @@ import android.util.MathUtils;
|
||||
import android.util.MutableFloat;
|
||||
import android.util.MutableInt;
|
||||
import android.util.Slog;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.R;
|
||||
@@ -109,7 +106,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
private static final String SCREEN_OFF_BLOCKED_TRACE_NAME = "Screen off blocked";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
|
||||
|
||||
|
||||
// If true, uses the color fade on animation.
|
||||
// We might want to turn this off if we cannot get a guarantee that the screen
|
||||
@@ -123,31 +120,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
private static final int COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS = 400;
|
||||
|
||||
private static final int MSG_UPDATE_POWER_STATE = 1;
|
||||
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
|
||||
private static final int MSG_SCREEN_ON_UNBLOCKED = 3;
|
||||
private static final int MSG_SCREEN_OFF_UNBLOCKED = 4;
|
||||
private static final int MSG_CONFIGURE_BRIGHTNESS = 5;
|
||||
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 MSG_UPDATE_BRIGHTNESS = 10;
|
||||
private static final int MSG_UPDATE_RBC = 11;
|
||||
private static final int MSG_BRIGHTNESS_RAMP_DONE = 12;
|
||||
private static final int MSG_STATSD_HBM_BRIGHTNESS = 13;
|
||||
|
||||
private static final int PROXIMITY_UNKNOWN = -1;
|
||||
private static final int PROXIMITY_NEGATIVE = 0;
|
||||
private static final int PROXIMITY_POSITIVE = 1;
|
||||
|
||||
// Proximity sensor debounce delay in milliseconds for positive or negative transitions.
|
||||
private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
|
||||
private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
|
||||
private static final int MSG_SCREEN_ON_UNBLOCKED = 2;
|
||||
private static final int MSG_SCREEN_OFF_UNBLOCKED = 3;
|
||||
private static final int MSG_CONFIGURE_BRIGHTNESS = 4;
|
||||
private static final int MSG_SET_TEMPORARY_BRIGHTNESS = 5;
|
||||
private static final int MSG_SET_TEMPORARY_AUTO_BRIGHTNESS_ADJUSTMENT = 6;
|
||||
private static final int MSG_STOP = 7;
|
||||
private static final int MSG_UPDATE_BRIGHTNESS = 8;
|
||||
private static final int MSG_UPDATE_RBC = 9;
|
||||
private static final int MSG_BRIGHTNESS_RAMP_DONE = 10;
|
||||
private static final int MSG_STATSD_HBM_BRIGHTNESS = 11;
|
||||
|
||||
private static final int BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS = 500;
|
||||
|
||||
// Trigger proximity if distance is less than 5 cm.
|
||||
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
|
||||
|
||||
// State machine constants for tracking initial brightness ramp skipping when enabled.
|
||||
private static final int RAMP_STATE_SKIP_NONE = 0;
|
||||
@@ -200,9 +185,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// Tracker for brightness settings changes.
|
||||
private final SettingsObserver mSettingsObserver;
|
||||
|
||||
// The proximity sensor, or null if not available or needed.
|
||||
private Sensor mProximitySensor;
|
||||
|
||||
// The doze screen brightness.
|
||||
private final float mScreenBrightnessDozeConfig;
|
||||
|
||||
@@ -266,10 +248,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
@GuardedBy("mLock")
|
||||
private DisplayPowerRequest mPendingRequestLocked;
|
||||
|
||||
// True if a request has been made to wait for the proximity sensor to go negative.
|
||||
@GuardedBy("mLock")
|
||||
private boolean mPendingWaitForNegativeProximityLocked;
|
||||
|
||||
// True if the pending power request or wait for negative proximity flag
|
||||
// has been changed since the last update occurred.
|
||||
@GuardedBy("mLock")
|
||||
@@ -296,37 +274,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// Must only be accessed on the handler thread.
|
||||
private DisplayPowerState mPowerState;
|
||||
|
||||
// True if the device should wait for negative proximity sensor before
|
||||
// waking up the screen. This is set to false as soon as a negative
|
||||
// proximity sensor measurement is observed or when the device is forced to
|
||||
// go to sleep by the user. While true, the screen remains off.
|
||||
private boolean mWaitingForNegativeProximity;
|
||||
|
||||
// True if the device should not take into account the proximity sensor
|
||||
// until either the proximity sensor state changes, or there is no longer a
|
||||
// request to listen to proximity sensor.
|
||||
private boolean mIgnoreProximityUntilChanged;
|
||||
|
||||
// The actual proximity sensor threshold value.
|
||||
private float mProximityThreshold;
|
||||
|
||||
// Set to true if the proximity sensor listener has been registered
|
||||
// with the sensor manager.
|
||||
private boolean mProximitySensorEnabled;
|
||||
|
||||
// The debounced proximity sensor state.
|
||||
private int mProximity = PROXIMITY_UNKNOWN;
|
||||
|
||||
// The raw non-debounced proximity sensor state.
|
||||
private int mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
|
||||
// -1 if fully debounced. Else, represents the time in ms when the debounce suspend blocker will
|
||||
// be removed. Applies for both positive and negative proximity flips.
|
||||
private long mPendingProximityDebounceTime = -1;
|
||||
|
||||
// True if the screen was turned off because of the proximity sensor.
|
||||
// When the screen turns on again, we report user activity to the power manager.
|
||||
private boolean mScreenOffBecauseOfProximity;
|
||||
|
||||
// The currently active screen on unblocker. This field is non-null whenever
|
||||
// we are waiting for a callback to release it and unblock the screen.
|
||||
@@ -407,6 +355,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// a medium of communication between this class and the PowerManagerService.
|
||||
private final WakelockController mWakelockController;
|
||||
|
||||
// Tracks and manages the proximity state of the associated display.
|
||||
private final DisplayPowerProximityStateController mDisplayPowerProximityStateController;
|
||||
|
||||
// A record of state for skipping brightness ramps.
|
||||
private int mSkipRampState = RAMP_STATE_SKIP_NONE;
|
||||
|
||||
@@ -491,13 +442,20 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
mClock = mInjector.getClock();
|
||||
mLogicalDisplay = logicalDisplay;
|
||||
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
|
||||
mSensorManager = sensorManager;
|
||||
mHandler = new DisplayControllerHandler(handler.getLooper());
|
||||
mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
|
||||
.getDisplayDeviceConfig();
|
||||
mWakelockController = mInjector.getWakelockController(mDisplayId, callbacks);
|
||||
mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
|
||||
mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
|
||||
() -> updatePowerState(), mDisplayId, mSensorManager);
|
||||
mTag = "DisplayPowerController2[" + mDisplayId + "]";
|
||||
|
||||
mDisplayDevice = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
|
||||
mUniqueDisplayId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
|
||||
mDisplayStatsId = mUniqueDisplayId.hashCode();
|
||||
mHandler = new DisplayControllerHandler(handler.getLooper());
|
||||
|
||||
mLastBrightnessEvent = new BrightnessEvent(mDisplayId);
|
||||
mTempBrightnessEvent = new BrightnessEvent(mDisplayId);
|
||||
|
||||
@@ -508,7 +466,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
}
|
||||
|
||||
mSettingsObserver = new SettingsObserver(mHandler);
|
||||
mSensorManager = sensorManager;
|
||||
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
|
||||
mBlanker = blanker;
|
||||
mContext = context;
|
||||
@@ -545,9 +502,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
|
||||
R.bool.config_allowAutoBrightnessWhileDozing);
|
||||
|
||||
mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
|
||||
.getDisplayDeviceConfig();
|
||||
|
||||
loadBrightnessRampRates();
|
||||
mSkipScreenOnBrightnessRamp = resources.getBoolean(
|
||||
R.bool.config_skipScreenOnBrightnessRamp);
|
||||
@@ -611,8 +565,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
mBrightnessBucketsInDozeConfig = resources.getBoolean(
|
||||
R.bool.config_displayBrightnessBucketsInDoze);
|
||||
|
||||
loadProximitySensor();
|
||||
|
||||
mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
|
||||
mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
|
||||
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
|
||||
@@ -653,7 +605,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
*/
|
||||
@Override
|
||||
public boolean isProximitySensorAvailable() {
|
||||
return mProximitySensor != null;
|
||||
return mDisplayPowerProximityStateController.isProximitySensorAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -727,13 +679,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (waitForNegativeProximity
|
||||
&& !mPendingWaitForNegativeProximityLocked) {
|
||||
mPendingWaitForNegativeProximityLocked = true;
|
||||
changed = true;
|
||||
}
|
||||
boolean changed = mDisplayPowerProximityStateController
|
||||
.setPendingWaitForNegativeProximityLocked(waitForNegativeProximity);
|
||||
|
||||
if (mPendingRequestLocked == null) {
|
||||
mPendingRequestLocked = new DisplayPowerRequest(request);
|
||||
@@ -790,6 +737,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
mDisplayStatsId = mUniqueDisplayId.hashCode();
|
||||
mDisplayDeviceConfig = config;
|
||||
loadFromDisplayDeviceConfig(token, info);
|
||||
mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config);
|
||||
updatePowerState();
|
||||
}
|
||||
});
|
||||
@@ -838,7 +786,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// All properties that depend on the associated DisplayDevice and the DDC must be
|
||||
// updated here.
|
||||
loadBrightnessRampRates();
|
||||
loadProximitySensor();
|
||||
loadNitsRange(mContext.getResources());
|
||||
setUpAutoBrightness(mContext.getResources(), mHandler);
|
||||
reloadReduceBrightColours();
|
||||
@@ -1134,7 +1081,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
|
||||
/** Clean up all resources that are accessed via the {@link #mHandler} thread. */
|
||||
private void cleanupHandlerThreadAfterStop() {
|
||||
setProximitySensorEnabled(false);
|
||||
mDisplayPowerProximityStateController.cleanup();
|
||||
mHbmController.stop();
|
||||
mBrightnessThrottler.stop();
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
@@ -1179,7 +1126,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
|
||||
if (mPowerRequest == null) {
|
||||
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
|
||||
updatePendingProximityRequestsLocked();
|
||||
mDisplayPowerProximityStateController.updatePendingProximityRequestsLocked();
|
||||
mPendingRequestChangedLocked = false;
|
||||
mustInitialize = true;
|
||||
// Assume we're on and bright until told otherwise, since that's the state we turn
|
||||
@@ -1188,7 +1135,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
} else if (mPendingRequestChangedLocked) {
|
||||
previousPolicy = mPowerRequest.policy;
|
||||
mPowerRequest.copyFrom(mPendingRequestLocked);
|
||||
updatePendingProximityRequestsLocked();
|
||||
mDisplayPowerProximityStateController.updatePendingProximityRequestsLocked();
|
||||
mPendingRequestChangedLocked = false;
|
||||
mDisplayReadyLocked = false;
|
||||
} else {
|
||||
@@ -1231,55 +1178,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
}
|
||||
assert (state != Display.STATE_UNKNOWN);
|
||||
|
||||
boolean skipRampBecauseOfProximityChangeToNegative = false;
|
||||
// Apply the proximity sensor.
|
||||
if (mProximitySensor != null) {
|
||||
if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
|
||||
// At this point the policy says that the screen should be on, but we've been
|
||||
// asked to listen to the prox sensor to adjust the display state, so lets make
|
||||
// sure the sensor is on.
|
||||
setProximitySensorEnabled(true);
|
||||
if (!mScreenOffBecauseOfProximity
|
||||
&& mProximity == PROXIMITY_POSITIVE
|
||||
&& !mIgnoreProximityUntilChanged) {
|
||||
// Prox sensor already reporting "near" so we should turn off the screen.
|
||||
// Also checked that we aren't currently set to ignore the proximity sensor
|
||||
// temporarily.
|
||||
mScreenOffBecauseOfProximity = true;
|
||||
sendOnProximityPositiveWithWakelock();
|
||||
}
|
||||
} else if (mWaitingForNegativeProximity
|
||||
&& mScreenOffBecauseOfProximity
|
||||
&& mProximity == PROXIMITY_POSITIVE
|
||||
&& state != Display.STATE_OFF) {
|
||||
// The policy says that we should have the screen on, but it's off due to the prox
|
||||
// and we've been asked to wait until the screen is far from the user to turn it
|
||||
// back on. Let keep the prox sensor on so we can tell when it's far again.
|
||||
setProximitySensorEnabled(true);
|
||||
} else {
|
||||
// We haven't been asked to use the prox sensor and we're not waiting on the screen
|
||||
// to turn back on...so lets shut down the prox sensor.
|
||||
setProximitySensorEnabled(false);
|
||||
mWaitingForNegativeProximity = false;
|
||||
}
|
||||
|
||||
if (mScreenOffBecauseOfProximity
|
||||
&& (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
|
||||
// The screen *was* off due to prox being near, but now it's "far" so lets turn
|
||||
// the screen back on. Also turn it back on if we've been asked to ignore the
|
||||
// prox sensor temporarily.
|
||||
mScreenOffBecauseOfProximity = false;
|
||||
skipRampBecauseOfProximityChangeToNegative = true;
|
||||
sendOnProximityNegativeWithWakelock();
|
||||
}
|
||||
} else {
|
||||
mWaitingForNegativeProximity = false;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
}
|
||||
mDisplayPowerProximityStateController.updateProximityState(mPowerRequest, state);
|
||||
|
||||
if (!mLogicalDisplay.isEnabled()
|
||||
|| mLogicalDisplay.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
|
||||
|| mScreenOffBecauseOfProximity) {
|
||||
|| mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
|
||||
state = Display.STATE_OFF;
|
||||
}
|
||||
|
||||
@@ -1550,7 +1453,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
final boolean wasOrWillBeInVr =
|
||||
(state == Display.STATE_VR || oldState == Display.STATE_VR);
|
||||
final boolean initialRampSkip = (state == Display.STATE_ON && mSkipRampState
|
||||
!= RAMP_STATE_SKIP_NONE) || skipRampBecauseOfProximityChangeToNegative;
|
||||
!= RAMP_STATE_SKIP_NONE) || mDisplayPowerProximityStateController
|
||||
.shouldSkipRampBecauseOfProximityChangeToNegative();
|
||||
// While dozing, sometimes the brightness is split into buckets. Rather than animating
|
||||
// through the buckets, which is unlikely to be smooth in the first place, just jump
|
||||
// right to the suggested brightness.
|
||||
@@ -1770,7 +1674,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
*/
|
||||
@Override
|
||||
public void ignoreProximitySensorUntilChanged() {
|
||||
mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
|
||||
mDisplayPowerProximityStateController.ignoreProximitySensorUntilChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1936,7 +1840,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
|| mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
|
||||
// If we are trying to turn screen off, give policy a chance to do something before we
|
||||
// actually turn the screen off.
|
||||
if (isOff && !mScreenOffBecauseOfProximity) {
|
||||
if (isOff && !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
|
||||
if (mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_ON
|
||||
|| mReportedScreenStateToPolicy == REPORTED_TO_POLICY_UNREPORTED) {
|
||||
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_TURNING_OFF);
|
||||
@@ -1966,7 +1870,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
// it is only removed once the window manager tells us that the activity has
|
||||
// finished drawing underneath.
|
||||
if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF
|
||||
&& !mScreenOffBecauseOfProximity) {
|
||||
&& !mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity()) {
|
||||
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
|
||||
unblockScreenOn();
|
||||
mWindowManagerPolicy.screenTurnedOff(mDisplayId);
|
||||
@@ -2008,22 +1912,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
fallbackType);
|
||||
}
|
||||
|
||||
private void loadProximitySensor() {
|
||||
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
||||
return;
|
||||
}
|
||||
final DisplayDeviceConfig.SensorData proxSensor =
|
||||
mDisplayDeviceConfig.getProximitySensor();
|
||||
final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
|
||||
? Sensor.TYPE_PROXIMITY : SensorUtils.NO_FALLBACK;
|
||||
mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name,
|
||||
fallbackType);
|
||||
if (mProximitySensor != null) {
|
||||
mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
|
||||
TYPICAL_PROXIMITY_THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
private float clampScreenBrightnessForVr(float value) {
|
||||
return MathUtils.constrain(
|
||||
value, mScreenBrightnessForVrRangeMinimum,
|
||||
@@ -2225,98 +2113,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
|
||||
private final Runnable mCleanListener = this::sendUpdatePowerState;
|
||||
|
||||
private void setProximitySensorEnabled(boolean enable) {
|
||||
if (enable) {
|
||||
if (!mProximitySensorEnabled) {
|
||||
// Register the listener.
|
||||
// Proximity sensor state already cleared initially.
|
||||
mProximitySensorEnabled = true;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
|
||||
}
|
||||
} else {
|
||||
if (mProximitySensorEnabled) {
|
||||
// Unregister the listener.
|
||||
// Clear the proximity sensor state for next time.
|
||||
mProximitySensorEnabled = false;
|
||||
mProximity = PROXIMITY_UNKNOWN;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mSensorManager.unregisterListener(mProximitySensorListener);
|
||||
// release wake lock(must be last)
|
||||
boolean proxDebounceSuspendBlockerReleased =
|
||||
mWakelockController.releaseWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
|
||||
if (proxDebounceSuspendBlockerReleased) {
|
||||
mPendingProximityDebounceTime = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleProximitySensorEvent(long time, boolean positive) {
|
||||
if (mProximitySensorEnabled) {
|
||||
if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
// Only accept a proximity sensor reading if it remains
|
||||
// stable for the entire debounce delay. We hold a wake lock while
|
||||
// debouncing the sensor.
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
if (positive) {
|
||||
mPendingProximity = PROXIMITY_POSITIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
|
||||
mWakelockController.acquireWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE); // acquire wake lock
|
||||
} else {
|
||||
mPendingProximity = PROXIMITY_NEGATIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
|
||||
mWakelockController.acquireWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE); // acquire wake lock
|
||||
}
|
||||
|
||||
// Debounce the new sensor reading.
|
||||
debounceProximitySensor();
|
||||
}
|
||||
}
|
||||
|
||||
private void debounceProximitySensor() {
|
||||
if (mProximitySensorEnabled
|
||||
&& mPendingProximity != PROXIMITY_UNKNOWN
|
||||
&& mPendingProximityDebounceTime >= 0) {
|
||||
final long now = mClock.uptimeMillis();
|
||||
if (mPendingProximityDebounceTime <= now) {
|
||||
if (mProximity != mPendingProximity) {
|
||||
// if the status of the sensor changed, stop ignoring.
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
Slog.i(mTag, "No longer ignoring proximity [" + mPendingProximity + "]");
|
||||
}
|
||||
// Sensor reading accepted. Apply the change then release the wake lock.
|
||||
mProximity = mPendingProximity;
|
||||
updatePowerState();
|
||||
// (must be last)
|
||||
boolean proxDebounceSuspendBlockerReleased =
|
||||
mWakelockController.releaseWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
|
||||
if (proxDebounceSuspendBlockerReleased) {
|
||||
mPendingProximityDebounceTime = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Need to wait a little longer.
|
||||
// Debounce again later. We continue holding a wake lock while waiting.
|
||||
Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOnStateChangedWithWakelock() {
|
||||
boolean wakeLockAcquired = mWakelockController.acquireWakelock(
|
||||
WakelockController.WAKE_LOCK_STATE_CHANGED);
|
||||
@@ -2461,39 +2257,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
return mAutomaticBrightnessController.convertToNits(brightness);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void updatePendingProximityRequestsLocked() {
|
||||
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
|
||||
mPendingWaitForNegativeProximityLocked = false;
|
||||
|
||||
if (mIgnoreProximityUntilChanged) {
|
||||
// Also, lets stop waiting for negative proximity if we're ignoring it.
|
||||
mWaitingForNegativeProximity = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ignoreProximitySensorUntilChangedInternal() {
|
||||
if (!mIgnoreProximityUntilChanged
|
||||
&& mProximity == PROXIMITY_POSITIVE) {
|
||||
// Only ignore if it is still reporting positive (near)
|
||||
mIgnoreProximityUntilChanged = true;
|
||||
Slog.i(mTag, "Ignoring proximity");
|
||||
updatePowerState();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOnProximityPositiveWithWakelock() {
|
||||
mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_PROXIMITY_POSITIVE);
|
||||
mHandler.post(mWakelockController.getOnProximityPositiveRunnable());
|
||||
}
|
||||
|
||||
|
||||
private void sendOnProximityNegativeWithWakelock() {
|
||||
mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_PROXIMITY_NEGATIVE);
|
||||
mHandler.post(mWakelockController.getOnProximityNegativeRunnable());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void dump(final PrintWriter pw) {
|
||||
synchronized (mLock) {
|
||||
@@ -2507,8 +2270,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
pw.println(" mDisplayReadyLocked=" + mDisplayReadyLocked);
|
||||
pw.println(" mPendingRequestLocked=" + mPendingRequestLocked);
|
||||
pw.println(" mPendingRequestChangedLocked=" + mPendingRequestChangedLocked);
|
||||
pw.println(" mPendingWaitForNegativeProximityLocked="
|
||||
+ mPendingWaitForNegativeProximityLocked);
|
||||
pw.println(" mPendingUpdatePowerStateLocked=" + mPendingUpdatePowerStateLocked);
|
||||
}
|
||||
|
||||
@@ -2543,7 +2304,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
}
|
||||
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
|
||||
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
|
||||
|
||||
mHandler.runWithScissors(() -> dumpLocal(pw), 1000);
|
||||
}
|
||||
|
||||
@@ -2551,15 +2311,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
pw.println();
|
||||
pw.println("Display Power Controller Thread State:");
|
||||
pw.println(" mPowerRequest=" + mPowerRequest);
|
||||
pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
|
||||
pw.println(" mProximitySensor=" + mProximitySensor);
|
||||
pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
|
||||
pw.println(" mProximityThreshold=" + mProximityThreshold);
|
||||
pw.println(" mProximity=" + proximityToString(mProximity));
|
||||
pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
|
||||
pw.println(" mPendingProximityDebounceTime="
|
||||
+ TimeUtils.formatUptime(mPendingProximityDebounceTime));
|
||||
pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
|
||||
pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
|
||||
pw.println(" mPendingScreenBrightnessSetting="
|
||||
+ mPendingScreenBrightnessSetting);
|
||||
@@ -2631,21 +2382,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
if (mWakelockController != null) {
|
||||
mWakelockController.dumpLocal(pw);
|
||||
}
|
||||
}
|
||||
|
||||
private static String proximityToString(int state) {
|
||||
switch (state) {
|
||||
case PROXIMITY_UNKNOWN:
|
||||
return "Unknown";
|
||||
case PROXIMITY_NEGATIVE:
|
||||
return "Negative";
|
||||
case PROXIMITY_POSITIVE:
|
||||
return "Positive";
|
||||
default:
|
||||
return Integer.toString(state);
|
||||
if (mDisplayPowerProximityStateController != null) {
|
||||
mDisplayPowerProximityStateController.dumpLocal(pw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String reportedToPolicyToString(int state) {
|
||||
switch (state) {
|
||||
case REPORTED_TO_POLICY_SCREEN_OFF:
|
||||
@@ -2795,10 +2538,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
updatePowerState();
|
||||
break;
|
||||
|
||||
case MSG_PROXIMITY_SENSOR_DEBOUNCED:
|
||||
debounceProximitySensor();
|
||||
break;
|
||||
|
||||
case MSG_SCREEN_ON_UNBLOCKED:
|
||||
if (mPendingScreenOnUnblocker == msg.obj) {
|
||||
unblockScreenOn();
|
||||
@@ -2827,10 +2566,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
updatePowerState();
|
||||
break;
|
||||
|
||||
case MSG_IGNORE_PROXIMITY:
|
||||
ignoreProximitySensorUntilChangedInternal();
|
||||
break;
|
||||
|
||||
case MSG_STOP:
|
||||
cleanupHandlerThreadAfterStop();
|
||||
break;
|
||||
@@ -2860,23 +2595,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
}
|
||||
}
|
||||
|
||||
private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mProximitySensorEnabled) {
|
||||
final long time = mClock.uptimeMillis();
|
||||
final float distance = event.values[0];
|
||||
boolean positive = distance >= 0.0f && distance < mProximityThreshold;
|
||||
handleProximitySensorEvent(time, positive);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final class SettingsObserver extends ContentObserver {
|
||||
SettingsObserver(Handler handler) {
|
||||
@@ -2966,6 +2684,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
||||
DisplayPowerCallbacks displayPowerCallbacks) {
|
||||
return new WakelockController(displayId, displayPowerCallbacks);
|
||||
}
|
||||
|
||||
DisplayPowerProximityStateController getDisplayPowerProximityStateController(
|
||||
WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig,
|
||||
Looper looper, Runnable nudgeUpdatePowerState,
|
||||
int displayId, SensorManager sensorManager) {
|
||||
return new DisplayPowerProximityStateController(wakelockController, displayDeviceConfig,
|
||||
looper, nudgeUpdatePowerState,
|
||||
displayId, sensorManager);
|
||||
}
|
||||
}
|
||||
|
||||
static class CachedBrightnessInfo {
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* 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 android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.display.utils.SensorUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Maintains the proximity state of the display.
|
||||
* Internally listens for proximity updates and schedules a power state update when the proximity
|
||||
* state changes.
|
||||
*/
|
||||
public final class DisplayPowerProximityStateController {
|
||||
private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 1;
|
||||
private static final int MSG_IGNORE_PROXIMITY = 2;
|
||||
|
||||
private static final int PROXIMITY_UNKNOWN = -1;
|
||||
private static final int PROXIMITY_NEGATIVE = 0;
|
||||
private static final int PROXIMITY_POSITIVE = 1;
|
||||
|
||||
private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
|
||||
// Proximity sensor debounce delay in milliseconds for positive transitions.
|
||||
private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
|
||||
// Proximity sensor debounce delay in milliseconds for negative transitions.
|
||||
private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
|
||||
// Trigger proximity if distance is less than 5 cm.
|
||||
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
|
||||
|
||||
private final String mTag;
|
||||
// A lock to handle the deadlock and race conditions.
|
||||
private final Object mLock = new Object();
|
||||
// The manager which lets us access the device's ProximitySensor
|
||||
private final SensorManager mSensorManager;
|
||||
// An entity which manages the wakelocks.
|
||||
private final WakelockController mWakelockController;
|
||||
// A handler to process all the events on this thread in a synchronous manner
|
||||
private final DisplayPowerProximityStateHandler mHandler;
|
||||
// A runnable to execute the utility to update the power state.
|
||||
private final Runnable mNudgeUpdatePowerState;
|
||||
// A listener which listen's to the events emitted by the proximity sensor.
|
||||
private final SensorEventListener mProximitySensorListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mProximitySensorEnabled) {
|
||||
final long time = SystemClock.uptimeMillis();
|
||||
final float distance = event.values[0];
|
||||
boolean positive = distance >= 0.0f && distance < mProximityThreshold;
|
||||
handleProximitySensorEvent(time, positive);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// Not used.
|
||||
}
|
||||
};
|
||||
|
||||
// The proximity sensor, or null if not available or needed.
|
||||
private Sensor mProximitySensor;
|
||||
|
||||
// The configurations for the associated display
|
||||
private DisplayDeviceConfig mDisplayDeviceConfig;
|
||||
|
||||
// True if a request has been made to wait for the proximity sensor to go negative.
|
||||
@GuardedBy("mLock")
|
||||
private boolean mPendingWaitForNegativeProximityLocked;
|
||||
|
||||
// True if the device should wait for negative proximity sensor before
|
||||
// waking up the screen. This is set to false as soon as a negative
|
||||
// proximity sensor measurement is observed or when the device is forced to
|
||||
// go to sleep by the user. While true, the screen remains off.
|
||||
private boolean mWaitingForNegativeProximity;
|
||||
|
||||
// True if the device should not take into account the proximity sensor
|
||||
// until either the proximity sensor state changes, or there is no longer a
|
||||
// request to listen to proximity sensor.
|
||||
private boolean mIgnoreProximityUntilChanged;
|
||||
|
||||
// Set to true if the proximity sensor listener has been registered
|
||||
// with the sensor manager.
|
||||
private boolean mProximitySensorEnabled;
|
||||
|
||||
// The raw non-debounced proximity sensor state.
|
||||
private int mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
|
||||
// -1 if fully debounced. Else, represents the time in ms when the debounce suspend blocker will
|
||||
// be removed. Applies for both positive and negative proximity flips.
|
||||
private long mPendingProximityDebounceTime = -1;
|
||||
|
||||
// True if the screen was turned off because of the proximity sensor.
|
||||
// When the screen turns on again, we report user activity to the power manager.
|
||||
private boolean mScreenOffBecauseOfProximity;
|
||||
|
||||
// The debounced proximity sensor state.
|
||||
private int mProximity = PROXIMITY_UNKNOWN;
|
||||
|
||||
// The actual proximity sensor threshold value.
|
||||
private float mProximityThreshold;
|
||||
|
||||
// A flag representing if the ramp is to be skipped when the proximity changes from positive
|
||||
// to negative
|
||||
private boolean mSkipRampBecauseOfProximityChangeToNegative = false;
|
||||
|
||||
// The DisplayId of the associated Logical Display.
|
||||
private int mDisplayId;
|
||||
|
||||
/**
|
||||
* Create a new instance of DisplayPowerProximityStateController.
|
||||
*
|
||||
* @param wakeLockController WakelockController used to acquire/release wakelocks
|
||||
* @param displayDeviceConfig DisplayDeviceConfig instance from which the configs(Proximity
|
||||
* Sensor) are to be loaded
|
||||
* @param looper A looper onto which the handler is to be associated.
|
||||
* @param nudgeUpdatePowerState A runnable to execute the utility to update the power state
|
||||
* @param displayId The DisplayId of the associated Logical Display.
|
||||
* @param sensorManager The manager which lets us access the display's ProximitySensor
|
||||
*/
|
||||
public DisplayPowerProximityStateController(
|
||||
WakelockController wakeLockController, DisplayDeviceConfig displayDeviceConfig,
|
||||
Looper looper,
|
||||
Runnable nudgeUpdatePowerState, int displayId, SensorManager sensorManager) {
|
||||
mWakelockController = wakeLockController;
|
||||
mHandler = new DisplayPowerProximityStateHandler(looper);
|
||||
mNudgeUpdatePowerState = nudgeUpdatePowerState;
|
||||
mDisplayDeviceConfig = displayDeviceConfig;
|
||||
mDisplayId = displayId;
|
||||
mTag = "DisplayPowerProximityStateController[" + mDisplayId + "]";
|
||||
mSensorManager = sensorManager;
|
||||
loadProximitySensor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the pending state of the proximity.
|
||||
*/
|
||||
public void updatePendingProximityRequestsLocked() {
|
||||
synchronized (mLock) {
|
||||
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
|
||||
mPendingWaitForNegativeProximityLocked = false;
|
||||
|
||||
if (mIgnoreProximityUntilChanged) {
|
||||
// Also, lets stop waiting for negative proximity if we're ignoring it.
|
||||
mWaitingForNegativeProximity = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all resources that are accessed via the {@link #mHandler} thread.
|
||||
*/
|
||||
public void cleanup() {
|
||||
setProximitySensorEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the proximity sensor screen-off function is available.
|
||||
*/
|
||||
public boolean isProximitySensorAvailable() {
|
||||
return mProximitySensor != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag to indicate that the system is waiting for the negative proximity event
|
||||
*/
|
||||
public boolean setPendingWaitForNegativeProximityLocked(
|
||||
boolean requestWaitForNegativeProximity) {
|
||||
synchronized (mLock) {
|
||||
if (requestWaitForNegativeProximity
|
||||
&& !mPendingWaitForNegativeProximityLocked) {
|
||||
mPendingWaitForNegativeProximityLocked = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the proximity state of the display, based on the newly received DisplayPowerRequest
|
||||
* and the target display state
|
||||
*/
|
||||
public void updateProximityState(
|
||||
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
|
||||
int displayState) {
|
||||
mSkipRampBecauseOfProximityChangeToNegative = false;
|
||||
if (mProximitySensor != null) {
|
||||
if (displayPowerRequest.useProximitySensor && displayState != Display.STATE_OFF) {
|
||||
// At this point the policy says that the screen should be on, but we've been
|
||||
// asked to listen to the prox sensor to adjust the display state, so lets make
|
||||
// sure the sensor is on.
|
||||
setProximitySensorEnabled(true);
|
||||
if (!mScreenOffBecauseOfProximity
|
||||
&& mProximity == PROXIMITY_POSITIVE
|
||||
&& !mIgnoreProximityUntilChanged) {
|
||||
// Prox sensor already reporting "near" so we should turn off the screen.
|
||||
// Also checked that we aren't currently set to ignore the proximity sensor
|
||||
// temporarily.
|
||||
mScreenOffBecauseOfProximity = true;
|
||||
sendOnProximityPositiveWithWakelock();
|
||||
}
|
||||
} else if (mWaitingForNegativeProximity
|
||||
&& mScreenOffBecauseOfProximity
|
||||
&& mProximity == PROXIMITY_POSITIVE
|
||||
&& displayState != Display.STATE_OFF) {
|
||||
// The policy says that we should have the screen on, but it's off due to the prox
|
||||
// and we've been asked to wait until the screen is far from the user to turn it
|
||||
// back on. Let keep the prox sensor on so we can tell when it's far again.
|
||||
setProximitySensorEnabled(true);
|
||||
} else {
|
||||
// We haven't been asked to use the prox sensor and we're not waiting on the screen
|
||||
// to turn back on...so let's shut down the prox sensor.
|
||||
setProximitySensorEnabled(false);
|
||||
mWaitingForNegativeProximity = false;
|
||||
}
|
||||
|
||||
if (mScreenOffBecauseOfProximity
|
||||
&& (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
|
||||
// The screen *was* off due to prox being near, but now it's "far" so lets turn
|
||||
// the screen back on. Also turn it back on if we've been asked to ignore the
|
||||
// prox sensor temporarily.
|
||||
mScreenOffBecauseOfProximity = false;
|
||||
mSkipRampBecauseOfProximityChangeToNegative = true;
|
||||
sendOnProximityNegativeWithWakelock();
|
||||
}
|
||||
} else {
|
||||
mWaitingForNegativeProximity = false;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility to check if the brightness change ramp is to be skipped because the proximity was
|
||||
* changed from positive to negative.
|
||||
*/
|
||||
public boolean shouldSkipRampBecauseOfProximityChangeToNegative() {
|
||||
return mSkipRampBecauseOfProximityChangeToNegative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents of the screen is currently turned off because of the proximity state.
|
||||
*/
|
||||
public boolean isScreenOffBecauseOfProximity() {
|
||||
return mScreenOffBecauseOfProximity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignores the proximity sensor until the sensor state changes, but only if the sensor is
|
||||
* currently enabled and forcing the screen to be dark.
|
||||
*/
|
||||
public void ignoreProximitySensorUntilChanged() {
|
||||
mHandler.sendEmptyMessage(MSG_IGNORE_PROXIMITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This adjusts the state of this class when a change in the DisplayDevice is detected.
|
||||
*/
|
||||
public void notifyDisplayDeviceChanged(DisplayDeviceConfig displayDeviceConfig) {
|
||||
this.mDisplayDeviceConfig = displayDeviceConfig;
|
||||
loadProximitySensor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to dump the state.
|
||||
*
|
||||
* @param pw The PrintWriter used to dump the state.
|
||||
*/
|
||||
public void dumpLocal(PrintWriter pw) {
|
||||
pw.println();
|
||||
pw.println("DisplayPowerProximityStateController:");
|
||||
synchronized (mLock) {
|
||||
pw.println(" mPendingWaitForNegativeProximityLocked="
|
||||
+ mPendingWaitForNegativeProximityLocked);
|
||||
}
|
||||
pw.println(" mDisplayId=" + mDisplayId);
|
||||
pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
|
||||
pw.println(" mIgnoreProximityUntilChanged=" + mIgnoreProximityUntilChanged);
|
||||
pw.println(" mProximitySensor=" + mProximitySensor);
|
||||
pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled);
|
||||
pw.println(" mProximityThreshold=" + mProximityThreshold);
|
||||
pw.println(" mProximity=" + proximityToString(mProximity));
|
||||
pw.println(" mPendingProximity=" + proximityToString(mPendingProximity));
|
||||
pw.println(" mPendingProximityDebounceTime="
|
||||
+ TimeUtils.formatUptime(mPendingProximityDebounceTime));
|
||||
pw.println(" mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
|
||||
pw.println(" mSkipRampBecauseOfProximityChangeToNegative="
|
||||
+ mSkipRampBecauseOfProximityChangeToNegative);
|
||||
}
|
||||
|
||||
private void ignoreProximitySensorUntilChangedInternal() {
|
||||
if (!mIgnoreProximityUntilChanged
|
||||
&& mProximity == PROXIMITY_POSITIVE) {
|
||||
// Only ignore if it is still reporting positive (near)
|
||||
mIgnoreProximityUntilChanged = true;
|
||||
Slog.i(mTag, "Ignoring proximity");
|
||||
mNudgeUpdatePowerState.run();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendOnProximityPositiveWithWakelock() {
|
||||
mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_PROXIMITY_POSITIVE);
|
||||
mHandler.post(mWakelockController.getOnProximityPositiveRunnable());
|
||||
}
|
||||
|
||||
private void sendOnProximityNegativeWithWakelock() {
|
||||
mWakelockController.acquireWakelock(WakelockController.WAKE_LOCK_PROXIMITY_NEGATIVE);
|
||||
mHandler.post(mWakelockController.getOnProximityNegativeRunnable());
|
||||
}
|
||||
|
||||
private void loadProximitySensor() {
|
||||
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
||||
return;
|
||||
}
|
||||
final DisplayDeviceConfig.SensorData proxSensor =
|
||||
mDisplayDeviceConfig.getProximitySensor();
|
||||
final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
|
||||
? Sensor.TYPE_PROXIMITY : SensorUtils.NO_FALLBACK;
|
||||
mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name,
|
||||
fallbackType);
|
||||
if (mProximitySensor != null) {
|
||||
mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
|
||||
TYPICAL_PROXIMITY_THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProximitySensorEnabled(boolean enable) {
|
||||
if (enable) {
|
||||
if (!mProximitySensorEnabled) {
|
||||
// Register the listener.
|
||||
// Proximity sensor state already cleared initially.
|
||||
mProximitySensorEnabled = true;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
|
||||
}
|
||||
} else {
|
||||
if (mProximitySensorEnabled) {
|
||||
// Unregister the listener.
|
||||
// Clear the proximity sensor state for next time.
|
||||
mProximitySensorEnabled = false;
|
||||
mProximity = PROXIMITY_UNKNOWN;
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
mPendingProximity = PROXIMITY_UNKNOWN;
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mSensorManager.unregisterListener(mProximitySensorListener);
|
||||
// release wake lock(must be last)
|
||||
boolean proxDebounceSuspendBlockerReleased =
|
||||
mWakelockController.releaseWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
|
||||
if (proxDebounceSuspendBlockerReleased) {
|
||||
mPendingProximityDebounceTime = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleProximitySensorEvent(long time, boolean positive) {
|
||||
if (mProximitySensorEnabled) {
|
||||
if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
|
||||
return; // no change
|
||||
}
|
||||
if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
// Only accept a proximity sensor reading if it remains
|
||||
// stable for the entire debounce delay. We hold a wake lock while
|
||||
// debouncing the sensor.
|
||||
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
if (positive) {
|
||||
mPendingProximity = PROXIMITY_POSITIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
|
||||
mWakelockController.acquireWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE); // acquire wake lock
|
||||
} else {
|
||||
mPendingProximity = PROXIMITY_NEGATIVE;
|
||||
mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
|
||||
mWakelockController.acquireWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE); // acquire wake lock
|
||||
}
|
||||
|
||||
// Debounce the new sensor reading.
|
||||
debounceProximitySensor();
|
||||
}
|
||||
}
|
||||
|
||||
private void debounceProximitySensor() {
|
||||
if (mProximitySensorEnabled
|
||||
&& mPendingProximity != PROXIMITY_UNKNOWN
|
||||
&& mPendingProximityDebounceTime >= 0) {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
if (mPendingProximityDebounceTime <= now) {
|
||||
if (mProximity != mPendingProximity) {
|
||||
// if the status of the sensor changed, stop ignoring.
|
||||
mIgnoreProximityUntilChanged = false;
|
||||
Slog.i(mTag, "No longer ignoring proximity [" + mPendingProximity + "]");
|
||||
}
|
||||
// Sensor reading accepted. Apply the change then release the wake lock.
|
||||
mProximity = mPendingProximity;
|
||||
mNudgeUpdatePowerState.run();
|
||||
// (must be last)
|
||||
boolean proxDebounceSuspendBlockerReleased =
|
||||
mWakelockController.releaseWakelock(
|
||||
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
|
||||
if (proxDebounceSuspendBlockerReleased) {
|
||||
mPendingProximityDebounceTime = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Need to wait a little longer.
|
||||
// Debounce again later. We continue holding a wake lock while waiting.
|
||||
Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
|
||||
mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DisplayPowerProximityStateHandler extends Handler {
|
||||
DisplayPowerProximityStateHandler(Looper looper) {
|
||||
super(looper, null, true /*async*/);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_PROXIMITY_SENSOR_DEBOUNCED:
|
||||
debounceProximitySensor();
|
||||
break;
|
||||
|
||||
case MSG_IGNORE_PROXIMITY:
|
||||
ignoreProximitySensorUntilChangedInternal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String proximityToString(int state) {
|
||||
switch (state) {
|
||||
case PROXIMITY_UNKNOWN:
|
||||
return "Unknown";
|
||||
case PROXIMITY_NEGATIVE:
|
||||
return "Negative";
|
||||
case PROXIMITY_POSITIVE:
|
||||
return "Positive";
|
||||
default:
|
||||
return Integer.toString(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.test.TestLooper;
|
||||
import android.util.FloatProperty;
|
||||
@@ -135,6 +136,16 @@ public final class DisplayPowerController2Test {
|
||||
DisplayPowerCallbacks displayPowerCallbacks) {
|
||||
return mWakelockController;
|
||||
}
|
||||
|
||||
@Override
|
||||
DisplayPowerProximityStateController getDisplayPowerProximityStateController(
|
||||
WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig,
|
||||
Looper looper, Runnable nudgeUpdatePowerState, int displayId,
|
||||
SensorManager sensorManager) {
|
||||
return new DisplayPowerProximityStateController(wakelockController,
|
||||
displayDeviceConfig, looper, nudgeUpdatePowerState, displayId,
|
||||
sensorManager);
|
||||
}
|
||||
};
|
||||
|
||||
addLocalServiceMock(WindowManagerPolicy.class, mWindowManagerPolicyMock);
|
||||
|
||||
Reference in New Issue
Block a user