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

Commit 6dceace0 authored by Jason Monk's avatar Jason Monk
Browse files

Reduce usages of main looper in sysui tests

Push over to a standard testable looper, and a testable looper +
setAsMain when needed.

Also make tests more synchronous and single threaded as possible.
This will make them more deterministic and speeds them up noticeably.

Test: runtest systemui
Bug: 79550837
Change-Id: Iab0eb794329d7b1de95aef904ec08ecae7dadc98
parent 1e352f4c
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -137,9 +137,15 @@ public class NotificationInflater {
            return;
        }
        StatusBarNotification sbn = mRow.getEntry().notification;
        new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority,
        AsyncInflationTask task = new AsyncInflationTask(sbn, reInflateFlags, mRow,
                mIsLowPriority,
                mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
                mCallback, mRemoteViewClickHandler).execute();
                mCallback, mRemoteViewClickHandler);
        if (mCallback != null && mCallback.doInflateSynchronous()) {
            task.onPostExecute(task.doInBackground());
        } else {
            task.execute();
        }
    }

    @VisibleForTesting
@@ -331,6 +337,30 @@ public class NotificationInflater {
            final HashMap<Integer, CancellationSignal> runningInflations,
            ApplyCallback applyCallback) {
        RemoteViews newContentView = applyCallback.getRemoteView();
        if (callback != null && callback.doInflateSynchronous()) {
            try {
                if (isNewView) {
                    View v = newContentView.apply(
                            result.packageContext,
                            parentLayout,
                            remoteViewClickHandler);
                    v.setIsRootNamespace(true);
                    applyCallback.setResultView(v);
                } else {
                    newContentView.reapply(
                            result.packageContext,
                            existingView,
                            remoteViewClickHandler);
                    existingWrapper.onReinflated();
                }
            } catch (Exception e) {
                handleInflationError(runningInflations, e, entry.notification, callback);
                // Add a running inflation to make sure we don't trigger callbacks.
                // Safe to do because only happens in tests.
                runningInflations.put(inflationId, new CancellationSignal());
            }
            return;
        }
        RemoteViews.OnViewAppliedListener listener
                = new RemoteViews.OnViewAppliedListener() {

@@ -515,6 +545,13 @@ public class NotificationInflater {
    public interface InflationCallback {
        void handleInflationException(StatusBarNotification notification, Exception e);
        void onAsyncInflationFinished(NotificationData.Entry entry);

        /**
         * Used to disable async-ness for tests. Should only be used for tests.
         */
        default boolean doInflateSynchronous() {
            return false;
        }
    }

    public void onDensityOrFontScaleChanged() {
@@ -646,6 +683,11 @@ public class NotificationInflater {
            mRow.onNotificationUpdated();
            mCallback.onAsyncInflationFinished(mRow.getEntry());
        }

        @Override
        public boolean doInflateSynchronous() {
            return mCallback != null && mCallback.doInflateSynchronous();
        }
    }

    @VisibleForTesting
+8 −17
Original line number Diff line number Diff line
@@ -20,10 +20,9 @@ import static junit.framework.Assert.assertEquals;

import static org.mockito.Mockito.mock;

import android.os.Handler;
import android.os.Looper;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;

import com.android.systemui.SysuiTestCase;

@@ -32,33 +31,25 @@ import org.junit.Test;
import org.junit.runner.RunWith;

@SmallTest
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class KeyguardMessageAreaTest extends SysuiTestCase {
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private KeyguardMessageArea mMessageArea;

    @Before
    public void setUp() throws Exception {
        KeyguardUpdateMonitor monitor = mock(KeyguardUpdateMonitor.class);
        mHandler.post(()-> mMessageArea = new KeyguardMessageArea(mContext, null, monitor));
        mMessageArea = new KeyguardMessageArea(mContext, null, monitor);
        waitForIdleSync();
    }

    @Test
    public void clearFollowedByMessage_keepsMessage() {
        mHandler.post(()-> {
        mMessageArea.setMessage("");
        mMessageArea.setMessage("test");
        });

        waitForIdleSync();

        CharSequence[] messageText = new CharSequence[1];
        mHandler.post(()-> {
        messageText[0] = mMessageArea.getText();
        });

        waitForIdleSync();

        assertEquals("test", messageText[0]);
    }
+5 −4
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;

import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationTestHelper;
@@ -35,7 +37,8 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@SmallTest
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
public class ExpandHelperTest extends SysuiTestCase {

    private ExpandableNotificationRow mRow;
@@ -47,9 +50,7 @@ public class ExpandHelperTest extends SysuiTestCase {
        Context context = getContext();
        mRow = new NotificationTestHelper(context).createRow();
        mCallback = mock(ExpandHelper.Callback.class);
        InstrumentationRegistry.getInstrumentation().runOnMainSync(
                () -> mExpandHelper = new ExpandHelper(context, mCallback, 10, 100));

        mExpandHelper = new ExpandHelper(context, mCallback, 10, 100);
    }

    @Test
+12 −22
Original line number Diff line number Diff line
@@ -29,7 +29,8 @@ import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;

import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.systemui.SysuiTestCase;
@@ -46,7 +47,8 @@ import org.junit.runner.RunWith;

@SmallTest
@Ignore("failing")
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
public class DozeTriggersTest extends SysuiTestCase {
    private DozeTriggers mTriggers;
    private DozeMachine mMachine;
@@ -54,7 +56,6 @@ public class DozeTriggersTest extends SysuiTestCase {
    private AmbientDisplayConfiguration mConfig;
    private DozeParameters mParameters;
    private FakeSensorManager mSensors;
    private Handler mHandler;
    private WakeLock mWakeLock;
    private Instrumentation mInstrumentation;
    private AlarmManager mAlarmManager;
@@ -74,40 +75,29 @@ public class DozeTriggersTest extends SysuiTestCase {
        mConfig = DozeConfigurationUtil.createMockConfig();
        mParameters = DozeConfigurationUtil.createMockParameters();
        mSensors = new FakeSensorManager(mContext);
        mHandler = new Handler(Looper.getMainLooper());
        mWakeLock = new WakeLockFake();

        mInstrumentation.runOnMainSync(() -> {
            mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager,
                    mConfig, mParameters, mSensors, mHandler, mWakeLock, true);
        });
        mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, mConfig, mParameters,
                mSensors, Handler.createAsync(Looper.myLooper()), mWakeLock, true);
    }

    @Test
    public void testOnNotification_stillWorksAfterOneFailedProxCheck() throws Exception {
        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);

        mInstrumentation.runOnMainSync(()->{
        mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
        mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);

        mHost.callback.onNotificationHeadsUp();
        });

        mInstrumentation.runOnMainSync(() -> {
        mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
        });

        verify(mMachine, never()).requestState(any());
        verify(mMachine, never()).requestPulse(anyInt());

        mInstrumentation.runOnMainSync(()->{
        mHost.callback.onNotificationHeadsUp();
        });

        mInstrumentation.runOnMainSync(() -> {
        mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
        });

        verify(mMachine).requestPulse(anyInt());
    }
+10 −14
Original line number Diff line number Diff line
@@ -24,43 +24,36 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.pip.phone.PipTouchState;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@RunWith(AndroidJUnit4.class)
@RunWith(AndroidTestingRunner.class)
@SmallTest
@RunWithLooper
public class PipTouchStateTest extends SysuiTestCase {

    private Handler mHandler;
    private HandlerThread mHandlerThread;
    private PipTouchState mTouchState;
    private CountDownLatch mDoubleTapCallbackTriggeredLatch;

    @Before
    public void setUp() throws Exception {
        mHandlerThread = new HandlerThread("PipTouchStateTestThread");
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());

        mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
        mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
                mHandler, () -> {
                Handler.createAsync(Looper.myLooper()), () -> {
            mDoubleTapCallbackTriggeredLatch.countDown();
        });
        assertFalse(mTouchState.isDoubleTap());
@@ -91,7 +84,10 @@ public class PipTouchStateTest extends SysuiTestCase {

        assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == 10);
        mTouchState.scheduleDoubleTapTimeoutCallback();
        mDoubleTapCallbackTriggeredLatch.await(1, TimeUnit.SECONDS);

        // TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
        Thread.sleep(15);
        TestableLooper.get(this).processAllMessages();
        assertTrue(mDoubleTapCallbackTriggeredLatch.getCount() == 0);
    }

Loading