Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c870ab2d authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

Fix ShortcutLoggingTests flaky tests.

Use TestLooper to finish all callbacks correctly to fix flakiness
caused due to handler callbacks being added on handler thread
itself which runWithScissors() call doesn't finish all together.

Test: atest ShortcutLoggingTests
Bug: 300023716
Change-Id: I29feec5188bdb3aa4b5297f5cf56969e36ca48a8
parent d99ac13e
Loading
Loading
Loading
Loading
+15 −3
Original line number Original line Diff line number Diff line
@@ -139,6 +139,7 @@ import android.os.DeviceIdleManager;
import android.os.FactoryTest;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.PowerManager.WakeReason;
import android.os.PowerManager.WakeReason;
@@ -715,6 +716,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final int MSG_LOG_KEYBOARD_SYSTEM_EVENT = 26;
    private static final int MSG_LOG_KEYBOARD_SYSTEM_EVENT = 26;


    private class PolicyHandler extends Handler {
    private class PolicyHandler extends Handler {

        private PolicyHandler(Looper looper) {
            super(looper);
        }

        @Override
        @Override
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            switch (msg.what) {
@@ -2166,10 +2172,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static class Injector {
    static class Injector {
        private final Context mContext;
        private final Context mContext;
        private final WindowManagerFuncs mWindowManagerFuncs;
        private final WindowManagerFuncs mWindowManagerFuncs;
        private final Looper mLooper;


        Injector(Context context, WindowManagerFuncs funcs) {
        Injector(Context context, WindowManagerFuncs funcs, Looper looper) {
            mContext = context;
            mContext = context;
            mWindowManagerFuncs = funcs;
            mWindowManagerFuncs = funcs;
            mLooper = looper;
        }
        }


        Context getContext() {
        Context getContext() {
@@ -2180,6 +2188,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return mWindowManagerFuncs;
            return mWindowManagerFuncs;
        }
        }


        Looper getLooper() {
            return mLooper;
        }

        AccessibilityShortcutController getAccessibilityShortcutController(
        AccessibilityShortcutController getAccessibilityShortcutController(
                Context context, Handler handler, int initialUserId) {
                Context context, Handler handler, int initialUserId) {
            return new AccessibilityShortcutController(context, handler, initialUserId);
            return new AccessibilityShortcutController(context, handler, initialUserId);
@@ -2208,7 +2220,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    /** {@inheritDoc} */
    /** {@inheritDoc} */
    @Override
    @Override
    public void init(Context context, WindowManagerFuncs funcs) {
    public void init(Context context, WindowManagerFuncs funcs) {
        init(new Injector(context, funcs));
        init(new Injector(context, funcs, Looper.myLooper()));
    }
    }


    @VisibleForTesting
    @VisibleForTesting
@@ -2284,7 +2296,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
                    mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
        }
        }


        mHandler = new PolicyHandler();
        mHandler = new PolicyHandler(injector.getLooper());
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mSettingsObserver = new SettingsObserver(mHandler);
        mSettingsObserver = new SettingsObserver(mHandler);
        mSettingsObserver.observe();
        mSettingsObserver.observe();
+0 −5
Original line number Original line Diff line number Diff line
@@ -46,7 +46,6 @@ import static com.android.server.policy.WindowManagerPolicy.ACTION_PASS_TO_USER;
import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableMap;


import android.content.Context;
import android.content.Context;
import android.os.Looper;
import android.os.SystemClock;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.view.InputDevice;
import android.view.InputDevice;
@@ -99,10 +98,6 @@ class ShortcutKeyTestBase {
     *      settings values.
     *      settings values.
     */
     */
    protected final void setUpPhoneWindowManager(boolean supportSettingsUpdate) {
    protected final void setUpPhoneWindowManager(boolean supportSettingsUpdate) {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        doReturn(mSettingsProviderRule.mockContentResolver(mContext))
        doReturn(mSettingsProviderRule.mockContentResolver(mContext))
                .when(mContext).getContentResolver();
                .when(mContext).getContentResolver();
        mPhoneWindowManager = new TestPhoneWindowManager(mContext, supportSettingsUpdate);
        mPhoneWindowManager = new TestPhoneWindowManager(mContext, supportSettingsUpdate);
+29 −34
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.Vibrator;
import android.os.Vibrator;
import android.os.VibratorInfo;
import android.os.VibratorInfo;
import android.os.test.TestLooper;
import android.service.dreams.DreamManagerInternal;
import android.service.dreams.DreamManagerInternal;
import android.telecom.TelecomManager;
import android.telecom.TelecomManager;
import android.util.FeatureFlagUtils;
import android.util.FeatureFlagUtils;
@@ -160,12 +161,13 @@ class TestPhoneWindowManager {
    @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate;
    @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate;


    private StaticMockitoSession mMockitoSession;
    private StaticMockitoSession mMockitoSession;
    private TestLooper mTestLooper = new TestLooper();
    private HandlerThread mHandlerThread;
    private HandlerThread mHandlerThread;
    private Handler mHandler;
    private Handler mHandler;


    private class TestInjector extends PhoneWindowManager.Injector {
    private class TestInjector extends PhoneWindowManager.Injector {
        TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs) {
        TestInjector(Context context, WindowManagerPolicy.WindowManagerFuncs funcs) {
            super(context, funcs);
            super(context, funcs, mTestLooper.getLooper());
        }
        }


        AccessibilityShortcutController getAccessibilityShortcutController(
        AccessibilityShortcutController getAccessibilityShortcutController(
@@ -184,12 +186,10 @@ class TestPhoneWindowManager {


    TestPhoneWindowManager(Context context, boolean supportSettingsUpdate) {
    TestPhoneWindowManager(Context context, boolean supportSettingsUpdate) {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mHandlerThread = new HandlerThread("fake window manager");
        mHandler = new Handler(mTestLooper.getLooper());
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        mContext = mockingDetails(context).isSpy() ? context : spy(context);
        mContext = mockingDetails(context).isSpy() ? context : spy(context);
        mHandler.runWithScissors(() -> setUp(supportSettingsUpdate),  0 /* timeout */);
        mHandler.post(() -> setUp(supportSettingsUpdate));
        waitForIdle();
        mTestLooper.dispatchAll();
    }
    }


    private void setUp(boolean supportSettingsUpdate) {
    private void setUp(boolean supportSettingsUpdate) {
@@ -301,7 +301,6 @@ class TestPhoneWindowManager {
    }
    }


    void tearDown() {
    void tearDown() {
        mHandlerThread.quitSafely();
        LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
        LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
        Mockito.reset(mPhoneWindowManager);
        Mockito.reset(mPhoneWindowManager);
        mMockitoSession.finishMocking();
        mMockitoSession.finishMocking();
@@ -327,10 +326,6 @@ class TestPhoneWindowManager {
        mPhoneWindowManager.dispatchUnhandledKey(null /*focusedToken*/, event, FLAG_INTERACTIVE);
        mPhoneWindowManager.dispatchUnhandledKey(null /*focusedToken*/, event, FLAG_INTERACTIVE);
    }
    }


    void waitForIdle() {
        mHandler.runWithScissors(() -> { }, 0 /* timeout */);
    }

    /**
    /**
     * Below functions will override the setting or the policy behavior.
     * Below functions will override the setting or the policy behavior.
     */
     */
@@ -504,13 +499,13 @@ class TestPhoneWindowManager {
     * Below functions will check the policy behavior could be invoked.
     * Below functions will check the policy behavior could be invoked.
     */
     */
    void assertTakeScreenshotCalled() {
    void assertTakeScreenshotCalled() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mDisplayPolicy, timeout(SHORTCUT_KEY_DELAY_MILLIS))
        verify(mDisplayPolicy, timeout(SHORTCUT_KEY_DELAY_MILLIS))
                .takeScreenshot(anyInt(), anyInt());
                .takeScreenshot(anyInt(), anyInt());
    }
    }


    void assertShowGlobalActionsCalled() {
    void assertShowGlobalActionsCalled() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPhoneWindowManager).showGlobalActions();
        verify(mPhoneWindowManager).showGlobalActions();
        verify(mGlobalActions, timeout(SHORTCUT_KEY_DELAY_MILLIS))
        verify(mGlobalActions, timeout(SHORTCUT_KEY_DELAY_MILLIS))
                .showDialog(anyBoolean(), anyBoolean());
                .showDialog(anyBoolean(), anyBoolean());
@@ -519,53 +514,53 @@ class TestPhoneWindowManager {
    }
    }


    void assertVolumeMute() {
    void assertVolumeMute() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mAudioManagerInternal, timeout(SHORTCUT_KEY_DELAY_MILLIS))
        verify(mAudioManagerInternal, timeout(SHORTCUT_KEY_DELAY_MILLIS))
                .silenceRingerModeInternal(eq("volume_hush"));
                .silenceRingerModeInternal(eq("volume_hush"));
    }
    }


    void assertAccessibilityKeychordCalled() {
    void assertAccessibilityKeychordCalled() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mAccessibilityShortcutController,
        verify(mAccessibilityShortcutController,
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).performAccessibilityShortcut();
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).performAccessibilityShortcut();
    }
    }


    void assertDreamRequest() {
    void assertDreamRequest() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mDreamManagerInternal).requestDream();
        verify(mDreamManagerInternal).requestDream();
    }
    }


    void assertPowerSleep() {
    void assertPowerSleep() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPowerManager,
        verify(mPowerManager,
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).goToSleep(anyLong(), anyInt(), anyInt());
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).goToSleep(anyLong(), anyInt(), anyInt());
    }
    }


    void assertPowerWakeUp() {
    void assertPowerWakeUp() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPowerManager,
        verify(mPowerManager,
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).wakeUp(anyLong(), anyInt(), anyString());
                timeout(SHORTCUT_KEY_DELAY_MILLIS)).wakeUp(anyLong(), anyInt(), anyString());
    }
    }


    void assertNoPowerSleep() {
    void assertNoPowerSleep() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPowerManager, never()).goToSleep(anyLong(), anyInt(), anyInt());
        verify(mPowerManager, never()).goToSleep(anyLong(), anyInt(), anyInt());
    }
    }


    void assertCameraLaunch() {
    void assertCameraLaunch() {
        waitForIdle();
        mTestLooper.dispatchAll();
        // GestureLauncherService should receive interceptPowerKeyDown twice.
        // GestureLauncherService should receive interceptPowerKeyDown twice.
        verify(mGestureLauncherService, times(2))
        verify(mGestureLauncherService, times(2))
                .interceptPowerKeyDown(any(), anyBoolean(), any());
                .interceptPowerKeyDown(any(), anyBoolean(), any());
    }
    }


    void assertSearchManagerLaunchAssist() {
    void assertSearchManagerLaunchAssist() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mSearchManager, timeout(SHORTCUT_KEY_DELAY_MILLIS)).launchAssist(any());
        verify(mSearchManager, timeout(SHORTCUT_KEY_DELAY_MILLIS)).launchAssist(any());
    }
    }


    void assertLaunchCategory(String category) {
    void assertLaunchCategory(String category) {
        waitForIdle();
        mTestLooper.dispatchAll();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        try {
        try {
            verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
            verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
@@ -578,17 +573,17 @@ class TestPhoneWindowManager {
    }
    }


    void assertShowRecentApps() {
    void assertShowRecentApps() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mStatusBarManagerInternal).showRecentApps(anyBoolean());
        verify(mStatusBarManagerInternal).showRecentApps(anyBoolean());
    }
    }


    void assertStatusBarStartAssist() {
    void assertStatusBarStartAssist() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mStatusBarManagerInternal).startAssist(any());
        verify(mStatusBarManagerInternal).startAssist(any());
    }
    }


    void assertSwitchKeyboardLayout(int direction) {
    void assertSwitchKeyboardLayout(int direction) {
        waitForIdle();
        mTestLooper.dispatchAll();
        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)) {
        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)) {
            verify(mInputMethodManagerInternal).switchKeyboardLayout(eq(direction));
            verify(mInputMethodManagerInternal).switchKeyboardLayout(eq(direction));
            verify(mWindowManagerFuncsImpl, never()).switchKeyboardLayout(anyInt(), anyInt());
            verify(mWindowManagerFuncsImpl, never()).switchKeyboardLayout(anyInt(), anyInt());
@@ -599,7 +594,7 @@ class TestPhoneWindowManager {
    }
    }


    void assertTakeBugreport() {
    void assertTakeBugreport() {
        waitForIdle();
        mTestLooper.dispatchAll();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).sendOrderedBroadcastAsUser(intentCaptor.capture(), any(), any(), any(),
        verify(mContext).sendOrderedBroadcastAsUser(intentCaptor.capture(), any(), any(), any(),
                any(), anyInt(), any(), any());
                any(), anyInt(), any(), any());
@@ -607,17 +602,17 @@ class TestPhoneWindowManager {
    }
    }


    void assertTogglePanel() throws RemoteException {
    void assertTogglePanel() throws RemoteException {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPhoneWindowManager.mStatusBarService).togglePanel();
        verify(mPhoneWindowManager.mStatusBarService).togglePanel();
    }
    }


    void assertToggleShortcutsMenu() {
    void assertToggleShortcutsMenu() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mStatusBarManagerInternal).toggleKeyboardShortcutsMenu(anyInt());
        verify(mStatusBarManagerInternal).toggleKeyboardShortcutsMenu(anyInt());
    }
    }


    void assertToggleCapsLock() {
    void assertToggleCapsLock() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mInputManagerInternal).toggleCapsLock(anyInt());
        verify(mInputManagerInternal).toggleCapsLock(anyInt());
    }
    }


@@ -642,12 +637,12 @@ class TestPhoneWindowManager {
    }
    }


    void assertGoToHomescreen() {
    void assertGoToHomescreen() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
        verify(mPhoneWindowManager).launchHomeFromHotKey(anyInt());
    }
    }


    void assertOpenAllAppView() {
    void assertOpenAllAppView() {
        waitForIdle();
        mTestLooper.dispatchAll();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
        verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
                .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
                .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
@@ -655,13 +650,13 @@ class TestPhoneWindowManager {
    }
    }


    void assertNotOpenAllAppView() {
    void assertNotOpenAllAppView() {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(mContext, after(TEST_SINGLE_KEY_DELAY_MILLIS).never())
        verify(mContext, after(TEST_SINGLE_KEY_DELAY_MILLIS).never())
                .startActivityAsUser(any(Intent.class), any(), any(UserHandle.class));
                .startActivityAsUser(any(Intent.class), any(), any(UserHandle.class));
    }
    }


    void assertActivityTargetLaunched(ComponentName targetActivity) {
    void assertActivityTargetLaunched(ComponentName targetActivity) {
        waitForIdle();
        mTestLooper.dispatchAll();
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
        verify(mContext, timeout(TEST_SINGLE_KEY_DELAY_MILLIS))
                .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
                .startActivityAsUser(intentCaptor.capture(), isNull(), any(UserHandle.class));
@@ -670,7 +665,7 @@ class TestPhoneWindowManager {


    void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
    void assertShortcutLogged(int vendorId, int productId, KeyboardLogEvent logEvent,
            int expectedKey, int expectedModifierState, String errorMsg) {
            int expectedKey, int expectedModifierState, String errorMsg) {
        waitForIdle();
        mTestLooper.dispatchAll();
        verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
        verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
                        vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
                        vendorId, productId, logEvent.getIntValue(), new int[]{expectedKey},
                        expectedModifierState), description(errorMsg));
                        expectedModifierState), description(errorMsg));