Merge "Add setting to disable camera gesture" into mnc-dr-dev
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fe95864..78be3cd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5712,6 +5712,13 @@
         public static final String ASSISTANT = "assistant";
 
         /**
+         * Whether the camera launch gesture should be disabled.
+         *
+         * @hide
+         */
+        public static final String CAMERA_GESTURE_DISABLED = "camera_gesture_disabled";
+
+        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -5767,6 +5774,7 @@
             MOUNT_UMS_NOTIFY_ENABLED,
             SLEEP_TIMEOUT,
             DOUBLE_TAP_TO_WAKE,
+            CAMERA_GESTURE_DISABLED,
         };
 
         /**
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index e17ff5c..1f3d61c 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -16,21 +16,26 @@
 
 package com.android.server;
 
+import android.app.ActivityManager;
 import android.app.KeyguardManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.os.Handler;
 import android.os.PowerManager;
-import android.os.Vibrator;
 import android.os.PowerManager.WakeLock;
 import android.os.SystemProperties;
+import android.os.Vibrator;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.util.Slog;
@@ -56,6 +61,8 @@
 
     /** The wake lock held when a gesture is detected. */
     private WakeLock mWakeLock;
+    private boolean mRegistered;
+    private int mUserId;
 
     public GestureLauncherService(Context context) {
         super(context);
@@ -81,9 +88,35 @@
             mWakeLock = powerManager.newWakeLock(
                     PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
                     "GestureLauncherService");
-            if (isCameraLaunchEnabled(resources)) {
-                registerCameraLaunchGesture(resources);
-            }
+            updateCameraRegistered();
+
+            mUserId = ActivityManager.getCurrentUser();
+            mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));
+            registerContentObserver();
+        }
+    }
+
+    private void registerContentObserver() {
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.CAMERA_GESTURE_DISABLED),
+                false, mSettingObserver, mUserId);
+    }
+
+    private void updateCameraRegistered() {
+        Resources resources = mContext.getResources();
+        if (isCameraLaunchSettingEnabled(mContext, mUserId)) {
+            registerCameraLaunchGesture(resources);
+        } else {
+            unregisterCameraLaunchGesture();
+        }
+    }
+
+    private void unregisterCameraLaunchGesture() {
+        if (mRegistered) {
+            mRegistered = false;
+            SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                    Context.SENSOR_SERVICE);
+            sensorManager.unregisterListener(mGestureListener);
         }
     }
 
@@ -91,12 +124,15 @@
      * Registers for the camera launch gesture.
      */
     private void registerCameraLaunchGesture(Resources resources) {
+        if (mRegistered) {
+            return;
+        }
         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;
+            mRegistered = false;
             String sensorName = resources.getString(
                 com.android.internal.R.string.config_cameraLaunchGestureSensorStringType);
             mCameraLaunchSensor = sensorManager.getDefaultSensor(
@@ -108,7 +144,7 @@
             // makes the code more robust.
             if (mCameraLaunchSensor != null) {
                 if (sensorName.equals(mCameraLaunchSensor.getStringType())) {
-                    registered = sensorManager.registerListener(mGestureListener,
+                    mRegistered = sensorManager.registerListener(mGestureListener,
                             mCameraLaunchSensor, 0);
                 } else {
                     String message = String.format("Wrong configuration. Sensor type and sensor "
@@ -117,12 +153,18 @@
                     throw new RuntimeException(message);
                 }
             }
-            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + registered);
+            if (DBG) Slog.d(TAG, "Camera launch sensor registered: " + mRegistered);
         } else {
             if (DBG) Slog.d(TAG, "Camera launch sensor is not specified.");
         }
     }
 
+    public static boolean isCameraLaunchSettingEnabled(Context context, int userId) {
+        return isCameraLaunchEnabled(context.getResources())
+                && (Settings.Secure.getIntForUser(context.getContentResolver(),
+                        Settings.Secure.CAMERA_GESTURE_DISABLED, 0, userId) == 0);
+    }
+
     /**
      * Whether to enable the camera launch gesture.
      */
@@ -142,6 +184,26 @@
         return isCameraLaunchEnabled(resources);
     }
 
+    private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
+                registerContentObserver();
+                updateCameraRegistered();
+            }
+        }
+    };
+
+    private final ContentObserver mSettingObserver = new ContentObserver(new Handler()) {
+        public void onChange(boolean selfChange, android.net.Uri uri, int userId) {
+            if (userId == mUserId) {
+                updateCameraRegistered();
+            }
+        }
+    };
+
     private final class GestureEventListener implements SensorEventListener {
         @Override
         public void onSensorChanged(SensorEvent event) {