Merge "Allow Power-button to temporarily ignore proximity sensor." into rvc-d1-dev

This commit is contained in:
Santos Cordon
2020-08-07 09:33:05 +00:00
committed by Android (Google) Code Review
6 changed files with 116 additions and 9 deletions

View File

@@ -259,6 +259,13 @@ public abstract class DisplayManagerInternal {
public abstract DisplayedContentSample getDisplayedContentSample(
int displayId, long maxFrames, long timestamp);
/**
* Temporarily ignore proximity-sensor-based display behavior until there is a change
* to the proximity sensor state. This allows the display to turn back on even if something
* is obstructing the proximity sensor.
*/
public abstract void ignoreProximitySensorUntilChanged();
/**
* Describes the requested power state of the display.
*

View File

@@ -17,6 +17,7 @@
package android.os;
import android.view.Display;
import android.view.KeyEvent;
import java.util.function.Consumer;
@@ -319,4 +320,7 @@ public abstract class PowerManagerInternal {
/** Returns information about the last wakeup event. */
public abstract PowerManager.WakeData getLastWakeup();
/** Allows power button to intercept a power key button press. */
public abstract boolean interceptPowerKeyDown(KeyEvent event);
}

View File

@@ -2548,8 +2548,7 @@ public final class DisplayManagerService extends SystemService {
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mSyncRoot) {
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);
return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity);
}
}
@@ -2677,6 +2676,10 @@ public final class DisplayManagerService extends SystemService {
return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp);
}
@Override
public void ignoreProximitySensorUntilChanged() {
mDisplayPowerController.ignoreProximitySensorUntilChanged();
}
}
class DesiredDisplayModeSpecsObserver

View File

@@ -117,6 +117,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
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 PROXIMITY_UNKNOWN = -1;
private static final int PROXIMITY_NEGATIVE = 0;
@@ -263,6 +264,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// 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;
@@ -760,8 +766,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mPowerRequest == null) {
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
mPendingWaitForNegativeProximityLocked = false;
updatePendingProximityRequestsLocked();
mPendingRequestChangedLocked = false;
mustInitialize = true;
// Assume we're on and bright until told otherwise, since that's the state we turn
@@ -770,8 +775,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
} else if (mPendingRequestChangedLocked) {
previousPolicy = mPowerRequest.policy;
mPowerRequest.copyFrom(mPendingRequestLocked);
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
mPendingWaitForNegativeProximityLocked = false;
updatePendingProximityRequestsLocked();
mPendingRequestChangedLocked = false;
mDisplayReadyLocked = false;
} else {
@@ -822,9 +826,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// 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) {
&& 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();
}
@@ -832,18 +843,28 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
&& 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) {
&& (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;
sendOnProximityNegativeWithWakelock();
}
} else {
mWaitingForNegativeProximity = false;
mIgnoreProximityUntilChanged = false;
}
if (mScreenOffBecauseOfProximity) {
state = Display.STATE_OFF;
@@ -1181,6 +1202,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
sendUpdatePowerState();
}
/**
* 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);
}
public void setBrightnessConfiguration(BrightnessConfiguration c) {
Message msg = mHandler.obtainMessage(MSG_CONFIGURE_BRIGHTNESS, c);
msg.sendToTarget();
@@ -1529,6 +1558,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Register the listener.
// Proximity sensor state already cleared initially.
mProximitySensorEnabled = true;
mIgnoreProximityUntilChanged = false;
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
}
@@ -1538,6 +1568,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// 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);
@@ -1580,6 +1611,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
&& 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(TAG, "No longer ignoring proximity [" + mPendingProximity + "]");
}
// Sensor reading accepted. Apply the change then release the wake lock.
mProximity = mPendingProximity;
updatePowerState();
@@ -1723,6 +1759,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
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
&& mPowerRequest.useProximitySensor
&& mProximity == PROXIMITY_POSITIVE) {
// Only ignore if it is still reporting positive (near)
mIgnoreProximityUntilChanged = true;
Slog.i(TAG, "Ignoring proximity");
updatePowerState();
}
}
private final Runnable mOnStateChangedRunnable = new Runnable() {
@Override
public void run() {
@@ -1961,6 +2018,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mTemporaryAutoBrightnessAdjustment = Float.intBitsToFloat(msg.arg1);
updatePowerState();
break;
case MSG_IGNORE_PROXIMITY:
ignoreProximitySensorUntilChangedInternal();
break;
}
}
}

View File

@@ -934,6 +934,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
final boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event);
GestureLauncherService gestureService = LocalServices.getService(
GestureLauncherService.class);
boolean gesturedServiceIntercepted = false;
@@ -953,7 +955,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If the power key has still not yet been handled, then detect short
// press, long press, or multi press and decide what to do.
mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
|| mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted;
|| mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted
|| handledByPowerManager;
if (!mPowerKeyHandled) {
if (interactive) {
// When interactive, we're already awake.

View File

@@ -85,6 +85,7 @@ import android.util.SparseArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.KeyEvent;
import com.android.internal.BrightnessSynchronizer;
import com.android.internal.annotations.VisibleForTesting;
@@ -5425,6 +5426,29 @@ public final class PowerManagerService extends SystemService
}
}
/**
* If the user presses power while the proximity sensor is enabled and keeping
* the screen off, then turn the screen back on by telling display manager to
* ignore the proximity sensor. We don't turn off the proximity sensor because
* we still want it to be reenabled if it's state changes.
*
* @return True if the proximity sensor was successfully ignored and we should
* consume the key event.
*/
private boolean interceptPowerKeyDownInternal(KeyEvent event) {
synchronized (mLock) {
// DisplayPowerController only reports proximity positive (near) if it's
// positive and the proximity wasn't already being ignored. So it reliably
// also tells us that we're not already ignoring the proximity sensor.
if (mDisplayPowerRequest.useProximitySensor && mProximityPositive) {
mDisplayManagerInternal.ignoreProximitySensorUntilChanged();
return true;
}
}
return false;
}
@VisibleForTesting
final class LocalService extends PowerManagerInternal {
@Override
@@ -5561,5 +5585,10 @@ public final class PowerManagerService extends SystemService
public WakeData getLastWakeup() {
return getLastWakeupInternal();
}
@Override
public boolean interceptPowerKeyDown(KeyEvent event) {
return interceptPowerKeyDownInternal(event);
}
}
}