Revert^2 "Launch wallet app on double tap option."
bf5db7350ead6807896e0bee85d9ef264435c4d0
Bug: 382133936
Test: android.platform.test.scenario.sysui.power.PowerMenuTest#testPower_verifySystemPowerMenuAppears
Change-Id: I1aebd5ab6d4da314a9bd043deaf131b5fae62d3e
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index 19bc8e3..d84a892 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -16,10 +16,14 @@
package com.android.server;
+import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap;
+
import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
import static com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -34,6 +38,7 @@
import android.hardware.SensorManager;
import android.hardware.TriggerEvent;
import android.hardware.TriggerEventListener;
+import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
@@ -42,10 +47,12 @@
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.util.MutableBoolean;
import android.util.Slog;
import android.view.KeyEvent;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
@@ -71,7 +78,8 @@
* Time in milliseconds in which the power button must be pressed twice so it will be considered
* as a camera launch.
*/
- @VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
+ @VisibleForTesting
+ static final long POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
/**
@@ -101,10 +109,23 @@
@VisibleForTesting
static final int EMERGENCY_GESTURE_POWER_BUTTON_COOLDOWN_PERIOD_MS_MAX = 5000;
- /**
- * Number of taps required to launch camera shortcut.
- */
- public static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;
+ /** Indicates camera should be launched on power double tap. */
+ @VisibleForTesting static final int LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER = 0;
+
+ /** Indicates wallet should be launched on power double tap. */
+ @VisibleForTesting static final int LAUNCH_WALLET_ON_DOUBLE_TAP_POWER = 1;
+
+ /** Number of taps required to launch the double tap shortcut (either camera or wallet). */
+ public static final int DOUBLE_POWER_TAP_COUNT_THRESHOLD = 2;
+
+ /** Bundle to send with PendingIntent to grant background activity start privileges. */
+ private static final Bundle GRANT_BACKGROUND_START_PRIVILEGES =
+ ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS)
+ .toBundle();
+
+ private final QuickAccessWalletClient mQuickAccessWalletClient;
/** The listener that receives the gesture event. */
private final GestureEventListener mGestureListener = new GestureEventListener();
@@ -159,6 +180,9 @@
*/
private boolean mCameraDoubleTapPowerEnabled;
+ /** Whether wallet double tap power button gesture is currently enabled. */
+ private boolean mWalletDoubleTapPowerEnabled;
+
/**
* Whether emergency gesture is currently enabled
*/
@@ -205,16 +229,22 @@
}
}
public GestureLauncherService(Context context) {
- this(context, new MetricsLogger(), new UiEventLoggerImpl());
+ this(
+ context,
+ new MetricsLogger(),
+ QuickAccessWalletClient.create(context),
+ new UiEventLoggerImpl());
}
@VisibleForTesting
public GestureLauncherService(
Context context,
MetricsLogger metricsLogger,
+ QuickAccessWalletClient quickAccessWalletClient,
UiEventLogger uiEventLogger) {
super(context);
mContext = context;
+ mQuickAccessWalletClient = quickAccessWalletClient;
mMetricsLogger = metricsLogger;
mUiEventLogger = uiEventLogger;
}
@@ -240,6 +270,9 @@
"GestureLauncherService");
updateCameraRegistered();
updateCameraDoubleTapPowerEnabled();
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ updateWalletDoubleTapPowerEnabled();
+ }
updateEmergencyGestureEnabled();
updateEmergencyGesturePowerButtonCooldownPeriodMs();
@@ -295,6 +328,14 @@
}
@VisibleForTesting
+ void updateWalletDoubleTapPowerEnabled() {
+ boolean enabled = isWalletDoubleTapPowerSettingEnabled(mContext, mUserId);
+ synchronized (this) {
+ mWalletDoubleTapPowerEnabled = enabled;
+ }
+ }
+
+ @VisibleForTesting
void updateEmergencyGestureEnabled() {
boolean enabled = isEmergencyGestureSettingEnabled(mContext, mUserId);
synchronized (this) {
@@ -421,10 +462,33 @@
Settings.Secure.CAMERA_GESTURE_DISABLED, 0, userId) == 0);
}
+ /** Checks if camera should be launched on double press of the power button. */
public static boolean isCameraDoubleTapPowerSettingEnabled(Context context, int userId) {
- return isCameraDoubleTapPowerEnabled(context.getResources())
- && (Settings.Secure.getIntForUser(context.getContentResolver(),
- Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
+ boolean res;
+
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ res = isDoubleTapPowerGestureSettingEnabled(context, userId)
+ && getDoubleTapPowerGestureAction(context, userId)
+ == LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER;
+ } else {
+ // These are legacy settings that will be deprecated once the option to launch both
+ // wallet and camera has been created.
+ res = isCameraDoubleTapPowerEnabled(context.getResources())
+ && (Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0, userId) == 0);
+ }
+ return res;
+ }
+
+ /** Checks if wallet should be launched on double tap of the power button. */
+ public static boolean isWalletDoubleTapPowerSettingEnabled(Context context, int userId) {
+ if (!launchWalletOptionOnPowerDoubleTap()) {
+ return false;
+ }
+
+ return isDoubleTapPowerGestureSettingEnabled(context, userId)
+ && getDoubleTapPowerGestureAction(context, userId)
+ == LAUNCH_WALLET_ON_DOUBLE_TAP_POWER;
}
public static boolean isCameraLiftTriggerSettingEnabled(Context context, int userId) {
@@ -444,6 +508,28 @@
isDefaultEmergencyGestureEnabled(context.getResources()) ? 1 : 0, userId) != 0;
}
+ private static int getDoubleTapPowerGestureAction(Context context, int userId) {
+ return Settings.Secure.getIntForUser(
+ context.getContentResolver(),
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+ LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER,
+ userId);
+ }
+
+ /** Whether the shortcut to launch app on power double press is enabled. */
+ private static boolean isDoubleTapPowerGestureSettingEnabled(Context context, int userId) {
+ return Settings.Secure.getIntForUser(
+ context.getContentResolver(),
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+ isDoubleTapConfigEnabled(context.getResources()) ? 1 : 0,
+ userId)
+ == 1;
+ }
+
+ private static boolean isDoubleTapConfigEnabled(Resources resources) {
+ return resources.getBoolean(R.bool.config_doubleTapPowerGestureEnabled);
+ }
+
/**
* Gets power button cooldown period in milliseconds after emergency gesture is triggered. The
* value is capped at a maximum
@@ -497,10 +583,16 @@
* Whether GestureLauncherService should be enabled according to system properties.
*/
public static boolean isGestureLauncherEnabled(Resources resources) {
- return isCameraLaunchEnabled(resources)
- || isCameraDoubleTapPowerEnabled(resources)
- || isCameraLiftTriggerEnabled(resources)
- || isEmergencyGestureEnabled(resources);
+ boolean res =
+ isCameraLaunchEnabled(resources)
+ || isCameraLiftTriggerEnabled(resources)
+ || isEmergencyGestureEnabled(resources);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ res |= isDoubleTapConfigEnabled(resources);
+ } else {
+ res |= isCameraDoubleTapPowerEnabled(resources);
+ }
+ return res;
}
/**
@@ -530,7 +622,7 @@
mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps = 1;
- } else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
+ } else if (powerTapInterval >= POWER_DOUBLE_TAP_MAX_TIME_MS) {
// Tap too slow for shortcuts
mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
@@ -573,6 +665,7 @@
return false;
}
boolean launchCamera = false;
+ boolean launchWallet = false;
boolean launchEmergencyGesture = false;
boolean intercept = false;
long powerTapInterval;
@@ -584,7 +677,7 @@
mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps = 1;
- } else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
+ } else if (powerTapInterval >= POWER_DOUBLE_TAP_MAX_TIME_MS) {
// Tap too slow for shortcuts
mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
@@ -629,10 +722,16 @@
}
}
if (mCameraDoubleTapPowerEnabled
- && powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
- && mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD) {
+ && powerTapInterval < POWER_DOUBLE_TAP_MAX_TIME_MS
+ && mPowerButtonConsecutiveTaps == DOUBLE_POWER_TAP_COUNT_THRESHOLD) {
launchCamera = true;
intercept = interactive;
+ } else if (launchWalletOptionOnPowerDoubleTap()
+ && mWalletDoubleTapPowerEnabled
+ && powerTapInterval < POWER_DOUBLE_TAP_MAX_TIME_MS
+ && mPowerButtonConsecutiveTaps == DOUBLE_POWER_TAP_COUNT_THRESHOLD) {
+ launchWallet = true;
+ intercept = interactive;
}
}
if (mPowerButtonConsecutiveTaps > 1 || mPowerButtonSlowConsecutiveTaps > 1) {
@@ -651,6 +750,10 @@
(int) powerTapInterval);
mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
}
+ } else if (launchWallet) {
+ Slog.i(TAG, "Power button double tap gesture detected, launching wallet. Interval="
+ + powerTapInterval + "ms");
+ launchWallet = sendGestureTargetActivityPendingIntent();
} else if (launchEmergencyGesture) {
Slog.i(TAG, "Emergency gesture detected, launching.");
launchEmergencyGesture = handleEmergencyGesture();
@@ -666,11 +769,74 @@
mPowerButtonSlowConsecutiveTaps);
mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval);
- outLaunched.value = launchCamera || launchEmergencyGesture;
+ outLaunched.value = launchCamera || launchEmergencyGesture || launchWallet;
// Intercept power key event if the press is part of a gesture (camera, eGesture) and the
// user has completed setup.
return intercept && isUserSetupComplete();
}
+
+ /**
+ * Fetches and sends gestureTargetActivityPendingIntent from QuickAccessWallet, which is a
+ * specific activity that QuickAccessWalletService has defined to be launch on detection of the
+ * power button gesture.
+ */
+ private boolean sendGestureTargetActivityPendingIntent() {
+ boolean userSetupComplete = isUserSetupComplete();
+ if (mQuickAccessWalletClient == null
+ || !mQuickAccessWalletClient.isWalletServiceAvailable()) {
+ Slog.w(TAG, "QuickAccessWalletService is not available, ignoring wallet gesture.");
+ return false;
+ }
+
+ if (!userSetupComplete) {
+ if (DBG) {
+ Slog.d(TAG, "userSetupComplete = false, ignoring wallet gesture.");
+ }
+ return false;
+ }
+ if (DBG) {
+ Slog.d(TAG, "userSetupComplete = true, performing wallet gesture.");
+ }
+
+ mQuickAccessWalletClient.getGestureTargetActivityPendingIntent(
+ getContext().getMainExecutor(),
+ gesturePendingIntent -> {
+ if (gesturePendingIntent == null) {
+ Slog.d(TAG, "getGestureTargetActivityPendingIntent is null.");
+ sendFallbackPendingIntent();
+ return;
+ }
+ sendPendingIntentWithBackgroundStartPrivileges(gesturePendingIntent);
+ });
+ return true;
+ }
+
+ /**
+ * If gestureTargetActivityPendingIntent is null, this method is invoked to start the activity
+ * that QuickAccessWalletService has defined to host the Wallet view, which is typically the
+ * home screen of the Wallet application.
+ */
+ private void sendFallbackPendingIntent() {
+ mQuickAccessWalletClient.getWalletPendingIntent(
+ getContext().getMainExecutor(),
+ walletPendingIntent -> {
+ if (walletPendingIntent == null) {
+ Slog.w(TAG, "getWalletPendingIntent returns null. Not launching "
+ + "anything for wallet.");
+ return;
+ }
+ sendPendingIntentWithBackgroundStartPrivileges(walletPendingIntent);
+ });
+ }
+
+ private void sendPendingIntentWithBackgroundStartPrivileges(PendingIntent pendingIntent) {
+ try {
+ pendingIntent.send(GRANT_BACKGROUND_START_PRIVILEGES);
+ } catch (PendingIntent.CanceledException e) {
+ Slog.e(TAG, "PendingIntent was canceled", e);
+ }
+ }
+
/**
* @return true if camera was launched, false otherwise.
*/
@@ -743,31 +909,39 @@
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
}
- 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);
- registerContentObservers();
- updateCameraRegistered();
- updateCameraDoubleTapPowerEnabled();
- updateEmergencyGestureEnabled();
- updateEmergencyGesturePowerButtonCooldownPeriodMs();
- }
- }
- };
+ 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);
+ registerContentObservers();
+ updateCameraRegistered();
+ updateCameraDoubleTapPowerEnabled();
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ updateWalletDoubleTapPowerEnabled();
+ }
+ updateEmergencyGestureEnabled();
+ updateEmergencyGesturePowerButtonCooldownPeriodMs();
+ }
+ }
+ };
- private final ContentObserver mSettingObserver = new ContentObserver(new Handler()) {
- public void onChange(boolean selfChange, android.net.Uri uri, int userId) {
- if (userId == mUserId) {
- updateCameraRegistered();
- updateCameraDoubleTapPowerEnabled();
- updateEmergencyGestureEnabled();
- updateEmergencyGesturePowerButtonCooldownPeriodMs();
- }
- }
- };
+ private final ContentObserver mSettingObserver =
+ new ContentObserver(new Handler()) {
+ public void onChange(boolean selfChange, android.net.Uri uri, int userId) {
+ if (userId == mUserId) {
+ updateCameraRegistered();
+ updateCameraDoubleTapPowerEnabled();
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ updateWalletDoubleTapPowerEnabled();
+ }
+ updateEmergencyGestureEnabled();
+ updateEmergencyGesturePowerButtonCooldownPeriodMs();
+ }
+ }
+ };
private final class GestureEventListener implements SensorEventListener {
@Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3fb371c..f8a9a9f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -91,7 +91,7 @@
import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
-import static com.android.server.GestureLauncherService.CAMERA_POWER_TAP_COUNT_THRESHOLD;
+import static com.android.server.GestureLauncherService.DOUBLE_POWER_TAP_COUNT_THRESHOLD;
import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
@@ -4150,7 +4150,7 @@
}
// Intercept keys (don't send to app) for 3x, 4x, 5x gestures)
- if (mPowerButtonConsecutiveTaps > CAMERA_POWER_TAP_COUNT_THRESHOLD) {
+ if (mPowerButtonConsecutiveTaps > DOUBLE_POWER_TAP_COUNT_THRESHOLD) {
setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, event.getDownTime());
return true;
}
@@ -5954,7 +5954,7 @@
}
return powerTapInterval < POWER_MULTI_PRESS_TIMEOUT_MILLIS
- && mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD;
+ && mPowerButtonConsecutiveTaps == DOUBLE_POWER_TAP_COUNT_THRESHOLD;
}
// The camera gesture will be detected by GestureLauncherService.
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 2349def..9850cb0 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -16,7 +16,12 @@
package com.android.server;
-import static com.android.server.GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+import static android.service.quickaccesswallet.Flags.FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP;
+import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap;
+
+import static com.android.server.GestureLauncherService.LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER;
+import static com.android.server.GestureLauncherService.LAUNCH_WALLET_ON_DOUBLE_TAP_POWER;
+import static com.android.server.GestureLauncherService.POWER_DOUBLE_TAP_MAX_TIME_MS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -24,19 +29,27 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.PendingIntent;
import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.Looper;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
import android.telecom.TelecomManager;
import android.test.mock.MockContentResolver;
import android.testing.TestableLooper;
@@ -55,6 +68,7 @@
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -62,6 +76,8 @@
import org.mockito.MockitoAnnotations;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Unit tests for {@link GestureLauncherService}.
@@ -90,9 +106,32 @@
private @Mock TelecomManager mTelecomManager;
private @Mock MetricsLogger mMetricsLogger;
@Mock private UiEventLogger mUiEventLogger;
+ @Mock private QuickAccessWalletClient mQuickAccessWalletClient;
private MockContentResolver mContentResolver;
private GestureLauncherService mGestureLauncherService;
+ private Context mInstrumentationContext =
+ InstrumentationRegistry.getInstrumentation().getContext();
+
+ private static final String LAUNCH_TEST_WALLET_ACTION = "LAUNCH_TEST_WALLET_ACTION";
+ private static final String LAUNCH_FALLBACK_ACTION = "LAUNCH_FALLBACK_ACTION";
+ private PendingIntent mGesturePendingIntent =
+ PendingIntent.getBroadcast(
+ mInstrumentationContext,
+ 0,
+ new Intent(LAUNCH_TEST_WALLET_ACTION),
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);
+
+ private PendingIntent mFallbackPendingIntent =
+ PendingIntent.getBroadcast(
+ mInstrumentationContext,
+ 0,
+ new Intent(LAUNCH_FALLBACK_ACTION),
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@BeforeClass
public static void oneTimeInitialization() {
if (Looper.myLooper() == null) {
@@ -115,9 +154,49 @@
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager);
when(mTelecomManager.createLaunchEmergencyDialerIntent(null)).thenReturn(new Intent());
+ when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(true);
- mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger,
- mUiEventLogger);
+ mGestureLauncherService =
+ new GestureLauncherService(
+ mContext, mMetricsLogger, mQuickAccessWalletClient, mUiEventLogger);
+
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ }
+
+ private WalletLaunchedReceiver registerWalletLaunchedReceiver(String action) {
+ IntentFilter filter = new IntentFilter(action);
+ WalletLaunchedReceiver receiver = new WalletLaunchedReceiver();
+ mInstrumentationContext.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
+ return receiver;
+ }
+
+ /**
+ * A simple {@link BroadcastReceiver} implementation that counts down a {@link CountDownLatch}
+ * when a matching message is received
+ */
+ private static final class WalletLaunchedReceiver extends BroadcastReceiver {
+ private static final int TIMEOUT_SECONDS = 3;
+
+ private final CountDownLatch mLatch;
+
+ WalletLaunchedReceiver() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mLatch.countDown();
+ context.unregisterReceiver(this);
+ }
+
+ Boolean waitUntilShown() {
+ try {
+ return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
}
@Test
@@ -134,37 +213,123 @@
@Test
public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingDisabled() {
- withCameraDoubleTapPowerEnableConfigValue(false);
- withCameraDoubleTapPowerDisableSettingValue(1);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerEnabledConfigValue(false);
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(false);
+ withCameraDoubleTapPowerDisableSettingValue(1);
+ }
assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
mContext, FAKE_USER_ID));
}
@Test
public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingEnabled() {
- withCameraDoubleTapPowerEnableConfigValue(false);
- withCameraDoubleTapPowerDisableSettingValue(0);
- assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
- mContext, FAKE_USER_ID));
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerEnabledConfigValue(false);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(false);
+ withCameraDoubleTapPowerDisableSettingValue(0);
+ assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
}
@Test
public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingDisabled() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(1);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(true);
+ withCameraDoubleTapPowerDisableSettingValue(1);
+ }
assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
mContext, FAKE_USER_ID));
}
@Test
public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingEnabled() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(true);
+ withCameraDoubleTapPowerDisableSettingValue(0);
+ }
assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
mContext, FAKE_USER_ID));
}
@Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testIsCameraDoubleTapPowerSettingEnabled_actionWallet() {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER);
+
+ assertFalse(
+ mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testIsWalletDoubleTapPowerSettingEnabled() {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER);
+
+ assertTrue(
+ mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testIsWalletDoubleTapPowerSettingEnabled_configDisabled() {
+ withDoubleTapPowerEnabledConfigValue(false);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER);
+
+ assertTrue(
+ mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testIsWalletDoubleTapPowerSettingEnabled_settingDisabled() {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER);
+
+ assertFalse(
+ mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testIsWalletDoubleTapPowerSettingEnabled_actionCamera() {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+
+ assertFalse(
+ mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled(
+ mContext, FAKE_USER_ID));
+ }
+
+ @Test
public void testIsEmergencyGestureSettingEnabled_settingDisabled() {
withEmergencyGestureEnabledConfigValue(true);
withEmergencyGestureEnabledSettingValue(false);
@@ -245,12 +410,9 @@
@Test
public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
- long eventTime = INITIAL_EVENT_TIME_MILLIS +
- CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ long eventTime = INITIAL_EVENT_TIME_MILLIS + POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
boolean interactive = true;
@@ -284,8 +446,12 @@
@Test
public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(false);
- withCameraDoubleTapPowerDisableSettingValue(1);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(false);
+ withCameraDoubleTapPowerDisableSettingValue(1);
+ }
mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -298,7 +464,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -329,8 +495,12 @@
@Test
public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOffInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(false);
- withCameraDoubleTapPowerDisableSettingValue(1);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(false);
+ withCameraDoubleTapPowerDisableSettingValue(1);
+ }
mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -343,7 +513,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -422,10 +592,7 @@
@Test
public void
testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
- withUserSetupCompleteValue(true);
+ enableCameraGesture();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
@@ -437,7 +604,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -470,15 +637,145 @@
}
@Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void
+ testInterceptPowerKeyDown_fiveInboundPresses_walletAndEmergencyEnabled_bothLaunch() {
+ WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent);
+ enableEmergencyGesture();
+ enableWalletGesture();
+
+ // First event
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);
+
+ assertTrue(receiver.waitUntilShown());
+
+ // Presses 3 and 4 should not trigger any gesture
+ for (int i = 0; i < 2; i++) {
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false);
+ }
+
+ // Fifth button press should trigger the emergency flow
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);
+
+ verify(mUiEventLogger, times(1))
+ .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
+ verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testInterceptPowerKeyDown_intervalInBoundsWalletPowerGesture() {
+ WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent);
+ enableWalletGesture();
+ enableEmergencyGesture();
+
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);
+ assertTrue(receiver.waitUntilShown());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testInterceptPowerKeyDown_walletGestureOn_quickAccessWalletServiceUnavailable() {
+ when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
+ WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent);
+ enableWalletGesture();
+
+ // First event
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false);
+
+ assertFalse(receiver.waitUntilShown());
+ }
+
+ @Test
+ public void testInterceptPowerKeyDown_walletGestureOn_userSetupIncomplete() {
+ WalletLaunchedReceiver receiver = registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(mGesturePendingIntent);
+ enableWalletGesture();
+ withUserSetupCompleteValue(false);
+
+ // First event
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ assertFalse(receiver.waitUntilShown());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testInterceptPowerKeyDown_walletPowerGesture_nullPendingIntent() {
+ WalletLaunchedReceiver gestureReceiver =
+ registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(null);
+ WalletLaunchedReceiver fallbackReceiver =
+ registerWalletLaunchedReceiver(LAUNCH_FALLBACK_ACTION);
+ setUpWalletFallbackPendingIntent(mFallbackPendingIntent);
+ enableWalletGesture();
+ enableEmergencyGesture();
+
+ // First event
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);
+
+ assertFalse(gestureReceiver.waitUntilShown());
+ assertTrue(fallbackReceiver.waitUntilShown());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP)
+ public void testInterceptPowerKeyDown_walletPowerGesture_intervalOutOfBounds() {
+ WalletLaunchedReceiver gestureReceiver =
+ registerWalletLaunchedReceiver(LAUNCH_TEST_WALLET_ACTION);
+ setUpGetGestureTargetActivityPendingIntent(null);
+ WalletLaunchedReceiver fallbackReceiver =
+ registerWalletLaunchedReceiver(LAUNCH_FALLBACK_ACTION);
+ setUpWalletFallbackPendingIntent(mFallbackPendingIntent);
+ enableWalletGesture();
+ enableEmergencyGesture();
+
+ // First event
+ long eventTime = INITIAL_EVENT_TIME_MILLIS;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS;
+ eventTime += interval;
+ sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+ assertFalse(gestureReceiver.waitUntilShown());
+ assertFalse(fallbackReceiver.waitUntilShown());
+ }
+
+ @Test
public void
testInterceptPowerKeyDown_fiveInboundPresses_cameraAndEmergencyEnabled_bothLaunch() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- withEmergencyGestureEnabledConfigValue(true);
- withEmergencyGestureEnabledSettingValue(true);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
- mGestureLauncherService.updateEmergencyGestureEnabled();
- withUserSetupCompleteValue(true);
+ enableCameraGesture();
+ enableEmergencyGesture();
// First button press does nothing
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -491,7 +788,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 2nd button triggers camera
eventTime += interval;
@@ -580,7 +877,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 3 more button presses which should not trigger any gesture (camera gesture disabled)
for (int i = 0; i < 3; i++) {
eventTime += interval;
@@ -634,7 +931,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 3 more button presses which should not trigger any gesture, but intercepts action.
for (int i = 0; i < 3; i++) {
eventTime += interval;
@@ -737,7 +1034,7 @@
interactive, outLaunched);
assertTrue(intercepted);
assertFalse(outLaunched.value);
- interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
}
}
@@ -765,7 +1062,7 @@
interactive, outLaunched);
assertTrue(intercepted);
assertFalse(outLaunched.value);
- interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
}
}
@@ -916,7 +1213,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE,
@@ -947,9 +1244,7 @@
@Test
public void
testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
withUserSetupCompleteValue(false);
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -962,7 +1257,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -995,9 +1290,7 @@
@Test
public void testInterceptPowerKeyDown_intervalMidBoundsCameraPowerGestureOnInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
@@ -1009,7 +1302,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1042,9 +1335,7 @@
@Test
public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
@@ -1087,8 +1378,12 @@
@Test
public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(false);
- withCameraDoubleTapPowerDisableSettingValue(1);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerGestureEnableSettingValue(false);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(false);
+ withCameraDoubleTapPowerDisableSettingValue(1);
+ }
mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -1101,7 +1396,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1146,7 +1441,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1223,10 +1518,7 @@
@Test
public void
testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
- withUserSetupCompleteValue(true);
+ enableCameraGesture();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
@@ -1238,7 +1530,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1272,9 +1564,7 @@
@Test
public void
testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
withUserSetupCompleteValue(false);
long eventTime = INITIAL_EVENT_TIME_MILLIS;
@@ -1287,7 +1577,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1332,7 +1622,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1365,9 +1655,7 @@
@Test
public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
- mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+ enableCameraGesture();
long eventTime = INITIAL_EVENT_TIME_MILLIS;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
@@ -1423,7 +1711,7 @@
sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
//Second event; call processPowerKeyDown without calling interceptPowerKeyDown
- final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
KeyEvent keyEvent =
new KeyEvent(
@@ -1455,7 +1743,7 @@
* @return last event time.
*/
private long triggerEmergencyGesture() {
- return triggerEmergencyGesture(CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1);
+ return triggerEmergencyGesture(POWER_DOUBLE_TAP_MAX_TIME_MS - 1);
}
/**
@@ -1514,6 +1802,27 @@
.thenReturn(enableConfigValue);
}
+ private void withDoubleTapPowerEnabledConfigValue(boolean enable) {
+ when(mResources.getBoolean(com.android.internal.R.bool.config_doubleTapPowerGestureEnabled))
+ .thenReturn(enable);
+ }
+
+ private void withDoubleTapPowerGestureEnableSettingValue(boolean enable) {
+ Settings.Secure.putIntForUser(
+ mContentResolver,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+ enable ? 1 : 0,
+ UserHandle.USER_CURRENT);
+ }
+
+ private void withDefaultDoubleTapPowerGestureAction(int action) {
+ Settings.Secure.putIntForUser(
+ mContentResolver,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+ action,
+ UserHandle.USER_CURRENT);
+ }
+
private void withEmergencyGestureEnabledConfigValue(boolean enableConfigValue) {
when(mResources.getBoolean(
com.android.internal.R.bool.config_emergencyGestureEnabled))
@@ -1552,6 +1861,40 @@
UserHandle.USER_CURRENT);
}
+ private void setUpGetGestureTargetActivityPendingIntent(PendingIntent pendingIntent) {
+ doAnswer(
+ invocation -> {
+ QuickAccessWalletClient.GesturePendingIntentCallback callback =
+ (QuickAccessWalletClient.GesturePendingIntentCallback)
+ invocation.getArguments()[1];
+ callback.onGesturePendingIntentRetrieved(pendingIntent);
+ return null;
+ })
+ .when(mQuickAccessWalletClient)
+ .getGestureTargetActivityPendingIntent(any(), any());
+ }
+
+ private void setUpWalletFallbackPendingIntent(PendingIntent pendingIntent) {
+ doAnswer(
+ invocation -> {
+ QuickAccessWalletClient.WalletPendingIntentCallback callback =
+ (QuickAccessWalletClient.WalletPendingIntentCallback)
+ invocation.getArguments()[1];
+ callback.onWalletPendingIntentRetrieved(pendingIntent);
+ return null;
+ })
+ .when(mQuickAccessWalletClient)
+ .getWalletPendingIntent(any(), any());
+ }
+
+ private void enableWalletGesture() {
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDoubleTapPowerEnabledConfigValue(true);
+
+ mGestureLauncherService.updateWalletDoubleTapPowerEnabled();
+ withUserSetupCompleteValue(true);
+ }
private void enableEmergencyGesture() {
withEmergencyGestureEnabledConfigValue(true);
@@ -1561,8 +1904,14 @@
}
private void enableCameraGesture() {
- withCameraDoubleTapPowerEnableConfigValue(true);
- withCameraDoubleTapPowerDisableSettingValue(0);
+ if (launchWalletOptionOnPowerDoubleTap()) {
+ withDoubleTapPowerEnabledConfigValue(true);
+ withDoubleTapPowerGestureEnableSettingValue(true);
+ withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER);
+ } else {
+ withCameraDoubleTapPowerEnableConfigValue(true);
+ withCameraDoubleTapPowerDisableSettingValue(0);
+ }
mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
withUserSetupCompleteValue(true);
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 18ecfa1..f06b45e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -278,7 +278,7 @@
mHandler = new Handler(mTestLooper.getLooper());
mContext = mockingDetails(context).isSpy() ? context : spy(context);
mGestureLauncherService = spy(new GestureLauncherService(mContext, mMetricsLogger,
- mUiEventLogger));
+ mQuickAccessWalletClient, mUiEventLogger));
setUp(supportSettingsUpdate);
mTestLooper.dispatchAll();
}