Merge "Introduce onNewActivityOptions for return activity"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 228d82e..28498ec 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5284,6 +5284,14 @@
         }
     }
 
+    /** @hide */
+    public void onNewActivityOptions(ActivityOptions options) {
+        mActivityTransitionState.setEnterActivityOptions(this, options);
+        if (!mStopped) {
+            mActivityTransitionState.enterReady(this);
+        }
+    }
+
     /**
      * Retrieve the ActivityOptions passed in from the launching activity or passed back
      * from an activity launched by this activity in its call to {@link
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 422d88c..7b48e1d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -77,6 +77,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SuperNotCalledException;
@@ -1113,6 +1114,11 @@
             sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
         }
 
+        public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
+            sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
+                    new Pair<IBinder, ActivityOptions>(token, options));
+        }
+
         public void setProcessState(int state) {
             updateProcessState(state, true);
         }
@@ -1196,6 +1202,7 @@
         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
         public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
         public static final int INSTALL_PROVIDER        = 145;
+        public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
 
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
@@ -1245,6 +1252,7 @@
                     case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
                     case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
                     case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
+                    case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
                 }
             }
             return Integer.toString(code);
@@ -1459,6 +1467,10 @@
                 case INSTALL_PROVIDER:
                     handleInstallProvider((ProviderInfo) msg.obj);
                     break;
+                case ON_NEW_ACTIVITY_OPTIONS:
+                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
+                    onNewActivityOptions(pair.first, pair.second);
+                    break;
             }
             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
         }
@@ -2435,6 +2447,13 @@
         }
     }
 
+    public void onNewActivityOptions(IBinder token, ActivityOptions options) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onNewActivityOptions(options);
+        }
+    }
+
     public void handleInstallProvider(ProviderInfo info) {
         installContentProviders(mInitialApplication, Lists.newArrayList(info));
     }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 5998d7a..6dead08 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -611,6 +611,16 @@
             return true;
         }
 
+        case SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            ActivityOptions options = new ActivityOptions(data.readBundle());
+            scheduleOnNewActivityOptions(token, options);
+            reply.writeNoException();
+            return true;
+        }
+
         case SET_PROCESS_STATE_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -1251,7 +1261,20 @@
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(timeout ? 1 : 0);
-        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeBundle(options == null ? null : options.toBundle());
+        mRemote.transact(SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index d0df7c3..d3c4854 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -140,6 +140,8 @@
             throws RemoteException;
     void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
             throws RemoteException;
+    void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
+            throws RemoteException;
     void setProcessState(int state) throws RemoteException;
     void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
     void updateTimePrefs(boolean is24Hour) throws RemoteException;
@@ -176,7 +178,7 @@
     int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
     int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
     int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
-
+    int SCHEDULE_ON_NEW_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
     int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
     int DISPATCH_PACKAGE_BROADCAST_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
     int SCHEDULE_CRASH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6474047..42afd67 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9370,8 +9370,11 @@
                     mWindowManager.setAppFullscreen(token, false);
                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
                     return true;
+                } else {
+                    r.task.stack.mReturningActivityOptions = options;
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                    return false;
                 }
-                return false;
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 545423b..ca518f3 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -209,7 +209,7 @@
     // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
     // background activity being drawn then the same call will be made with a true value.
     ActivityRecord mTranslucentActivityWaiting = null;
-    ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
+    private ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
             new ArrayList<ActivityRecord>();
     // Options passed from the caller of the convertToTranslucent to the activity that will
     // appear below it.
@@ -1203,7 +1203,17 @@
                         // else to do here.
                         if (DEBUG_VISBILITY) Slog.v(TAG, "Skipping: already visible at " + r);
                         r.stopFreezingScreenLocked(false);
-
+                        try {
+                            if (mReturningActivityOptions != null) {
+                                if (activityNdx > 0) {
+                                    ActivityRecord under = activities.get(activityNdx - 1);
+                                    under.app.thread.scheduleOnNewActivityOptions(under.appToken,
+                                            mReturningActivityOptions);
+                                }
+                                mReturningActivityOptions = null;
+                            }
+                        } catch(RemoteException e) {
+                        }
                     } else if (onlyThisProcess == null) {
                         // This activity is not currently visible, but is running.
                         // Tell it to become visible.
@@ -1291,6 +1301,12 @@
                 }
             }
         }
+
+        if (mTranslucentActivityWaiting != null &&
+                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
+            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
+            notifyActivityDrawnLocked(null);
+        }
     }
 
     void convertToTranslucent(ActivityRecord r, ActivityOptions options) {