Merge "Add camera lift trigger to GestureLauncherService"

This commit is contained in:
Jonathan Solnit
2017-05-15 16:20:33 +00:00
committed by Android (Google) Code Review
8 changed files with 135 additions and 16 deletions

View File

@@ -92,6 +92,7 @@ public class StatusBarManager {
public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
private Context mContext;
private IStatusBarService mService;

View File

@@ -2947,4 +2947,10 @@
<!-- Volume level of in-call notification tone playback,
relative to the overall voice call stream volume [0..100] -->
<integer name="config_inCallNotificationVolumeRelative">67</integer>
<!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
<integer name="config_cameraLiftTriggerSensorType">-1</integer>
<!-- The OEM specified sensor string type for the gesture to launch camera app, this value
must match the value of config_cameraLiftTriggerSensorType in OEM's HAL -->
<string translatable="false" name="config_cameraLiftTriggerSensorStringType"></string>
</resources>

View File

@@ -2523,6 +2523,8 @@
<java-symbol type="integer" name="config_cameraLaunchGestureSensorType" />
<java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" />
<java-symbol type="bool" name="config_cameraDoubleTapPowerGestureEnabled" />
<java-symbol type="integer" name="config_cameraLiftTriggerSensorType" />
<java-symbol type="string" name="config_cameraLiftTriggerSensorStringType" />
<java-symbol type="drawable" name="platlogo_m" />

View File

@@ -100,6 +100,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
public static final String CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = "power_double_tap";
public static final String CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = "lift_to_launch_ml";
public static final String EXTRA_CAMERA_LAUNCH_SOURCE
= "com.android.systemui.camera_launch_source";

View File

@@ -2390,6 +2390,8 @@ public class NotificationPanelView extends PanelView implements
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP;
} else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) {
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE;
} else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) {
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER;
} else {
// Default.

View File

@@ -3974,6 +3974,11 @@ message MetricsEvent {
// OPEN: Settings > Battery > High Usage
DIALOG_HANDLE_ANOMALY = 988;
// ACTION: Camera lift gesture
// CATEGORY: GLOBAL_SYSTEM_UI
// OS: O
ACTION_CAMERA_LIFT_TRIGGER = 989;
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}

View File

@@ -71,14 +71,18 @@ public class GestureLauncherService extends SystemService {
/** The listener that receives the gesture event. */
private final GestureEventListener mGestureListener = new GestureEventListener();
private final CameraLiftTriggerEventListener mCameraLiftTriggerListener =
new CameraLiftTriggerEventListener();
private Sensor mCameraLaunchSensor;
private Sensor mCameraLiftTriggerSensor;
private Context mContext;
private final MetricsLogger mMetricsLogger;
/** The wake lock held when a gesture is detected. */
private WakeLock mWakeLock;
private boolean mRegistered;
private boolean mCameraLaunchRegistered;
private boolean mCameraLiftRegistered;
private int mUserId;
// Below are fields used for event logging only.
@@ -161,6 +165,9 @@ public class GestureLauncherService extends SystemService {
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED),
false, mSettingObserver, mUserId);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED),
false, mSettingObserver, mUserId);
}
private void updateCameraRegistered() {
@@ -170,6 +177,12 @@ public class GestureLauncherService extends SystemService {
} else {
unregisterCameraLaunchGesture();
}
if (isCameraLiftTriggerSettingEnabled(mContext, mUserId)) {
registerCameraLiftTrigger(resources);
} else {
unregisterCameraLiftTrigger();
}
}
@VisibleForTesting
@@ -181,8 +194,8 @@ public class GestureLauncherService extends SystemService {
}
private void unregisterCameraLaunchGesture() {
if (mRegistered) {
mRegistered = false;
if (mCameraLaunchRegistered) {
mCameraLaunchRegistered = false;
mCameraGestureOnTimeMs = 0L;
mCameraGestureLastEventTime = 0L;
mCameraGestureSensor1LastOnTimeMs = 0;
@@ -199,7 +212,7 @@ public class GestureLauncherService extends SystemService {
* Registers for the camera launch gesture.
*/
private void registerCameraLaunchGesture(Resources resources) {
if (mRegistered) {
if (mCameraLaunchRegistered) {
return;
}
mCameraGestureOnTimeMs = SystemClock.elapsedRealtime();
@@ -209,7 +222,7 @@ public class GestureLauncherService extends SystemService {
int cameraLaunchGestureId = resources.getInteger(
com.android.internal.R.integer.config_cameraLaunchGestureSensorType);
if (cameraLaunchGestureId != -1) {
mRegistered = false;
mCameraLaunchRegistered = false;
String sensorName = resources.getString(
com.android.internal.R.string.config_cameraLaunchGestureSensorStringType);
mCameraLaunchSensor = sensorManager.getDefaultSensor(
@@ -221,7 +234,7 @@ public class GestureLauncherService extends SystemService {
// makes the code more robust.
if (mCameraLaunchSensor != null) {
if (sensorName.equals(mCameraLaunchSensor.getStringType())) {
mRegistered = sensorManager.registerListener(mGestureListener,
mCameraLaunchRegistered = sensorManager.registerListener(mGestureListener,
mCameraLaunchSensor, 0);
} else {
String message = String.format("Wrong configuration. Sensor type and sensor "
@@ -230,12 +243,61 @@ public class GestureLauncherService extends SystemService {
throw new RuntimeException(message);
}
}
if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mRegistered);
if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mCameraLaunchRegistered);
} else {
if (DBG) Slog.d(TAG, "Camera launch sensor is not specified.");
}
}
private void unregisterCameraLiftTrigger() {
if (mCameraLiftRegistered) {
mCameraLiftRegistered = false;
SensorManager sensorManager = (SensorManager) mContext.getSystemService(
Context.SENSOR_SERVICE);
sensorManager.unregisterListener(mCameraLiftTriggerListener);
}
}
/**
* Registers for the camera lift trigger.
*/
private void registerCameraLiftTrigger(Resources resources) {
if (mCameraLiftRegistered) {
return;
}
SensorManager sensorManager = (SensorManager) mContext.getSystemService(
Context.SENSOR_SERVICE);
int cameraLiftTriggerId = resources.getInteger(
com.android.internal.R.integer.config_cameraLiftTriggerSensorType);
if (cameraLiftTriggerId != -1) {
mCameraLiftRegistered = false;
String sensorName = resources.getString(
com.android.internal.R.string.config_cameraLiftTriggerSensorStringType);
mCameraLiftTriggerSensor = sensorManager.getDefaultSensor(
cameraLiftTriggerId,
false /*wakeUp*/);
// Compare the camera lift trigger string type to that in the resource file to make
// sure we are registering the correct sensor. This is redundant check, it
// makes the code more robust.
if (mCameraLiftTriggerSensor != null) {
if (sensorName.equals(mCameraLiftTriggerSensor.getStringType())) {
mCameraLiftRegistered = sensorManager.registerListener(mCameraLiftTriggerListener,
mCameraLiftTriggerSensor, 0);
} else {
String message = String.format("Wrong configuration. Sensor type and sensor "
+ "string type don't match: %s in resources, %s in the sensor.",
sensorName, mCameraLiftTriggerSensor.getStringType());
throw new RuntimeException(message);
}
}
if (DBG) Slog.d(TAG, "Camera lift trigger sensor registered: " + mCameraLiftRegistered);
} else {
if (DBG) Slog.d(TAG, "Camera lift trigger sensor is not specified.");
}
}
public static boolean isCameraLaunchSettingEnabled(Context context, int userId) {
return isCameraLaunchEnabled(context.getResources())
&& (Settings.Secure.getIntForUser(context.getContentResolver(),
@@ -248,6 +310,12 @@ public class GestureLauncherService extends SystemService {
Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
}
public static boolean isCameraLiftTriggerSettingEnabled(Context context, int userId) {
return isCameraLiftTriggerEnabled(context.getResources())
&& (Settings.Secure.getIntForUser(context.getContentResolver(),
Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, 0, userId) != 0);
}
/**
* Whether to enable the camera launch gesture.
*/
@@ -263,11 +331,18 @@ public class GestureLauncherService extends SystemService {
com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled);
}
public static boolean isCameraLiftTriggerEnabled(Resources resources) {
boolean configSet = resources.getInteger(
com.android.internal.R.integer.config_cameraLiftTriggerSensorType) != -1;
return configSet;
}
/**
* Whether GestureLauncherService should be enabled according to system properties.
*/
public static boolean isGestureLauncherEnabled(Resources resources) {
return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources);
return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources) ||
isCameraLiftTriggerEnabled(resources);
}
public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
@@ -296,7 +371,7 @@ public class GestureLauncherService extends SystemService {
if (launched) {
Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval="
+ powerTapInterval + "ms");
launched = handleCameraLaunchGesture(false /* useWakelock */,
launched = handleCameraGesture(false /* useWakelock */,
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
if (launched) {
mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
@@ -313,17 +388,17 @@ public class GestureLauncherService extends SystemService {
* @return true if camera was launched, false otherwise.
*/
@VisibleForTesting
boolean handleCameraLaunchGesture(boolean useWakelock, int source) {
boolean handleCameraGesture(boolean useWakelock, int source) {
boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
if (!userSetupComplete) {
if (DBG) Slog.d(TAG, String.format(
"userSetupComplete = %s, ignoring camera launch gesture.",
"userSetupComplete = %s, ignoring camera gesture.",
userSetupComplete));
return false;
}
if (DBG) Slog.d(TAG, String.format(
"userSetupComplete = %s, performing camera launch gesture.",
"userSetupComplete = %s, performing camera gesture.",
userSetupComplete));
if (useWakelock) {
@@ -361,7 +436,7 @@ public class GestureLauncherService extends SystemService {
private final class GestureEventListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
if (!mRegistered) {
if (!mCameraLaunchRegistered) {
if (DBG) Slog.d(TAG, "Ignoring gesture event because it's unregistered.");
return;
}
@@ -371,7 +446,7 @@ public class GestureLauncherService extends SystemService {
Slog.d(TAG, String.format("Received a camera launch event: " +
"values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2]));
}
if (handleCameraLaunchGesture(true /* useWakelock */,
if (handleCameraGesture(true /* useWakelock */,
StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
mMetricsLogger.action(MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
trackCameraLaunchEvent(event);
@@ -430,4 +505,31 @@ public class GestureLauncherService extends SystemService {
mCameraLaunchLastEventExtra = extra;
}
}
private final class CameraLiftTriggerEventListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
if (!mCameraLiftRegistered) {
if (DBG) Slog.d(TAG, "Ignoring camera lift event because it's unregistered.");
return;
}
if (event.sensor == mCameraLiftTriggerSensor) {
if (DBG) {
float[] values = event.values;
Slog.d(TAG, String.format("Received a camera lift trigger event: " +
"values=[%.4f].", values[0]));
}
if (handleCameraGesture(true /* useWakelock */,
StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
}
return;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Ignored.
}
}
}

View File

@@ -154,7 +154,7 @@ public class GestureLauncherServiceTest {
withUserSetupCompleteValue(true);
boolean useWakeLock = false;
assertTrue(mGestureLauncherService.handleCameraLaunchGesture(useWakeLock, FAKE_SOURCE));
assertTrue(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE);
}
@@ -163,7 +163,7 @@ public class GestureLauncherServiceTest {
withUserSetupCompleteValue(false);
boolean useWakeLock = false;
assertFalse(mGestureLauncherService.handleCameraLaunchGesture(useWakeLock, FAKE_SOURCE));
assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE));
}
@Test