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

Commit 81c9e17a 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: 7d2b33d4

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



Change-Id: I157d0eae3ceb2f93e8910b7a09e6e6e6eff8925d
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 2d5afb38 7d2b33d4
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.
     */