Wake-screen gesture implementation

Bug: 111414690
Test: adb shell dumpsys activity service com.android.systemui
Test: manual with alternative sensor event
Change-Id: Ib38085388c0e9ebce9eb59712cdfde5f8d7ccc8c
This commit is contained in:
Lucas Dupin
2018-08-27 16:55:56 -07:00
parent 322a8b214c
commit 323f9ffcb4
9 changed files with 104 additions and 24 deletions

View File

@@ -7255,6 +7255,14 @@ public final class Settings {
private static final Validator DOZE_REACH_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
/**
* Gesture that wakes up the display, showing the ambient version of the status bar.
* @hide
*/
public static final String DOZE_WAKE_SCREEN_GESTURE = "doze_wake_screen_gesture";
private static final Validator DOZE_WAKE_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
/**
* The current night mode that has been selected by the user. Owned
* and controlled by UiModeManagerService. Constants are as per
@@ -8158,6 +8166,7 @@ public final class Settings {
DOZE_PICK_UP_GESTURE,
DOZE_DOUBLE_TAP_GESTURE,
DOZE_REACH_GESTURE,
DOZE_WAKE_SCREEN_GESTURE,
NFC_PAYMENT_DEFAULT_COMPONENT,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
FACE_UNLOCK_KEYGUARD_ENABLED,
@@ -8302,6 +8311,7 @@ public final class Settings {
VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_REACH_GESTURE, DOZE_REACH_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_WAKE_SCREEN_GESTURE, DOZE_WAKE_SCREEN_GESTURE_VALIDATOR);
VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);

View File

@@ -75,6 +75,15 @@ public class AmbientDisplayConfiguration {
return !TextUtils.isEmpty(reachSensorType());
}
public boolean wakeScreenGestureEnabled(int user) {
return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, user)
&& wakeScreenGestureAvailable();
}
public boolean wakeScreenGestureAvailable() {
return !TextUtils.isEmpty(wakeScreenSensorType());
}
public String doubleTapSensorType() {
return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
}
@@ -87,6 +96,10 @@ public class AmbientDisplayConfiguration {
return mContext.getResources().getString(R.string.config_dozeReachSensorType);
}
public String wakeScreenSensorType() {
return mContext.getResources().getString(R.string.config_dozeWakeScreenSensorType);
}
public boolean pulseOnLongPressEnabled(int user) {
return pulseOnLongPressAvailable() && boolSettingDefaultOff(
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);

View File

@@ -2116,6 +2116,9 @@
<!-- Type of the reach sensor. Empty if reach is not supported. -->
<string name="config_dozeReachSensorType" translatable="false"></string>
<!-- Type of the wake up sensor. Empty if not supported. -->
<string name="config_dozeWakeScreenSensorType" translatable="false"></string>
<!-- Control whether the always on display mode is available. This should only be enabled on
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
states. -->

View File

@@ -3462,4 +3462,5 @@
<java-symbol type="integer" name="db_wal_truncate_size" />
<java-symbol type="integer" name="config_wakeUpDelayDoze" />
<java-symbol type="string" name="config_dozeWakeScreenSensorType" />
</resources>

View File

@@ -35,7 +35,7 @@ public class DozeLog {
private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
private static final int PULSE_REASONS = 7;
private static final int REASONS = 8;
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -45,6 +45,7 @@ public class DozeLog {
public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
public static final int PULSE_REASON_SENSOR_REACH = 6;
public static final int REASON_SENSOR_WAKE_UP = 7;
private static boolean sRegisterKeyguardCallback = true;
@@ -74,7 +75,7 @@ public class DozeLog {
public static void tracePulseStart(int reason) {
if (!ENABLED) return;
sPulsing = true;
log("pulseStart reason=" + pulseReasonToString(reason));
log("pulseStart reason=" + reasonToString(reason));
}
public static void tracePulseFinish() {
@@ -102,8 +103,8 @@ public class DozeLog {
sScreenOnPulsingStats = new SummaryStats();
sScreenOnNotPulsingStats = new SummaryStats();
sEmergencyCallStats = new SummaryStats();
sProxStats = new SummaryStats[PULSE_REASONS][2];
for (int i = 0; i < PULSE_REASONS; i++) {
sProxStats = new SummaryStats[REASONS][2];
for (int i = 0; i < REASONS; i++) {
sProxStats[i][0] = new SummaryStats();
sProxStats[i][1] = new SummaryStats();
}
@@ -176,15 +177,15 @@ public class DozeLog {
}
public static void traceProximityResult(Context context, boolean near, long millis,
int pulseReason) {
int reason) {
if (!ENABLED) return;
init(context);
log("proximityResult reason=" + pulseReasonToString(pulseReason) + " near=" + near
log("proximityResult reason=" + reasonToString(reason) + " near=" + near
+ " millis=" + millis);
sProxStats[pulseReason][near ? 0 : 1].append();
sProxStats[reason][near ? 0 : 1].append();
}
public static String pulseReasonToString(int pulseReason) {
public static String reasonToString(int pulseReason) {
switch (pulseReason) {
case PULSE_REASON_INTENT: return "intent";
case PULSE_REASON_NOTIFICATION: return "notification";
@@ -193,6 +194,7 @@ public class DozeLog {
case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
case PULSE_REASON_SENSOR_REACH: return "reach";
case REASON_SENSOR_WAKE_UP: return "wakeup";
default: throw new IllegalArgumentException("bad reason: " + pulseReason);
}
}
@@ -218,8 +220,8 @@ public class DozeLog {
sScreenOnPulsingStats.dump(pw, "Screen on (pulsing)");
sScreenOnNotPulsingStats.dump(pw, "Screen on (not pulsing)");
sEmergencyCallStats.dump(pw, "Emergency call");
for (int i = 0; i < PULSE_REASONS; i++) {
final String reason = pulseReasonToString(i);
for (int i = 0; i < REASONS; i++) {
final String reason = reasonToString(i);
sProxStats[i][0].dump(pw, "Proximity near (" + reason + ")");
sProxStats[i][1].dump(pw, "Proximity far (" + reason + ")");
}
@@ -262,10 +264,10 @@ public class DozeLog {
}
}
public static void traceSensor(Context context, int pulseReason) {
public static void traceSensor(Context context, int reason) {
if (!ENABLED) return;
init(context);
log("sensor type=" + pulseReasonToString(pulseReason));
log("sensor type=" + reasonToString(reason));
}
private static class SummaryStats {

View File

@@ -63,6 +63,7 @@ public class DozeSensors {
private final AmbientDisplayConfiguration mConfig;
private final WakeLock mWakeLock;
private final Consumer<Boolean> mProxCallback;
private final Consumer<Boolean> mWakeScreenCallback;
private final Callback mCallback;
private final Handler mHandler = new Handler();
@@ -70,9 +71,9 @@ public class DozeSensors {
public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
DozeParameters dozeParameters,
AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback,
Consumer<Boolean> proxCallback, AlwaysOnDisplayPolicy policy) {
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
Callback callback, Consumer<Boolean> proxCallback,
Consumer<Boolean> wakeScreenCallback, AlwaysOnDisplayPolicy policy) {
mContext = context;
mAlarmManager = alarmManager;
mSensorManager = sensorManager;
@@ -80,6 +81,7 @@ public class DozeSensors {
mConfig = config;
mWakeLock = wakeLock;
mProxCallback = proxCallback;
mWakeScreenCallback = wakeScreenCallback;
mResolver = mContext.getContentResolver();
mSensors = new TriggerSensor[] {
@@ -117,6 +119,7 @@ public class DozeSensors {
DozeLog.PULSE_REASON_SENSOR_REACH,
false /* reports touch coordinates */,
false /* touchscreen */),
new WakeScreenSensor(),
};
mProxSensor = new ProxSensor(policy);
@@ -302,9 +305,9 @@ public class DozeSensors {
final boolean mSettingDefault;
final boolean mRequiresTouchscreen;
private boolean mRequested;
private boolean mRegistered;
private boolean mDisabled;
protected boolean mRequested;
protected boolean mRegistered;
protected boolean mDisabled;
public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
@@ -348,7 +351,7 @@ public class DozeSensors {
}
}
private boolean enabledBySetting() {
protected boolean enabledBySetting() {
if (TextUtils.isEmpty(mSetting)) {
return true;
}
@@ -401,7 +404,7 @@ public class DozeSensors {
}
}
private String triggerEventToString(TriggerEvent event) {
protected String triggerEventToString(TriggerEvent event) {
if (event == null) return null;
final StringBuilder sb = new StringBuilder("TriggerEvent[")
.append(event.timestamp).append(',')
@@ -415,6 +418,28 @@ public class DozeSensors {
}
}
private class WakeScreenSensor extends TriggerSensor {
WakeScreenSensor() {
super(findSensorWithType(mConfig.wakeScreenSensorType()),
Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, true /* configured */,
DozeLog.REASON_SENSOR_WAKE_UP, false /* reportsTouchCoordinates */,
false /* requiresTouchscreen */);
}
@Override
@AnyThread
public void onTrigger(TriggerEvent event) {
DozeLog.traceSensor(mContext, mPulseReason);
mHandler.post(mWakeLock.wrap(() -> {
if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
mRegistered = false;
mWakeScreenCallback.accept(event.values[0] > 0);
updateListener(); // reregister, this sensor only fires once
}));
}
}
public interface Callback {
/**

View File

@@ -84,7 +84,7 @@ public class DozeTriggers implements DozeMachine.Part {
mWakeLock = wakeLock;
mAllowPulseTriggers = allowPulseTriggers;
mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters,
config, wakeLock, this::onSensor, this::onProximityFar,
config, wakeLock, this::onSensor, this::onProximityFar, this::onWakeScreen,
dozeParameters.getPolicy());
mUiModeManager = mContext.getSystemService(UiModeManager.class);
}
@@ -103,7 +103,7 @@ public class DozeTriggers implements DozeMachine.Part {
private void proximityCheckThenCall(IntConsumer callback,
boolean alreadyPerformedProxCheck,
int pulseReason) {
int reason) {
Boolean cachedProxFar = mDozeSensors.isProximityCurrentlyFar();
if (alreadyPerformedProxCheck) {
callback.accept(ProximityCheck.RESULT_NOT_CHECKED);
@@ -116,7 +116,7 @@ public class DozeTriggers implements DozeMachine.Part {
public void onProximityResult(int result) {
final long end = SystemClock.uptimeMillis();
DozeLog.traceProximityResult(mContext, result == RESULT_NEAR,
end - start, pulseReason);
end - start, reason);
callback.accept(result);
}
}.check();
@@ -182,6 +182,28 @@ public class DozeTriggers implements DozeMachine.Part {
}
}
private void onWakeScreen(boolean wake) {
DozeMachine.State state = mMachine.getState();
boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
if (wake) {
proximityCheckThenCall((result) -> {
if (result == ProximityCheck.RESULT_NEAR) {
// In pocket, drop event.
return;
}
if (pausing || paused) {
mMachine.requestState(DozeMachine.State.DOZE_AOD);
}
}, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
} else {
if (!pausing && !paused) {
mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
}
}
}
@Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {

View File

@@ -45,7 +45,7 @@ public class DozeScrimController {
public void onDisplayBlanked() {
if (DEBUG) {
Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
+ DozeLog.pulseReasonToString(mPulseReason));
+ DozeLog.reasonToString(mPulseReason));
}
if (!mDozing) {
return;

View File

@@ -6508,6 +6508,10 @@ message MetricsEvent {
// OS: Q
ACTION_EMERGENCY_DIALER_FROM_POWER_MENU = 1569;
// OPEN: Settings > System > Input & Gesture > Wake screen
// OS: Q
SETTINGS_GESTURE_WAKE_SCREEN = 1570;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.