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

Commit 32040c16 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Apply delivery group policies to ACTION_DROPBOX_ENTRY_ADDED."

parents a2756b7c 98f06c98
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -85,37 +85,43 @@ public class BundleMerger implements Parcelable {
    /**
     * Merge strategy that numerically adds both conflicting values.
     */
    public static final int STRATEGY_NUMBER_ADD = 5;
    public static final int STRATEGY_NUMBER_ADD = 10;

    /**
     * Merge strategy that numerically increments the first conflicting value by
     * {@code 1} and ignores the last conflicting value.
     */
    public static final int STRATEGY_NUMBER_INCREMENT_FIRST = 6;
    public static final int STRATEGY_NUMBER_INCREMENT_FIRST = 20;

    /**
     * Merge strategy that numerically increments the first conflicting value by
     * {@code 1} and also numerically adds both conflicting values.
     */
    public static final int STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD = 25;

    /**
     * Merge strategy that combines conflicting values using a boolean "and"
     * operation.
     */
    public static final int STRATEGY_BOOLEAN_AND = 7;
    public static final int STRATEGY_BOOLEAN_AND = 30;

    /**
     * Merge strategy that combines conflicting values using a boolean "or"
     * operation.
     */
    public static final int STRATEGY_BOOLEAN_OR = 8;
    public static final int STRATEGY_BOOLEAN_OR = 40;

    /**
     * Merge strategy that combines two conflicting array values by appending
     * the last array after the first array.
     */
    public static final int STRATEGY_ARRAY_APPEND = 9;
    public static final int STRATEGY_ARRAY_APPEND = 50;

    /**
     * Merge strategy that combines two conflicting {@link ArrayList} values by
     * appending the last {@link ArrayList} after the first {@link ArrayList}.
     */
    public static final int STRATEGY_ARRAY_LIST_APPEND = 10;
    public static final int STRATEGY_ARRAY_LIST_APPEND = 60;

    @IntDef(flag = false, prefix = { "STRATEGY_" }, value = {
            STRATEGY_REJECT,
@@ -125,6 +131,7 @@ public class BundleMerger implements Parcelable {
            STRATEGY_COMPARABLE_MAX,
            STRATEGY_NUMBER_ADD,
            STRATEGY_NUMBER_INCREMENT_FIRST,
            STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD,
            STRATEGY_BOOLEAN_AND,
            STRATEGY_BOOLEAN_OR,
            STRATEGY_ARRAY_APPEND,
@@ -282,6 +289,8 @@ public class BundleMerger implements Parcelable {
                return numberAdd(first, last);
            case STRATEGY_NUMBER_INCREMENT_FIRST:
                return numberIncrementFirst(first, last);
            case STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD:
                return numberAdd(numberIncrementFirst(first, last), last);
            case STRATEGY_BOOLEAN_AND:
                return booleanAnd(first, last);
            case STRATEGY_BOOLEAN_OR:
+43 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.os.BundleMerger.STRATEGY_FIRST;
import static android.os.BundleMerger.STRATEGY_LAST;
import static android.os.BundleMerger.STRATEGY_NUMBER_ADD;
import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST;
import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD;
import static android.os.BundleMerger.STRATEGY_REJECT;
import static android.os.BundleMerger.merge;

@@ -150,6 +151,14 @@ public class BundleMergerTest {
        assertEquals(21L, merge(STRATEGY_NUMBER_INCREMENT_FIRST, 20L, 10L));
    }

    @Test
    public void testStrategyNumberIncrementFirstAndAdd() throws Exception {
        assertEquals(31, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 10, 20));
        assertEquals(31, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 20, 10));
        assertEquals(31L, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 10L, 20L));
        assertEquals(31L, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 20L, 10L));
    }

    @Test
    public void testStrategyBooleanAnd() throws Exception {
        assertEquals(false, merge(STRATEGY_BOOLEAN_AND, false, false));
@@ -214,6 +223,29 @@ public class BundleMergerTest {
        });
    }

    @Test
    public void testSetDefaultMergeStrategy() throws Exception {
        final BundleMerger merger = new BundleMerger();
        merger.setDefaultMergeStrategy(STRATEGY_FIRST);
        merger.setMergeStrategy(Intent.EXTRA_INDEX, STRATEGY_COMPARABLE_MAX);

        Bundle a = new Bundle();
        a.putString(Intent.EXTRA_SUBJECT, "SubjectA");
        a.putInt(Intent.EXTRA_INDEX, 10);

        Bundle b = new Bundle();
        b.putString(Intent.EXTRA_SUBJECT, "SubjectB");
        b.putInt(Intent.EXTRA_INDEX, 20);

        Bundle ab = merger.merge(a, b);
        assertEquals("SubjectA", ab.getString(Intent.EXTRA_SUBJECT));
        assertEquals(20, ab.getInt(Intent.EXTRA_INDEX));

        Bundle ba = merger.merge(b, a);
        assertEquals("SubjectB", ba.getString(Intent.EXTRA_SUBJECT));
        assertEquals(20, ba.getInt(Intent.EXTRA_INDEX));
    }

    @Test
    public void testMerge_Simple() throws Exception {
        final BundleMerger merger = new BundleMerger();
@@ -323,7 +355,7 @@ public class BundleMergerTest {
        merger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
                STRATEGY_COMPARABLE_MAX);
        merger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
                STRATEGY_NUMBER_INCREMENT_FIRST);
                STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);

        final long now = System.currentTimeMillis();
        final Bundle a = new Bundle();
@@ -341,6 +373,11 @@ public class BundleMergerTest {
        c.putLong(DropBoxManager.EXTRA_TIME, now + 2000);
        c.putInt(DropBoxManager.EXTRA_DROPPED_COUNT, 0);

        final Bundle d = new Bundle();
        d.putString(DropBoxManager.EXTRA_TAG, "system_server_strictmode");
        d.putLong(DropBoxManager.EXTRA_TIME, now + 3000);
        d.putInt(DropBoxManager.EXTRA_DROPPED_COUNT, 5);

        final Bundle ab = merger.merge(a, b);
        assertEquals("system_server_strictmode", ab.getString(DropBoxManager.EXTRA_TAG));
        assertEquals(now + 1000, ab.getLong(DropBoxManager.EXTRA_TIME));
@@ -350,6 +387,11 @@ public class BundleMergerTest {
        assertEquals("system_server_strictmode", abc.getString(DropBoxManager.EXTRA_TAG));
        assertEquals(now + 2000, abc.getLong(DropBoxManager.EXTRA_TIME));
        assertEquals(2, abc.getInt(DropBoxManager.EXTRA_DROPPED_COUNT));

        final Bundle abcd = merger.merge(abc, d);
        assertEquals("system_server_strictmode", abcd.getString(DropBoxManager.EXTRA_TAG));
        assertEquals(now + 3000, abcd.getLong(DropBoxManager.EXTRA_TIME));
        assertEquals(8, abcd.getInt(DropBoxManager.EXTRA_DROPPED_COUNT));
    }

    private static ArrayList<Object> arrayListOf(Object... values) {
+30 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -29,6 +30,8 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.BundleMerger;
import android.os.Debug;
import android.os.DropBoxManager;
import android.os.FileUtils;
@@ -264,7 +267,7 @@ public final class DropBoxManagerService extends SystemService {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SEND_BROADCAST:
                    prepareAndSendBroadcast((Intent) msg.obj);
                    prepareAndSendBroadcast((Intent) msg.obj, null);
                    break;
                case MSG_SEND_DEFERRED_BROADCAST:
                    Intent deferredIntent;
@@ -272,27 +275,50 @@ public final class DropBoxManagerService extends SystemService {
                        deferredIntent = mDeferredMap.remove((String) msg.obj);
                    }
                    if (deferredIntent != null) {
                        prepareAndSendBroadcast(deferredIntent);
                        prepareAndSendBroadcast(deferredIntent,
                                createBroadcastOptions(deferredIntent));
                    }
                    break;
            }
        }

        private void prepareAndSendBroadcast(Intent intent) {
        private void prepareAndSendBroadcast(Intent intent, Bundle options) {
            if (!DropBoxManagerService.this.mBooted) {
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            }
            getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                    android.Manifest.permission.READ_LOGS);
                    android.Manifest.permission.READ_LOGS, options);
        }

        private Intent createIntent(String tag, long time) {
            final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
            dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
            dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
            dropboxIntent.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, 0);
            return dropboxIntent;
        }

        private Bundle createBroadcastOptions(Intent intent) {
            final BundleMerger extrasMerger = new BundleMerger();
            extrasMerger.setDefaultMergeStrategy(BundleMerger.STRATEGY_FIRST);
            extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
                    BundleMerger.STRATEGY_COMPARABLE_MAX);
            extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
                    BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);

            final String tag = intent.getStringExtra(DropBoxManager.EXTRA_TAG);
            final IntentFilter matchingFilter = new IntentFilter(
                    DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
            matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);

            return BroadcastOptions.makeBasic()
                    .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
                    .setDeliveryGroupMatchingFilter(matchingFilter)
                    .setDeliveryGroupExtrasMerger(extrasMerger)
                    .setDeferUntilActive(true)
                    .toBundle();
        }

        /**
         * Schedule a dropbox broadcast to be sent asynchronously.
         */
+55 −0
Original line number Diff line number Diff line
@@ -60,11 +60,13 @@ import android.content.pm.ResolveInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.BundleMerger;
import android.os.DropBoxManager;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.IndentingPrintWriter;
import android.util.Pair;

import androidx.test.filters.SmallTest;

@@ -977,6 +979,59 @@ public class BroadcastQueueModernImplTest {
                List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
    }

    @Test
    public void testDeliveryGroupPolicy_merged_matchingFilter() {
        final long now = SystemClock.elapsedRealtime();
        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast1 = createDropboxBroadcast(
                "TAG_A", now, 2);
        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast2 = createDropboxBroadcast(
                "TAG_B", now + 1000, 4);
        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,
                dropboxEntryBroadcast2.second));
        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast3.first,
                dropboxEntryBroadcast3.second));

        final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
                getUidForPackage(PACKAGE_GREEN));
        // dropboxEntryBroadcast1 and dropboxEntryBroadcast3 should be merged as they use the same
        // tag and there shouldn't be a change to dropboxEntryBroadcast2.
        final Pair<Intent, BroadcastOptions> expectedMergedBroadcast = createDropboxBroadcast(
                "TAG_A", now + 2000, 10);
        verifyPendingRecords(queue, List.of(
                dropboxEntryBroadcast2.first, expectedMergedBroadcast.first));
    }

    private Pair<Intent, BroadcastOptions> createDropboxBroadcast(String tag, long timestampMs,
            int droppedCount) {
        final Intent dropboxEntryAdded = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TAG, tag);
        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TIME, timestampMs);
        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, droppedCount);

        final BundleMerger extrasMerger = new BundleMerger();
        extrasMerger.setDefaultMergeStrategy(BundleMerger.STRATEGY_FIRST);
        extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
                BundleMerger.STRATEGY_COMPARABLE_MAX);
        extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
                BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
        final IntentFilter matchingFilter = new IntentFilter(
                DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
        matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);
        final BroadcastOptions optionsDropboxEntryAdded = BroadcastOptions.makeBasic()
                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
                .setDeliveryGroupMatchingFilter(matchingFilter)
                .setDeliveryGroupExtrasMerger(extrasMerger);
        return Pair.create(dropboxEntryAdded, optionsDropboxEntryAdded);
    }

    @Test
    public void testVerifyEnqueuedTime_withReplacePending() {
        final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Looper;
import android.os.Parcel;
@@ -66,7 +67,7 @@ public class DropBoxTest extends AndroidTestCase {
        mContext = new ContextWrapper(super.getContext()) {
            @Override
            public void sendBroadcastAsUser(Intent intent,
                    UserHandle user, String receiverPermission) {
                    UserHandle user, String receiverPermission, Bundle options) {
                // Don't actually send broadcasts.
            }
        };