Merge "Include more broadcasts related data in the activity service dump." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
46354b9f21
@@ -142,6 +142,7 @@ message BroadcastQueueProto {
|
||||
optional int64 finish_clock_time_ms = 4;
|
||||
}
|
||||
repeated BroadcastSummary historical_broadcasts_summary = 6;
|
||||
repeated BroadcastRecordProto pending_broadcasts = 7;
|
||||
}
|
||||
|
||||
message MemInfoDumpProto {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.am;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.TimeUtils;
|
||||
@@ -26,6 +27,7 @@ import dalvik.annotation.optimization.NeverCompile;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -47,6 +49,11 @@ public class BroadcastHistory {
|
||||
mSummaryHistoryFinishTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of broadcasts which are being delivered or yet to be delivered.
|
||||
*/
|
||||
private final ArrayList<BroadcastRecord> mPendingBroadcasts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Historical data of past broadcasts, for debugging. This is a ring buffer
|
||||
* whose last element is at mHistoryNext.
|
||||
@@ -70,7 +77,16 @@ public class BroadcastHistory {
|
||||
final long[] mSummaryHistoryDispatchTime;
|
||||
final long[] mSummaryHistoryFinishTime;
|
||||
|
||||
public void addBroadcastToHistoryLocked(BroadcastRecord original) {
|
||||
void onBroadcastEnqueuedLocked(@NonNull BroadcastRecord r) {
|
||||
mPendingBroadcasts.add(r);
|
||||
}
|
||||
|
||||
void onBroadcastFinishedLocked(@NonNull BroadcastRecord r) {
|
||||
mPendingBroadcasts.remove(r);
|
||||
addBroadcastToHistoryLocked(r);
|
||||
}
|
||||
|
||||
public void addBroadcastToHistoryLocked(@NonNull BroadcastRecord original) {
|
||||
// Note sometimes (only for sticky broadcasts?) we reuse BroadcastRecords,
|
||||
// So don't change the incoming record directly.
|
||||
final BroadcastRecord historyRecord = original.maybeStripForHistory();
|
||||
@@ -93,7 +109,12 @@ public class BroadcastHistory {
|
||||
}
|
||||
|
||||
@NeverCompile
|
||||
public void dumpDebug(ProtoOutputStream proto) {
|
||||
public void dumpDebug(@NonNull ProtoOutputStream proto) {
|
||||
for (int i = 0; i < mPendingBroadcasts.size(); ++i) {
|
||||
final BroadcastRecord r = mPendingBroadcasts.get(i);
|
||||
r.dumpDebug(proto, BroadcastQueueProto.PENDING_BROADCASTS);
|
||||
}
|
||||
|
||||
int lastIndex = mHistoryNext;
|
||||
int ringIndex = lastIndex;
|
||||
do {
|
||||
@@ -127,8 +148,20 @@ public class BroadcastHistory {
|
||||
}
|
||||
|
||||
@NeverCompile
|
||||
public boolean dumpLocked(PrintWriter pw, String dumpPackage, String queueName,
|
||||
SimpleDateFormat sdf, boolean dumpAll, boolean needSep) {
|
||||
public boolean dumpLocked(@NonNull PrintWriter pw, @Nullable String dumpPackage,
|
||||
@NonNull String queueName, @NonNull SimpleDateFormat sdf,
|
||||
boolean dumpAll, boolean needSep) {
|
||||
pw.println(" Pending broadcasts:");
|
||||
if (mPendingBroadcasts.isEmpty()) {
|
||||
pw.println(" <empty>");
|
||||
} else {
|
||||
for (int idx = mPendingBroadcasts.size() - 1; idx >= 0; --idx) {
|
||||
final BroadcastRecord r = mPendingBroadcasts.get(idx);
|
||||
pw.print(" Broadcast #"); pw.print(idx); pw.println(":");
|
||||
r.dump(pw, " ", sdf);
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
boolean printed = false;
|
||||
|
||||
|
||||
@@ -1145,8 +1145,11 @@ class BroadcastProcessQueue {
|
||||
pw.print(" because ");
|
||||
pw.print(reasonToString(mRunnableAtReason));
|
||||
pw.println();
|
||||
pw.print("mProcessCached="); pw.println(mProcessCached);
|
||||
|
||||
pw.increaseIndent();
|
||||
dumpProcessState(pw);
|
||||
dumpBroadcastCounts(pw);
|
||||
|
||||
if (mActive != null) {
|
||||
dumpRecord("ACTIVE", now, pw, mActive, mActiveIndex);
|
||||
}
|
||||
@@ -1166,6 +1169,49 @@ class BroadcastProcessQueue {
|
||||
pw.println();
|
||||
}
|
||||
|
||||
@NeverCompile
|
||||
private void dumpProcessState(@NonNull IndentingPrintWriter pw) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (mProcessCached) {
|
||||
sb.append("CACHED");
|
||||
}
|
||||
if (mProcessInstrumented) {
|
||||
if (sb.length() > 0) sb.append("|");
|
||||
sb.append("INSTR");
|
||||
}
|
||||
if (mProcessPersistent) {
|
||||
if (sb.length() > 0) sb.append("|");
|
||||
sb.append("PER");
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
pw.print("state:"); pw.println(sb);
|
||||
}
|
||||
if (runningOomAdjusted) {
|
||||
pw.print("runningOomAdjusted:"); pw.println(runningOomAdjusted);
|
||||
}
|
||||
}
|
||||
|
||||
@NeverCompile
|
||||
private void dumpBroadcastCounts(@NonNull IndentingPrintWriter pw) {
|
||||
pw.print("e:"); pw.print(mCountEnqueued);
|
||||
pw.print(" d:"); pw.print(mCountDeferred);
|
||||
pw.print(" f:"); pw.print(mCountForeground);
|
||||
pw.print(" fd:"); pw.print(mCountForegroundDeferred);
|
||||
pw.print(" o:"); pw.print(mCountOrdered);
|
||||
pw.print(" a:"); pw.print(mCountAlarm);
|
||||
pw.print(" p:"); pw.print(mCountPrioritized);
|
||||
pw.print(" pd:"); pw.print(mCountPrioritizedDeferred);
|
||||
pw.print(" int:"); pw.print(mCountInteractive);
|
||||
pw.print(" rt:"); pw.print(mCountResultTo);
|
||||
pw.print(" ins:"); pw.print(mCountInstrumented);
|
||||
pw.print(" m:"); pw.print(mCountManifest);
|
||||
|
||||
pw.print(" csi:"); pw.print(mActiveCountSinceIdle);
|
||||
pw.print(" ccu:"); pw.print(mActiveCountConsecutiveUrgent);
|
||||
pw.print(" ccn:"); pw.print(mActiveCountConsecutiveNormal);
|
||||
pw.println();
|
||||
}
|
||||
|
||||
@NeverCompile
|
||||
private void dumpRecord(@Nullable String flavor, @UptimeMillisLong long now,
|
||||
@NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record, int recordIndex) {
|
||||
|
||||
@@ -90,7 +90,6 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -602,6 +601,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
r.enqueueTime = SystemClock.uptimeMillis();
|
||||
r.enqueueRealTime = SystemClock.elapsedRealtime();
|
||||
r.enqueueClockTime = System.currentTimeMillis();
|
||||
mHistory.onBroadcastEnqueuedLocked(r);
|
||||
|
||||
ArraySet<BroadcastRecord> replacedBroadcasts = mReplacedBroadcastsCache.getAndSet(null);
|
||||
if (replacedBroadcasts == null) {
|
||||
@@ -825,8 +825,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
if (app != null && app.isInFullBackup()) {
|
||||
return "isInFullBackup";
|
||||
}
|
||||
if (mSkipPolicy.shouldSkip(r, receiver)) {
|
||||
return "mSkipPolicy";
|
||||
final String skipReason = mSkipPolicy.shouldSkipMessage(r, receiver);
|
||||
if (skipReason != null) {
|
||||
return skipReason;
|
||||
}
|
||||
final Intent receiverIntent = r.getReceiverIntent(receiver);
|
||||
if (receiverIntent == null) {
|
||||
@@ -1100,7 +1101,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
*/
|
||||
private void setDeliveryState(@Nullable BroadcastProcessQueue queue,
|
||||
@Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
|
||||
@NonNull Object receiver, @DeliveryState int newDeliveryState, String reason) {
|
||||
@NonNull Object receiver, @DeliveryState int newDeliveryState,
|
||||
@NonNull String reason) {
|
||||
final int cookie = traceBegin("setDeliveryState");
|
||||
final int oldDeliveryState = getDeliveryState(r, index);
|
||||
boolean checkFinished = false;
|
||||
@@ -1108,7 +1110,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
// Only apply state when we haven't already reached a terminal state;
|
||||
// this is how we ignore racing timeout messages
|
||||
if (!isDeliveryStateTerminal(oldDeliveryState)) {
|
||||
r.setDeliveryState(index, newDeliveryState);
|
||||
r.setDeliveryState(index, newDeliveryState, reason);
|
||||
if (oldDeliveryState == BroadcastRecord.DELIVERY_DEFERRED) {
|
||||
r.deferredCount--;
|
||||
} else if (newDeliveryState == BroadcastRecord.DELIVERY_DEFERRED) {
|
||||
@@ -1659,7 +1661,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
mService.notifyBroadcastFinishedLocked(r);
|
||||
r.finishTime = SystemClock.uptimeMillis();
|
||||
r.nextReceiver = r.receivers.size();
|
||||
mHistory.addBroadcastToHistoryLocked(r);
|
||||
mHistory.onBroadcastFinishedLocked(r);
|
||||
|
||||
BroadcastQueueImpl.logBootCompletedBroadcastCompletionLatencyIfPossible(r);
|
||||
|
||||
@@ -1833,8 +1835,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
if (dumpConstants) {
|
||||
mConstants.dump(ipw);
|
||||
}
|
||||
|
||||
if (dumpHistory) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
needSep = mHistory.dumpLocked(ipw, dumpPackage, mQueueName, sdf, dumpAll, needSep);
|
||||
}
|
||||
return needSep;
|
||||
|
||||
@@ -99,6 +99,7 @@ final class BroadcastRecord extends Binder {
|
||||
final @Nullable BroadcastOptions options; // BroadcastOptions supplied by caller
|
||||
final @NonNull List<Object> receivers; // contains BroadcastFilter and ResolveInfo
|
||||
final @DeliveryState int[] delivery; // delivery state of each receiver
|
||||
final @NonNull String[] deliveryReasons; // reasons for delivery state of each receiver
|
||||
final boolean[] deferredUntilActive; // whether each receiver is infinitely deferred
|
||||
final int[] blockedUntilTerminalCount; // blocked until count of each receiver
|
||||
@Nullable ProcessRecord resultToApp; // who receives final result if non-null
|
||||
@@ -298,7 +299,7 @@ final class BroadcastRecord extends Binder {
|
||||
pw.print(" initialSticky="); pw.println(initialSticky);
|
||||
}
|
||||
if (nextReceiver != 0) {
|
||||
pw.print(prefix); pw.print("nextReceiver="); pw.print(nextReceiver);
|
||||
pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
|
||||
}
|
||||
if (curFilter != null) {
|
||||
pw.print(prefix); pw.print("curFilter="); pw.println(curFilter);
|
||||
@@ -328,6 +329,7 @@ final class BroadcastRecord extends Binder {
|
||||
}
|
||||
pw.print(prefix); pw.print("state="); pw.print(state); pw.println(stateStr);
|
||||
}
|
||||
pw.print(prefix); pw.print("terminalCount="); pw.println(terminalCount);
|
||||
final int N = receivers != null ? receivers.size() : 0;
|
||||
String p2 = prefix + " ";
|
||||
PrintWriterPrinter printer = new PrintWriterPrinter(pw);
|
||||
@@ -346,6 +348,7 @@ final class BroadcastRecord extends Binder {
|
||||
TimeUtils.formatDuration(terminalTime[i] - scheduledTime[i], pw);
|
||||
pw.print(' ');
|
||||
}
|
||||
pw.print("("); pw.print(blockedUntilTerminalCount[i]); pw.print(") ");
|
||||
pw.print("#"); pw.print(i); pw.print(": ");
|
||||
if (o instanceof BroadcastFilter) {
|
||||
pw.println(o);
|
||||
@@ -356,6 +359,9 @@ final class BroadcastRecord extends Binder {
|
||||
} else {
|
||||
pw.println(o);
|
||||
}
|
||||
if (deliveryReasons[i] != null) {
|
||||
pw.print(p2); pw.print("reason: "); pw.println(deliveryReasons[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,6 +399,7 @@ final class BroadcastRecord extends Binder {
|
||||
options = _options;
|
||||
receivers = (_receivers != null) ? _receivers : EMPTY_RECEIVERS;
|
||||
delivery = new int[_receivers != null ? _receivers.size() : 0];
|
||||
deliveryReasons = new String[delivery.length];
|
||||
deferUntilActive = options != null ? options.isDeferUntilActive() : false;
|
||||
deferredUntilActive = new boolean[deferUntilActive ? delivery.length : 0];
|
||||
blockedUntilTerminalCount = calculateBlockedUntilTerminalCount(receivers, _serialized);
|
||||
@@ -448,6 +455,7 @@ final class BroadcastRecord extends Binder {
|
||||
options = from.options;
|
||||
receivers = from.receivers;
|
||||
delivery = from.delivery;
|
||||
deliveryReasons = from.deliveryReasons;
|
||||
deferUntilActive = from.deferUntilActive;
|
||||
deferredUntilActive = from.deferredUntilActive;
|
||||
blockedUntilTerminalCount = from.blockedUntilTerminalCount;
|
||||
@@ -609,8 +617,10 @@ final class BroadcastRecord extends Binder {
|
||||
* Update the delivery state of the given {@link #receivers} index.
|
||||
* Automatically updates any time measurements related to state changes.
|
||||
*/
|
||||
void setDeliveryState(int index, @DeliveryState int deliveryState) {
|
||||
void setDeliveryState(int index, @DeliveryState int deliveryState,
|
||||
@NonNull String reason) {
|
||||
delivery[index] = deliveryState;
|
||||
deliveryReasons[index] = reason;
|
||||
if (deferUntilActive) deferredUntilActive[index] = false;
|
||||
switch (deliveryState) {
|
||||
case DELIVERY_DELIVERED:
|
||||
@@ -977,7 +987,8 @@ final class BroadcastRecord extends Binder {
|
||||
if (label == null) {
|
||||
label = intent.toString();
|
||||
}
|
||||
mCachedToShortString = label + "/u" + userId;
|
||||
mCachedToShortString = Integer.toHexString(System.identityHashCode(this))
|
||||
+ ":" + label + "/u" + userId;
|
||||
}
|
||||
return mCachedToShortString;
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ public final class BroadcastQueueModernImplTest {
|
||||
|
||||
// To maximize test coverage, dump current state; we're not worried
|
||||
// about the actual output, just that we don't crash
|
||||
queue.getActive().setDeliveryState(0, BroadcastRecord.DELIVERY_SCHEDULED);
|
||||
queue.getActive().setDeliveryState(0, BroadcastRecord.DELIVERY_SCHEDULED, "Test-driven");
|
||||
queue.dumpLocked(SystemClock.uptimeMillis(),
|
||||
new IndentingPrintWriter(new PrintWriter(new ByteArrayOutputStream())));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user