Loading core/res/res/values/config.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2269,4 +2269,9 @@ <string-array name="config_cell_retries_per_error_code"> </string-array> <!-- The OEM specified sensor type for the gesture to launch the camear app. --> <integer name="config_cameraLaunchGestureSensorType">-1</integer> <!-- The OEM specified sensor string type for the gesture to launch camera app, this value must match the value of config_cameraLaunchGestureSensorType in OEM's HAL --> <string translatable="false" name="config_cameraLaunchGestureSensorStringType"></string> </resources> core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2315,4 +2315,7 @@ <java-symbol type="array" name="config_cell_retries_per_error_code" /> <java-symbol type="drawable" name="ic_more_items" /> <!-- Gesture --> <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" /> <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" /> </resources> services/core/java/com/android/server/GestureLauncherService.java 0 → 100644 +185 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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; import android.app.KeyguardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.PowerManager; import android.os.Vibrator; import android.os.PowerManager.WakeLock; import android.os.SystemProperties; import android.provider.MediaStore; import android.util.Slog; /** * The service that listens for gestures detected in sensor firmware and starts the intent * accordingly. * <p>For now, only camera launch gesture is supported, and in the future, more gestures can be * added.</p> * @hide */ class GestureLauncherService extends SystemService { private static final boolean DBG = false; private static final String TAG = "GestureLauncherService"; /** The listener that receives the gesture event. */ private final GestureEventListener mGestureListener = new GestureEventListener(); private Sensor mCameraLaunchSensor; private Vibrator mVibrator; private KeyguardManager mKeyGuard; private Context mContext; /** The wake lock held when a gesture is detected. */ private WakeLock mWakeLock; public GestureLauncherService(Context context) { super(context); mContext = context; } public void onStart() { // Nothing to publish. } public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { Resources resources = mContext.getResources(); if (!isGestureLauncherEnabled(resources)) { if (DBG) Slog.d(TAG, "Gesture launcher is disabled in system properties."); return; } mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); mKeyGuard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService( Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "GestureLauncherService"); if (isCameraLaunchEnabled(resources)) { registerCameraLaunchGesture(resources); } } } /** * Registers for the camera launch gesture. */ private void registerCameraLaunchGesture(Resources resources) { SensorManager sensorManager = (SensorManager) mContext.getSystemService( Context.SENSOR_SERVICE); int cameraLaunchGestureId = resources.getInteger( com.android.internal.R.integer.config_cameraLaunchGestureSensorType); if (cameraLaunchGestureId != -1) { boolean registered = false; String sensorName = resources.getString( com.android.internal.R.string.config_cameraLaunchGestureSensorStringType); mCameraLaunchSensor = sensorManager.getDefaultSensor( cameraLaunchGestureId, true /*wakeUp*/); // Compare the camera gesture 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 (mCameraLaunchSensor != null) { if (sensorName.equals(mCameraLaunchSensor.getStringType())) { registered = sensorManager.registerListener(mGestureListener, mCameraLaunchSensor, 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, mCameraLaunchSensor.getStringType()); throw new RuntimeException(message); } } if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + registered); } else { if (DBG) Slog.d(TAG, "Camera launch sensor is not specified."); } } /** * Whether to enable the camera launch gesture. */ public static boolean isCameraLaunchEnabled(Resources resources) { boolean configSet = resources.getInteger( com.android.internal.R.integer.config_cameraLaunchGestureSensorType) != -1; return configSet && !SystemProperties.getBoolean("gesture.disable_camera_launch", false); } /** * Whether GestureLauncherService should be enabled according to system properties. */ public static boolean isGestureLauncherEnabled(Resources resources) { // For now, the only supported gesture is camera launch gesture, so whether to enable this // service equals to isCameraLaunchEnabled(); return isCameraLaunchEnabled(resources); } private final class GestureEventListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { if (event.sensor == mCameraLaunchSensor) { handleCameraLaunchGesture(); return; } } private void handleCameraLaunchGesture() { if (DBG) Slog.d(TAG, "Received a camera launch event."); boolean locked = mKeyGuard != null && mKeyGuard.inKeyguardRestrictedInputMode(); String action = locked ? MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA; Intent intent = new Intent(action); PackageManager pm = mContext.getPackageManager(); ResolveInfo componentInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); if (componentInfo == null) { if (DBG) Slog.d(TAG, "Couldn't find an app to process the camera intent."); return; } if (mVibrator != null && mVibrator.hasVibrator()) { mVibrator.vibrate(1000L); } // Turn on the screen before the camera launches. mWakeLock.acquire(500L); intent.setComponent(new ComponentName(componentInfo.activityInfo.packageName, componentInfo.activityInfo.name)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); mWakeLock.release(); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Ignored. } } } services/java/com/android/server/SystemServer.java +5 −0 Original line number Diff line number Diff line Loading @@ -857,6 +857,11 @@ public final class SystemServer { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_VOICE_RECOGNIZERS)) { mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS); } if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) { Slog.i(TAG, "Gesture Launcher Service"); mSystemServiceManager.startService(GestureLauncherService.class); } } try { Loading Loading
core/res/res/values/config.xml +5 −0 Original line number Diff line number Diff line Loading @@ -2269,4 +2269,9 @@ <string-array name="config_cell_retries_per_error_code"> </string-array> <!-- The OEM specified sensor type for the gesture to launch the camear app. --> <integer name="config_cameraLaunchGestureSensorType">-1</integer> <!-- The OEM specified sensor string type for the gesture to launch camera app, this value must match the value of config_cameraLaunchGestureSensorType in OEM's HAL --> <string translatable="false" name="config_cameraLaunchGestureSensorStringType"></string> </resources>
core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2315,4 +2315,7 @@ <java-symbol type="array" name="config_cell_retries_per_error_code" /> <java-symbol type="drawable" name="ic_more_items" /> <!-- Gesture --> <java-symbol type="integer" name="config_cameraLaunchGestureSensorType" /> <java-symbol type="string" name="config_cameraLaunchGestureSensorStringType" /> </resources>
services/core/java/com/android/server/GestureLauncherService.java 0 → 100644 +185 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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; import android.app.KeyguardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.PowerManager; import android.os.Vibrator; import android.os.PowerManager.WakeLock; import android.os.SystemProperties; import android.provider.MediaStore; import android.util.Slog; /** * The service that listens for gestures detected in sensor firmware and starts the intent * accordingly. * <p>For now, only camera launch gesture is supported, and in the future, more gestures can be * added.</p> * @hide */ class GestureLauncherService extends SystemService { private static final boolean DBG = false; private static final String TAG = "GestureLauncherService"; /** The listener that receives the gesture event. */ private final GestureEventListener mGestureListener = new GestureEventListener(); private Sensor mCameraLaunchSensor; private Vibrator mVibrator; private KeyguardManager mKeyGuard; private Context mContext; /** The wake lock held when a gesture is detected. */ private WakeLock mWakeLock; public GestureLauncherService(Context context) { super(context); mContext = context; } public void onStart() { // Nothing to publish. } public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { Resources resources = mContext.getResources(); if (!isGestureLauncherEnabled(resources)) { if (DBG) Slog.d(TAG, "Gesture launcher is disabled in system properties."); return; } mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); mKeyGuard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService( Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "GestureLauncherService"); if (isCameraLaunchEnabled(resources)) { registerCameraLaunchGesture(resources); } } } /** * Registers for the camera launch gesture. */ private void registerCameraLaunchGesture(Resources resources) { SensorManager sensorManager = (SensorManager) mContext.getSystemService( Context.SENSOR_SERVICE); int cameraLaunchGestureId = resources.getInteger( com.android.internal.R.integer.config_cameraLaunchGestureSensorType); if (cameraLaunchGestureId != -1) { boolean registered = false; String sensorName = resources.getString( com.android.internal.R.string.config_cameraLaunchGestureSensorStringType); mCameraLaunchSensor = sensorManager.getDefaultSensor( cameraLaunchGestureId, true /*wakeUp*/); // Compare the camera gesture 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 (mCameraLaunchSensor != null) { if (sensorName.equals(mCameraLaunchSensor.getStringType())) { registered = sensorManager.registerListener(mGestureListener, mCameraLaunchSensor, 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, mCameraLaunchSensor.getStringType()); throw new RuntimeException(message); } } if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + registered); } else { if (DBG) Slog.d(TAG, "Camera launch sensor is not specified."); } } /** * Whether to enable the camera launch gesture. */ public static boolean isCameraLaunchEnabled(Resources resources) { boolean configSet = resources.getInteger( com.android.internal.R.integer.config_cameraLaunchGestureSensorType) != -1; return configSet && !SystemProperties.getBoolean("gesture.disable_camera_launch", false); } /** * Whether GestureLauncherService should be enabled according to system properties. */ public static boolean isGestureLauncherEnabled(Resources resources) { // For now, the only supported gesture is camera launch gesture, so whether to enable this // service equals to isCameraLaunchEnabled(); return isCameraLaunchEnabled(resources); } private final class GestureEventListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { if (event.sensor == mCameraLaunchSensor) { handleCameraLaunchGesture(); return; } } private void handleCameraLaunchGesture() { if (DBG) Slog.d(TAG, "Received a camera launch event."); boolean locked = mKeyGuard != null && mKeyGuard.inKeyguardRestrictedInputMode(); String action = locked ? MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA; Intent intent = new Intent(action); PackageManager pm = mContext.getPackageManager(); ResolveInfo componentInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); if (componentInfo == null) { if (DBG) Slog.d(TAG, "Couldn't find an app to process the camera intent."); return; } if (mVibrator != null && mVibrator.hasVibrator()) { mVibrator.vibrate(1000L); } // Turn on the screen before the camera launches. mWakeLock.acquire(500L); intent.setComponent(new ComponentName(componentInfo.activityInfo.packageName, componentInfo.activityInfo.name)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); mWakeLock.release(); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Ignored. } } }
services/java/com/android/server/SystemServer.java +5 −0 Original line number Diff line number Diff line Loading @@ -857,6 +857,11 @@ public final class SystemServer { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_VOICE_RECOGNIZERS)) { mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS); } if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) { Slog.i(TAG, "Gesture Launcher Service"); mSystemServiceManager.startService(GestureLauncherService.class); } } try { Loading