Separate ambient display triggers

Allows configuring notification and sensor triggers
separately. Introduces a helper class that hosts the
logic for determining what kinds of triggers a device
supports.

Bug: 32073185
Change-Id: Ie7e8eb6b895dcc54e6f972e70642c7248b9e223a
Test: disable "ambient display", sensor triggers should still work
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
new file mode 100644
index 0000000..cf1bf62
--- /dev/null
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 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.internal.hardware;
+
+import com.android.internal.R;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+public class AmbientDisplayConfiguration {
+
+    private final Context mContext;
+
+    public AmbientDisplayConfiguration(Context context) {
+        mContext = context;
+    }
+    
+    public boolean enabled(int user) {
+        return pulseOnNotificationEnabled(user)
+                || pulseOnPickupEnabled(user)
+                || pulseOnDoubleTapEnabled(user);
+    }
+    
+    public boolean available() {
+        return pulseOnNotificationAvailable() || pulseOnPickupAvailable()
+                || pulseOnDoubleTapAvailable();
+    }
+    
+    public boolean pulseOnNotificationEnabled(int user) {
+        return boolSetting(Settings.Secure.DOZE_ENABLED, user) && pulseOnNotificationAvailable();
+    }
+
+    public boolean pulseOnNotificationAvailable() {
+        return ambientDisplayAvailable();
+    }
+
+    public boolean pulseOnPickupEnabled(int user) {
+        return boolSetting(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user)
+                && pulseOnPickupAvailable();
+    }
+    
+    public boolean pulseOnPickupAvailable() {
+        return mContext.getResources().getBoolean(R.bool.config_dozePulsePickup)
+                && ambientDisplayAvailable();
+    }
+    
+    public boolean pulseOnDoubleTapEnabled(int user) {
+        return boolSetting(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, user)
+                && pulseOnDoubleTapAvailable();
+    }
+
+    public boolean pulseOnDoubleTapAvailable() {
+        return !TextUtils.isEmpty(doubleTapSensorType()) && ambientDisplayAvailable();
+    }
+
+    public String doubleTapSensorType() {
+        return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
+    }
+
+    public String ambientDisplayComponent() {
+        return mContext.getResources().getString(R.string.config_dozeComponent);
+    }
+
+    private boolean ambientDisplayAvailable() {
+        return !TextUtils.isEmpty(ambientDisplayComponent());
+    }
+
+    private boolean boolSetting(String name, int user) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, 1, user) != 0;
+    }
+
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 18467ae..ae8edab 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1661,6 +1661,12 @@
          turned off and the screen off animation has been performed. -->
     <bool name="config_dozeAfterScreenOff">false</bool>
 
+    <!-- Doze: should the TYPE_PICK_UP_GESTURE sensor be used as a pulse signal. -->
+    <bool name="config_dozePulsePickup">false</bool>
+
+    <!-- Type of the double tap sensor. Empty if double tap is not supported. -->
+    <string name="config_dozeDoubleTapSensorType" translatable="false"></string>
+
     <!-- Power Management: Specifies whether to decouple the auto-suspend state of the
          device from the display on/off state.
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b03a616..826161e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2668,6 +2668,9 @@
   <java-symbol type="string" name="config_emergency_call_number" />
   <java-symbol type="array" name="config_emergency_mcc_codes" />
 
+  <java-symbol type="string" name="config_dozeDoubleTapSensorType" />
+  <java-symbol type="bool" name="config_dozePulsePickup" />
+
   <!-- Used for MimeIconUtils. -->
   <java-symbol type="drawable" name="ic_doc_apk" />
   <java-symbol type="drawable" name="ic_doc_audio" />
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index eb1a1eb..9eea375 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -209,9 +209,6 @@
     <!-- Doze: should the significant motion sensor be used as a pulse signal? -->
     <bool name="doze_pulse_on_significant_motion">false</bool>
 
-    <!-- Doze: should the pickup sensor be used as a pulse signal? -->
-    <bool name="doze_pulse_on_pick_up">false</bool>
-
     <!-- Doze: check proximity sensor before pulsing? -->
     <bool name="doze_proximity_check_before_pulse">true</bool>
 
@@ -240,9 +237,6 @@
     -->
     <string name="doze_pickup_subtype_performs_proximity_check"></string>
 
-    <!-- Type of the double tap sensor. Empty if double tap is not supported. -->
-    <string name="doze_double_tap_sensor_type" translatable="false"></string>
-
     <!-- Doze: pulse parameter - how long does it take to fade in? -->
     <integer name="doze_pulse_duration_in">900</integer>
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 56f6b8d..6c35243 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -43,6 +43,7 @@
 import android.util.Log;
 import android.view.Display;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.SystemUIApplication;
@@ -85,6 +86,8 @@
     private boolean mCarMode;
     private long mNotificationPulseTime;
 
+    private AmbientDisplayConfiguration mConfig;
+
     public DozeService() {
         if (DEBUG) Log.d(mTag, "new DozeService()");
         setDebug(DEBUG);
@@ -125,6 +128,7 @@
         setWindowless(true);
 
         mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+        mConfig = new AmbientDisplayConfiguration(mContext);
         mSensors = new TriggerSensor[] {
                 new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
@@ -135,12 +139,12 @@
                 mPickupSensor = new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PULSE_ON_PICK_UP,
-                        mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(),
+                        mConfig.pulseOnPickupAvailable(), mDozeParameters.getVibrateOnPickup(),
                         DozeLog.PULSE_REASON_SENSOR_PICKUP),
                 new TriggerSensor(
-                        findSensorWithType(mDozeParameters.getDoubleTapSensorType()),
-                        Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
-                        mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(),
+                        findSensorWithType(mConfig.doubleTapSensorType()),
+                        Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, true,
+                        mDozeParameters.getVibrateOnPickup(),
                         DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
         };
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -359,7 +363,7 @@
 
     private void requestNotificationPulse() {
         if (DEBUG) Log.d(mTag, "requestNotificationPulse");
-        if (!mDozeParameters.getPulseOnNotifications()) return;
+        if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) return;
         mNotificationPulseTime = SystemClock.elapsedRealtime();
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
     }
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 d5bf499..9e9bdd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -18,11 +18,13 @@
 
 import android.content.Context;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.systemui.R;
 
 import java.io.PrintWriter;
@@ -31,9 +33,6 @@
 import java.util.regex.Pattern;
 
 public class DozeParameters {
-    private static final String TAG = "DozeParameters";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
     private static final int MAX_DURATION = 60 * 1000;
 
     private final Context mContext;
@@ -55,10 +54,8 @@
         pw.print("    getPulseOutDuration(): "); pw.println(getPulseOutDuration());
         pw.print("    getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
         pw.print("    getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion());
-        pw.print("    getPulseOnPickup(): "); pw.println(getPulseOnPickup());
         pw.print("    getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
         pw.print("    getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
-        pw.print("    getPulseOnNotifications(): "); pw.println(getPulseOnNotifications());
         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
         pw.print("    getPickupSubtypePerformsProxCheck(): ");pw.println(
                 dumpPickupSubtypePerformsProxCheck());
@@ -106,26 +103,14 @@
         return SystemProperties.getBoolean("doze.vibrate.sigmotion", false);
     }
 
-    public boolean getPulseOnPickup() {
-        return getBoolean("doze.pulse.pickup", R.bool.doze_pulse_on_pick_up);
-    }
-
     public boolean getVibrateOnPickup() {
         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);
     }
 
-    public boolean getPulseOnNotifications() {
-        return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications);
-    }
-
     public int getPickupVibrationThreshold() {
         return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
     }
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 20bccf1..1991c00 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.BIND_DREAM_SERVICE;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.util.DumpUtils;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -88,6 +89,8 @@
     private int mCurrentDreamDozeScreenState = Display.STATE_UNKNOWN;
     private int mCurrentDreamDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
 
+    private AmbientDisplayConfiguration mDozeConfig;
+
     public DreamManagerService(Context context) {
         super(context);
         mContext = context;
@@ -97,6 +100,7 @@
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mPowerManagerInternal = getLocalService(PowerManagerInternal.class);
         mDozeWakeLock = mPowerManager.newWakeLock(PowerManager.DOZE_WAKE_LOCK, TAG);
+        mDozeConfig = new AmbientDisplayConfiguration(mContext);
     }
 
     @Override
@@ -121,7 +125,7 @@
                 }
             }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
             mContext.getContentResolver().registerContentObserver(
-                    Settings.Secure.getUriFor(Settings.Secure.DOZE_ENABLED), false,
+                    Settings.Secure.getUriFor(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP), false,
                     mDozeEnabledObserver, UserHandle.USER_ALL);
             writePulseGestureEnabled();
         }
@@ -326,19 +330,12 @@
     }
 
     private ComponentName getDozeComponent(int userId) {
-        // Read the component from a system property to facilitate debugging.
-        // Note that for production devices, the dream should actually be declared in
-        // a config.xml resource.
-        String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
-        if (TextUtils.isEmpty(name)) {
-            // Read the component from a config.xml resource.
-            // The value should be specified in a resource overlay for the product.
-            name = mContext.getResources().getString(
-                    com.android.internal.R.string.config_dozeComponent);
+        if (mDozeConfig.enabled(userId)) {
+            return ComponentName.unflattenFromString(mDozeConfig.ambientDisplayComponent());
+        } else {
+            return null;
         }
-        boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.DOZE_ENABLED, 1, userId) != 0;
-        return TextUtils.isEmpty(name) || !enabled ? null : ComponentName.unflattenFromString(name);
+
     }
 
     private ServiceInfo getServiceInfo(ComponentName name) {