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

Commit c90cc43e authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Automerger Merge Worker
Browse files

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

parents 6a5cb92d f2382cf7
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.