diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index f62f08df511f7..a91a7ca2f055b 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 mOrderedBroadcasts = new ArrayList(); /** - * 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 0 && ringIndex != lastIndex;) { + ringIndex = ringAdvance(ringIndex, -1, MAX_BROADCAST_SUMMARY_HISTORY); + BroadcastRecord r = mBroadcastHistory[ringIndex]; + if (r == null) { + continue; + } + j--; + } } - for (; i