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.doAnswer;
31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
36 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
37 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
38 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
39 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
40 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
41 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
42 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;
43 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GO_TO_VOICE_ASSIST;
44 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_NOTHING;
45 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF;
46 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
47 import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;
48 
49 import static org.mockito.ArgumentMatchers.anyBoolean;
50 import static org.mockito.ArgumentMatchers.isNull;
51 import static org.mockito.Mockito.CALLS_REAL_METHODS;
52 import static org.mockito.Mockito.after;
53 import static org.mockito.Mockito.doThrow;
54 import static org.mockito.Mockito.mockingDetails;
55 import static org.mockito.Mockito.timeout;
56 import static org.mockito.Mockito.withSettings;
57 
58 import android.app.ActivityManagerInternal;
59 import android.app.AppOpsManager;
60 import android.app.IActivityManager;
61 import android.app.NotificationManager;
62 import android.app.SearchManager;
63 import android.app.role.RoleManager;
64 import android.content.ComponentName;
65 import android.content.Context;
66 import android.content.Intent;
67 import android.content.pm.PackageManager;
68 import android.content.pm.ResolveInfo;
69 import android.database.ContentObserver;
70 import android.hardware.SensorPrivacyManager;
71 import android.hardware.display.DisplayManager;
72 import android.hardware.display.DisplayManagerInternal;
73 import android.hardware.input.InputManager;
74 import android.media.AudioManagerInternal;
75 import android.os.Handler;
76 import android.os.HandlerThread;
77 import android.os.IBinder;
78 import android.os.Looper;
79 import android.os.PowerManager;
80 import android.os.PowerManagerInternal;
81 import android.os.RemoteException;
82 import android.os.UserHandle;
83 import android.os.Vibrator;
84 import android.os.VibratorInfo;
85 import android.os.test.TestLooper;
86 import android.service.dreams.DreamManagerInternal;
87 import android.telecom.TelecomManager;
88 import android.view.Display;
89 import android.view.InputDevice;
90 import android.view.KeyEvent;
91 import android.view.accessibility.AccessibilityManager;
92 import android.view.autofill.AutofillManagerInternal;
93 
94 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
95 import com.android.internal.accessibility.AccessibilityShortcutController;
96 import com.android.internal.policy.KeyInterceptionInfo;
97 import com.android.internal.util.FrameworkStatsLog;
98 import com.android.server.GestureLauncherService;
99 import com.android.server.LocalServices;
100 import com.android.server.input.InputManagerInternal;
101 import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent;
102 import com.android.server.inputmethod.InputMethodManagerInternal;
103 import com.android.server.pm.UserManagerInternal;
104 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
105 import com.android.server.statusbar.StatusBarManagerInternal;
106 import com.android.server.testutils.OffsettableClock;
107 import com.android.server.vr.VrManagerInternal;
108 import com.android.server.wm.ActivityTaskManagerInternal;
109 import com.android.server.wm.DisplayPolicy;
110 import com.android.server.wm.DisplayRotation;
111 import com.android.server.wm.WindowManagerInternal;
112 import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
113 
114 import junit.framework.Assert;
115 
116 import org.mockito.AdditionalMatchers;
117 import org.mockito.ArgumentCaptor;
118 import org.mockito.Mock;
119 import org.mockito.MockSettings;
120 import org.mockito.Mockito;
121 import org.mockito.MockitoAnnotations;
122 import org.mockito.quality.Strictness;
123 
124 import java.util.function.Supplier;
125 
126 class TestPhoneWindowManager {
127     private static final long TEST_SINGLE_KEY_DELAY_MILLIS
128             = SingleKeyGestureDetector.MULTI_PRESS_TIMEOUT + 1000L * HW_TIMEOUT_MULTIPLIER;
129     private static final String TEST_BROWSER_ROLE_PACKAGE_NAME = "com.browser";
130     private static final String TEST_SMS_ROLE_PACKAGE_NAME = "com.sms";
131 
132     private PhoneWindowManager mPhoneWindowManager;
133     private Context mContext;
134 
135     @Mock private WindowManagerInternal mWindowManagerInternal;
136     @Mock private ActivityManagerInternal mActivityManagerInternal;
137     @Mock ActivityTaskManagerInternal mActivityTaskManagerInternal;
138     @Mock IActivityManager mActivityManagerService;
139     @Mock private InputManagerInternal mInputManagerInternal;
140     @Mock private InputManager mInputManager;
141     @Mock private SensorPrivacyManager mSensorPrivacyManager;
142     @Mock private DreamManagerInternal mDreamManagerInternal;
143     @Mock private PowerManagerInternal mPowerManagerInternal;
144     @Mock private DisplayManagerInternal mDisplayManagerInternal;
145     @Mock private AppOpsManager mAppOpsManager;
146     @Mock private DisplayManager mDisplayManager;
147     @Mock private PackageManager mPackageManager;
148     @Mock private TelecomManager mTelecomManager;
149     @Mock private NotificationManager mNotificationManager;
150     @Mock private Vibrator mVibrator;
151     @Mock private VibratorInfo mVibratorInfo;
152     @Mock private PowerManager mPowerManager;
153     @Mock private WindowManagerPolicy.WindowManagerFuncs mWindowManagerFuncsImpl;
154     @Mock private InputMethodManagerInternal mInputMethodManagerInternal;
155     @Mock private UserManagerInternal mUserManagerInternal;
156     @Mock private AudioManagerInternal mAudioManagerInternal;
157     @Mock private SearchManager mSearchManager;
158     @Mock private RoleManager mRoleManager;
159     @Mock private AccessibilityManager mAccessibilityManager;
160 
161     @Mock private Display mDisplay;
162     @Mock private DisplayRotation mDisplayRotation;
163     @Mock private DisplayPolicy mDisplayPolicy;
164     @Mock private WindowManagerPolicy.ScreenOnListener mScreenOnListener;
165     @Mock private GestureLauncherService mGestureLauncherService;
166     @Mock private GlobalActions mGlobalActions;
167     @Mock private AccessibilityShortcutController mAccessibilityShortcutController;
168 
169     @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
170 
171     @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate;
172 
173     @Mock
174     private PhoneWindowManager.ButtonOverridePermissionChecker mButtonOverridePermissionChecker;
175     @Mock private WindowWakeUpPolicy mWindowWakeUpPolicy;
176 
177     @Mock private IBinder mInputToken;
178     @Mock private IBinder mImeTargetWindowToken;
179 
180     private StaticMockitoSession mMockitoSession;
181     private OffsettableClock mClock = new OffsettableClock();
182     private TestLooper mTestLooper = new TestLooper(() -> mClock.now());
183     private HandlerThread mHandlerThread;
184     private Handler mHandler;
185 
186     private boolean mIsTalkBackEnabled;
187     private boolean mIsTalkBackShortcutGestureEnabled;
188 
189     private Intent mBrowserIntent;
190     private Intent mSmsIntent;
191 
192     private int mKeyEventPolicyFlags = FLAG_INTERACTIVE;
193 
194     private class TestTalkbackShortcutController extends TalkbackShortcutController {
TestTalkbackShortcutController(Context context)195         TestTalkbackShortcutController(Context context) {
196             super(context);
197         }
198 
199         @Override
toggleTalkback(int currentUserId)200         boolean toggleTalkback(int currentUserId) {
201             mIsTalkBackEnabled = !mIsTalkBackEnabled;
202             return mIsTalkBackEnabled;
203         }
204 
205         @Override
isTalkBackShortcutGestureEnabled()206         boolean isTalkBackShortcutGestureEnabled() {
207             return mIsTalkBackShortcutGestureEnabled;
208         }
209     }
210 
211     private class TestInjector extends PhoneWindowManager.Injector {
TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs)212         TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs) {
213             super(context, funcs);
214         }
215 
216         @Override
getLooper()217         Looper getLooper() {
218             return mTestLooper.getLooper();
219         }
220 
getAccessibilityShortcutController( Context context, Handler handler, int initialUserId)221         AccessibilityShortcutController getAccessibilityShortcutController(
222                 Context context, Handler handler, int initialUserId) {
223             return mAccessibilityShortcutController;
224         }
225 
getGlobalActionsFactory()226         Supplier<GlobalActions> getGlobalActionsFactory() {
227             return () -> mGlobalActions;
228         }
229 
getKeyguardServiceDelegate()230         KeyguardServiceDelegate getKeyguardServiceDelegate() {
231             return mKeyguardServiceDelegate;
232         }
233 
getActivityManagerService()234         IActivityManager getActivityManagerService() {
235             return mActivityManagerService;
236         }
237 
getButtonOverridePermissionChecker()238         PhoneWindowManager.ButtonOverridePermissionChecker getButtonOverridePermissionChecker() {
239             return mButtonOverridePermissionChecker;
240         }
241 
getTalkbackShortcutController()242         TalkbackShortcutController getTalkbackShortcutController() {
243             return new TestTalkbackShortcutController(mContext);
244         }
245 
getWindowWakeUpPolicy()246         WindowWakeUpPolicy getWindowWakeUpPolicy() {
247             return mWindowWakeUpPolicy;
248         }
249     }
250 
251     /**
252      * {@link TestPhoneWindowManager}'s constructor.
253      *
254      * @param context The {@Context} to be used in any Context-related actions.
255      * @param supportSettingsUpdate {@code true} if this object should read and listen to provider
256      *      settings values.
257      */
TestPhoneWindowManager(Context context, boolean supportSettingsUpdate)258     TestPhoneWindowManager(Context context, boolean supportSettingsUpdate) {
259         MockitoAnnotations.initMocks(this);
260         mHandler = new Handler(mTestLooper.getLooper());
261         mContext = mockingDetails(context).isSpy() ? context : spy(context);
262         setUp(supportSettingsUpdate);
263         mTestLooper.dispatchAll();
264     }
265 
setUp(boolean supportSettingsUpdate)266     private void setUp(boolean supportSettingsUpdate) {
267         // Use stubOnly() to reduce memory usage if it doesn't need verification.
268         final MockSettings spyStubOnly = withSettings().stubOnly()
269                 .defaultAnswer(CALLS_REAL_METHODS);
270         // Return mocked services: LocalServices.getService
271         mMockitoSession = mockitoSession()
272                 .mockStatic(LocalServices.class, spyStubOnly)
273                 .mockStatic(FrameworkStatsLog.class)
274                 .strictness(Strictness.LENIENT)
275                 .startMocking();
276 
277         mPhoneWindowManager = spy(new PhoneWindowManager());
278 
279         doReturn(mWindowManagerInternal).when(
280                 () -> LocalServices.getService(eq(WindowManagerInternal.class)));
281         doReturn(mActivityManagerInternal).when(
282                 () -> LocalServices.getService(eq(ActivityManagerInternal.class)));
283         doReturn(mActivityTaskManagerInternal).when(
284                 () -> LocalServices.getService(eq(ActivityTaskManagerInternal.class)));
285         doReturn(mInputManagerInternal).when(
286                 () -> LocalServices.getService(eq(InputManagerInternal.class)));
287         doReturn(mDreamManagerInternal).when(
288                 () -> LocalServices.getService(eq(DreamManagerInternal.class)));
289         doReturn(mPowerManagerInternal).when(
290                 () -> LocalServices.getService(eq(PowerManagerInternal.class)));
291         doReturn(mDisplayManagerInternal).when(
292                 () -> LocalServices.getService(eq(DisplayManagerInternal.class)));
293         doReturn(mGestureLauncherService).when(
294                 () -> LocalServices.getService(eq(GestureLauncherService.class)));
295         doReturn(mUserManagerInternal).when(
296                 () -> LocalServices.getService(eq(UserManagerInternal.class)));
297         doReturn(null).when(() -> LocalServices.getService(eq(VrManagerInternal.class)));
298         doReturn(null).when(() -> LocalServices.getService(eq(AutofillManagerInternal.class)));
299         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
300         LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal);
301 
302         doReturn(mAppOpsManager).when(mContext).getSystemService(eq(AppOpsManager.class));
303         doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
304         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
305         doReturn(mPackageManager).when(mContext).getPackageManager();
306         doReturn(mSensorPrivacyManager).when(mContext).getSystemService(
307                 eq(SensorPrivacyManager.class));
308         doReturn(mSearchManager).when(mContext).getSystemService(eq(SearchManager.class));
309         doReturn(mRoleManager).when(mContext).getSystemService(eq(RoleManager.class));
310         doReturn(mAccessibilityManager).when(mContext).getSystemService(
311                 eq(AccessibilityManager.class));
312         doReturn(false).when(mAccessibilityManager).isEnabled();
313         doReturn(false).when(mPackageManager).hasSystemFeature(any());
314         try {
315             doThrow(new PackageManager.NameNotFoundException("test")).when(mPackageManager)
316                     .getActivityInfo(any(), anyInt());
317             doReturn(new String[] { "testPackage" }).when(mPackageManager)
318                     .canonicalToCurrentPackageNames(any());
319         } catch (PackageManager.NameNotFoundException ignored) { }
320 
321         doReturn(false).when(mTelecomManager).isInCall();
322         doReturn(false).when(mTelecomManager).isRinging();
323         doReturn(mTelecomManager).when(mPhoneWindowManager).getTelecommService();
324         doNothing().when(mNotificationManager).silenceNotificationSound();
325         doReturn(mNotificationManager).when(mPhoneWindowManager).getNotificationService();
326         doReturn(mVibratorInfo).when(mVibrator).getInfo();
327         doReturn(mVibrator).when(mContext).getSystemService(eq(Context.VIBRATOR_SERVICE));
328 
329         final PowerManager.WakeLock wakeLock = mock(PowerManager.WakeLock.class);
330         doReturn(wakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
331         doReturn(mPowerManager).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
332         doReturn(true).when(mPowerManager).isInteractive();
333 
334         doReturn(mDisplay).when(mDisplayManager).getDisplay(eq(DEFAULT_DISPLAY));
335         doReturn(STATE_ON).when(mDisplay).getState();
336         doReturn(true).when(mDisplayPolicy).isAwake();
337         doNothing().when(mDisplayPolicy).takeScreenshot(anyInt(), anyInt());
338         doReturn(mDisplayPolicy).when(mDisplayRotation).getDisplayPolicy();
339         doReturn(mScreenOnListener).when(mDisplayPolicy).getScreenOnListener();
340         mPhoneWindowManager.setDefaultDisplay(new WindowManagerPolicy.DisplayContentInfo() {
341             @Override
342             public DisplayRotation getDisplayRotation() {
343                 return mDisplayRotation;
344             }
345             @Override
346             public Display getDisplay() {
347                 return mDisplay;
348             }
349         });
350 
351         doNothing().when(mPhoneWindowManager).initializeHdmiState();
352         if (supportSettingsUpdate) {
353             doAnswer(inv -> {
354                 // Make any call to updateSettings run synchronously for tests.
355                 mPhoneWindowManager.updateSettings(null);
356                 return null;
357             }).when(mPhoneWindowManager).updateSettings(any(Handler.class));
358         } else {
359             doNothing().when(mPhoneWindowManager).updateSettings(any());
360         }
361         doNothing().when(mPhoneWindowManager).screenTurningOn(anyInt(), any());
362         doNothing().when(mPhoneWindowManager).screenTurnedOn(anyInt());
363         doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt(), anyInt());
364         doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt(), anyInt());
365         doNothing().when(mPhoneWindowManager).lockNow(any());
366 
367         doReturn(mImeTargetWindowToken)
368                 .when(mWindowManagerInternal).getTargetWindowTokenFromInputToken(mInputToken);
369 
370         mPhoneWindowManager.init(new TestInjector(mContext, mWindowManagerFuncsImpl));
371         mPhoneWindowManager.systemReady();
372         mPhoneWindowManager.systemBooted();
373 
374         overrideLaunchAccessibility();
375         doReturn(false).when(mPhoneWindowManager).keyguardOn();
376         doNothing().when(mContext).startActivityAsUser(any(), any());
377         doNothing().when(mContext).startActivityAsUser(any(), any(), any());
378 
379         KeyInterceptionInfo interceptionInfo = new KeyInterceptionInfo(0, 0, null, 0);
380         doReturn(interceptionInfo)
381                 .when(mWindowManagerInternal).getKeyInterceptionInfoFromToken(any());
382 
383         doReturn(true).when(mRoleManager).isRoleAvailable(eq(RoleManager.ROLE_BROWSER));
384         doReturn(true).when(mRoleManager).isRoleAvailable(eq(RoleManager.ROLE_SMS));
385         doReturn(TEST_BROWSER_ROLE_PACKAGE_NAME).when(mRoleManager).getDefaultApplication(
386                 eq(RoleManager.ROLE_BROWSER));
387         doReturn(TEST_SMS_ROLE_PACKAGE_NAME).when(mRoleManager).getDefaultApplication(
388                 eq(RoleManager.ROLE_SMS));
389         mBrowserIntent = new Intent(Intent.ACTION_MAIN);
390         mBrowserIntent.setPackage(TEST_BROWSER_ROLE_PACKAGE_NAME);
391         mSmsIntent = new Intent(Intent.ACTION_MAIN);
392         mSmsIntent.setPackage(TEST_SMS_ROLE_PACKAGE_NAME);
393         doReturn(mBrowserIntent).when(mPackageManager).getLaunchIntentForPackage(
394                 eq(TEST_BROWSER_ROLE_PACKAGE_NAME));
395         doReturn(mSmsIntent).when(mPackageManager).getLaunchIntentForPackage(
396                 eq(TEST_SMS_ROLE_PACKAGE_NAME));
397 
398         Mockito.reset(mContext);
399     }
400 
tearDown()401     void tearDown() {
402         LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
403         Mockito.reset(mPhoneWindowManager);
404         mMockitoSession.finishMocking();
405     }
406 
dispatchAllPendingEvents()407     void dispatchAllPendingEvents() {
408         mTestLooper.dispatchAll();
409     }
410 
411     // Override accessibility setting and perform function.
overrideLaunchAccessibility()412     private void overrideLaunchAccessibility() {
413         doReturn(true).when(mAccessibilityShortcutController)
414                 .isAccessibilityShortcutAvailable(anyBoolean());
415         doNothing().when(mAccessibilityShortcutController).performAccessibilityShortcut();
416     }
417 
interceptKeyBeforeQueueing(KeyEvent event)418     int interceptKeyBeforeQueueing(KeyEvent event) {
419         return mPhoneWindowManager.interceptKeyBeforeQueueing(event, mKeyEventPolicyFlags);
420     }
421 
interceptKeyBeforeDispatching(KeyEvent event)422     long interceptKeyBeforeDispatching(KeyEvent event) {
423         return mPhoneWindowManager.interceptKeyBeforeDispatching(mInputToken, event,
424                 mKeyEventPolicyFlags);
425     }
426 
dispatchUnhandledKey(KeyEvent event)427     void dispatchUnhandledKey(KeyEvent event) {
428         mPhoneWindowManager.dispatchUnhandledKey(mInputToken, event, FLAG_INTERACTIVE);
429     }
430 
431     /**
432      * Provide access to the SettingsObserver so that tests can manually trigger Settings changes.
433      */
getSettingsObserver()434     ContentObserver getSettingsObserver() {
435         return mPhoneWindowManager.mSettingsObserver;
436     }
437 
getCurrentTime()438     long getCurrentTime() {
439         return mClock.now();
440     }
441 
moveTimeForward(long timeMs)442     void moveTimeForward(long timeMs) {
443         mClock.fastForward(timeMs);
444         mTestLooper.dispatchAll();
445     }
446 
447     /**
448      * Below functions will override the setting or the policy behavior.
449      */
overridePowerVolumeUp(int behavior)450     void overridePowerVolumeUp(int behavior) {
451         mPhoneWindowManager.mPowerVolUpBehavior = behavior;
452 
453         // override mRingerToggleChord as mute so we could trigger the behavior.
454         if (behavior == POWER_VOLUME_UP_BEHAVIOR_MUTE) {
455             mPhoneWindowManager.mRingerToggleChord = VOLUME_HUSH_MUTE;
456             doReturn(mAudioManagerInternal).when(
457                     () -> LocalServices.getService(eq(AudioManagerInternal.class)));
458         }
459     }
460 
overrideShortPressOnPower(int behavior)461     void overrideShortPressOnPower(int behavior) {
462         mPhoneWindowManager.mShortPressOnPowerBehavior = behavior;
463     }
464 
overrideShouldEarlyShortPressOnStemPrimary(boolean shouldEarlyShortPress)465     void overrideShouldEarlyShortPressOnStemPrimary(boolean shouldEarlyShortPress) {
466         mPhoneWindowManager.mShouldEarlyShortPressOnStemPrimary = shouldEarlyShortPress;
467     }
468 
overrideTalkbackShortcutGestureEnabled(boolean enabled)469     void overrideTalkbackShortcutGestureEnabled(boolean enabled) {
470         mIsTalkBackShortcutGestureEnabled = enabled;
471     }
472 
473      // Override assist perform function.
overrideLongPressOnPower(int behavior)474     void overrideLongPressOnPower(int behavior) {
475         mPhoneWindowManager.mLongPressOnPowerBehavior = behavior;
476 
477         switch (behavior) {
478             case LONG_PRESS_POWER_NOTHING:
479             case LONG_PRESS_POWER_GLOBAL_ACTIONS:
480             case LONG_PRESS_POWER_SHUT_OFF:
481             case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
482             case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
483                 break;
484             case LONG_PRESS_POWER_ASSISTANT:
485                 setupAssistForLaunch();
486                 mPhoneWindowManager.mLongPressOnPowerAssistantTimeoutMs = 500;
487                 break;
488         }
489     }
490 
overrideLongPressOnHomeBehavior(int behavior)491     void overrideLongPressOnHomeBehavior(int behavior) {
492         mPhoneWindowManager.mLongPressOnHomeBehavior = behavior;
493     }
494 
overriderDoubleTapOnHomeBehavior(int behavior)495     void overriderDoubleTapOnHomeBehavior(int behavior) {
496         mPhoneWindowManager.mDoubleTapOnHomeBehavior = behavior;
497     }
498 
overrideSettingsKeyBehavior(int behavior)499     void overrideSettingsKeyBehavior(int behavior) {
500         mPhoneWindowManager.mSettingsKeyBehavior = behavior;
501     }
502 
overrideCanStartDreaming(boolean canDream)503     void overrideCanStartDreaming(boolean canDream) {
504         doReturn(canDream).when(mDreamManagerInternal).canStartDreaming(anyBoolean());
505     }
506 
overrideIsDreaming(boolean isDreaming)507     void overrideIsDreaming(boolean isDreaming) {
508         doReturn(isDreaming).when(mDreamManagerInternal).isDreaming();
509     }
510 
overrideDisplayState(int state)511     void overrideDisplayState(int state) {
512         doReturn(state).when(mDisplay).getState();
513         doReturn(state == STATE_ON).when(mDisplayPolicy).isAwake();
514         Mockito.reset(mPowerManager);
515     }
516 
overrideIncallPowerBehavior(int behavior)517     void overrideIncallPowerBehavior(int behavior) {
518         mPhoneWindowManager.mIncallPowerBehavior = behavior;
519         setPhoneCallIsInProgress();
520     }
521 
prepareBrightnessDecrease(float currentBrightness)522     void prepareBrightnessDecrease(float currentBrightness) {
523         doReturn(0.0f).when(mPowerManager)
524                 .getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
525         doReturn(1.0f).when(mPowerManager)
526                 .getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
527         doReturn(currentBrightness).when(mDisplayManager)
528                 .getBrightness(0);
529     }
530 
verifyNewBrightness(float newBrightness)531     void verifyNewBrightness(float newBrightness) {
532         verify(mDisplayManager).setBrightness(Mockito.eq(0),
533                 AdditionalMatchers.eq(newBrightness, 0.001f));
534     }
535 
setPhoneCallIsInProgress()536     void setPhoneCallIsInProgress() {
537         // Let device has an ongoing phone call.
538         doReturn(false).when(mTelecomManager).isRinging();
539         doReturn(true).when(mTelecomManager).isInCall();
540         doReturn(true).when(mTelecomManager).endCall();
541     }
542 
overrideTogglePanel()543     void overrideTogglePanel() {
544         // Can't directly mock on IStatusbarService, use spyOn and override the specific api.
545         mPhoneWindowManager.getStatusBarService();
546         spyOn(mPhoneWindowManager.mStatusBarService);
547         try {
548             doNothing().when(mPhoneWindowManager.mStatusBarService).togglePanel();
549         } catch (RemoteException e) {
550             e.printStackTrace();
551         }
552     }
553 
overrideStatusBarManagerInternal()554     void overrideStatusBarManagerInternal() {
555         doReturn(mStatusBarManagerInternal).when(
556                 () -> LocalServices.getService(eq(StatusBarManagerInternal.class)));
557     }
558 
overrideLaunchHome()559     void overrideLaunchHome() {
560         doNothing().when(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
561     }
562 
overrideIsUserSetupComplete(boolean isCompleted)563     void overrideIsUserSetupComplete(boolean isCompleted) {
564         doReturn(isCompleted).when(mPhoneWindowManager).isUserSetupComplete();
565     }
566 
setKeyguardServiceDelegateIsShowing(boolean isShowing)567     void setKeyguardServiceDelegateIsShowing(boolean isShowing) {
568         doReturn(isShowing).when(mKeyguardServiceDelegate).isShowing();
569     }
570 
setupAssistForLaunch()571     void setupAssistForLaunch() {
572         doNothing().when(mPhoneWindowManager).sendCloseSystemWindows();
573         doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
574         doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
575         doReturn(mSearchManager).when(mContext).getSystemService(eq(SearchManager.class));
576     }
577 
overrideSearchManager(SearchManager searchManager)578     void overrideSearchManager(SearchManager searchManager) {
579         doReturn(searchManager).when(mContext).getSystemService(eq(SearchManager.class));
580     }
581 
assumeResolveActivityNotNull()582     void assumeResolveActivityNotNull() {
583         ResolveInfo resolveInfo = new ResolveInfo();
584         doReturn(resolveInfo).when(mPackageManager).resolveActivity(any(), anyInt());
585         doReturn(mPackageManager).when(mContext).getPackageManager();
586     }
587 
overrideKeyEventSource(int vendorId, int productId, int deviceBus)588     void overrideKeyEventSource(int vendorId, int productId, int deviceBus) {
589         InputDevice device = new InputDevice.Builder()
590                 .setId(1)
591                 .setVendorId(vendorId)
592                 .setProductId(productId)
593                 .setDeviceBus(deviceBus)
594                 .setSources(InputDevice.SOURCE_KEYBOARD)
595                 .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
596                 .build();
597         doReturn(mInputManager).when(mContext).getSystemService(eq(InputManager.class));
598         doReturn(device).when(mInputManager).getInputDevice(anyInt());
599     }
600 
overrideInjectKeyEvent()601     void overrideInjectKeyEvent() {
602         doReturn(true).when(mInputManager).injectInputEvent(any(KeyEvent.class), anyInt());
603     }
604 
overrideSearchKeyBehavior(int behavior)605     void overrideSearchKeyBehavior(int behavior) {
606         mPhoneWindowManager.mSearchKeyBehavior = behavior;
607     }
608 
overrideEnableBugReportTrigger(boolean enable)609     void overrideEnableBugReportTrigger(boolean enable) {
610         mPhoneWindowManager.mEnableBugReportKeyboardShortcut = enable;
611     }
612 
overrideStartActivity()613     void overrideStartActivity() {
614         doNothing().when(mContext).startActivityAsUser(any(), any());
615         doNothing().when(mContext).startActivityAsUser(any(), any(), any());
616     }
617 
overrideSendBroadcast()618     void overrideSendBroadcast() {
619         doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
620     }
621 
overrideUserSetupComplete()622     void overrideUserSetupComplete() {
623         doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
624     }
625 
overrideStemPressTargetActivity(ComponentName component)626     void overrideStemPressTargetActivity(ComponentName component) {
627         mPhoneWindowManager.mPrimaryShortPressTargetActivity = component;
628     }
629 
overrideFocusedWindowButtonOverridePermission(boolean granted)630     void overrideFocusedWindowButtonOverridePermission(boolean granted) {
631         doReturn(granted)
632                 .when(mButtonOverridePermissionChecker).canAppOverrideSystemKey(any(), anyInt());
633     }
634 
overrideKeyEventPolicyFlags(int flags)635     void overrideKeyEventPolicyFlags(int flags) {
636         mKeyEventPolicyFlags = flags;
637     }
638 
639     /**
640      * Below functions will check the policy behavior could be invoked.
641      */
assertTakeScreenshotCalled()642     void assertTakeScreenshotCalled() {
643         mTestLooper.dispatchAll();
644         verify(mDisplayPolicy).takeScreenshot(anyInt(), anyInt());
645     }
646 
assertTakeScreenshotNotCalled()647     void assertTakeScreenshotNotCalled() {
648         mTestLooper.dispatchAll();
649         verify(mDisplayPolicy, never()).takeScreenshot(anyInt(), anyInt());
650     }
651 
assertShowGlobalActionsCalled()652     void assertShowGlobalActionsCalled() {
653         mTestLooper.dispatchAll();
654         verify(mPhoneWindowManager).showGlobalActions();
655         verify(mGlobalActions).showDialog(anyBoolean(), anyBoolean());
656         verify(mPowerManager).userActivity(anyLong(), anyBoolean());
657     }
658 
assertVolumeMute()659     void assertVolumeMute() {
660         mTestLooper.dispatchAll();
661         verify(mAudioManagerInternal).silenceRingerModeInternal(eq("volume_hush"));
662     }
663 
assertAccessibilityKeychordCalled()664     void assertAccessibilityKeychordCalled() {
665         mTestLooper.dispatchAll();
666         verify(mAccessibilityShortcutController).performAccessibilityShortcut();
667     }
668 
assertDreamRequest()669     void assertDreamRequest() {
670         mTestLooper.dispatchAll();
671         verify(mDreamManagerInternal).requestDream();
672     }
673 
assertPowerSleep()674     void assertPowerSleep() {
675         mTestLooper.dispatchAll();
676         verify(mPowerManager).goToSleep(anyLong(), anyInt(), anyInt());
677     }
678 
assertPowerWakeUp()679     void assertPowerWakeUp() {
680         mTestLooper.dispatchAll();
681         verify(mWindowWakeUpPolicy)
682                 .wakeUpFromKey(anyLong(), eq(KeyEvent.KEYCODE_POWER), anyBoolean());
683     }
684 
assertNoPowerSleep()685     void assertNoPowerSleep() {
686         mTestLooper.dispatchAll();
687         verify(mPowerManager, never()).goToSleep(anyLong(), anyInt(), anyInt());
688     }
689 
assertCameraLaunch()690     void assertCameraLaunch() {
691         mTestLooper.dispatchAll();
692         // GestureLauncherService should receive interceptPowerKeyDown twice.
693         verify(mGestureLauncherService, times(2))
694                 .interceptPowerKeyDown(any(), anyBoolean(), any());
695     }
696 
assertSearchManagerLaunchAssist()697     void assertSearchManagerLaunchAssist() {
698         mTestLooper.dispatchAll();
699         verify(mSearchManager).launchAssist(any());
700     }
701 
assertLaunchCategory(String category)702     void assertLaunchCategory(String category) {
703         mTestLooper.dispatchAll();
704         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
705         try {
706             verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
707             Assert.assertTrue(intentCaptor.getValue().getSelector().hasCategory(category));
708         } catch (Throwable t) {
709             throw new AssertionError("failed to assert " + category, t);
710         }
711         // Reset verifier for next call.
712         Mockito.reset(mContext);
713     }
714 
assertLaunchRole(String role)715     void assertLaunchRole(String role) {
716         mTestLooper.dispatchAll();
717         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
718         try {
719             verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
720             switch (role) {
721                 case RoleManager.ROLE_BROWSER:
722                     Assert.assertEquals(intentCaptor.getValue(), mBrowserIntent);
723                     break;
724                 case RoleManager.ROLE_SMS:
725                     Assert.assertEquals(intentCaptor.getValue(), mSmsIntent);
726                     break;
727                 default:
728                     throw new AssertionError("Role " + role + " not supported in tests.");
729             }
730         } catch (Throwable t) {
731             throw new AssertionError("failed to assert " + role, t);
732         }
733         // Reset verifier for next call.
734         Mockito.reset(mContext);
735     }
736 
737 
assertShowRecentApps()738     void assertShowRecentApps() {
739         mTestLooper.dispatchAll();
740         verify(mStatusBarManagerInternal).showRecentApps(anyBoolean());
741     }
742 
assertStatusBarStartAssist()743     void assertStatusBarStartAssist() {
744         mTestLooper.dispatchAll();
745         verify(mStatusBarManagerInternal).startAssist(any());
746     }
747 
assertSwitchKeyboardLayout(int direction, int displayId)748     void assertSwitchKeyboardLayout(int direction, int displayId) {
749         mTestLooper.dispatchAll();
750         verify(mInputMethodManagerInternal).onSwitchKeyboardLayoutShortcut(eq(direction),
751                 eq(displayId), eq(mImeTargetWindowToken));
752     }
753 
assertTakeBugreport(boolean wasCalled)754     void assertTakeBugreport(boolean wasCalled) throws RemoteException {
755         mTestLooper.dispatchAll();
756         if (wasCalled) {
757             verify(mActivityManagerService).requestInteractiveBugReport();
758         } else {
759             verify(mActivityManagerService, never()).requestInteractiveBugReport();
760         }
761 
762     }
763 
assertTogglePanel()764     void assertTogglePanel() throws RemoteException {
765         mTestLooper.dispatchAll();
766         verify(mPhoneWindowManager.mStatusBarService).togglePanel();
767     }
768 
assertToggleShortcutsMenu()769     void assertToggleShortcutsMenu() {
770         mTestLooper.dispatchAll();
771         verify(mStatusBarManagerInternal).toggleKeyboardShortcutsMenu(anyInt());
772     }
773 
assertToggleCapsLock()774     void assertToggleCapsLock() {
775         mTestLooper.dispatchAll();
776         verify(mInputManagerInternal).toggleCapsLock(anyInt());
777     }
778 
assertLockedAfterAppTransitionFinished()779     void assertLockedAfterAppTransitionFinished() {
780         ArgumentCaptor<AppTransitionListener> transitionCaptor =
781                 ArgumentCaptor.forClass(AppTransitionListener.class);
782         verify(mWindowManagerInternal).registerAppTransitionListener(
783                 transitionCaptor.capture());
784         final IBinder token = mock(IBinder.class);
785         transitionCaptor.getValue().onAppTransitionFinishedLocked(token);
786         verify(mPhoneWindowManager).lockNow(null);
787     }
788 
assertDidNotLockAfterAppTransitionFinished()789     void assertDidNotLockAfterAppTransitionFinished() {
790         ArgumentCaptor<AppTransitionListener> transitionCaptor =
791                 ArgumentCaptor.forClass(AppTransitionListener.class);
792         verify(mWindowManagerInternal).registerAppTransitionListener(
793                 transitionCaptor.capture());
794         final IBinder token = mock(IBinder.class);
795         transitionCaptor.getValue().onAppTransitionFinishedLocked(token);
796         verify(mPhoneWindowManager, never()).lockNow(null);
797     }
798 
assertGoToHomescreen()799     void assertGoToHomescreen() {
800         mTestLooper.dispatchAll();
801         verify(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
802     }
803 
assertOpenAllAppView()804     void assertOpenAllAppView() {
805         moveTimeForward(TEST_SINGLE_KEY_DELAY_MILLIS);
806         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
807         verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
808                 .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
809         Assert.assertEquals(Intent.ACTION_ALL_APPS, intentCaptor.getValue().getAction());
810     }
811 
assertNotOpenAllAppView()812     void assertNotOpenAllAppView() {
813         mTestLooper.dispatchAll();
814         verify(mContext, after(TEST_SINGLE_KEY_DELAY_MILLIS).never())
815                 .startActivityAsUser(any(Intent.class), any(), any(UserHandle.class));
816     }
817 
assertActivityTargetLaunched(ComponentName targetActivity)818     void assertActivityTargetLaunched(ComponentName targetActivity) {
819         moveTimeForward(TEST_SINGLE_KEY_DELAY_MILLIS);
820         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
821         verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
822                 .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
823         Assert.assertEquals(targetActivity, intentCaptor.getValue().getComponent());
824     }
825 
assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent, int expectedKey, int expectedModifierState, int deviceBus, String errorMsg)826     void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
827             int expectedKey, int expectedModifierState, int deviceBus, String errorMsg) {
828         mTestLooper.dispatchAll();
829         verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
830                         vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
831                         expectedModifierState, deviceBus), description(errorMsg));
832     }
833 
assertSwitchToTask(int persistentId)834     void assertSwitchToTask(int persistentId) throws RemoteException {
835         mTestLooper.dispatchAll();
836         verify(mActivityManagerService,
837                 timeout(TEST_SINGLE_KEY_DELAY_MILLIS)).startActivityFromRecents(eq(persistentId),
838                 isNull());
839     }
840 
assertTalkBack(boolean expectEnabled)841     void assertTalkBack(boolean expectEnabled) {
842         mTestLooper.dispatchAll();
843         Assert.assertEquals(expectEnabled, mIsTalkBackEnabled);
844     }
845 }
846