1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.policy;
18 
19 import static android.os.Build.HW_TIMEOUT_MULTIPLIER;
20 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
21 import static android.view.Display.DEFAULT_DISPLAY;
22 import static android.view.Display.STATE_ON;
23 import static android.view.WindowManagerPolicyConstants.FLAG_INTERACTIVE;
24 
25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
27 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyLong;
28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.description;
30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
36 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
37 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
38 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
39 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
40 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
41 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;
42 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GO_TO_VOICE_ASSIST;
43 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_NOTHING;
44 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF;
45 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
46 import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;
47 
48 import static org.mockito.ArgumentMatchers.anyBoolean;
49 import static org.mockito.ArgumentMatchers.isNull;
50 import static org.mockito.Mockito.CALLS_REAL_METHODS;
51 import static org.mockito.Mockito.after;
52 import static org.mockito.Mockito.doThrow;
53 import static org.mockito.Mockito.mockingDetails;
54 import static org.mockito.Mockito.timeout;
55 import static org.mockito.Mockito.withSettings;
56 
57 import android.app.ActivityManagerInternal;
58 import android.app.AppOpsManager;
59 import android.app.NotificationManager;
60 import android.app.SearchManager;
61 import android.content.Context;
62 import android.content.Intent;
63 import android.content.pm.PackageManager;
64 import android.hardware.SensorPrivacyManager;
65 import android.hardware.display.DisplayManager;
66 import android.hardware.display.DisplayManagerInternal;
67 import android.hardware.input.InputManager;
68 import android.media.AudioManagerInternal;
69 import android.os.Handler;
70 import android.os.HandlerThread;
71 import android.os.IBinder;
72 import android.os.PowerManager;
73 import android.os.PowerManagerInternal;
74 import android.os.RemoteException;
75 import android.os.UserHandle;
76 import android.os.Vibrator;
77 import android.service.dreams.DreamManagerInternal;
78 import android.telecom.TelecomManager;
79 import android.util.FeatureFlagUtils;
80 import android.view.Display;
81 import android.view.InputDevice;
82 import android.view.KeyEvent;
83 import android.view.autofill.AutofillManagerInternal;
84 
85 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
86 import com.android.internal.accessibility.AccessibilityShortcutController;
87 import com.android.internal.util.FrameworkStatsLog;
88 import com.android.server.GestureLauncherService;
89 import com.android.server.LocalServices;
90 import com.android.server.input.InputManagerInternal;
91 import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent;
92 import com.android.server.inputmethod.InputMethodManagerInternal;
93 import com.android.server.pm.UserManagerInternal;
94 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
95 import com.android.server.statusbar.StatusBarManagerInternal;
96 import com.android.server.vr.VrManagerInternal;
97 import com.android.server.wm.ActivityTaskManagerInternal;
98 import com.android.server.wm.DisplayPolicy;
99 import com.android.server.wm.DisplayRotation;
100 import com.android.server.wm.WindowManagerInternal;
101 import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
102 
103 import junit.framework.Assert;
104 
105 import org.mockito.AdditionalMatchers;
106 import org.mockito.ArgumentCaptor;
107 import org.mockito.Mock;
108 import org.mockito.MockSettings;
109 import org.mockito.Mockito;
110 import org.mockito.MockitoAnnotations;
111 import org.mockito.quality.Strictness;
112 
113 import java.util.function.Supplier;
114 
115 class TestPhoneWindowManager {
116     private static final long SHORTCUT_KEY_DELAY_MILLIS = 150;
117     private static final long TEST_SINGLE_KEY_DELAY_MILLIS
118             = SingleKeyGestureDetector.MULTI_PRESS_TIMEOUT + 1000L * HW_TIMEOUT_MULTIPLIER;
119 
120     private PhoneWindowManager mPhoneWindowManager;
121     private Context mContext;
122 
123     @Mock private WindowManagerInternal mWindowManagerInternal;
124     @Mock private ActivityManagerInternal mActivityManagerInternal;
125     @Mock private ActivityTaskManagerInternal mActivityTaskManagerInternal;
126     @Mock private InputManagerInternal mInputManagerInternal;
127     @Mock private InputManager mInputManager;
128     @Mock private SensorPrivacyManager mSensorPrivacyManager;
129     @Mock private DreamManagerInternal mDreamManagerInternal;
130     @Mock private PowerManagerInternal mPowerManagerInternal;
131     @Mock private DisplayManagerInternal mDisplayManagerInternal;
132     @Mock private AppOpsManager mAppOpsManager;
133     @Mock private DisplayManager mDisplayManager;
134     @Mock private PackageManager mPackageManager;
135     @Mock private TelecomManager mTelecomManager;
136     @Mock private NotificationManager mNotificationManager;
137     @Mock private Vibrator mVibrator;
138     @Mock private PowerManager mPowerManager;
139     @Mock private WindowManagerPolicy.WindowManagerFuncs mWindowManagerFuncsImpl;
140     @Mock private InputMethodManagerInternal mInputMethodManagerInternal;
141     @Mock private UserManagerInternal mUserManagerInternal;
142     @Mock private AudioManagerInternal mAudioManagerInternal;
143     @Mock private SearchManager mSearchManager;
144 
145     @Mock private Display mDisplay;
146     @Mock private DisplayRotation mDisplayRotation;
147     @Mock private DisplayPolicy mDisplayPolicy;
148     @Mock private WindowManagerPolicy.ScreenOnListener mScreenOnListener;
149     @Mock private GestureLauncherService mGestureLauncherService;
150     @Mock private GlobalActions mGlobalActions;
151     @Mock private AccessibilityShortcutController mAccessibilityShortcutController;
152 
153     @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
154 
155     @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate;
156 
157     private StaticMockitoSession mMockitoSession;
158     private HandlerThread mHandlerThread;
159     private Handler mHandler;
160 
161     private class TestInjector extends PhoneWindowManager.Injector {
TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs)162         TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs) {
163             super(context, funcs);
164         }
165 
getAccessibilityShortcutController( Context context, Handler handler, int initialUserId)166         AccessibilityShortcutController getAccessibilityShortcutController(
167                 Context context, Handler handler, int initialUserId) {
168             return mAccessibilityShortcutController;
169         }
170 
getGlobalActionsFactory()171         Supplier<GlobalActions> getGlobalActionsFactory() {
172             return () -> mGlobalActions;
173         }
174 
getKeyguardServiceDelegate()175         KeyguardServiceDelegate getKeyguardServiceDelegate() {
176             return mKeyguardServiceDelegate;
177         }
178     }
179 
TestPhoneWindowManager(Context context)180     TestPhoneWindowManager(Context context) {
181         MockitoAnnotations.initMocks(this);
182         mHandlerThread = new HandlerThread("fake window manager");
183         mHandlerThread.start();
184         mHandler = new Handler(mHandlerThread.getLooper());
185         mContext = mockingDetails(context).isSpy() ? context : spy(context);
186         mHandler.runWithScissors(this::setUp,  0 /* timeout */);
187     }
188 
setUp()189     private void setUp() {
190         mPhoneWindowManager = spy(new PhoneWindowManager());
191 
192         // Use stubOnly() to reduce memory usage if it doesn't need verification.
193         final MockSettings spyStubOnly = withSettings().stubOnly()
194                 .defaultAnswer(CALLS_REAL_METHODS);
195         // Return mocked services: LocalServices.getService
196         mMockitoSession = mockitoSession()
197                 .mockStatic(LocalServices.class, spyStubOnly)
198                 .mockStatic(FrameworkStatsLog.class)
199                 .strictness(Strictness.LENIENT)
200                 .startMocking();
201 
202         doReturn(mWindowManagerInternal).when(
203                 () -> LocalServices.getService(eq(WindowManagerInternal.class)));
204         doReturn(mActivityManagerInternal).when(
205                 () -> LocalServices.getService(eq(ActivityManagerInternal.class)));
206         doReturn(mActivityTaskManagerInternal).when(
207                 () -> LocalServices.getService(eq(ActivityTaskManagerInternal.class)));
208         doReturn(mInputManagerInternal).when(
209                 () -> LocalServices.getService(eq(InputManagerInternal.class)));
210         doReturn(mDreamManagerInternal).when(
211                 () -> LocalServices.getService(eq(DreamManagerInternal.class)));
212         doReturn(mPowerManagerInternal).when(
213                 () -> LocalServices.getService(eq(PowerManagerInternal.class)));
214         doReturn(mDisplayManagerInternal).when(
215                 () -> LocalServices.getService(eq(DisplayManagerInternal.class)));
216         doReturn(mGestureLauncherService).when(
217                 () -> LocalServices.getService(eq(GestureLauncherService.class)));
218         doReturn(mUserManagerInternal).when(
219                 () -> LocalServices.getService(eq(UserManagerInternal.class)));
220         doReturn(null).when(() -> LocalServices.getService(eq(VrManagerInternal.class)));
221         doReturn(null).when(() -> LocalServices.getService(eq(AutofillManagerInternal.class)));
222         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
223         LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal);
224 
225         doReturn(mAppOpsManager).when(mContext).getSystemService(eq(AppOpsManager.class));
226         doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
227         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
228         doReturn(mPackageManager).when(mContext).getPackageManager();
229         doReturn(mSensorPrivacyManager).when(mContext).getSystemService(
230                 eq(SensorPrivacyManager.class));
231         doReturn(false).when(mPackageManager).hasSystemFeature(any());
232         try {
233             doThrow(new PackageManager.NameNotFoundException("test")).when(mPackageManager)
234                     .getActivityInfo(any(), anyInt());
235             doReturn(new String[] { "testPackage" }).when(mPackageManager)
236                     .canonicalToCurrentPackageNames(any());
237         } catch (PackageManager.NameNotFoundException ignored) { }
238 
239         doReturn(false).when(mTelecomManager).isInCall();
240         doReturn(false).when(mTelecomManager).isRinging();
241         doReturn(mTelecomManager).when(mPhoneWindowManager).getTelecommService();
242         doNothing().when(mNotificationManager).silenceNotificationSound();
243         doReturn(mNotificationManager).when(mPhoneWindowManager).getNotificationService();
244         doReturn(mVibrator).when(mContext).getSystemService(eq(Context.VIBRATOR_SERVICE));
245 
246         final PowerManager.WakeLock wakeLock = mock(PowerManager.WakeLock.class);
247         doReturn(wakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
248         doReturn(mPowerManager).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
249         doReturn(true).when(mPowerManager).isInteractive();
250 
251         doReturn(mDisplay).when(mDisplayManager).getDisplay(eq(DEFAULT_DISPLAY));
252         doReturn(STATE_ON).when(mDisplay).getState();
253         doReturn(true).when(mDisplayPolicy).isAwake();
254         doNothing().when(mDisplayPolicy).takeScreenshot(anyInt(), anyInt());
255         doReturn(mDisplayPolicy).when(mDisplayRotation).getDisplayPolicy();
256         doReturn(mScreenOnListener).when(mDisplayPolicy).getScreenOnListener();
257         mPhoneWindowManager.setDefaultDisplay(new WindowManagerPolicy.DisplayContentInfo() {
258             @Override
259             public DisplayRotation getDisplayRotation() {
260                 return mDisplayRotation;
261             }
262             @Override
263             public Display getDisplay() {
264                 return mDisplay;
265             }
266         });
267 
268         doNothing().when(mPhoneWindowManager).initializeHdmiState();
269         doNothing().when(mPhoneWindowManager).updateSettings();
270         doNothing().when(mPhoneWindowManager).screenTurningOn(anyInt(), any());
271         doNothing().when(mPhoneWindowManager).screenTurnedOn(anyInt());
272         doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt(), anyInt());
273         doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt(), anyInt());
274         doNothing().when(mPhoneWindowManager).lockNow(any());
275 
276         mPhoneWindowManager.init(new TestInjector(mContext, mWindowManagerFuncsImpl));
277         mPhoneWindowManager.systemReady();
278         mPhoneWindowManager.systemBooted();
279 
280         overrideLaunchAccessibility();
281         doReturn(false).when(mPhoneWindowManager).keyguardOn();
282         doNothing().when(mContext).startActivityAsUser(any(), any());
283         doNothing().when(mContext).startActivityAsUser(any(), any(), any());
284         Mockito.reset(mContext);
285     }
286 
tearDown()287     void tearDown() {
288         mHandlerThread.quitSafely();
289         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
290         Mockito.reset(mPhoneWindowManager);
291         mMockitoSession.finishMocking();
292     }
293 
294     // Override accessibility setting and perform function.
overrideLaunchAccessibility()295     private void overrideLaunchAccessibility() {
296         doReturn(true).when(mAccessibilityShortcutController)
297                 .isAccessibilityShortcutAvailable(anyBoolean());
298         doNothing().when(mAccessibilityShortcutController).performAccessibilityShortcut();
299     }
300 
interceptKeyBeforeQueueing(KeyEvent event)301     int interceptKeyBeforeQueueing(KeyEvent event) {
302         return mPhoneWindowManager.interceptKeyBeforeQueueing(event, FLAG_INTERACTIVE);
303     }
304 
interceptKeyBeforeDispatching(KeyEvent event)305     long interceptKeyBeforeDispatching(KeyEvent event) {
306         return mPhoneWindowManager.interceptKeyBeforeDispatching(null /*focusedToken*/,
307                 event, FLAG_INTERACTIVE);
308     }
309 
dispatchUnhandledKey(KeyEvent event)310     void dispatchUnhandledKey(KeyEvent event) {
311         mPhoneWindowManager.dispatchUnhandledKey(null /*focusedToken*/, event, FLAG_INTERACTIVE);
312     }
313 
waitForIdle()314     void waitForIdle() {
315         mHandler.runWithScissors(() -> { }, 0 /* timeout */);
316     }
317 
318     /**
319      * Below functions will override the setting or the policy behavior.
320      */
overridePowerVolumeUp(int behavior)321     void overridePowerVolumeUp(int behavior) {
322         mPhoneWindowManager.mPowerVolUpBehavior = behavior;
323 
324         // override mRingerToggleChord as mute so we could trigger the behavior.
325         if (behavior == POWER_VOLUME_UP_BEHAVIOR_MUTE) {
326             mPhoneWindowManager.mRingerToggleChord = VOLUME_HUSH_MUTE;
327             doReturn(mAudioManagerInternal).when(
328                     () -> LocalServices.getService(eq(AudioManagerInternal.class)));
329         }
330     }
331 
overrideShortPressOnPower(int behavior)332     void overrideShortPressOnPower(int behavior) {
333         mPhoneWindowManager.mShortPressOnPowerBehavior = behavior;
334     }
335 
336      // Override assist perform function.
overrideLongPressOnPower(int behavior)337     void overrideLongPressOnPower(int behavior) {
338         mPhoneWindowManager.mLongPressOnPowerBehavior = behavior;
339 
340         switch (behavior) {
341             case LONG_PRESS_POWER_NOTHING:
342             case LONG_PRESS_POWER_GLOBAL_ACTIONS:
343             case LONG_PRESS_POWER_SHUT_OFF:
344             case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
345             case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
346                 break;
347             case LONG_PRESS_POWER_ASSISTANT:
348                 doNothing().when(mPhoneWindowManager).sendCloseSystemWindows();
349                 doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
350                 doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
351                 doReturn(mSearchManager).when(mContext)
352                         .getSystemService(eq(Context.SEARCH_SERVICE));
353                 mPhoneWindowManager.mLongPressOnPowerAssistantTimeoutMs = 500;
354                 break;
355         }
356     }
357 
overrideCanStartDreaming(boolean canDream)358     void overrideCanStartDreaming(boolean canDream) {
359         doReturn(canDream).when(mDreamManagerInternal).canStartDreaming(anyBoolean());
360     }
361 
overrideIsDreaming(boolean isDreaming)362     void overrideIsDreaming(boolean isDreaming) {
363         doReturn(isDreaming).when(mDreamManagerInternal).isDreaming();
364     }
365 
overrideDisplayState(int state)366     void overrideDisplayState(int state) {
367         doReturn(state).when(mDisplay).getState();
368         doReturn(state == STATE_ON).when(mDisplayPolicy).isAwake();
369         Mockito.reset(mPowerManager);
370     }
371 
overrideIncallPowerBehavior(int behavior)372     void overrideIncallPowerBehavior(int behavior) {
373         mPhoneWindowManager.mIncallPowerBehavior = behavior;
374         setPhoneCallIsInProgress();
375     }
376 
prepareBrightnessDecrease(float currentBrightness)377     void prepareBrightnessDecrease(float currentBrightness) {
378         doReturn(0.0f).when(mPowerManager)
379                 .getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
380         doReturn(1.0f).when(mPowerManager)
381                 .getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
382         doReturn(currentBrightness).when(mDisplayManager)
383                 .getBrightness(0);
384     }
385 
verifyNewBrightness(float newBrightness)386     void verifyNewBrightness(float newBrightness) {
387         verify(mDisplayManager).setBrightness(Mockito.eq(0),
388                 AdditionalMatchers.eq(newBrightness, 0.001f));
389     }
390 
setPhoneCallIsInProgress()391     void setPhoneCallIsInProgress() {
392         // Let device has an ongoing phone call.
393         doReturn(false).when(mTelecomManager).isRinging();
394         doReturn(true).when(mTelecomManager).isInCall();
395         doReturn(true).when(mTelecomManager).endCall();
396     }
397 
overrideTogglePanel()398     void overrideTogglePanel() {
399         // Can't directly mock on IStatusbarService, use spyOn and override the specific api.
400         mPhoneWindowManager.getStatusBarService();
401         spyOn(mPhoneWindowManager.mStatusBarService);
402         try {
403             doNothing().when(mPhoneWindowManager.mStatusBarService).togglePanel();
404         } catch (RemoteException e) {
405             e.printStackTrace();
406         }
407     }
408 
overrideStatusBarManagerInternal()409     void overrideStatusBarManagerInternal() {
410         doReturn(mStatusBarManagerInternal).when(
411                 () -> LocalServices.getService(eq(StatusBarManagerInternal.class)));
412     }
413 
overrideLaunchHome()414     void overrideLaunchHome() {
415         doNothing().when(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
416     }
417 
overrideIsUserSetupComplete(boolean isCompleted)418     void overrideIsUserSetupComplete(boolean isCompleted) {
419         doReturn(isCompleted).when(mPhoneWindowManager).isUserSetupComplete();
420     }
421 
setKeyguardServiceDelegateIsShowing(boolean isShowing)422     void setKeyguardServiceDelegateIsShowing(boolean isShowing) {
423         doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing();
424     }
425 
overrideKeyEventSource(int vendorId, int productId)426     void overrideKeyEventSource(int vendorId, int productId) {
427         InputDevice device = new InputDevice.Builder().setId(1).setVendorId(vendorId).setProductId(
428                 productId).setSources(InputDevice.SOURCE_KEYBOARD).setKeyboardType(
429                 InputDevice.KEYBOARD_TYPE_ALPHABETIC).build();
430         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
431         doReturn(device).when(mInputManager).getInputDevice(anyInt());
432     }
433 
overrideSearchKeyBehavior(int behavior)434     void overrideSearchKeyBehavior(int behavior) {
435         mPhoneWindowManager.mSearchKeyBehavior = behavior;
436     }
437 
overrideEnableBugReportTrigger(boolean enable)438     void overrideEnableBugReportTrigger(boolean enable) {
439         mPhoneWindowManager.mEnableShiftMenuBugReports = enable;
440     }
441 
overrideStartActivity()442     void overrideStartActivity() {
443         doNothing().when(mContext).startActivityAsUser(any(), any());
444         doNothing().when(mContext).startActivityAsUser(any(), any(), any());
445     }
446 
overrideUserSetupComplete()447     void overrideUserSetupComplete() {
448         doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
449     }
450 
451     /**
452      * Below functions will check the policy behavior could be invoked.
453      */
assertTakeScreenshotCalled()454     void assertTakeScreenshotCalled() {
455         waitForIdle();
456         verify(mDisplayPolicy, timeout(SHORTCUT_KEY_DELAY_MILLIS))
457                 .takeScreenshot(anyInt(), anyInt());
458     }
459 
assertShowGlobalActionsCalled()460     void assertShowGlobalActionsCalled() {
461         waitForIdle();
462         verify(mPhoneWindowManager).showGlobalActions();
463         verify(mGlobalActions, timeout(SHORTCUT_KEY_DELAY_MILLIS))
464                 .showDialog(anyBoolean(), anyBoolean());
465         verify(mPowerManager, timeout(SHORTCUT_KEY_DELAY_MILLIS))
466                 .userActivity(anyLong(), anyBoolean());
467     }
468 
assertVolumeMute()469     void assertVolumeMute() {
470         waitForIdle();
471         verify(mAudioManagerInternal, timeout(SHORTCUT_KEY_DELAY_MILLIS))
472                 .silenceRingerModeInternal(eq("volume_hush"));
473     }
474 
assertAccessibilityKeychordCalled()475     void assertAccessibilityKeychordCalled() {
476         waitForIdle();
477         verify(mAccessibilityShortcutController,
478                 timeout(SHORTCUT_KEY_DELAY_MILLIS)).performAccessibilityShortcut();
479     }
480 
assertDreamRequest()481     void assertDreamRequest() {
482         waitForIdle();
483         verify(mDreamManagerInternal).requestDream();
484     }
485 
assertPowerSleep()486     void assertPowerSleep() {
487         waitForIdle();
488         verify(mPowerManager,
489                 timeout(SHORTCUT_KEY_DELAY_MILLIS)).goToSleep(anyLong(), anyInt(), anyInt());
490     }
491 
assertPowerWakeUp()492     void assertPowerWakeUp() {
493         waitForIdle();
494         verify(mPowerManager,
495                 timeout(SHORTCUT_KEY_DELAY_MILLIS)).wakeUp(anyLong(), anyInt(), anyString());
496     }
497 
assertNoPowerSleep()498     void assertNoPowerSleep() {
499         waitForIdle();
500         verify(mPowerManager, never()).goToSleep(anyLong(), anyInt(), anyInt());
501     }
502 
assertCameraLaunch()503     void assertCameraLaunch() {
504         waitForIdle();
505         // GestureLauncherService should receive interceptPowerKeyDown twice.
506         verify(mGestureLauncherService, times(2))
507                 .interceptPowerKeyDown(any(), anyBoolean(), any());
508     }
509 
assertAssistLaunch()510     void assertAssistLaunch() {
511         waitForIdle();
512         verify(mSearchManager, timeout(SHORTCUT_KEY_DELAY_MILLIS)).launchAssist(any());
513     }
514 
assertLaunchCategory(String category)515     void assertLaunchCategory(String category) {
516         waitForIdle();
517         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
518         try {
519             verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
520             Assert.assertTrue(intentCaptor.getValue().getSelector().hasCategory(category));
521         } catch (Throwable t) {
522             throw new AssertionError("failed to assert " + category, t);
523         }
524         // Reset verifier for next call.
525         Mockito.reset(mContext);
526     }
527 
assertShowRecentApps()528     void assertShowRecentApps() {
529         waitForIdle();
530         verify(mStatusBarManagerInternal).showRecentApps(anyBoolean());
531     }
532 
assertSwitchKeyboardLayout(int direction)533     void assertSwitchKeyboardLayout(int direction) {
534         waitForIdle();
535         if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)) {
536             verify(mInputMethodManagerInternal).switchKeyboardLayout(eq(direction));
537             verify(mWindowManagerFuncsImpl, never()).switchKeyboardLayout(anyInt(), anyInt());
538         } else {
539             verify(mWindowManagerFuncsImpl).switchKeyboardLayout(anyInt(), eq(direction));
540             verify(mInputMethodManagerInternal, never()).switchKeyboardLayout(anyInt());
541         }
542     }
543 
assertTakeBugreport()544     void assertTakeBugreport() {
545         waitForIdle();
546         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
547         verify(mContext).sendOrderedBroadcastAsUser(intentCaptor.capture(), any(), any(), any(),
548                 any(), anyInt(), any(), any());
549         Assert.assertTrue(intentCaptor.getValue().getAction() == Intent.ACTION_BUG_REPORT);
550     }
551 
assertTogglePanel()552     void assertTogglePanel() throws RemoteException {
553         waitForIdle();
554         verify(mPhoneWindowManager.mStatusBarService).togglePanel();
555     }
556 
assertToggleShortcutsMenu()557     void assertToggleShortcutsMenu() {
558         waitForIdle();
559         verify(mStatusBarManagerInternal).toggleKeyboardShortcutsMenu(anyInt());
560     }
561 
assertToggleCapsLock()562     void assertToggleCapsLock() {
563         waitForIdle();
564         verify(mInputManagerInternal).toggleCapsLock(anyInt());
565     }
566 
assertLockedAfterAppTransitionFinished()567     void assertLockedAfterAppTransitionFinished() {
568         ArgumentCaptor<AppTransitionListener> transitionCaptor =
569                 ArgumentCaptor.forClass(AppTransitionListener.class);
570         verify(mWindowManagerInternal).registerAppTransitionListener(
571                 transitionCaptor.capture());
572         final IBinder token = mock(IBinder.class);
573         transitionCaptor.getValue().onAppTransitionFinishedLocked(token);
574         verify(mPhoneWindowManager).lockNow(null);
575     }
576 
assertDidNotLockAfterAppTransitionFinished()577     void assertDidNotLockAfterAppTransitionFinished() {
578         ArgumentCaptor<AppTransitionListener> transitionCaptor =
579                 ArgumentCaptor.forClass(AppTransitionListener.class);
580         verify(mWindowManagerInternal).registerAppTransitionListener(
581                 transitionCaptor.capture());
582         final IBinder token = mock(IBinder.class);
583         transitionCaptor.getValue().onAppTransitionFinishedLocked(token);
584         verify(mPhoneWindowManager, never()).lockNow(null);
585     }
586 
assertGoToHomescreen()587     void assertGoToHomescreen() {
588         waitForIdle();
589         verify(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
590     }
591 
assertOpenAllAppView()592     void assertOpenAllAppView() {
593         waitForIdle();
594         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
595         verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
596                 .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
597         Assert.assertEquals(Intent.ACTION_ALL_APPS, intentCaptor.getValue().getAction());
598     }
599 
assertNotOpenAllAppView()600     void assertNotOpenAllAppView() {
601         waitForIdle();
602         verify(mContext, after(TEST_SINGLE_KEY_DELAY_MILLIS).never())
603                 .startActivityAsUser(any(Intent.class), any(), any(UserHandle.class));
604     }
605 
assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent, int expectedKey, int expectedModifierState, String errorMsg)606     void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
607             int expectedKey, int expectedModifierState, String errorMsg) {
608         waitForIdle();
609         verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
610                         vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
611                         expectedModifierState), description(errorMsg));
612     }
613 }
614