Merge "Apply delivery group policies to ACTION_DROPBOX_ENTRY_ADDED."
This commit is contained in:
committed by
Android (Google) Code Review
commit
32040c1622
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user