summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/Intent.java94
-rw-r--r--core/java/android/os/Bundle.java9
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java22
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java49
4 files changed, 138 insertions, 36 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f70215b46a5e..daeb987f5f2a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5587,6 +5587,16 @@ public class Intent implements Parcelable, Cloneable {
// ---------------------------------------------------------------------
+ private static final int COPY_MODE_ALL = 0;
+ private static final int COPY_MODE_FILTER = 1;
+ private static final int COPY_MODE_HISTORY = 2;
+
+ /** @hide */
+ @IntDef(value = {COPY_MODE_ALL, COPY_MODE_FILTER, COPY_MODE_HISTORY})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CopyMode {}
+
+
/**
* Create an empty intent.
*/
@@ -5597,28 +5607,46 @@ public class Intent implements Parcelable, Cloneable {
* Copy constructor.
*/
public Intent(Intent o) {
+ this(o, COPY_MODE_ALL);
+ }
+
+ private Intent(Intent o, @CopyMode int copyMode) {
this.mAction = o.mAction;
this.mData = o.mData;
this.mType = o.mType;
this.mPackage = o.mPackage;
this.mComponent = o.mComponent;
- this.mFlags = o.mFlags;
- this.mContentUserHint = o.mContentUserHint;
- this.mLaunchToken = o.mLaunchToken;
+
if (o.mCategories != null) {
- this.mCategories = new ArraySet<String>(o.mCategories);
- }
- if (o.mExtras != null) {
- this.mExtras = new Bundle(o.mExtras);
- }
- if (o.mSourceBounds != null) {
- this.mSourceBounds = new Rect(o.mSourceBounds);
- }
- if (o.mSelector != null) {
- this.mSelector = new Intent(o.mSelector);
+ this.mCategories = new ArraySet<>(o.mCategories);
}
- if (o.mClipData != null) {
- this.mClipData = new ClipData(o.mClipData);
+
+ if (copyMode != COPY_MODE_FILTER) {
+ this.mFlags = o.mFlags;
+ this.mContentUserHint = o.mContentUserHint;
+ this.mLaunchToken = o.mLaunchToken;
+ if (o.mSourceBounds != null) {
+ this.mSourceBounds = new Rect(o.mSourceBounds);
+ }
+ if (o.mSelector != null) {
+ this.mSelector = new Intent(o.mSelector);
+ }
+
+ if (copyMode != COPY_MODE_HISTORY) {
+ if (o.mExtras != null) {
+ this.mExtras = new Bundle(o.mExtras);
+ }
+ if (o.mClipData != null) {
+ this.mClipData = new ClipData(o.mClipData);
+ }
+ } else {
+ if (o.mExtras != null && !o.mExtras.maybeIsEmpty()) {
+ this.mExtras = Bundle.STRIPPED;
+ }
+
+ // Also set "stripped" clip data when we ever log mClipData in the (broadcast)
+ // history.
+ }
}
}
@@ -5627,23 +5655,12 @@ public class Intent implements Parcelable, Cloneable {
return new Intent(this);
}
- private Intent(Intent o, boolean all) {
- this.mAction = o.mAction;
- this.mData = o.mData;
- this.mType = o.mType;
- this.mPackage = o.mPackage;
- this.mComponent = o.mComponent;
- if (o.mCategories != null) {
- this.mCategories = new ArraySet<String>(o.mCategories);
- }
- }
-
/**
* Make a clone of only the parts of the Intent that are relevant for
* filter matching: the action, data, type, component, and categories.
*/
public @NonNull Intent cloneFilter() {
- return new Intent(this, false);
+ return new Intent(this, COPY_MODE_FILTER);
}
/**
@@ -7395,6 +7412,29 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * @return Whether {@link #maybeStripForHistory} will return an lightened intent or
+ * return itself as-is.
+ * @hide
+ */
+ public boolean canStripForHistory() {
+ return ((mExtras != null) && mExtras.isParcelled()) || (mClipData != null);
+ }
+
+ /**
+ * Call it when the system needs to keep an intent for logging purposes to remove fields
+ * that are not needed for logging.
+ * @hide
+ */
+ public Intent maybeStripForHistory() {
+ // TODO Scan and remove possibly heavy instances like Bitmaps from unparcelled extras?
+
+ if (!canStripForHistory()) {
+ return this;
+ }
+ return new Intent(this, COPY_MODE_HISTORY);
+ }
+
+ /**
* Retrieve any special flags associated with this intent. You will
* normally just set them with {@link #setFlags} and let the system
* take the appropriate action with them.
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index ec01364b63b4..51f96eed822e 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -38,9 +38,18 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
public static final Bundle EMPTY;
+ /**
+ * Special extras used to denote extras have been stripped off.
+ * @hide
+ */
+ public static final Bundle STRIPPED;
+
static {
EMPTY = new Bundle();
EMPTY.mMap = ArrayMap.EMPTY;
+
+ STRIPPED = new Bundle();
+ STRIPPED.putInt("STRIPPED", 1);
}
/**
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 064ca58dee96..739497b771aa 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1498,25 +1498,29 @@ public final class BroadcastQueue {
else return x;
}
- private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
- if (r.callingUid < 0) {
+ private final void addBroadcastToHistoryLocked(BroadcastRecord original) {
+ if (original.callingUid < 0) {
// This was from a registerReceiver() call; ignore it.
return;
}
- r.finishTime = SystemClock.uptimeMillis();
+ original.finishTime = SystemClock.uptimeMillis();
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
- createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
- System.identityHashCode(r));
+ createBroadcastTraceTitle(original, BroadcastRecord.DELIVERY_DELIVERED),
+ System.identityHashCode(original));
}
- mBroadcastHistory[mHistoryNext] = r;
+ // Note sometimes (only for sticky broadcasts?) we reuse BroadcastRecords,
+ // So don't change the incoming record directly.
+ final BroadcastRecord historyRecord = original.maybeStripForHistory();
+
+ mBroadcastHistory[mHistoryNext] = historyRecord;
mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
- mBroadcastSummaryHistory[mSummaryHistoryNext] = r.intent;
- mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = r.enqueueClockTime;
- mSummaryHistoryDispatchTime[mSummaryHistoryNext] = r.dispatchClockTime;
+ mBroadcastSummaryHistory[mSummaryHistoryNext] = historyRecord.intent;
+ mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = historyRecord.enqueueClockTime;
+ mSummaryHistoryDispatchTime[mSummaryHistoryNext] = historyRecord.dispatchClockTime;
mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis();
mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 7764be794c19..6bc0744fe9a4 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -248,6 +248,55 @@ final class BroadcastRecord extends Binder {
state = IDLE;
}
+ /**
+ * Copy constructor which takes a different intent.
+ * Only used by {@link #maybeStripForHistory}.
+ */
+ private BroadcastRecord(BroadcastRecord from, Intent newIntent) {
+ intent = newIntent;
+ targetComp = newIntent.getComponent();
+
+ callerApp = from.callerApp;
+ callerPackage = from.callerPackage;
+ callingPid = from.callingPid;
+ callingUid = from.callingUid;
+ callerInstantApp = from.callerInstantApp;
+ ordered = from.ordered;
+ sticky = from.sticky;
+ initialSticky = from.initialSticky;
+ userId = from.userId;
+ resolvedType = from.resolvedType;
+ requiredPermissions = from.requiredPermissions;
+ appOp = from.appOp;
+ options = from.options;
+ receivers = from.receivers;
+ delivery = from.delivery;
+ resultTo = from.resultTo;
+ enqueueClockTime = from.enqueueClockTime;
+ dispatchTime = from.dispatchTime;
+ dispatchClockTime = from.dispatchClockTime;
+ receiverTime = from.receiverTime;
+ finishTime = from.finishTime;
+ resultCode = from.resultCode;
+ resultData = from.resultData;
+ resultExtras = from.resultExtras;
+ resultAbort = from.resultAbort;
+ nextReceiver = from.nextReceiver;
+ receiver = from.receiver;
+ state = from.state;
+ anrCount = from.anrCount;
+ manifestCount = from.manifestCount;
+ manifestSkipCount = from.manifestSkipCount;
+ queue = from.queue;
+ }
+
+ public BroadcastRecord maybeStripForHistory() {
+ if (!intent.canStripForHistory()) {
+ return this;
+ }
+ return new BroadcastRecord(this, intent.maybeStripForHistory());
+ }
+
boolean cleanupDisabledPackageReceiversLocked(
String packageName, Set<String> filterByClasses, int userId, boolean doit) {
if ((userId != UserHandle.USER_ALL && this.userId != userId) || receivers == null) {