Import wear emergency gesture handling logic into master.

Wear OS doesn't have StatusBarManager. So we have to add a special
handling logic for emergency gesture.

Bug: 200218055
Test: manually tested
Change-Id: If6bf76b02706a2c3d2c165044f30b76ea1db6214
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3d28b15..d7abfbb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4948,12 +4948,6 @@
          button. -->
     <integer name="config_mashPressVibrateTimeOnPowerButton">0</integer>
 
-    <!-- Control the behavior when the user presses the power button 5 times.
-           0 - Nothing
-           1 - Launch panic button gesture
-    -->
-    <integer name="config_mashPressOnPowerBehavior">0</integer>
-
     <!-- Whether or not to enable the binder heavy hitter watcher by default -->
     <bool name="config_defaultBinderHeavyHitterWatcherEnabled">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 63c1a1f..0495122 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4617,4 +4617,6 @@
   <java-symbol type="array" name="config_roundedCornerBottomRadiusAdjustmentArray" />
   <java-symbol type="bool" name="config_secondaryBuiltInDisplayIsRound" />
   <java-symbol type="array" name="config_builtInDisplayIsRoundArray" />
+
+  <java-symbol type="integer" name="config_mashPressVibrateTimeOnPowerButton" />
 </resources>
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index b0c80ae..25b36e8 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -19,10 +19,12 @@
 import android.app.ActivityManager;
 import android.app.StatusBarManager;
 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;
@@ -38,6 +40,8 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.provider.Settings;
 import android.util.MutableBoolean;
 import android.util.Slog;
@@ -88,6 +92,19 @@
      */
     private static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;
 
+    /** Action for starting emergency alerts on Wear OS. */
+    private static final String WEAR_LAUNCH_EMERGENCY_ACTION =
+            "com.android.systemui.action.LAUNCH_EMERGENCY";
+
+    /** Action for starting emergency alerts in retail mode on Wear OS. */
+    private static final String WEAR_LAUNCH_EMERGENCY_RETAIL_ACTION =
+            "com.android.systemui.action.LAUNCH_EMERGENCY_RETAIL";
+
+    /**
+     * Boolean extra for distinguishing intents coming from power button gesture.
+     */
+    private static final String EXTRA_LAUNCH_EMERGENCY_VIA_GESTURE = "launch_emergency_via_gesture";
+
     /** The listener that receives the gesture event. */
     private final GestureEventListener mGestureListener = new GestureEventListener();
     private final CameraLiftTriggerEventListener mCameraLiftTriggerListener =
@@ -152,6 +169,7 @@
     private final UiEventLogger mUiEventLogger;
 
     private boolean mHasFeatureWatch;
+    private long mVibrateMilliSecondsForPanicGesture;
 
     @VisibleForTesting
     public enum GestureLauncherEvent implements UiEventLogger.UiEventEnum {
@@ -220,6 +238,13 @@
 
             mHasFeatureWatch =
                     mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+            mVibrateMilliSecondsForPanicGesture =
+                    resources.getInteger(
+                            com.android
+                                    .internal
+                                    .R
+                                    .integer
+                                    .config_mashPressVibrateTimeOnPowerButton);
         }
     }
 
@@ -584,6 +609,12 @@
                         "userSetupComplete = %s, performing emergency gesture.",
                         userSetupComplete));
             }
+
+            if (mHasFeatureWatch) {
+                onEmergencyGestureDetectedOnWatch();
+                return true;
+            }
+
             StatusBarManagerInternal service = LocalServices.getService(
                     StatusBarManagerInternal.class);
             service.onEmergencyActionLaunchGestureDetected();
@@ -593,6 +624,37 @@
         }
     }
 
+    private void onEmergencyGestureDetectedOnWatch() {
+        Intent emergencyIntent =
+                new Intent(
+                        isInRetailMode()
+                                ? WEAR_LAUNCH_EMERGENCY_RETAIL_ACTION
+                                : WEAR_LAUNCH_EMERGENCY_ACTION);
+        PackageManager pm = mContext.getPackageManager();
+        ResolveInfo resolveInfo = pm.resolveActivity(emergencyIntent, /*flags=*/0);
+        if (resolveInfo == null) {
+            Slog.w(TAG, "Couldn't find an app to process the emergency intent "
+                    + emergencyIntent.getAction());
+            return;
+        }
+
+        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
+        vibrator.vibrate(VibrationEffect.createOneShot(mVibrateMilliSecondsForPanicGesture,
+                VibrationEffect.DEFAULT_AMPLITUDE));
+
+        emergencyIntent.setComponent(
+                new ComponentName(
+                        resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name));
+        emergencyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        emergencyIntent.putExtra(EXTRA_LAUNCH_EMERGENCY_VIA_GESTURE, true);
+        mContext.startActivityAsUser(emergencyIntent, new UserHandle(mUserId));
+    }
+
+    private boolean isInRetailMode() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_DEMO_MODE, 0) == 1;
+    }
+
     private boolean isUserSetupComplete() {
         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;