Merge "Fix waitForBroadcastIdle()"
This commit is contained in:
committed by
Android (Google) Code Review
commit
4d1f54e33a
@@ -18100,8 +18100,10 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
if (!queue.isIdle()) {
|
||||
final String msg = "Waiting for queue " + queue + " to become idle...";
|
||||
pw.println(msg);
|
||||
pw.println(queue.describeState());
|
||||
pw.flush();
|
||||
Slog.v(TAG, msg);
|
||||
queue.cancelDeferrals();
|
||||
idle = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,14 @@ public class BroadcastDispatcher {
|
||||
broadcasts.add(br);
|
||||
}
|
||||
|
||||
int size() {
|
||||
return broadcasts.size();
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return broadcasts.isEmpty();
|
||||
}
|
||||
|
||||
void writeToProto(ProtoOutputStream proto, long fieldId) {
|
||||
for (BroadcastRecord br : broadcasts) {
|
||||
br.writeToProto(proto, fieldId);
|
||||
@@ -252,22 +260,48 @@ public class BroadcastDispatcher {
|
||||
synchronized (mLock) {
|
||||
return mCurrentBroadcast == null
|
||||
&& mOrderedBroadcasts.isEmpty()
|
||||
&& mDeferredBroadcasts.isEmpty()
|
||||
&& mAlarmBroadcasts.isEmpty();
|
||||
&& isDeferralsListEmpty(mDeferredBroadcasts)
|
||||
&& isDeferralsListEmpty(mAlarmBroadcasts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not quite the traditional size() measurement; includes any in-process but
|
||||
* not yet retired active outbound broadcast.
|
||||
*/
|
||||
public int totalUndelivered() {
|
||||
synchronized (mLock) {
|
||||
return mAlarmBroadcasts.size()
|
||||
+ mDeferredBroadcasts.size()
|
||||
+ mOrderedBroadcasts.size()
|
||||
+ (mCurrentBroadcast == null ? 0 : 1);
|
||||
private static int pendingInDeferralsList(ArrayList<Deferrals> list) {
|
||||
int pending = 0;
|
||||
final int numEntries = list.size();
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
pending += list.get(i).size();
|
||||
}
|
||||
return pending;
|
||||
}
|
||||
|
||||
private static boolean isDeferralsListEmpty(ArrayList<Deferrals> list) {
|
||||
return pendingInDeferralsList(list) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strictly for logging, describe the currently pending contents in a human-
|
||||
* readable way
|
||||
*/
|
||||
public String describeStateLocked() {
|
||||
final StringBuilder sb = new StringBuilder(128);
|
||||
if (mCurrentBroadcast != null) {
|
||||
sb.append("1 in flight, ");
|
||||
}
|
||||
sb.append(mOrderedBroadcasts.size());
|
||||
sb.append(" ordered");
|
||||
int n = pendingInDeferralsList(mAlarmBroadcasts);
|
||||
if (n > 0) {
|
||||
sb.append(", ");
|
||||
sb.append(n);
|
||||
sb.append(" deferrals in alarm recipients");
|
||||
}
|
||||
n = pendingInDeferralsList(mDeferredBroadcasts);
|
||||
if (n > 0) {
|
||||
sb.append(", ");
|
||||
sb.append(n);
|
||||
sb.append(" deferred");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
@@ -579,6 +613,26 @@ public class BroadcastDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all current deferrals; that is, make all currently-deferred broadcasts
|
||||
* immediately deliverable. Used by the wait-for-broadcast-idle mechanism.
|
||||
*/
|
||||
public void cancelDeferrals() {
|
||||
synchronized (mLock) {
|
||||
zeroDeferralTimes(mAlarmBroadcasts);
|
||||
zeroDeferralTimes(mDeferredBroadcasts);
|
||||
}
|
||||
}
|
||||
|
||||
private static void zeroDeferralTimes(ArrayList<Deferrals> list) {
|
||||
final int num = list.size();
|
||||
for (int i = 0; i < num; i++) {
|
||||
Deferrals d = list.get(i);
|
||||
// Safe to do this in-place because it won't break ordering
|
||||
d.deferUntil = d.deferredBy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -928,8 +928,8 @@ public final class BroadcastQueue {
|
||||
|
||||
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
|
||||
+ mQueueName + "]: "
|
||||
+ mParallelBroadcasts.size() + " parallel broadcasts, "
|
||||
+ mDispatcher.totalUndelivered() + " ordered broadcasts");
|
||||
+ mParallelBroadcasts.size() + " parallel broadcasts; "
|
||||
+ mDispatcher.describeStateLocked());
|
||||
|
||||
mService.updateCpuStats();
|
||||
|
||||
@@ -1827,11 +1827,24 @@ public final class BroadcastQueue {
|
||||
record.intent == null ? "" : record.intent.getAction());
|
||||
}
|
||||
|
||||
final boolean isIdle() {
|
||||
boolean isIdle() {
|
||||
return mParallelBroadcasts.isEmpty() && mDispatcher.isEmpty()
|
||||
&& (mPendingBroadcast == null);
|
||||
}
|
||||
|
||||
// Used by wait-for-broadcast-idle : fast-forward all current deferrals to
|
||||
// be immediately deliverable.
|
||||
void cancelDeferrals() {
|
||||
mDispatcher.cancelDeferrals();
|
||||
}
|
||||
|
||||
String describeState() {
|
||||
synchronized (mService) {
|
||||
return mParallelBroadcasts.size() + " parallel; "
|
||||
+ mDispatcher.describeStateLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void writeToProto(ProtoOutputStream proto, long fieldId) {
|
||||
long token = proto.start(fieldId);
|
||||
proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);
|
||||
|
||||
Reference in New Issue
Block a user