Merge "Use transaction for local activity relaunch" into pi-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f01eee4..1df724e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -30,12 +30,15 @@
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 @@
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 @@
// message is handled.
transaction.recycle();
}
+ // TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
Object obj = msg.obj;
@@ -2755,6 +2763,11 @@
}
}
+ @Override
+ TransactionExecutor getTransactionExecutor() {
+ return mTransactionExecutor;
+ }
+
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
@@ -4723,15 +4736,22 @@
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 961bca2..925080e 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -17,6 +17,7 @@
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 @@
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 7e66fd7..01b13a2 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.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 @@
* {@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 @@
* 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 @@
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.