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

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

Merge "Relax delivery group policy constraints for resultTo bcasts." into...

Merge "Relax delivery group policy constraints for resultTo bcasts." into udc-dev am: e12e7292 am: 09ba549b am: 18fa4658

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



Change-Id: Ie568fd3e81977288767c2f4c63ed1ea40b266c7d
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 8934ba40 18fa4658
Loading
Loading
Loading
Loading
+44 −9
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO;
import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
import static com.android.server.am.BroadcastProcessQueue.reasonToString;
import static com.android.server.am.BroadcastProcessQueue.reasonToString;
import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
import static com.android.server.am.BroadcastRecord.DELIVERY_DEFERRED;
import static com.android.server.am.BroadcastRecord.deliveryStateToString;
import static com.android.server.am.BroadcastRecord.deliveryStateToString;
import static com.android.server.am.BroadcastRecord.getReceiverClassName;
import static com.android.server.am.BroadcastRecord.getReceiverClassName;
import static com.android.server.am.BroadcastRecord.getReceiverPackageName;
import static com.android.server.am.BroadcastRecord.getReceiverPackageName;
@@ -68,6 +69,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserHandle;
import android.text.format.DateUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.IndentingPrintWriter;
import android.util.MathUtils;
import android.util.MathUtils;
@@ -212,6 +214,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
    private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache =
    private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache =
            new AtomicReference<>();
            new AtomicReference<>();


    /**
     * Container for holding the set of broadcast records that satisfied a certain criteria.
     */
    @GuardedBy("mService")
    private final AtomicReference<ArrayMap<BroadcastRecord, Boolean>> mRecordsLookupCache =
            new AtomicReference<>();

    /**
    /**
     * Map from UID to its last known "foreground" state. A UID is considered to be in
     * Map from UID to its last known "foreground" state. A UID is considered to be in
     * "foreground" state when it's procState is {@link ActivityManager#PROCESS_STATE_TOP}.
     * "foreground" state when it's procState is {@link ActivityManager#PROCESS_STATE_TOP}.
@@ -742,13 +751,16 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                broadcastConsumer = mBroadcastConsumerSkipAndCanceled;
                broadcastConsumer = mBroadcastConsumerSkipAndCanceled;
                break;
                break;
            case BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED:
            case BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED:
                // TODO: Allow applying MERGED policy for broadcasts with more than one receiver.
                if (r.receivers.size() > 1) {
                    return;
                }
                final BundleMerger extrasMerger = r.options.getDeliveryGroupExtrasMerger();
                final BundleMerger extrasMerger = r.options.getDeliveryGroupExtrasMerger();
                if (extrasMerger == null) {
                if (extrasMerger == null) {
                    // Extras merger is required to be able to merge the extras. So, if it's not
                    // Extras merger is required to be able to merge the extras. So, if it's not
                    // supplied, then ignore the delivery group policy.
                    // supplied, then ignore the delivery group policy.
                    return;
                    return;
                }
                }
                // TODO: Don't merge with the same BroadcastRecord more than once.
                broadcastConsumer = (record, recordIndex) -> {
                broadcastConsumer = (record, recordIndex) -> {
                    r.intent.mergeExtras(record.intent, extrasMerger);
                    r.intent.mergeExtras(record.intent, extrasMerger);
                    mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
                    mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
@@ -758,6 +770,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                logw("Unknown delivery group policy: " + policy);
                logw("Unknown delivery group policy: " + policy);
                return;
                return;
        }
        }
        final ArrayMap<BroadcastRecord, Boolean> recordsLookupCache = getRecordsLookupCache();
        forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
        forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
            // If the receiver is already in a terminal state, then ignore it.
            // If the receiver is already in a terminal state, then ignore it.
            if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
            if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
@@ -769,22 +782,44 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                    || !r.matchesDeliveryGroup(testRecord)) {
                    || !r.matchesDeliveryGroup(testRecord)) {
                return false;
                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
            // 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
            // of those for the previous one as skipping and removing only one of them could result
            // in an inconsistent state.
            // in an inconsistent state.
            if (testRecord.ordered || testRecord.resultTo != null) {
            if (testRecord.ordered || testRecord.prioritized) {
                // TODO: Cache this result in some way so that we don't have to perform the
                return containsAllReceivers(r, testRecord, recordsLookupCache);
                // same check for all the broadcast receivers.
            } else if (testRecord.resultTo != null) {
                return r.containsAllReceivers(testRecord.receivers);
                return testRecord.getDeliveryState(testIndex) == DELIVERY_DEFERRED
            } else if (testRecord.prioritized) {
                        ? r.containsReceiver(testRecord.receivers.get(testIndex))
                return r.containsAllReceivers(testRecord.receivers);
                        : containsAllReceivers(r, testRecord, recordsLookupCache);
            } else {
            } else {
                return r.containsReceiver(testRecord.receivers.get(testIndex));
                return r.containsReceiver(testRecord.receivers.get(testIndex));
            }
            }
        }, broadcastConsumer, true);
        }, broadcastConsumer, true);
        recordsLookupCache.clear();
        mRecordsLookupCache.compareAndSet(null, recordsLookupCache);
    }

    @NonNull
    private ArrayMap<BroadcastRecord, Boolean> getRecordsLookupCache() {
        ArrayMap<BroadcastRecord, Boolean> recordsLookupCache =
                mRecordsLookupCache.getAndSet(null);
        if (recordsLookupCache == null) {
            recordsLookupCache = new ArrayMap<>();
        }
        return recordsLookupCache;
    }

    private boolean containsAllReceivers(@NonNull BroadcastRecord record,
            @NonNull BroadcastRecord testRecord,
            @NonNull ArrayMap<BroadcastRecord, Boolean> recordsLookupCache) {
        final int idx = recordsLookupCache.indexOfKey(testRecord);
        if (idx > 0) {
            return recordsLookupCache.valueAt(idx);
        }
        final boolean containsAll = record.containsAllReceivers(testRecord.receivers);
        recordsLookupCache.put(testRecord, containsAll);
        return containsAll;
    }
    }


    /**
    /**
+41 −0
Original line number Original line Diff line number Diff line
@@ -1094,6 +1094,17 @@ public final class BroadcastQueueModernImplTest {
        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(redQueue, List.of(screenOff));
        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));

        final BroadcastRecord screenOffRecord = makeBroadcastRecord(screenOff, screenOnOffOptions,
                List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false);
        screenOffRecord.setDeliveryState(2, BroadcastRecord.DELIVERY_DEFERRED,
                "testDeliveryGroupPolicy_resultTo_diffReceivers");
        mImpl.enqueueBroadcastLocked(screenOffRecord);
        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(screenOn));
    }
    }


    @Test
    @Test
@@ -1278,6 +1289,36 @@ public final class BroadcastQueueModernImplTest {
                dropboxEntryBroadcast2.first, expectedMergedBroadcast.first));
                dropboxEntryBroadcast2.first, expectedMergedBroadcast.first));
    }
    }


    @Test
    public void testDeliveryGroupPolicy_merged_multipleReceivers() {
        final long now = SystemClock.elapsedRealtime();
        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast1 = createDropboxBroadcast(
                "TAG_A", now, 2);
        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast2 = createDropboxBroadcast(
                "TAG_A", now + 1000, 4);

        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast1.first,
                dropboxEntryBroadcast1.second,
                List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
                        makeManifestReceiver(PACKAGE_RED, CLASS_RED)),
                false));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast2.first,
                dropboxEntryBroadcast2.second,
                List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
                        makeManifestReceiver(PACKAGE_RED, CLASS_RED)),
                false));

        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED));

        verifyPendingRecords(greenQueue,
                List.of(dropboxEntryBroadcast1.first, dropboxEntryBroadcast2.first));
        verifyPendingRecords(redQueue,
                List.of(dropboxEntryBroadcast1.first, dropboxEntryBroadcast2.first));
    }

    @Test
    @Test
    public void testDeliveryGroupPolicy_sameAction_differentMatchingCriteria() {
    public void testDeliveryGroupPolicy_sameAction_differentMatchingCriteria() {
        final Intent closeSystemDialogs1 = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        final Intent closeSystemDialogs1 = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);