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

Commit b5be9150 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Automerger Merge Worker
Browse files

Merge "Apply delivery policies only to receivers that receive the new bcast."...

Merge "Apply delivery policies only to receivers that receive the new bcast." into udc-dev am: 8bfe37af am: ab4d18aa

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23391644



Change-Id: Idc3a71ca573d1338032f72d9790893513a78d75c
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents f530c32f ab4d18aa
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -720,6 +720,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                    // supplied, then ignore the delivery group policy.
                    return;
                }
                // TODO: Don't merge with the same BroadcastRecord more than once.
                broadcastConsumer = (record, recordIndex) -> {
                    r.intent.mergeExtras(record.intent, extrasMerger);
                    mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
@@ -730,10 +731,31 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                return;
        }
        forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
            // If the receiver is already in a terminal state, then ignore it.
            if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
                return false;
            }
            // We only allow caller to remove broadcasts they enqueued
            return (r.callingUid == testRecord.callingUid)
                    && (r.userId == testRecord.userId)
                    && r.matchesDeliveryGroup(testRecord);
            if ((r.callingUid != testRecord.callingUid)
                    || (r.userId != testRecord.userId)
                    || !r.matchesDeliveryGroup(testRecord)) {
                return false;
            }
            // TODO: If a process is in a deferred state, we can always apply the policy as long
            // as it is one of the receivers for the new broadcast.

            // For ordered broadcast, check if the receivers for the new broadcast is a superset
            // of those for the previous one as skipping and removing only one of them could result
            // in an inconsistent state.
            if (testRecord.ordered || testRecord.resultTo != null) {
                // TODO: Cache this result in some way so that we don't have to perform the
                // same check for all the broadcast receivers.
                return r.containsAllReceivers(testRecord.receivers);
            } else if (testRecord.prioritized) {
                return r.containsAllReceivers(testRecord.receivers);
            } else {
                return r.containsReceiver(testRecord.receivers.get(testIndex));
            }
        }, broadcastConsumer, true);
    }

+18 −0
Original line number Diff line number Diff line
@@ -1092,6 +1092,24 @@ final class BroadcastRecord extends Binder {
        }
    }

    boolean containsReceiver(@NonNull Object receiver) {
        for (int i = receivers.size() - 1; i >= 0; --i) {
            if (isReceiverEquals(receiver, receivers.get(i))) {
                return true;
            }
        }
        return false;
    }

    boolean containsAllReceivers(@NonNull List<Object> otherReceivers) {
        for (int i = otherReceivers.size() - 1; i >= 0; --i) {
            if (!containsReceiver(otherReceivers.get(i))) {
                return false;
            }
        }
        return true;
    }

    boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
        return matchesDeliveryGroup(this, other);
    }
+160 −0
Original line number Diff line number Diff line
@@ -976,6 +976,166 @@ public final class BroadcastQueueModernImplTest {
                List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
    }

    @Test
    public void testDeliveryGroupPolicy_diffReceivers() {
        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);

        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), false));
        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED));
        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
                getUidForPackage(PACKAGE_BLUE));
        verifyPendingRecords(greenQueue, List.of(screenOff));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff));

        assertTrue(greenQueue.isEmpty());
        assertTrue(redQueue.isEmpty());
        assertTrue(blueQueue.isEmpty());

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), false));
        verifyPendingRecords(greenQueue, List.of(screenOn));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOn));
    }

    @Test
    public void testDeliveryGroupPolicy_ordered_diffReceivers() {
        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);

        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), true));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), true));
        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED));
        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
                getUidForPackage(PACKAGE_BLUE));
        verifyPendingRecords(greenQueue, List.of(screenOff));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff));

        assertTrue(greenQueue.isEmpty());
        assertTrue(redQueue.isEmpty());
        assertTrue(blueQueue.isEmpty());

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), true));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), true));
        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
    }

    @Test
    public void testDeliveryGroupPolicy_resultTo_diffReceivers() {
        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);

        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
        final IIntentReceiver resultTo = mock(IIntentReceiver.class);

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), resultTo, false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED));
        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
                getUidForPackage(PACKAGE_BLUE));
        verifyPendingRecords(greenQueue, List.of(screenOff));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff));

        assertTrue(greenQueue.isEmpty());
        assertTrue(redQueue.isEmpty());
        assertTrue(blueQueue.isEmpty());

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), resultTo, false));
        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
    }

    @Test
    public void testDeliveryGroupPolicy_prioritized_diffReceivers() {
        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);

        final Object greenReceiver = withPriority(
                makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
        final Object redReceiver = withPriority(
                makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
        final Object blueReceiver = withPriority(
                makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), false));
        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED));
        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
                getUidForPackage(PACKAGE_BLUE));
        verifyPendingRecords(greenQueue, List.of(screenOff));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff));

        assertTrue(greenQueue.isEmpty());
        assertTrue(redQueue.isEmpty());
        assertTrue(blueQueue.isEmpty());

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
                List.of(greenReceiver, blueReceiver), false));
        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
    }

    /**
     * Verify that sending a broadcast with DELIVERY_GROUP_POLICY_MERGED works as expected.
     */