From 770c4030691f11ca36ef0028a336a27eda2049ef Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Wed, 2 May 2018 18:40:59 -0700 Subject: [PATCH] Preserve custom activity intent on relaunch An activity can have a custom intent set via Activity#setIntent(). This was lost in ag/3305584 Change-Id: I88f3e164d2cf7f6c62989bba05cd84b9b83befc3 Fixes: 73181785 Test: ActivityThreadTest#testCustomIntentPreservedOnRelaunch --- core/java/android/app/ActivityThread.java | 15 +++++--- .../android/app/ClientTransactionHandler.java | 3 +- .../servertransaction/LaunchActivityItem.java | 2 +- .../TransactionExecutor.java | 3 +- .../app/activity/ActivityThreadTest.java | 35 +++++++++++++++++++ 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 037a87b7b54ef..c9ee6ac7051c0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2683,7 +2683,7 @@ public final class ActivityThread extends ClientTransactionHandler { // TODO(lifecycler): Can't switch to use #handleLaunchActivity() because it will try to // call #reportSizeConfigurations(), but the server might not know anything about the // activity if it was launched from LocalAcvitivyManager. - return performLaunchActivity(r); + return performLaunchActivity(r, null /* customIntent */); } public final Activity getActivity(IBinder token) { @@ -2768,7 +2768,7 @@ public final class ActivityThread extends ClientTransactionHandler { } /** Core implementation of activity launch. */ - private Activity performLaunchActivity(ActivityClientRecord r) { + private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, @@ -2838,6 +2838,9 @@ public final class ActivityThread extends ClientTransactionHandler { r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback); + if (customIntent != null) { + activity.mIntent = customIntent; + } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; @@ -2982,7 +2985,7 @@ public final class ActivityThread extends ClientTransactionHandler { */ @Override public Activity handleLaunchActivity(ActivityClientRecord r, - PendingTransactionActions pendingActions) { + PendingTransactionActions pendingActions, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); @@ -3005,7 +3008,7 @@ public final class ActivityThread extends ClientTransactionHandler { } WindowManagerGlobal.initialize(); - final Activity a = performLaunchActivity(r); + final Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); @@ -4699,6 +4702,8 @@ public final class ActivityThread extends ClientTransactionHandler { List pendingResults, List pendingIntents, PendingTransactionActions pendingActions, boolean startsNotResumed, Configuration overrideConfig, String reason) { + // Preserve last used intent, it may be set from Activity#setIntent(). + final Intent customIntent = r.activity.mIntent; // Need to ensure state is saved. if (!r.paused) { performPauseActivity(r, false, reason, null /* pendingActions */); @@ -4731,7 +4736,7 @@ public final class ActivityThread extends ClientTransactionHandler { r.startsNotResumed = startsNotResumed; r.overrideConfig = overrideConfig; - handleLaunchActivity(r, pendingActions); + handleLaunchActivity(r, pendingActions, customIntent); } @Override diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java index ea0d703a30e3b..d9c7cf3ccc74a 100644 --- a/core/java/android/app/ClientTransactionHandler.java +++ b/core/java/android/app/ClientTransactionHandler.java @@ -18,6 +18,7 @@ package android.app; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.TransactionExecutor; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -140,7 +141,7 @@ public abstract class ClientTransactionHandler { /** Perform activity launch. */ public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r, - PendingTransactionActions pendingActions); + PendingTransactionActions pendingActions, Intent customIntent); /** Perform activity start. */ public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r, diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index 7be82bf9f5055..6bae3595be4d6 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -75,7 +75,7 @@ public class LaunchActivityItem extends ClientTransactionItem { mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client); - client.handleLaunchActivity(r, pendingActions); + client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java index 5c803a5c95991..43a2b4cc43f80 100644 --- a/core/java/android/app/servertransaction/TransactionExecutor.java +++ b/core/java/android/app/servertransaction/TransactionExecutor.java @@ -173,7 +173,8 @@ public class TransactionExecutor { log("Transitioning to state: " + state); switch (state) { case ON_CREATE: - mTransactionHandler.handleLaunchActivity(r, mPendingActions); + mTransactionHandler.handleLaunchActivity(r, mPendingActions, + null /* customIntent */); break; case ON_START: mTransactionHandler.handleStartActivity(r, mPendingActions); diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 9ef58abba79a6..1750dac60e33e 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -16,7 +16,11 @@ package android.app.activity; +import static android.content.Intent.ACTION_EDIT; +import static android.content.Intent.ACTION_VIEW; + import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import android.app.Activity; import android.app.ActivityThread; @@ -27,6 +31,7 @@ import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.ResumeActivityItem; import android.app.servertransaction.StopActivityItem; import android.content.Intent; +import android.os.IBinder; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; @@ -94,6 +99,36 @@ public class ActivityThreadTest { }); } + /** Verify that custom intent set via Activity#setIntent() is preserved on relaunch. */ + @Test + public void testCustomIntentPreservedOnRelaunch() throws Exception { + final Intent initIntent = new Intent(); + initIntent.setAction(ACTION_VIEW); + final Activity activity = mActivityTestRule.launchActivity(initIntent); + IBinder token = activity.getActivityToken(); + + final ActivityThread activityThread = activity.getActivityThread(); + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + // Recreate and check that intent is still the same. + activity.recreate(); + + final Activity newActivity = activityThread.getActivity(token); + assertTrue("Original intent must be preserved after recreate", + initIntent.filterEquals(newActivity.getIntent())); + + // Set custom intent, recreate and check if it is preserved. + final Intent customIntent = new Intent(); + customIntent.setAction(ACTION_EDIT); + newActivity.setIntent(customIntent); + + activity.recreate(); + + final Activity lastActivity = activityThread.getActivity(token); + assertTrue("Custom intent must be preserved after recreate", + customIntent.filterEquals(lastActivity.getIntent())); + }); + } + private static ClientTransaction newRelaunchResumeTransaction(Activity activity) { final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null, null, 0, new MergedConfiguration(), false /* preserveWindow */);