diff options
3 files changed, 69 insertions, 11 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f01eee4709b5..1df724edeccb 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -30,12 +30,15 @@ import android.annotation.Nullable; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; +import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityLifecycleItem.LifecycleState; +import android.app.servertransaction.ActivityRelaunchItem; import android.app.servertransaction.ActivityResultItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.PendingTransactionActions.StopInfo; import android.app.servertransaction.TransactionExecutor; +import android.app.servertransaction.TransactionExecutorHelper; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; import android.content.ComponentName; @@ -520,6 +523,10 @@ public final class ActivityThread extends ClientTransactionHandler { return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS; } + public boolean isVisibleFromServer() { + return activity != null && activity.mVisibleFromServer; + } + public String toString() { ComponentName componentName = intent != null ? intent.getComponent() : null; return "ActivityRecord{" @@ -1797,6 +1804,7 @@ public final class ActivityThread extends ClientTransactionHandler { // message is handled. transaction.recycle(); } + // TODO(lifecycler): Recycle locally scheduled transactions. break; } Object obj = msg.obj; @@ -2755,6 +2763,11 @@ public final class ActivityThread extends ClientTransactionHandler { } } + @Override + TransactionExecutor getTransactionExecutor() { + return mTransactionExecutor; + } + void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } @@ -4723,15 +4736,22 @@ public final class ActivityThread extends ClientTransactionHandler { return; } - // TODO(b/73747058): Investigate converting this to use transaction to relaunch. - handleRelaunchActivityInner(r, 0 /* configChanges */, null /* pendingResults */, - null /* pendingIntents */, null /* pendingActions */, prevState != ON_RESUME, - r.overrideConfig, "handleRelaunchActivityLocally"); - // Restore back to the previous state before relaunch if needed. - if (prevState != r.getLifecycleState()) { - mTransactionExecutor.cycleToPath(r, prevState); - } + // Initialize a relaunch request. + final MergedConfiguration mergedConfiguration = new MergedConfiguration( + r.createdConfig != null ? r.createdConfig : mConfiguration, + r.overrideConfig); + final ActivityRelaunchItem activityRelaunchItem = ActivityRelaunchItem.obtain( + null /* pendingResults */, null /* pendingIntents */, 0 /* configChanges */, + mergedConfiguration, r.mPreserveWindow); + // Make sure to match the existing lifecycle state in the end of the transaction. + final ActivityLifecycleItem lifecycleRequest = + TransactionExecutorHelper.getLifecycleRequestForCurrentState(r); + // Schedule the transaction. + final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); + transaction.addCallback(activityRelaunchItem); + transaction.setLifecycleStateRequest(lifecycleRequest); + executeTransaction(transaction); } private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges, diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java index 961bca23c91a..925080e44778 100644 --- a/core/java/android/app/ClientTransactionHandler.java +++ b/core/java/android/app/ClientTransactionHandler.java @@ -17,6 +17,7 @@ package android.app; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.PendingTransactionActions; +import android.app.servertransaction.TransactionExecutor; import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -43,6 +44,22 @@ public abstract class ClientTransactionHandler { sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } + /** + * Execute transaction immediately without scheduling it. This is used for local requests, so + * it will also recycle the transaction. + */ + void executeTransaction(ClientTransaction transaction) { + transaction.preExecute(this); + getTransactionExecutor().execute(transaction); + transaction.recycle(); + } + + /** + * Get the {@link TransactionExecutor} that will be performing lifecycle transitions and + * callbacks for activities. + */ + abstract TransactionExecutor getTransactionExecutor(); + abstract void sendMessage(int what, Object obj); diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java index 7e66fd7a2ead..01b13a28aed1 100644 --- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java +++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java @@ -26,7 +26,7 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE; import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED; -import android.app.ActivityThread; +import android.app.ActivityThread.ActivityClientRecord; import android.util.IntArray; import com.android.internal.annotations.VisibleForTesting; @@ -124,7 +124,7 @@ public class TransactionExecutorHelper { * {@link ActivityLifecycleItem#UNDEFINED} if there is not path. */ @VisibleForTesting - public int getClosestPreExecutionState(ActivityThread.ActivityClientRecord r, + public int getClosestPreExecutionState(ActivityClientRecord r, int postExecutionState) { switch (postExecutionState) { case UNDEFINED: @@ -147,7 +147,7 @@ public class TransactionExecutorHelper { * were provided or there is not path. */ @VisibleForTesting - public int getClosestOfStates(ActivityThread.ActivityClientRecord r, int[] finalStates) { + public int getClosestOfStates(ActivityClientRecord r, int[] finalStates) { if (finalStates == null || finalStates.length == 0) { return UNDEFINED; } @@ -168,6 +168,27 @@ public class TransactionExecutorHelper { return closestState; } + /** Get the lifecycle state request to match the current state in the end of a transaction. */ + public static ActivityLifecycleItem getLifecycleRequestForCurrentState(ActivityClientRecord r) { + final int prevState = r.getLifecycleState(); + final ActivityLifecycleItem lifecycleItem; + switch (prevState) { + // TODO(lifecycler): Extend to support all possible states. + case ON_PAUSE: + lifecycleItem = PauseActivityItem.obtain(); + break; + case ON_STOP: + lifecycleItem = StopActivityItem.obtain(r.isVisibleFromServer(), + 0 /* configChanges */); + break; + default: + lifecycleItem = ResumeActivityItem.obtain(false /* isForward */); + break; + } + + return lifecycleItem; + } + /** * Check if there is a destruction involved in the path. We want to avoid a lifecycle sequence * that involves destruction and recreation if there is another path. |