DozeService: Seperate double tap and pickup
Adds handling for a separate double tap gesture
and allows enabling double tap and pickup
individually.
Test: Turn screen off, toggle gestures with `adb shell settings put secure doze_pulse_on_pick_up 0/1` and `adb shell settings put secure doze_pulse_on_double_tap 0/1`
Bug: 30595437
Change-Id: Id7b79f90b28429cf321544a3e425cf33c575d1c3
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 874021a..b3038b9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,12 +35,13 @@
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 = 4;
+ private static final int PULSE_REASONS = 5;
public static final int PULSE_REASON_INTENT = 0;
public static final int PULSE_REASON_NOTIFICATION = 1;
public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
public static final int PULSE_REASON_SENSOR_PICKUP = 3;
+ public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
private static long[] sTimes;
private static String[] sMessages;
@@ -167,6 +168,7 @@
case PULSE_REASON_NOTIFICATION: return "notification";
case PULSE_REASON_SENSOR_SIGMOTION: return "sigmotion";
case PULSE_REASON_SENSOR_PICKUP: return "pickup";
+ case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
default: throw new IllegalArgumentException("bad reason: " + pulseReason);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index ec4f447..25d3691 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,12 +16,14 @@
package com.android.systemui.doze;
+import android.app.ActivityManager;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
+import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -29,11 +31,15 @@
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
import android.media.AudioAttributes;
+import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.service.dreams.DreamService;
+import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
@@ -45,6 +51,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Date;
+import java.util.List;
public class DozeService extends DreamService {
private static final String TAG = "DozeService";
@@ -59,8 +66,8 @@
private final Handler mHandler = new Handler();
private DozeHost mHost;
- private SensorManager mSensors;
- private TriggerSensor mSigMotionSensor;
+ private SensorManager mSensorManager;
+ private TriggerSensor[] mSensors;
private TriggerSensor mPickupSensor;
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
@@ -86,8 +93,10 @@
pw.print(" mWakeLock: held="); pw.println(mWakeLock.isHeld());
pw.print(" mHost: "); pw.println(mHost);
pw.print(" mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
- pw.print(" mSigMotionSensor: "); pw.println(mSigMotionSensor);
- pw.print(" mPickupSensor:"); pw.println(mPickupSensor);
+ for (TriggerSensor s : mSensors) {
+ pw.print(" sensor: ");
+ pw.println(s);
+ }
pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
pw.print(" mCarMode: "); pw.println(mCarMode);
@@ -110,13 +119,25 @@
setWindowless(true);
- mSensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
- mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION,
- mDozeParameters.getPulseOnSigMotion(), mDozeParameters.getVibrateOnSigMotion(),
- DozeLog.PULSE_REASON_SENSOR_SIGMOTION);
- mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE,
- mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(),
- DozeLog.PULSE_REASON_SENSOR_PICKUP);
+ mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+ mSensors = new TriggerSensor[] {
+ new TriggerSensor(
+ mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
+ null /* setting */,
+ mDozeParameters.getPulseOnSigMotion(),
+ mDozeParameters.getVibrateOnSigMotion(),
+ DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
+ mPickupSensor = new TriggerSensor(
+ mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
+ Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+ mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(),
+ DozeLog.PULSE_REASON_SENSOR_PICKUP),
+ new TriggerSensor(
+ findSensorWithType(mDozeParameters.getDoubleTapSensorType()),
+ Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+ mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(),
+ DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
+ };
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(true);
@@ -283,8 +304,9 @@
private void listenForPulseSignals(boolean listen) {
if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
- mSigMotionSensor.setListening(listen);
- mPickupSensor.setListening(listen);
+ for (TriggerSensor s : mSensors) {
+ s.setListening(listen);
+ }
listenForBroadcasts(listen);
listenForNotifications(listen);
}
@@ -293,11 +315,21 @@
if (listen) {
final IntentFilter filter = new IntentFilter(PULSE_ACTION);
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mBroadcastReceiver, filter);
+
+ for (TriggerSensor s : mSensors) {
+ if (s.mConfigured && !TextUtils.isEmpty(s.mSetting)) {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(s.mSetting), false /* descendants */,
+ mSettingsObserver, UserHandle.USER_ALL);
+ }
+ }
mBroadcastReceiverRegistered = true;
} else {
if (mBroadcastReceiverRegistered) {
mContext.unregisterReceiver(mBroadcastReceiver);
+ mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
}
mBroadcastReceiverRegistered = false;
}
@@ -344,6 +376,23 @@
finishForCarMode();
}
}
+ if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+ for (TriggerSensor s : mSensors) {
+ s.updateListener();
+ }
+ }
+ }
+ };
+
+ private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (userId != ActivityManager.getCurrentUser()) {
+ return;
+ }
+ for (TriggerSensor s : mSensors) {
+ s.updateListener();
+ }
}
};
@@ -375,18 +424,34 @@
}
};
+ private Sensor findSensorWithType(String type) {
+ if (TextUtils.isEmpty(type)) {
+ return null;
+ }
+ List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ for (Sensor s : sensorList) {
+ if (type.equals(s.getStringType())) {
+ return s;
+ }
+ }
+ return null;
+ }
+
private class TriggerSensor extends TriggerEventListener {
- private final Sensor mSensor;
- private final boolean mConfigured;
- private final boolean mDebugVibrate;
- private final int mPulseReason;
+ final Sensor mSensor;
+ final boolean mConfigured;
+ final boolean mDebugVibrate;
+ final int mPulseReason;
+ final String mSetting;
private boolean mRequested;
private boolean mRegistered;
private boolean mDisabled;
- public TriggerSensor(int type, boolean configured, boolean debugVibrate, int pulseReason) {
- mSensor = mSensors.getDefaultSensor(type);
+ public TriggerSensor(Sensor sensor, String setting, boolean configured,
+ boolean debugVibrate, int pulseReason) {
+ mSensor = sensor;
+ mSetting = setting;
mConfigured = configured;
mDebugVibrate = debugVibrate;
mPulseReason = pulseReason;
@@ -404,18 +469,26 @@
updateListener();
}
- private void updateListener() {
+ public void updateListener() {
if (!mConfigured || mSensor == null) return;
- if (mRequested && !mDisabled && !mRegistered) {
- mRegistered = mSensors.requestTriggerSensor(this, mSensor);
+ if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
+ mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
if (DEBUG) Log.d(mTag, "requestTriggerSensor " + mRegistered);
} else if (mRegistered) {
- final boolean rt = mSensors.cancelTriggerSensor(this, mSensor);
+ final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
if (DEBUG) Log.d(mTag, "cancelTriggerSensor " + rt);
mRegistered = false;
}
}
+ private boolean enabledBySetting() {
+ if (TextUtils.isEmpty(mSetting)) {
+ return true;
+ }
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(), mSetting, 1,
+ UserHandle.USER_CURRENT) != 0;
+ }
+
@Override
public String toString() {
return new StringBuilder("{mRegistered=").append(mRegistered)
@@ -484,7 +557,7 @@
public void check() {
if (mFinished || mRegistered) return;
- final Sensor sensor = mSensors.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+ final Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
if (sensor == null) {
if (DEBUG) Log.d(mTag, "No sensor found");
finishWithResult(RESULT_UNKNOWN);
@@ -494,7 +567,8 @@
mPickupSensor.setDisabled(true);
mMaxRange = sensor.getMaximumRange();
- mSensors.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, 0, mHandler);
+ mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, 0,
+ mHandler);
mHandler.postDelayed(this, TIMEOUT_DELAY_MS);
mRegistered = true;
}
@@ -521,7 +595,7 @@
if (mFinished) return;
if (mRegistered) {
mHandler.removeCallbacks(this);
- mSensors.unregisterListener(this);
+ mSensorManager.unregisterListener(this);
// we're done - reenable the pickup sensor
mPickupSensor.setDisabled(false);
mRegistered = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index efceed1..d5bf499 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -84,8 +84,8 @@
return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
}
- public int getPulseInDuration(boolean pickup) {
- return pickup
+ public int getPulseInDuration(boolean pickupOrDoubleTap) {
+ return pickupOrDoubleTap
? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
: getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
}
@@ -114,6 +114,10 @@
return SystemProperties.getBoolean("doze.vibrate.pickup", false);
}
+ public String getDoubleTapSensorType() {
+ return mContext.getString(R.string.doze_double_tap_sensor_type);
+ }
+
public boolean getProxCheckBeforePulse() {
return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 7d4515e..b44f5f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -109,10 +109,11 @@
public void onScreenTurnedOn() {
if (isPulsing()) {
- final boolean pickup = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP;
+ final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
+ || mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
startScrimAnimation(true /* inFront */, 0f,
- mDozeParameters.getPulseInDuration(pickup),
- pickup ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
+ mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
+ pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
mPulseInFinished);
}
}