Merge "Make sure to call the original reply-to receiver when..."
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 5ffb738..0d438cb 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -99,6 +99,7 @@
static final boolean DEBUG_VALIDATE = localLOGV || false;
static final boolean DEBUG_ALARM_CLOCK = localLOGV || false;
static final boolean DEBUG_LISTENER_CALLBACK = localLOGV || false;
+ static final boolean DEBUG_WAKELOCK = localLOGV || false;
static final boolean RECORD_ALARMS_IN_HISTORY = true;
static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
static final int ALARM_EVENT = 1;
@@ -2934,6 +2935,9 @@
updateStatsLocked(inflight);
}
mBroadcastRefCount--;
+ if (DEBUG_WAKELOCK) {
+ Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount);
+ }
if (mBroadcastRefCount == 0) {
mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget();
mWakeLock.release();
@@ -3074,6 +3078,9 @@
}
// The alarm is now in flight; now arrange wakelock and stats tracking
+ if (DEBUG_WAKELOCK) {
+ Slog.d(TAG, "mBroadcastRefCount -> " + (mBroadcastRefCount + 1));
+ }
if (mBroadcastRefCount == 0) {
setWakelockWorkSource(alarm.operation, alarm.workSource,
alarm.type, alarm.statsTag, (alarm.operation == null) ? alarm.uid : -1,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 300c7df..e9e73cc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18877,7 +18877,9 @@
appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
- final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
+ final boolean replaced = replacePending
+ && (queue.replaceParallelBroadcastLocked(r) != null);
+ // Note: We assume resultTo is null for non-ordered broadcasts.
if (!replaced) {
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
@@ -18976,8 +18978,25 @@
if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
"Enqueueing broadcast " + r.intent.getAction());
- boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
- if (!replaced) {
+ final BroadcastRecord oldRecord =
+ replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
+ if (oldRecord != null) {
+ // Replaced, fire the result-to receiver.
+ if (oldRecord.resultTo != null) {
+ final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
+ try {
+ oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
+ oldRecord.intent,
+ Activity.RESULT_CANCELED, null, null,
+ false, false, oldRecord.userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failure ["
+ + queue.mQueueName + "] sending broadcast result of "
+ + intent, e);
+
+ }
+ }
+ } else {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 68253c7..75b5929 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -239,33 +239,37 @@
}
}
- public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
- final Intent intent = r.intent;
- for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
- final Intent curIntent = mParallelBroadcasts.get(i).intent;
- if (intent.filterEquals(curIntent)) {
- if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
- "***** DROPPING PARALLEL ["
- + mQueueName + "]: " + intent);
- mParallelBroadcasts.set(i, r);
- return true;
- }
- }
- return false;
+ /**
+ * Find the same intent from queued parallel broadcast, replace with a new one and return
+ * the old one.
+ */
+ public final BroadcastRecord replaceParallelBroadcastLocked(BroadcastRecord r) {
+ return replaceBroadcastLocked(mParallelBroadcasts, r, "PARALLEL");
}
- public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
+ /**
+ * Find the same intent from queued ordered broadcast, replace with a new one and return
+ * the old one.
+ */
+ public final BroadcastRecord replaceOrderedBroadcastLocked(BroadcastRecord r) {
+ return replaceBroadcastLocked(mOrderedBroadcasts, r, "ORDERED");
+ }
+
+ private BroadcastRecord replaceBroadcastLocked(ArrayList<BroadcastRecord> queue,
+ BroadcastRecord r, String typeForLogging) {
final Intent intent = r.intent;
- for (int i = mOrderedBroadcasts.size() - 1; i > 0; i--) {
- if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
- if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
- "***** DROPPING ORDERED ["
- + mQueueName + "]: " + intent);
- mOrderedBroadcasts.set(i, r);
- return true;
+ for (int i = queue.size() - 1; i > 0; i--) {
+ final BroadcastRecord old = queue.get(i);
+ if (old.userId == r.userId && intent.filterEquals(old.intent)) {
+ if (DEBUG_BROADCAST) {
+ Slog.v(TAG_BROADCAST, "***** DROPPING "
+ + typeForLogging + " [" + mQueueName + "]: " + intent);
+ }
+ queue.set(i, r);
+ return old;
}
}
- return false;
+ return null;
}
private final void processCurBroadcastLocked(BroadcastRecord r,