summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java44
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java19
3 files changed, 88 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cf1036c03c83..72c10cc9a5e8 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -32,7 +32,6 @@ import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.O;
import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
-import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.STATE_OFF;
@@ -69,6 +68,7 @@ import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
+import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_WEAR_TRIPLE_PRESS_GESTURE;
@@ -101,6 +101,7 @@ import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityManagerInternal;
import android.app.ActivityTaskManager;
import android.app.AppOpsManager;
+import android.app.IActivityManager;
import android.app.IUiModeManager;
import android.app.NotificationManager;
import android.app.ProgressDialog;
@@ -427,6 +428,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManagerInternal mWindowManagerInternal;
PowerManager mPowerManager;
ActivityManagerInternal mActivityManagerInternal;
+ IActivityManager mActivityManagerService;
ActivityTaskManagerInternal mActivityTaskManagerInternal;
AutofillManagerInternal mAutofillManagerInternal;
InputManager mInputManager;
@@ -549,7 +551,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mLidNavigationAccessibility;
int mShortPressOnPowerBehavior;
private boolean mShouldEarlyShortPressOnPower;
- private boolean mShouldEarlyShortPressOnStemPrimary;
+ boolean mShouldEarlyShortPressOnStemPrimary;
int mLongPressOnPowerBehavior;
long mLongPressOnPowerAssistantTimeoutMs;
int mVeryLongPressOnPowerBehavior;
@@ -578,6 +580,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private int mDoublePressOnStemPrimaryBehavior;
private int mTriplePressOnStemPrimaryBehavior;
private int mLongPressOnStemPrimaryBehavior;
+ private RecentTaskInfo mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp;
private boolean mHandleVolumeKeysInWM;
@@ -1563,7 +1566,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
? false
: mKeyguardDelegate.isShowing();
if (!keyguardActive) {
- switchRecentTask();
+ performStemPrimaryDoublePressSwitchToRecentTask();
}
break;
}
@@ -1672,11 +1675,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/**
* Load most recent task (expect current task) and bring it to the front.
*/
- private void switchRecentTask() {
- RecentTaskInfo targetTask = mActivityTaskManagerInternal.getMostRecentTaskFromBackground();
+ void performStemPrimaryDoublePressSwitchToRecentTask() {
+ RecentTaskInfo targetTask = mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp;
if (targetTask == null) {
if (DEBUG_INPUT) {
- Slog.w(TAG, "No recent task available! Show watch face.");
+ Slog.w(TAG, "No recent task available! Show wallpaper.");
}
goHome();
return;
@@ -1695,7 +1698,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ targetTask.baseIntent);
}
try {
- ActivityManager.getService().startActivityFromRecents(targetTask.persistentId, null);
+ mActivityManagerService.startActivityFromRecents(targetTask.persistentId, null);
} catch (RemoteException | IllegalArgumentException e) {
Slog.e(TAG, "Failed to start task " + targetTask.persistentId + " from recents", e);
}
@@ -2219,6 +2222,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
});
}
+
+ IActivityManager getActivityManagerService() {
+ return ActivityManager.getService();
+ }
}
/** {@inheritDoc} */
@@ -2233,6 +2240,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mWindowManagerFuncs = injector.getWindowManagerFuncs();
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mActivityManagerService = injector.getActivityManagerService();
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mInputManager = mContext.getSystemService(InputManager.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
@@ -2767,8 +2775,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
void onKeyUp(long eventTime, int count) {
- if (mShouldEarlyShortPressOnStemPrimary && count == 1) {
- stemPrimaryPress(1 /*pressCount*/);
+ if (count == 1) {
+ // Save info about the most recent task on the first press of the stem key. This
+ // may be used later to switch to the most recent app using double press gesture.
+ // It is possible that we may navigate away from this task before the double
+ // press is detected, as a result of the first press, so we save the current
+ // most recent task before that happens.
+ mBackgroundRecentTaskInfoOnStemPrimarySingleKeyUp =
+ mActivityTaskManagerInternal.getMostRecentTaskFromBackground();
+ if (mShouldEarlyShortPressOnStemPrimary) {
+ stemPrimaryPress(1 /*pressCount*/);
+ }
}
}
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
index eab8757b7331..912e1d3df945 100644
--- a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
@@ -16,15 +16,19 @@
package com.android.server.policy;
+import static android.provider.Settings.Global.STEM_PRIMARY_BUTTON_DOUBLE_PRESS;
import static android.provider.Settings.Global.STEM_PRIMARY_BUTTON_LONG_PRESS;
import static android.provider.Settings.Global.STEM_PRIMARY_BUTTON_SHORT_PRESS;
import static android.view.KeyEvent.KEYCODE_STEM_PRIMARY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_PRIMARY_LAUNCH_VOICE_ASSISTANT;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY;
+import android.app.ActivityManager.RecentTaskInfo;
import android.content.ComponentName;
+import android.os.RemoteException;
import android.provider.Settings;
import org.junit.Test;
@@ -120,6 +124,46 @@ public class StemKeyGestureTests extends ShortcutKeyTestBase {
mPhoneWindowManager.assertStatusBarStartAssist();
}
+ @Test
+ public void stemDoubleKey_EarlyShortPress_AllAppsThenSwitchToMostRecent()
+ throws RemoteException {
+ overrideBehavior(STEM_PRIMARY_BUTTON_DOUBLE_PRESS, SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS);
+ setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
+ mPhoneWindowManager.overrideShouldEarlyShortPressOnStemPrimary(true);
+ mPhoneWindowManager.setKeyguardServiceDelegateIsShowing(false);
+ mPhoneWindowManager.overrideIsUserSetupComplete(true);
+ RecentTaskInfo recentTaskInfo = new RecentTaskInfo();
+ int referenceId = 666;
+ recentTaskInfo.persistentId = referenceId;
+ doReturn(recentTaskInfo).when(
+ mPhoneWindowManager.mActivityTaskManagerInternal).getMostRecentTaskFromBackground();
+
+ sendKey(KEYCODE_STEM_PRIMARY);
+ sendKey(KEYCODE_STEM_PRIMARY);
+
+ mPhoneWindowManager.assertOpenAllAppView();
+ mPhoneWindowManager.assertSwitchToRecent(referenceId);
+ }
+
+ @Test
+ public void stemDoubleKey_NoEarlyShortPress_SwitchToMostRecent() throws RemoteException {
+ overrideBehavior(STEM_PRIMARY_BUTTON_DOUBLE_PRESS, SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS);
+ setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
+ mPhoneWindowManager.overrideShouldEarlyShortPressOnStemPrimary(false);
+ mPhoneWindowManager.setKeyguardServiceDelegateIsShowing(false);
+ mPhoneWindowManager.overrideIsUserSetupComplete(true);
+ RecentTaskInfo recentTaskInfo = new RecentTaskInfo();
+ int referenceId = 666;
+ recentTaskInfo.persistentId = referenceId;
+ doReturn(recentTaskInfo).when(
+ mPhoneWindowManager.mActivityTaskManagerInternal).getMostRecentTaskFromBackground();
+
+ sendKey(KEYCODE_STEM_PRIMARY);
+ sendKey(KEYCODE_STEM_PRIMARY);
+
+ mPhoneWindowManager.assertNotOpenAllAppView();
+ mPhoneWindowManager.assertSwitchToRecent(referenceId);
+ }
private void overrideBehavior(String key, int expectedBehavior) {
Settings.Global.putLong(mContext.getContentResolver(), key, expectedBehavior);
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 e26260a6836c..314cd04695ba 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -57,6 +57,7 @@ import static org.mockito.Mockito.withSettings;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
+import android.app.IActivityManager;
import android.app.NotificationManager;
import android.app.SearchManager;
import android.content.ComponentName;
@@ -126,7 +127,8 @@ class TestPhoneWindowManager {
@Mock private WindowManagerInternal mWindowManagerInternal;
@Mock private ActivityManagerInternal mActivityManagerInternal;
- @Mock private ActivityTaskManagerInternal mActivityTaskManagerInternal;
+ @Mock ActivityTaskManagerInternal mActivityTaskManagerInternal;
+ @Mock IActivityManager mActivityManagerService;
@Mock private InputManagerInternal mInputManagerInternal;
@Mock private InputManager mInputManager;
@Mock private SensorPrivacyManager mSensorPrivacyManager;
@@ -181,6 +183,10 @@ class TestPhoneWindowManager {
KeyguardServiceDelegate getKeyguardServiceDelegate() {
return mKeyguardServiceDelegate;
}
+
+ IActivityManager getActivityManagerService() {
+ return mActivityManagerService;
+ }
}
TestPhoneWindowManager(Context context, boolean supportSettingsUpdate) {
@@ -347,6 +353,10 @@ class TestPhoneWindowManager {
mPhoneWindowManager.mShortPressOnPowerBehavior = behavior;
}
+ void overrideShouldEarlyShortPressOnStemPrimary(boolean shouldEarlyShortPress) {
+ mPhoneWindowManager.mShouldEarlyShortPressOnStemPrimary = shouldEarlyShortPress;
+ }
+
// Override assist perform function.
void overrideLongPressOnPower(int behavior) {
mPhoneWindowManager.mLongPressOnPowerBehavior = behavior;
@@ -667,4 +677,11 @@ class TestPhoneWindowManager {
vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
expectedModifierState), description(errorMsg));
}
+
+ void assertSwitchToRecent(int persistentId) throws RemoteException {
+ mTestLooper.dispatchAll();
+ verify(mActivityManagerService,
+ timeout(TEST_SINGLE_KEY_DELAY_MILLIS)).startActivityFromRecents(eq(persistentId),
+ isNull());
+ }
}