Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbac87dd authored by Andrii Kulian's avatar Andrii Kulian Committed by Android (Google) Code Review
Browse files

Merge "Use transaction for local activity relaunch" into pi-dev

parents f45b3a11 914aa7da
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -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,
+17 −0
Original line number Diff line number Diff line
@@ -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);


+24 −3
Original line number Diff line number Diff line
@@ -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.