merge from open-source master
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1a22a26a..5f6356d 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1905,11 +1905,16 @@
                 + " app=" + app + " knownToBeDead=" + knownToBeDead
                 + " thread=" + (app != null ? app.thread : null)
                 + " pid=" + (app != null ? app.pid : -1));
-        if (app != null &&
-                (!knownToBeDead || app.thread == null) && app.pid > 0) {
-            return app;
+        if (app != null && app.pid > 0) {
+            if (!knownToBeDead || app.thread == null) {
+                return app;
+            } else {
+                // An application record is attached to a previous process,
+                // clean it up now.
+                handleAppDiedLocked(app, true);
+            }
         }
-        
+
         String hostingNameStr = hostingName != null
                 ? hostingName.flattenToShortString() : null;
         
@@ -4553,7 +4558,9 @@
 
         mProcDeaths[0]++;
         
-        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
+        // Clean up already done if the process has been re-started.
+        if (app.pid == pid && app.thread != null &&
+                app.thread.asBinder() == thread.asBinder()) {
             Log.i(TAG, "Process " + app.processName + " (pid " + pid
                     + ") has died.");
             EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
@@ -4603,6 +4610,11 @@
                     scheduleAppGcsLocked();
                 }
             }
+        } else if (app.pid != pid) {
+            // A new process has already been started.
+            Log.i(TAG, "Process " + app.processName + " (pid " + pid
+                    + ") has died and restarted (pid " + app.pid + ").");
+            EventLog.writeEvent(LOG_AM_PROCESS_DIED, pid, app.processName);
         } else if (Config.LOGD) {
             Log.d(TAG, "Received spurious death notification for thread "
                     + thread.asBinder());
@@ -5424,6 +5436,8 @@
                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
                         br.resultExtras, br.resultAbort, true);
                 scheduleBroadcastsLocked();
+                // We need to reset the state if we fails to start the receiver.
+                br.state = BroadcastRecord.IDLE;
             }
         }