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

Commit ab4d18aa 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

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



Change-Id: Icd01a44bd63b7002777c7cc198f777fd14c29961
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents dd8c0d63 8bfe37af
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.
     */