Loading core/java/android/app/ActivityThread.java +28 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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{" Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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, Loading core/java/android/app/ClientTransactionHandler.java +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading core/java/android/app/servertransaction/TransactionExecutorHelper.java +24 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: Loading @@ -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; } Loading @@ -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. Loading Loading
core/java/android/app/ActivityThread.java +28 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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{" Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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, Loading
core/java/android/app/ClientTransactionHandler.java +17 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading
core/java/android/app/servertransaction/TransactionExecutorHelper.java +24 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: Loading @@ -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; } Loading @@ -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. Loading