Merge "Fix #2999258: ANR in Settings after every reboot" into gingerbread

This commit is contained in:
Dianne Hackborn
2010-09-20 22:19:47 -07:00
committed by Android (Google) Code Review

View File

@@ -560,6 +560,11 @@ public final class ActivityManagerService extends ActivityManagerNative
*/ */
BroadcastRecord mPendingBroadcast = null; BroadcastRecord mPendingBroadcast = null;
/**
* The receiver index that is pending, to restart the broadcast if needed.
*/
int mPendingBroadcastRecvIndex;
/** /**
* Keeps track of all IIntentReceivers that have been registered for * Keeps track of all IIntentReceivers that have been registered for
* broadcasts. Hash keys are the receiver IBinder, hash value is * broadcasts. Hash keys are the receiver IBinder, hash value is
@@ -747,6 +752,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ComponentName mTopComponent; ComponentName mTopComponent;
String mTopAction; String mTopAction;
String mTopData; String mTopData;
boolean mProcessesReady = false;
boolean mSystemReady = false; boolean mSystemReady = false;
boolean mBooting = false; boolean mBooting = false;
boolean mWaitingUpdate = false; boolean mWaitingUpdate = false;
@@ -964,7 +970,11 @@ public final class ActivityManagerService extends ActivityManagerNative
return; return;
} }
broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), Intent intent = new Intent("android.intent.action.ANR");
if (!mProcessesReady) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null, null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID); false, false, MY_PID, Process.SYSTEM_UID);
@@ -1051,7 +1061,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Only process broadcast timeouts if the system is ready. That way // Only process broadcast timeouts if the system is ready. That way
// PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
// to do heavy lifting for system up // to do heavy lifting for system up
if (mSystemReady) { if (mProcessesReady) {
broadcastTimeout(); broadcastTimeout();
} }
} break; } break;
@@ -1717,10 +1727,12 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!knownToBeDead || app.thread == null) { if (!knownToBeDead || app.thread == null) {
// We already have the app running, or are waiting for it to // We already have the app running, or are waiting for it to
// come up (we have a pid but not yet its thread), so keep it. // come up (we have a pid but not yet its thread), so keep it.
if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
return app; return app;
} else { } else {
// An application record is attached to a previous process, // An application record is attached to a previous process,
// clean it up now. // clean it up now.
if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
handleAppDiedLocked(app, true); handleAppDiedLocked(app, true);
} }
} }
@@ -1732,6 +1744,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// If we are in the background, then check to see if this process // If we are in the background, then check to see if this process
// is bad. If so, we will just silently fail. // is bad. If so, we will just silently fail.
if (mBadProcesses.get(info.processName, info.uid) != null) { if (mBadProcesses.get(info.processName, info.uid) != null) {
if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
+ "/" + info.processName);
return null; return null;
} }
} else { } else {
@@ -1739,6 +1753,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// crash count so that we won't make it bad until they see at // crash count so that we won't make it bad until they see at
// least one crash dialog again, and make the process good again // least one crash dialog again, and make the process good again
// if it had been bad. // if it had been bad.
if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
+ "/" + info.processName);
mProcessCrashTimes.remove(info.processName, info.uid); mProcessCrashTimes.remove(info.processName, info.uid);
if (mBadProcesses.get(info.processName, info.uid) != null) { if (mBadProcesses.get(info.processName, info.uid) != null) {
EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
@@ -1760,12 +1776,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// If the system is not ready yet, then hold off on starting this // If the system is not ready yet, then hold off on starting this
// process until it is. // process until it is.
if (!mSystemReady if (!mProcessesReady
&& !isAllowedWhileBooting(info) && !isAllowedWhileBooting(info)
&& !allowWhileBooting) { && !allowWhileBooting) {
if (!mProcessesOnHold.contains(app)) { if (!mProcessesOnHold.contains(app)) {
mProcessesOnHold.add(app); mProcessesOnHold.add(app);
} }
if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
return app; return app;
} }
@@ -1787,6 +1804,8 @@ public final class ActivityManagerService extends ActivityManagerNative
app.pid = 0; app.pid = 0;
} }
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"startProcessLocked removing on hold: " + app);
mProcessesOnHold.remove(app); mProcessesOnHold.remove(app);
updateCpuStats(); updateCpuStats();
@@ -3040,11 +3059,8 @@ public final class ActivityManagerService extends ActivityManagerNative
Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
Uri.fromParts("package", packageName, null)); Uri.fromParts("package", packageName, null));
intent.putExtra(Intent.EXTRA_UID, pkgUid); intent.putExtra(Intent.EXTRA_UID, pkgUid);
synchronized (this) { broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, false, false);
null, null, 0, null, null, null,
false, false, MY_PID, Process.SYSTEM_UID);
}
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} finally { } finally {
@@ -3148,6 +3164,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public void closeSystemDialogs(String reason) { public void closeSystemDialogs(String reason) {
Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
if (reason != null) { if (reason != null) {
intent.putExtra("reason", reason); intent.putExtra("reason", reason);
} }
@@ -3225,6 +3242,9 @@ public final class ActivityManagerService extends ActivityManagerNative
forceStopPackageLocked(packageName, uid, false, false, true); forceStopPackageLocked(packageName, uid, false, false, true);
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
Uri.fromParts("package", packageName, null)); Uri.fromParts("package", packageName, null));
if (!mProcessesReady) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
intent.putExtra(Intent.EXTRA_UID, uid); intent.putExtra(Intent.EXTRA_UID, uid);
broadcastIntentLocked(null, null, intent, broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null, null, null, 0, null, null, null,
@@ -3427,6 +3447,8 @@ public final class ActivityManagerService extends ActivityManagerNative
} }
if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null; mPendingBroadcast = null;
scheduleBroadcastsLocked(); scheduleBroadcastsLocked();
} }
@@ -3502,7 +3524,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
List providers = normalMode ? generateApplicationProvidersLocked(app) : null; List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
if (!normalMode) { if (!normalMode) {
@@ -3561,6 +3583,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// Remove this record from the list of starting applications. // Remove this record from the list of starting applications.
mPersistentStartingProcesses.remove(app); mPersistentStartingProcesses.remove(app);
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"Attach application locked removing on hold: " + app);
mProcessesOnHold.remove(app); mProcessesOnHold.remove(app);
boolean badApp = false; boolean badApp = false;
@@ -3702,7 +3726,9 @@ public final class ActivityManagerService extends ActivityManagerNative
ArrayList<ProcessRecord> procs = ArrayList<ProcessRecord> procs =
new ArrayList<ProcessRecord>(mProcessesOnHold); new ArrayList<ProcessRecord>(mProcessesOnHold);
for (int ip=0; ip<NP; ip++) { for (int ip=0; ip<NP; ip++) {
this.startProcessLocked(procs.get(ip), "on-hold", null); if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
+ procs.get(ip));
startProcessLocked(procs.get(ip), "on-hold", null);
} }
} }
@@ -5253,7 +5279,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg); throw new SecurityException(msg);
} }
if (!mSystemReady && !mDidUpdate && !mWaitingUpdate if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
&& !cpi.processName.equals("system")) { && !cpi.processName.equals("system")) {
// If this content provider does not run in the system // If this content provider does not run in the system
// process, and the system is not yet ready to run other // process, and the system is not yet ready to run other
@@ -6040,6 +6066,11 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Removing system update proc: " + proc); Slog.i(TAG, "Removing system update proc: " + proc);
removeProcessLocked(proc, true); removeProcessLocked(proc, true);
} }
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
mProcessesReady = true;
} }
} }
@@ -7283,8 +7314,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (dumpAll) { if (dumpAll) {
pw.println(" Total persistent processes: " + numPers); pw.println(" Total persistent processes: " + numPers);
pw.println(" mStartRunning=" + mStartRunning pw.println(" mStartRunning=" + mStartRunning
+ " mSystemReady=" + mSystemReady + " mProcessesReady=" + mProcessesReady
+ " mBooting=" + mBooting + " mSystemReady=" + mSystemReady);
pw.println(" mBooting=" + mBooting
+ " mBooted=" + mBooted + " mBooted=" + mBooted
+ " mFactoryTest=" + mFactoryTest); + " mFactoryTest=" + mFactoryTest);
pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep); pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
@@ -8098,6 +8130,8 @@ public final class ActivityManagerService extends ActivityManagerNative
restart = true; restart = true;
} }
} }
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
"Clean-up removing on hold: " + app);
mProcessesOnHold.remove(app); mProcessesOnHold.remove(app);
if (app == mHomeProcess) { if (app == mHomeProcess) {
@@ -10118,7 +10152,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} }
boolean replaced = false; boolean replaced = false;
if (replacePending) { if (replacePending) {
for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
if (DEBUG_BROADCAST) Slog.v(TAG, if (DEBUG_BROADCAST) Slog.v(TAG,
"***** DROPPING ORDERED: " + intent); "***** DROPPING ORDERED: " + intent);
@@ -10137,35 +10171,41 @@ public final class ActivityManagerService extends ActivityManagerNative
return BROADCAST_SUCCESS; return BROADCAST_SUCCESS;
} }
public final int broadcastIntent(IApplicationThread caller, final Intent verifyBroadcastLocked(Intent intent) {
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky) {
// Refuse possible leaked file descriptors // Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) { if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent"); throw new IllegalArgumentException("File descriptors passed in Intent");
} }
int flags = intent.getFlags();
if (!mProcessesReady) {
// if the caller really truly claims to know what they're doing, go
// ahead and allow the broadcast without launching any receivers
if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
intent = new Intent(intent);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
} else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
+ " before boot completion");
throw new IllegalStateException("Cannot broadcast before boot completed");
}
}
if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
throw new IllegalArgumentException(
"Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
}
return intent;
}
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky) {
synchronized(this) { synchronized(this) {
int flags = intent.getFlags(); intent = verifyBroadcastLocked(intent);
if (!mSystemReady) {
// if the caller really truly claims to know what they're doing, go
// ahead and allow the broadcast without launching any receivers
if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
intent = new Intent(intent);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
} else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
+ " before boot completion");
throw new IllegalStateException("Cannot broadcast before boot completed");
}
}
if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
throw new IllegalArgumentException(
"Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
}
final ProcessRecord callerApp = getRecordForAppLocked(caller); final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid();
@@ -10186,6 +10226,8 @@ public final class ActivityManagerService extends ActivityManagerNative
int resultCode, String resultData, Bundle map, int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky) { String requiredPermission, boolean serialized, boolean sticky) {
synchronized(this) { synchronized(this) {
intent = verifyBroadcastLocked(intent);
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
int res = broadcastIntentLocked(null, packageName, intent, resolvedType, int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
resultTo, resultCode, resultData, map, requiredPermission, resultTo, resultCode, resultData, map, requiredPermission,
@@ -10399,6 +10441,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private final void processCurBroadcastLocked(BroadcastRecord r, private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app) throws RemoteException { ProcessRecord app) throws RemoteException {
if (DEBUG_BROADCAST) Slog.v(TAG,
"Process cur broadcast " + r + " for app " + app);
if (app.thread == null) { if (app.thread == null) {
throw new RemoteException(); throw new RemoteException();
} }
@@ -10418,9 +10462,13 @@ public final class ActivityManagerService extends ActivityManagerNative
ensurePackageDexOpt(r.intent.getComponent().getPackageName()); ensurePackageDexOpt(r.intent.getComponent().getPackageName());
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
r.resultCode, r.resultData, r.resultExtras, r.ordered); r.resultCode, r.resultData, r.resultExtras, r.ordered);
if (DEBUG_BROADCAST) Slog.v(TAG,
"Process cur broadcast " + r + " DELIVERED for app " + app);
started = true; started = true;
} finally { } finally {
if (!started) { if (!started) {
if (DEBUG_BROADCAST) Slog.v(TAG,
"Process cur broadcast " + r + ": NOT STARTED!");
r.receiver = null; r.receiver = null;
r.curApp = null; r.curApp = null;
app.curReceiver = null; app.curReceiver = null;
@@ -10585,6 +10633,8 @@ public final class ActivityManagerService extends ActivityManagerNative
} else { } else {
Slog.w(TAG, "pending app " + mPendingBroadcast.curApp Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
+ " died before responding to broadcast"); + " died before responding to broadcast");
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null; mPendingBroadcast = null;
} }
} }
@@ -10615,7 +10665,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// one time heavy lifting after system upgrades and can take // one time heavy lifting after system upgrades and can take
// significant amounts of time. // significant amounts of time.
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if (mSystemReady && r.dispatchTime > 0) { if (mProcessesReady && r.dispatchTime > 0) {
long now = SystemClock.uptimeMillis(); long now = SystemClock.uptimeMillis();
if ((numReceivers > 0) && if ((numReceivers > 0) &&
(now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
@@ -10686,7 +10736,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast " if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
+ r); + r);
if (DEBUG_BROADCAST) Slog.v(TAG, if (DEBUG_BROADCAST) Slog.v(TAG,
"Submitting BROADCAST_TIMEOUT_MSG for " "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at "
+ (r.receiverTime + BROADCAST_TIMEOUT)); + (r.receiverTime + BROADCAST_TIMEOUT));
Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
@@ -10754,10 +10804,15 @@ public final class ActivityManagerService extends ActivityManagerNative
} }
if (r.curApp != null && r.curApp.crashing) { if (r.curApp != null && r.curApp.crashing) {
// If the target process is crashing, just skip it. // If the target process is crashing, just skip it.
if (DEBUG_BROADCAST) Slog.v(TAG,
"Skipping deliver ordered " + r + " to " + r.curApp
+ ": process crashing");
skip = true; skip = true;
} }
if (skip) { if (skip) {
if (DEBUG_BROADCAST) Slog.v(TAG,
"Skipping delivery of ordered " + r + " for whatever reason");
r.receiver = null; r.receiver = null;
r.curFilter = null; r.curFilter = null;
r.state = BroadcastRecord.IDLE; r.state = BroadcastRecord.IDLE;
@@ -10789,6 +10844,8 @@ public final class ActivityManagerService extends ActivityManagerNative
} }
// Not running -- get it started, to be executed when the app comes up. // Not running -- get it started, to be executed when the app comes up.
if (DEBUG_BROADCAST) Slog.v(TAG,
"Need to start app " + targetProcess + " for broadcast " + r);
if ((r.curApp=startProcessLocked(targetProcess, if ((r.curApp=startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true, info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
@@ -10810,6 +10867,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} }
mPendingBroadcast = r; mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recIdx;
} }
} }