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

Commit f2382cf7 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Use TestLooperManager to improve test robustness." into udc-dev

parents 8accc35a a83a690a
Loading
Loading
Loading
Loading
+22 −27
Original line number Diff line number Diff line
@@ -74,16 +74,17 @@ import android.os.BundleMerger;
import android.os.DropBoxManager;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.os.TestLooperManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.IndentingPrintWriter;
import android.util.Pair;

import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ExtendedMockitoRule;
import com.android.server.am.BroadcastQueueTest.SyncBarrier;

import org.junit.After;
import org.junit.Before;
@@ -96,6 +97,7 @@ import java.io.Writer;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@SmallTest
public final class BroadcastQueueModernImplTest {
@@ -111,6 +113,7 @@ public final class BroadcastQueueModernImplTest {
    @Mock BroadcastProcessQueue mQueue4;

    HandlerThread mHandlerThread;
    TestLooperManager mLooper;

    BroadcastConstants mConstants;
    BroadcastQueueModernImpl mImpl;
@@ -127,6 +130,10 @@ public final class BroadcastQueueModernImplTest {
        mHandlerThread = new HandlerThread(getClass().getSimpleName());
        mHandlerThread.start();

        // Pause all event processing until a test chooses to resume
        mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation()
                .acquireLooperManager(mHandlerThread.getLooper()));

        mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
        mConstants.DELAY_URGENT_MILLIS = -120_000;
        mConstants.DELAY_NORMAL_MILLIS = 10_000;
@@ -167,6 +174,17 @@ public final class BroadcastQueueModernImplTest {
        mHandlerThread.quit();
    }

    /**
     * Un-pause our handler to process pending events, wait for our queue to go
     * idle, and then re-pause the handler.
     */
    private void waitForIdle() throws Exception {
        mLooper.release();
        mImpl.waitForIdle(LOG_WRITER_INFO);
        mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation()
                .acquireLooperManager(mHandlerThread.getLooper()));
    }

    private static void assertOrphan(BroadcastProcessQueue queue) {
        assertNull(queue.runnableAtNext);
        assertNull(queue.runnableAtPrev);
@@ -836,9 +854,6 @@ public final class BroadcastQueueModernImplTest {
        optionsAlarmVolumeChanged.setDeliveryGroupMatchingKey("audio",
                String.valueOf(AudioManager.STREAM_ALARM));

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
                optionsMusicVolumeChanged));
@@ -905,9 +920,6 @@ public final class BroadcastQueueModernImplTest {
                String.valueOf(TEST_UID2));
        optionsPackageChangedForUid.setDeliveryGroupExtrasMerger(extrasMerger);

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(packageChangedForUid,
                optionsPackageChangedForUid));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(packageChangedForUid2,
@@ -955,9 +967,6 @@ public final class BroadcastQueueModernImplTest {
                BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);
        optionsAlarmVolumeChanged.setDeliveryGroupMatchingFilter(filterAlarmVolumeChanged);

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(musicVolumeChanged,
                optionsMusicVolumeChanged));
@@ -1004,9 +1013,6 @@ public final class BroadcastQueueModernImplTest {
        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast3 = createDropboxBroadcast(
                "TAG_A", now + 2000, 7);

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast1.first,
                dropboxEntryBroadcast1.second));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast2.first,
@@ -1036,9 +1042,6 @@ public final class BroadcastQueueModernImplTest {
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                .setDeliveryGroupMatchingKey(Intent.ACTION_CLOSE_SYSTEM_DIALOGS, "testing");

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
                closeSystemDialogs1, optionsCloseSystemDialog1));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(
@@ -1088,9 +1091,6 @@ public final class BroadcastQueueModernImplTest {
        final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
        userPresent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();

        final BroadcastRecord userPresentRecord1 = makeBroadcastRecord(userPresent);
        final BroadcastRecord userPresentRecord2 = makeBroadcastRecord(userPresent);

@@ -1129,8 +1129,6 @@ public final class BroadcastQueueModernImplTest {
                makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)
        ));

        // Halt all processing so that we get a consistent view
        mHandlerThread.getLooper().getQueue().postSyncBarrier();
        mImpl.enqueueBroadcastLocked(record1);
        mImpl.enqueueBroadcastLocked(record2);

@@ -1152,12 +1150,9 @@ public final class BroadcastQueueModernImplTest {
        final BroadcastOptions optionsTimeTick = BroadcastOptions.makeBasic();
        optionsTimeTick.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT);

        // Halt all processing so that we get a consistent view
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(timeTick, optionsTimeTick));
        }
        mImpl.waitForIdle(LOG_WRITER_INFO);
        waitForIdle();

        // Verify that there is only one delivery event reported since one of the broadcasts
        // should have been skipped.
+108 −129
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.PowerExemptionManager;
import android.os.SystemClock;
import android.os.TestLooperManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -146,6 +147,7 @@ public class BroadcastQueueTest {

    private Context mContext;
    private HandlerThread mHandlerThread;
    private TestLooperManager mLooper;
    private AtomicInteger mNextPid;

    @Mock
@@ -206,6 +208,11 @@ public class BroadcastQueueTest {

        mHandlerThread = new HandlerThread(TAG);
        mHandlerThread.start();

        // Pause all event processing until a test chooses to resume
        mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation()
                .acquireLooperManager(mHandlerThread.getLooper()));

        mNextPid = new AtomicInteger(100);

        LocalServices.removeServiceForTest(DropBoxManagerInternal.class);
@@ -360,25 +367,6 @@ public class BroadcastQueueTest {
        }
    }

    /**
     * Helper that leverages try-with-resources to pause dispatch of
     * {@link #mHandlerThread} until released.
     */
    static class SyncBarrier implements AutoCloseable {
        private final int mToken;
        private HandlerThread mThread;

        SyncBarrier(HandlerThread thread) {
            mThread = thread;
            mToken = mThread.getLooper().getQueue().postSyncBarrier();
        }

        @Override
        public void close() throws Exception {
            mThread.getLooper().getQueue().removeSyncBarrier(mToken);
        }
    }

    private enum ProcessStartBehavior {
        /** Process starts successfully */
        SUCCESS,
@@ -671,8 +659,15 @@ public class BroadcastQueueTest {
        }
    }

    /**
     * Un-pause our handler to process pending events, wait for our queue to go
     * idle, and then re-pause the handler.
     */
    private void waitForIdle() throws Exception {
        mLooper.release();
        mQueue.waitForIdle(LOG_WRITER_INFO);
        mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation()
                .acquireLooperManager(mHandlerThread.getLooper()));
    }

    private void verifyScheduleReceiver(ProcessRecord app, Intent intent) throws Exception {
@@ -1156,7 +1151,6 @@ public class BroadcastQueueTest {
        final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN);

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, new ArrayList<>(
                List.of(makeRegisteredReceiver(receiverApp),
                        makeManifestReceiver(PACKAGE_GREEN, CLASS_RED),
@@ -1172,7 +1166,6 @@ public class BroadcastQueueTest {
            mQueue.cleanupDisabledPackageReceiversLocked(PACKAGE_RED, null,
                    UserHandle.USER_SYSTEM);
            mQueue.cleanupDisabledPackageReceiversLocked(null, null, USER_GUEST);
            }

            // To maximize test coverage, dump current state; we're not worried
            // about the actual output, just that we don't crash
@@ -1200,7 +1193,6 @@ public class BroadcastQueueTest {

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        final Intent timeZone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, USER_GUEST, new ArrayList<>(
                List.of(makeRegisteredReceiver(callerApp),
                        makeManifestReceiver(PACKAGE_GREEN, CLASS_RED, USER_GUEST),
@@ -1215,7 +1207,6 @@ public class BroadcastQueueTest {
        synchronized (mAms) {
            mQueue.cleanupDisabledPackageReceiversLocked(null, null, USER_GUEST);
        }
        }

        waitForIdle();
        // Legacy stack does not remove registered receivers as part of
@@ -1240,16 +1231,13 @@ public class BroadcastQueueTest {
        final ProcessRecord oldApp = makeActiveProcessRecord(PACKAGE_GREEN);

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, new ArrayList<>(
                List.of(makeRegisteredReceiver(oldApp),
                        makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)))));

        synchronized (mAms) {
            oldApp.killLocked(TAG, 42, false);
            mQueue.onApplicationCleanupLocked(oldApp);
        }
        }
        waitForIdle();

        // Confirm that we cold-started after the kill
@@ -1621,7 +1609,6 @@ public class BroadcastQueueTest {
        final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                List.of(makeRegisteredReceiver(receiverBlueApp, 10),
                        makeRegisteredReceiver(receiverGreenApp, 10),
@@ -1630,8 +1617,6 @@ public class BroadcastQueueTest {
                        makeRegisteredReceiver(receiverYellowApp, -10))));
        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp,
                List.of(makeRegisteredReceiver(receiverBlueApp))));
        }

        waitForIdle();

        // Ignore the final foreground broadcast
@@ -1745,7 +1730,6 @@ public class BroadcastQueueTest {
        final IIntentReceiver resultToFirst = mock(IIntentReceiver.class);
        final IIntentReceiver resultToSecond = mock(IIntentReceiver.class);

        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeOrderedBroadcastRecord(timezoneFirst, callerApp,
                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE),
                        makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)),
@@ -1755,7 +1739,6 @@ public class BroadcastQueueTest {
        enqueueBroadcast(makeOrderedBroadcastRecord(timezoneSecond, callerApp,
                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)),
                resultToSecond, null));
        }

        waitForIdle();
        final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE,
@@ -1836,14 +1819,12 @@ public class BroadcastQueueTest {
        timeTickFirst.putExtra(Intent.EXTRA_INDEX, "third");
        timeTickThird.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        enqueueBroadcast(makeBroadcastRecord(timeTickFirst, callerApp,
                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
        enqueueBroadcast(makeBroadcastRecord(timeTickSecond, callerApp,
                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
        enqueueBroadcast(makeBroadcastRecord(timeTickThird, callerApp,
                List.of(makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE))));
        }

        waitForIdle();
        final IApplicationThread blueThread = mAms.getProcessRecordLocked(PACKAGE_BLUE,
@@ -1878,7 +1859,6 @@ public class BroadcastQueueTest {
        assertTrue(mQueue.isIdleLocked());
        assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst));

        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
                List.of(makeRegisteredReceiver(receiverApp))));
@@ -1897,7 +1877,8 @@ public class BroadcastQueueTest {
        assertTrue(mQueue.isBeyondBarrierLocked(beforeFirst));
        assertFalse(mQueue.isBeyondBarrierLocked(afterFirst));
        assertFalse(mQueue.isBeyondBarrierLocked(afterSecond));
        }

        mLooper.release();

        mQueue.waitForBarrier(LOG_WRITER_INFO);
        assertTrue(mQueue.isBeyondBarrierLocked(afterFirst));
@@ -2048,7 +2029,6 @@ public class BroadcastQueueTest {
        final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        try (SyncBarrier b = new SyncBarrier(mHandlerThread)) {
        final Object greenReceiver = makeRegisteredReceiver(receiverGreenApp);
        final Object blueReceiver = makeRegisteredReceiver(receiverBlueApp);
        final Object yellowReceiver = makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW);
@@ -2066,7 +2046,6 @@ public class BroadcastQueueTest {
            }
            return null;
        }).when(mSkipPolicy).shouldSkipMessage(any(BroadcastRecord.class), any());
        }

        waitForIdle();
        // Verify that only blue and yellow receiver apps received the broadcast.