Debugging for issue #2250075: Desk dock clock app sometimes doesn't
This adds a history of the last 100 broadcasts that is printed in the debug log, to be able to see what recently happened at the time the bug report was taken. Also does some optimization of the printing of the broadcast records to make it feasible to print this number of entries. (We kind-of need to do this because there are some broadcasts like SIG_STR and SYNC_STATE_CHANGED that are being broadcast a LOT.) Change-Id: I775e1ec0f63369c8bca8c83cee27b95ddc5ec450
This commit is contained in:
@ -309,15 +309,22 @@ public class ActivityInfo extends ComponentInfo
|
||||
|
||||
public void dump(Printer pw, String prefix) {
|
||||
super.dumpFront(pw, prefix);
|
||||
pw.println(prefix + "permission=" + permission);
|
||||
if (permission != null) {
|
||||
pw.println(prefix + "permission=" + permission);
|
||||
}
|
||||
pw.println(prefix + "taskAffinity=" + taskAffinity
|
||||
+ " targetActivity=" + targetActivity);
|
||||
pw.println(prefix + "launchMode=" + launchMode
|
||||
+ " flags=0x" + Integer.toHexString(flags)
|
||||
+ " theme=0x" + Integer.toHexString(theme));
|
||||
pw.println(prefix + "screenOrientation=" + screenOrientation
|
||||
+ " configChanges=0x" + Integer.toHexString(configChanges)
|
||||
+ " softInputMode=0x" + Integer.toHexString(softInputMode));
|
||||
if (launchMode != 0 || flags != 0 || theme != 0) {
|
||||
pw.println(prefix + "launchMode=" + launchMode
|
||||
+ " flags=0x" + Integer.toHexString(flags)
|
||||
+ " theme=0x" + Integer.toHexString(theme));
|
||||
}
|
||||
if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED
|
||||
|| configChanges != 0 || softInputMode != 0) {
|
||||
pw.println(prefix + "screenOrientation=" + screenOrientation
|
||||
+ " configChanges=0x" + Integer.toHexString(configChanges)
|
||||
+ " softInputMode=0x" + Integer.toHexString(softInputMode));
|
||||
}
|
||||
super.dumpBack(pw, prefix);
|
||||
}
|
||||
|
||||
|
@ -270,21 +270,31 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
|
||||
|
||||
public void dump(Printer pw, String prefix) {
|
||||
super.dumpFront(pw, prefix);
|
||||
pw.println(prefix + "className=" + className);
|
||||
pw.println(prefix + "permission=" + permission
|
||||
+ " uid=" + uid);
|
||||
pw.println(prefix + "taskAffinity=" + taskAffinity);
|
||||
pw.println(prefix + "theme=0x" + Integer.toHexString(theme));
|
||||
if (className != null) {
|
||||
pw.println(prefix + "className=" + className);
|
||||
}
|
||||
if (permission != null) {
|
||||
pw.println(prefix + "permission=" + permission);
|
||||
}
|
||||
pw.println(prefix + "uid=" + uid + " taskAffinity=" + taskAffinity);
|
||||
if (theme != 0) {
|
||||
pw.println(prefix + "theme=0x" + Integer.toHexString(theme));
|
||||
}
|
||||
pw.println(prefix + "flags=0x" + Integer.toHexString(flags)
|
||||
+ " processName=" + processName);
|
||||
pw.println(prefix + "sourceDir=" + sourceDir);
|
||||
pw.println(prefix + "publicSourceDir=" + publicSourceDir);
|
||||
pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
|
||||
pw.println(prefix + "dataDir=" + dataDir);
|
||||
pw.println(prefix + "targetSdkVersion=" + targetSdkVersion);
|
||||
pw.println(prefix + "enabled=" + enabled);
|
||||
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
|
||||
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
|
||||
if (sharedLibraryFiles != null) {
|
||||
pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
|
||||
}
|
||||
pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion);
|
||||
if (manageSpaceActivityName != null) {
|
||||
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
|
||||
}
|
||||
if (descriptionRes != 0) {
|
||||
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
|
||||
}
|
||||
super.dumpBack(pw, prefix);
|
||||
}
|
||||
|
||||
|
@ -141,11 +141,15 @@ public class PackageItemInfo {
|
||||
}
|
||||
|
||||
protected void dumpFront(Printer pw, String prefix) {
|
||||
pw.println(prefix + "name=" + name);
|
||||
if (name != null) {
|
||||
pw.println(prefix + "name=" + name);
|
||||
}
|
||||
pw.println(prefix + "packageName=" + packageName);
|
||||
pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
|
||||
+ " nonLocalizedLabel=" + nonLocalizedLabel
|
||||
+ " icon=0x" + Integer.toHexString(icon));
|
||||
if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) {
|
||||
pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
|
||||
+ " nonLocalizedLabel=" + nonLocalizedLabel
|
||||
+ " icon=0x" + Integer.toHexString(icon));
|
||||
}
|
||||
}
|
||||
|
||||
protected void dumpBack(Printer pw, String prefix) {
|
||||
|
@ -409,6 +409,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
final ArrayList<BroadcastRecord> mOrderedBroadcasts
|
||||
= new ArrayList<BroadcastRecord>();
|
||||
|
||||
/**
|
||||
* Historical data of past broadcasts, for debugging.
|
||||
*/
|
||||
static final int MAX_BROADCAST_HISTORY = 100;
|
||||
final BroadcastRecord[] mBroadcastHistory
|
||||
= new BroadcastRecord[MAX_BROADCAST_HISTORY];
|
||||
|
||||
/**
|
||||
* Set when we current have a BROADCAST_INTENT_MSG in flight.
|
||||
*/
|
||||
@ -9391,6 +9398,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
}
|
||||
|
||||
pw.println(" ");
|
||||
pw.println(" Historical broadcasts:");
|
||||
for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
|
||||
BroadcastRecord r = mBroadcastHistory[i];
|
||||
if (r == null) {
|
||||
break;
|
||||
}
|
||||
pw.println(" Historical Broadcast #" + i + ":");
|
||||
r.dump(pw, " ");
|
||||
}
|
||||
|
||||
pw.println(" ");
|
||||
pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
|
||||
if (mStickyBroadcasts != null) {
|
||||
@ -11610,7 +11628,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
Intent intent = (Intent)allSticky.get(i);
|
||||
BroadcastRecord r = new BroadcastRecord(intent, null,
|
||||
null, -1, -1, null, receivers, null, 0, null, null,
|
||||
false, true);
|
||||
false, true, true);
|
||||
if (mParallelBroadcasts.size() == 0) {
|
||||
scheduleBroadcastsLocked();
|
||||
}
|
||||
@ -11835,7 +11853,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
|
||||
callerPackage, callingPid, callingUid, requiredPermission,
|
||||
registeredReceivers, resultTo, resultCode, resultData, map,
|
||||
ordered, false);
|
||||
ordered, sticky, false);
|
||||
if (DEBUG_BROADCAST) Log.v(
|
||||
TAG, "Enqueueing parallel broadcast " + r
|
||||
+ ": prev had " + mParallelBroadcasts.size());
|
||||
@ -11914,7 +11932,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
|| resultTo != null) {
|
||||
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
|
||||
callerPackage, callingPid, callingUid, requiredPermission,
|
||||
receivers, resultTo, resultCode, resultData, map, ordered, false);
|
||||
receivers, resultTo, resultCode, resultData, map, ordered,
|
||||
sticky, false);
|
||||
if (DEBUG_BROADCAST) Log.v(
|
||||
TAG, "Enqueueing ordered broadcast " + r
|
||||
+ ": prev had " + mOrderedBroadcasts.size());
|
||||
@ -12132,17 +12151,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
long now = SystemClock.uptimeMillis();
|
||||
BroadcastRecord r = mOrderedBroadcasts.get(0);
|
||||
if ((r.startTime+BROADCAST_TIMEOUT) > now) {
|
||||
if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
|
||||
if (DEBUG_BROADCAST) Log.v(TAG,
|
||||
"Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
|
||||
+ (r.startTime + BROADCAST_TIMEOUT));
|
||||
+ (r.receiverTime + BROADCAST_TIMEOUT));
|
||||
Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
|
||||
mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
|
||||
mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
|
||||
r.startTime = now;
|
||||
r.receiverTime = now;
|
||||
r.anrCount++;
|
||||
|
||||
// Current receiver has passed its expiration date.
|
||||
@ -12290,7 +12309,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
performReceive(filter.receiverList.app, filter.receiverList.receiver,
|
||||
new Intent(r.intent), r.resultCode,
|
||||
r.resultData, r.resultExtras, r.ordered, r.sticky);
|
||||
r.resultData, r.resultExtras, r.ordered, r.initialSticky);
|
||||
if (ordered) {
|
||||
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
|
||||
}
|
||||
@ -12308,6 +12327,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private final void processNextBroadcast(boolean fromMsg) {
|
||||
synchronized(this) {
|
||||
BroadcastRecord r;
|
||||
@ -12325,6 +12355,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
// First, deliver any non-serialized broadcasts right away.
|
||||
while (mParallelBroadcasts.size() > 0) {
|
||||
r = mParallelBroadcasts.remove(0);
|
||||
r.dispatchTime = SystemClock.uptimeMillis();
|
||||
final int N = r.receivers.size();
|
||||
if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
|
||||
+ r);
|
||||
@ -12335,6 +12366,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
+ target + ": " + r);
|
||||
deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
|
||||
}
|
||||
addBroadcastToHistoryLocked(r);
|
||||
if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
|
||||
+ r);
|
||||
}
|
||||
@ -12392,7 +12424,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
Log.w(TAG, "Hung broadcast discarded after timeout failure:"
|
||||
+ " now=" + now
|
||||
+ " dispatchTime=" + r.dispatchTime
|
||||
+ " startTime=" + r.startTime
|
||||
+ " startTime=" + r.receiverTime
|
||||
+ " intent=" + r.intent
|
||||
+ " numReceivers=" + numReceivers
|
||||
+ " nextReceiver=" + r.nextReceiver
|
||||
@ -12436,6 +12468,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
+ r);
|
||||
|
||||
// ... and on to the next...
|
||||
addBroadcastToHistoryLocked(r);
|
||||
mOrderedBroadcasts.remove(0);
|
||||
r = null;
|
||||
looped = true;
|
||||
@ -12448,17 +12481,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
||||
|
||||
// Keep track of when this receiver started, and make sure there
|
||||
// is a timeout message pending to kill it if need be.
|
||||
r.startTime = SystemClock.uptimeMillis();
|
||||
r.receiverTime = SystemClock.uptimeMillis();
|
||||
if (recIdx == 0) {
|
||||
r.dispatchTime = r.startTime;
|
||||
r.dispatchTime = r.receiverTime;
|
||||
|
||||
if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
|
||||
+ r);
|
||||
if (DEBUG_BROADCAST) Log.v(TAG,
|
||||
"Submitting BROADCAST_TIMEOUT_MSG for "
|
||||
+ (r.startTime + BROADCAST_TIMEOUT));
|
||||
+ (r.receiverTime + BROADCAST_TIMEOUT));
|
||||
Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
|
||||
mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
|
||||
mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
|
||||
}
|
||||
|
||||
Object nextReceiver = r.receivers.get(recIdx);
|
||||
|
@ -39,8 +39,16 @@ class BroadcastFilter extends IntentFilter {
|
||||
receiverList.dumpLocal(pw, prefix);
|
||||
}
|
||||
|
||||
public void dumpBrief(PrintWriter pw, String prefix) {
|
||||
dumpBroadcastFilterState(pw, prefix);
|
||||
}
|
||||
|
||||
public void dumpInReceiverList(PrintWriter pw, Printer pr, String prefix) {
|
||||
super.dump(pr, prefix);
|
||||
dumpBroadcastFilterState(pw, prefix);
|
||||
}
|
||||
|
||||
void dumpBroadcastFilterState(PrintWriter pw, String prefix) {
|
||||
if (requiredPermission != null) {
|
||||
pw.print(prefix); pw.print("requiredPermission="); pw.println(requiredPermission);
|
||||
}
|
||||
|
@ -41,11 +41,13 @@ class BroadcastRecord extends Binder {
|
||||
final int callingUid; // the uid of who sent this
|
||||
final boolean ordered; // serialize the send to receivers?
|
||||
final boolean sticky; // originated from existing sticky data?
|
||||
final boolean initialSticky; // initial broadcast from register to sticky?
|
||||
final String requiredPermission; // a permission the caller has required
|
||||
final List receivers; // contains BroadcastFilter and ResolveInfo
|
||||
final IIntentReceiver resultTo; // who receives final result if non-null
|
||||
long dispatchTime; // when dispatch started on this set of receivers
|
||||
long startTime; // when current receiver started for timeouts.
|
||||
long receiverTime; // when current receiver started for timeouts.
|
||||
long finishTime; // when we finished the broadcast.
|
||||
int resultCode; // current result code value.
|
||||
String resultData; // current result data value.
|
||||
Bundle resultExtras; // current result extra data values.
|
||||
@ -73,28 +75,55 @@ class BroadcastRecord extends Binder {
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + this);
|
||||
pw.println(prefix + intent);
|
||||
if (sticky) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle != null) {
|
||||
pw.println(prefix + "extras: " + bundle.toString());
|
||||
}
|
||||
}
|
||||
pw.println(prefix + "proc=" + callerApp);
|
||||
pw.println(prefix + "caller=" + callerPackage
|
||||
+ " callingPid=" + callingPid
|
||||
+ " callingUid=" + callingUid);
|
||||
pw.println(prefix + "requiredPermission=" + requiredPermission);
|
||||
if (requiredPermission != null) {
|
||||
pw.println(prefix + "requiredPermission=" + requiredPermission);
|
||||
}
|
||||
pw.println(prefix + "dispatchTime=" + dispatchTime + " ("
|
||||
+ (SystemClock.uptimeMillis()-dispatchTime) + " since now)");
|
||||
pw.println(prefix + "startTime=" + startTime + " ("
|
||||
+ (SystemClock.uptimeMillis()-startTime) + " since now)");
|
||||
pw.println(prefix + "anrCount=" + anrCount);
|
||||
pw.println(prefix + "resultTo=" + resultTo
|
||||
+ " resultCode=" + resultCode + " resultData=" + resultData);
|
||||
pw.println(prefix + "resultExtras=" + resultExtras);
|
||||
pw.println(prefix + "resultAbort=" + resultAbort
|
||||
+ " ordered=" + ordered + " sticky=" + sticky);
|
||||
pw.println(prefix + "nextReceiver=" + nextReceiver
|
||||
+ " receiver=" + receiver);
|
||||
pw.println(prefix + "curFilter=" + curFilter);
|
||||
pw.println(prefix + "curReceiver="
|
||||
+ ((curReceiver != null) ? curReceiver : "(null)"));
|
||||
pw.println(prefix + "curApp=" + curApp);
|
||||
+ (SystemClock.uptimeMillis()-dispatchTime) + "ms since now)");
|
||||
if (finishTime != 0) {
|
||||
pw.println(prefix + "finishTime=" + finishTime + " ("
|
||||
+ (SystemClock.uptimeMillis()-finishTime) + "ms since now)");
|
||||
} else {
|
||||
pw.println(prefix + "receiverTime=" + receiverTime + " ("
|
||||
+ (SystemClock.uptimeMillis()-receiverTime) + "ms since now)");
|
||||
}
|
||||
if (anrCount != 0) {
|
||||
pw.println(prefix + "anrCount=" + anrCount);
|
||||
}
|
||||
if (resultTo != null || resultCode != -1 || resultData != null) {
|
||||
pw.println(prefix + "resultTo=" + resultTo
|
||||
+ " resultCode=" + resultCode + " resultData=" + resultData);
|
||||
}
|
||||
if (resultExtras != null) {
|
||||
pw.println(prefix + "resultExtras=" + resultExtras);
|
||||
}
|
||||
if (resultAbort || ordered || sticky || initialSticky) {
|
||||
pw.println(prefix + "resultAbort=" + resultAbort
|
||||
+ " ordered=" + ordered + " sticky=" + sticky
|
||||
+ " initialSticky=" + initialSticky);
|
||||
}
|
||||
if (nextReceiver != 0 || receiver != null) {
|
||||
pw.println(prefix + "nextReceiver=" + nextReceiver
|
||||
+ " receiver=" + receiver);
|
||||
}
|
||||
if (curFilter != null) {
|
||||
pw.println(prefix + "curFilter=" + curFilter);
|
||||
}
|
||||
if (curReceiver != null) {
|
||||
pw.println(prefix + "curReceiver=" + curReceiver);
|
||||
}
|
||||
if (curApp != null) {
|
||||
pw.println(prefix + "curApp=" + curApp);
|
||||
pw.println(prefix + "curComponent="
|
||||
+ (curComponent != null ? curComponent.toShortString() : "--"));
|
||||
pw.println(prefix + "curSourceDir=" + curReceiver.applicationInfo.sourceDir);
|
||||
@ -114,7 +143,7 @@ class BroadcastRecord extends Binder {
|
||||
Object o = receivers.get(i);
|
||||
pw.println(prefix + "Receiver #" + i + ": " + o);
|
||||
if (o instanceof BroadcastFilter)
|
||||
((BroadcastFilter)o).dump(pw, p2);
|
||||
((BroadcastFilter)o).dumpBrief(pw, p2);
|
||||
else if (o instanceof ResolveInfo)
|
||||
((ResolveInfo)o).dump(printer, p2);
|
||||
}
|
||||
@ -124,7 +153,7 @@ class BroadcastRecord extends Binder {
|
||||
int _callingPid, int _callingUid, String _requiredPermission,
|
||||
List _receivers, IIntentReceiver _resultTo, int _resultCode,
|
||||
String _resultData, Bundle _resultExtras, boolean _serialized,
|
||||
boolean _sticky) {
|
||||
boolean _sticky, boolean _initialSticky) {
|
||||
intent = _intent;
|
||||
callerApp = _callerApp;
|
||||
callerPackage = _callerPackage;
|
||||
@ -138,6 +167,7 @@ class BroadcastRecord extends Binder {
|
||||
resultExtras = _resultExtras;
|
||||
ordered = _serialized;
|
||||
sticky = _sticky;
|
||||
initialSticky = _initialSticky;
|
||||
nextReceiver = 0;
|
||||
state = IDLE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user