diff options
author | Zhentao Sun <robinvane@google.com> | 2015-07-21 17:43:53 -0700 |
---|---|---|
committer | Zhentao Sun <robinvane@google.com> | 2015-07-22 17:42:41 -0700 |
commit | c6cd1f9a83b2807ef7434b6775a07e1e9208d4e0 (patch) | |
tree | dc92ab99fec7f7bd61b1e6ace47a2c2113a69924 | |
parent | 58adc7ad48990f2ffa0d4858bd6910dd9eb6aabc (diff) | |
download | frameworks_base-c6cd1f9a83b2807ef7434b6775a07e1e9208d4e0.zip frameworks_base-c6cd1f9a83b2807ef7434b6775a07e1e9208d4e0.tar.gz frameworks_base-c6cd1f9a83b2807ef7434b6775a07e1e9208d4e0.tar.bz2 |
Added service that listens for gestures.
Added the GestureLauncherService that listens for camera launch gesture
and starts the camera app.
OEMs need to specify the sensor type of the camera launch gesture in
their overlays.
In the future, we can add more gesture support in this service.
Change-Id: I0769e7ca71e08bd9159aacf29bdcefd316efd2f0
-rwxr-xr-x | core/res/res/values/config.xml | 5 | ||||
-rwxr-xr-x | core/res/res/values/symbols.xml | 3 | ||||
-rw-r--r-- | services/core/java/com/android/server/GestureLauncherService.java | 185 | ||||
-rw-r--r-- | services/java/com/android/server/SystemServer.java | 5 |
4 files changed, 198 insertions, 0 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 06b6389..531f109 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -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> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fe82b8c..5087b2c 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -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> diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java new file mode 100644 index 0000000..d7b0765 --- /dev/null +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -0,0 +1,185 @@ +/* + * 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. + } + } +} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 014527b..f1fac9e 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -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 { |