diff options
author | Christopher Tate <ctate@google.com> | 2015-04-22 13:12:01 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2015-04-22 17:27:15 -0700 |
commit | f278f12fae6b0dada39fbdf90a84406053937933 (patch) | |
tree | 5d3f6aa4793c49907e945475cb1ec69a151d3a78 | |
parent | f7de58130a6a38d62857f6b885986f6a5cc74fcb (diff) | |
download | frameworks_base-f278f12fae6b0dada39fbdf90a84406053937933.zip frameworks_base-f278f12fae6b0dada39fbdf90a84406053937933.tar.gz frameworks_base-f278f12fae6b0dada39fbdf90a84406053937933.tar.bz2 |
Retain milestone timestamps of historical broadcast activity
Also use a ring buffer now instead of using arraycopy() every time
we send a broadcast.
Bug 20297662
Bug 20426398
Change-Id: I682461f358e5bc6ebc63bbeb87d0ad07d85fe4b6
-rw-r--r-- | services/core/java/com/android/server/am/BroadcastQueue.java | 88 |
1 files changed, 71 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index f62f08d..a91a7ca 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -18,7 +18,9 @@ package com.android.server.am; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import android.app.ActivityManager; import android.app.AppGlobals; @@ -95,14 +97,27 @@ public final class BroadcastQueue { final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>(); /** - * Historical data of past broadcasts, for debugging. + * Historical data of past broadcasts, for debugging. This is a ring buffer + * whose last element is at mHistoryNext. */ final BroadcastRecord[] mBroadcastHistory = new BroadcastRecord[MAX_BROADCAST_HISTORY]; + int mHistoryNext = 0; /** - * Summary of historical data of past broadcasts, for debugging. + * Summary of historical data of past broadcasts, for debugging. This is a + * ring buffer whose last element is at mSummaryHistoryNext. */ final Intent[] mBroadcastSummaryHistory = new Intent[MAX_BROADCAST_SUMMARY_HISTORY]; + int mSummaryHistoryNext = 0; + + /** + * Various milestone timestamps of entries in the mBroadcastSummaryHistory ring + * buffer, also tracked via the mSummaryHistoryNext index. These are all in wall + * clock time, not elapsed. + */ + final long[] mSummaryHistoryEnqueueTime = new long[MAX_BROADCAST_SUMMARY_HISTORY]; + final long[] mSummaryHistoryDispatchTime = new long[MAX_BROADCAST_SUMMARY_HISTORY]; + final long[] mSummaryHistoryFinishTime = new long[MAX_BROADCAST_SUMMARY_HISTORY]; /** * Set when we current have a BROADCAST_INTENT_MSG in flight. @@ -1060,18 +1075,28 @@ public final class BroadcastQueue { } } + private final int ringAdvance(int x, final int increment, final int ringSize) { + x += increment; + if (x < 0) return (ringSize - 1); + else if (x >= ringSize) return 0; + else return x; + } + private final void addBroadcastToHistoryLocked(BroadcastRecord r) { if (r.callingUid < 0) { // This was from a registerReceiver() call; ignore it. return; } - System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, - MAX_BROADCAST_HISTORY-1); r.finishTime = SystemClock.uptimeMillis(); - mBroadcastHistory[0] = r; - System.arraycopy(mBroadcastSummaryHistory, 0, mBroadcastSummaryHistory, 1, - MAX_BROADCAST_SUMMARY_HISTORY-1); - mBroadcastSummaryHistory[0] = r.intent; + + mBroadcastHistory[mHistoryNext] = r; + mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY); + + mBroadcastSummaryHistory[mSummaryHistoryNext] = r.intent; + mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = r.enqueueClockTime; + mSummaryHistoryDispatchTime[mSummaryHistoryNext] = r.dispatchClockTime; + mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis(); + mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY); } final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { @@ -1158,11 +1183,20 @@ public final class BroadcastQueue { int i; boolean printed = false; - for (i=0; i<MAX_BROADCAST_HISTORY; i++) { - BroadcastRecord r = mBroadcastHistory[i]; + + i = -1; + int lastIndex = mHistoryNext; + int ringIndex = lastIndex; + do { + // increasing index = more recent entry, and we want to print the most + // recent first and work backwards, so we roll through the ring backwards. + ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_HISTORY); + BroadcastRecord r = mBroadcastHistory[ringIndex]; if (r == null) { - break; + continue; } + + i++; // genuine record of some sort even if we're filtering it out if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) { continue; } @@ -1190,17 +1224,33 @@ public final class BroadcastQueue { pw.print(" extras: "); pw.println(bundle.toString()); } } - } + } while (ringIndex != lastIndex); if (dumpPackage == null) { + lastIndex = ringIndex = mSummaryHistoryNext; if (dumpAll) { - i = 0; printed = false; + i = -1; + } else { + // roll over the 'i' full dumps that have already been issued + for (int j = i; + j > 0 && ringIndex != lastIndex;) { + ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY); + BroadcastRecord r = mBroadcastHistory[ringIndex]; + if (r == null) { + continue; + } + j--; + } } - for (; i<MAX_BROADCAST_SUMMARY_HISTORY; i++) { - Intent intent = mBroadcastSummaryHistory[i]; + // done skipping; dump the remainder of the ring. 'i' is still the ordinal within + // the overall broadcast history. + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + do { + ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY); + Intent intent = mBroadcastSummaryHistory[ringIndex]; if (intent == null) { - break; + continue; } if (!printed) { if (needSep) { @@ -1214,13 +1264,17 @@ public final class BroadcastQueue { pw.println(" ..."); break; } + i++; pw.print(" #"); pw.print(i); pw.print(": "); pw.println(intent.toShortString(false, true, true, false)); + pw.print(" enq="); pw.print(sdf.format(new Date(mSummaryHistoryEnqueueTime[ringIndex]))); + pw.print(" disp="); pw.print(sdf.format(new Date(mSummaryHistoryDispatchTime[ringIndex]))); + pw.print(" fin="); pw.println(sdf.format(new Date(mSummaryHistoryFinishTime[ringIndex]))); Bundle bundle = intent.getExtras(); if (bundle != null) { pw.print(" extras: "); pw.println(bundle.toString()); } - } + } while (ringIndex != lastIndex); } return needSep; |