Merge "Put activity into stopped state if recreated while stopped"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index edeb838..a4c667f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5183,8 +5183,10 @@
         if (Looper.myLooper() != mMainThread.getLooper()) {
             throw new IllegalStateException("Must be called from main thread");
         }
-        mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, null, false,
-                false /* preserveWindow */);
+        try {
+            ActivityManagerNative.getDefault().requestActivityRelaunch(mToken);
+        } catch (RemoteException e) {
+        }
     }
 
     /**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index aacd5da..c7f19a2 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -413,6 +413,14 @@
             return true;
         }
 
+        case REQUEST_ACTIVITY_RELAUNCH: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            requestActivityRelaunch(token);
+            reply.writeNoException();
+            return true;
+        }
+
         case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -3434,6 +3442,16 @@
         data.recycle();
         reply.recycle();
     }
+    public void requestActivityRelaunch(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(REQUEST_ACTIVITY_RELAUNCH, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
     public boolean releaseActivityInstance(IBinder token) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index e411e03..dfeea57 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -102,6 +102,7 @@
     public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
     public boolean finishActivityAffinity(IBinder token) throws RemoteException;
     public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
+    public void requestActivityRelaunch(IBinder token) throws RemoteException;
     public boolean releaseActivityInstance(IBinder token) throws RemoteException;
     public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
     public boolean willActivityBeVisible(IBinder token) throws RemoteException;
@@ -958,7 +959,6 @@
     int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
     int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;
 
-
     // Start of L transactions
     int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
     int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
@@ -1062,4 +1062,7 @@
     int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
     int SET_RENDER_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 378;
     int SET_HAS_TOP_UI = IBinder.FIRST_CALL_TRANSACTION + 379;
+
+    // Start of O transactions
+    int REQUEST_ACTIVITY_RELAUNCH = IBinder.FIRST_CALL_TRANSACTION+400;
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 908b8e0..0cf7dc4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4764,6 +4764,23 @@
         }
     }
 
+    @Override
+    public final void requestActivityRelaunch(IBinder token) {
+        synchronized(this) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                return;
+            }
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                r.forceNewConfig = true;
+                r.task.stack.ensureActivityConfigurationLocked(r, 0, false);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
     /**
      * This is the internal entry point for handling Activity.finish().
      *
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index edc165a..fa9f518 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4860,6 +4860,11 @@
         } else {
             mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
             r.state = ActivityState.PAUSED;
+            // if the app is relaunched when it's stopped, and we're not resuming,
+            // put it back into stopped state.
+            if (r.stopped) {
+                addToStopping(r, true /* immediate */);
+            }
         }
 
         r.configChangeFlags = 0;