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

Commit 570d249c authored by Chris Li's avatar Chris Li Committed by Automerger Merge Worker
Browse files

Merge "Wait for TaskFragmentOrganizer to finish handling transaction" into...

Merge "Wait for TaskFragmentOrganizer to finish handling transaction" into tm-qpr-dev am: 3294ef42

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19564031



Change-Id: I55787b4ac6e4018b19ad03d33ca9e86e5ac000e1
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 0859d150 3294ef42
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package android.window;

import android.os.IBinder;
import android.view.RemoteAnimationDefinition;
import android.window.ITaskFragmentOrganizer;
import android.window.WindowContainerTransaction;

/** @hide */
interface ITaskFragmentOrganizerController {
@@ -50,4 +52,11 @@ interface ITaskFragmentOrganizerController {
     * only occupies a portion of Task bounds.
     */
    boolean isActivityEmbedded(in IBinder activityToken);

    /**
     * Notifies the server that the organizer has finished handling the given transaction. The
     * server should apply the given {@link WindowContainerTransaction} for the necessary changes.
     */
    void onTransactionHandled(in ITaskFragmentOrganizer organizer, in IBinder transactionToken,
        in WindowContainerTransaction wct);
}
+25 −7
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.content.Intent;
import android.content.res.Configuration;
@@ -148,6 +147,28 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
        }
    }

    /**
     * Notifies the server that the organizer has finished handling the given transaction. The
     * server should apply the given {@link WindowContainerTransaction} for the necessary changes.
     *
     * @param transactionToken  {@link TaskFragmentTransaction#getTransactionToken()} from
     *                          {@link #onTransactionReady(TaskFragmentTransaction)}
     * @param wct               {@link WindowContainerTransaction} that the server should apply for
     *                          update of the transaction.
     * @see com.android.server.wm.WindowOrganizerController#enforceTaskPermission for permission
     * requirement.
     * @hide
     */
    public void onTransactionHandled(@NonNull IBinder transactionToken,
            @NonNull WindowContainerTransaction wct) {
        wct.setTaskFragmentOrganizer(mInterface);
        try {
            getController().onTransactionHandled(mInterface, transactionToken, wct);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Called when a TaskFragment is created and organized by this organizer.
     *
@@ -318,12 +339,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
    /**
     * Called when the transaction is ready so that the organizer can update the TaskFragments based
     * on the changes in transaction.
     * Note: {@link WindowOrganizer#applyTransaction} permission requirement is conditional for
     * {@link TaskFragmentOrganizer}.
     * @see com.android.server.wm.WindowOrganizerController#enforceTaskPermission
     * @hide
     */
    @SuppressLint("AndroidFrameworkRequiresPermission")
    public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        final List<TaskFragmentTransaction.Change> changes = transaction.getChanges();
@@ -389,8 +406,9 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
                            "Unknown TaskFragmentEvent=" + change.getType());
            }
        }
        // TODO(b/240519866): notify TaskFragmentOrganizerController that the transition is done.
        applyTransaction(wct);

        // Notify the server, and the server should apply the WindowContainerTransaction.
        onTransactionHandled(transaction.getTransactionToken(), wct);
    }

    @Override
+17 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
@@ -41,19 +42,31 @@ import java.util.List;
 */
public final class TaskFragmentTransaction implements Parcelable {

    /** Unique token to represent this transaction. */
    private final IBinder mTransactionToken;

    /** Changes in this transaction. */
    private final ArrayList<Change> mChanges = new ArrayList<>();

    public TaskFragmentTransaction() {}
    public TaskFragmentTransaction() {
        mTransactionToken = new Binder();
    }

    private TaskFragmentTransaction(Parcel in) {
        mTransactionToken = in.readStrongBinder();
        in.readTypedList(mChanges, Change.CREATOR);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeStrongBinder(mTransactionToken);
        dest.writeTypedList(mChanges);
    }

    public IBinder getTransactionToken() {
        return mTransactionToken;
    }

    /** Adds a {@link Change} to this transaction. */
    public void addChange(@Nullable Change change) {
        if (change != null) {
@@ -74,7 +87,9 @@ public final class TaskFragmentTransaction implements Parcelable {
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("TaskFragmentTransaction{changes=[");
        sb.append("TaskFragmentTransaction{token=");
        sb.append(mTransactionToken);
        sb.append(" changes=[");
        for (int i = 0; i < mChanges.size(); ++i) {
            if (i > 0) {
                sb.append(',');
+12 −0
Original line number Diff line number Diff line
@@ -2041,6 +2041,12 @@
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "-108248992": {
      "message": "Defer transition ready for TaskFragmentTransaction=%s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
    },
    "-106400104": {
      "message": "Preload recents with %s",
      "level": "DEBUG",
@@ -2089,6 +2095,12 @@
      "group": "WM_DEBUG_STATES",
      "at": "com\/android\/server\/wm\/TaskFragment.java"
    },
    "-79016993": {
      "message": "Continue transition ready for TaskFragmentTransaction=%s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
    },
    "-70719599": {
      "message": "Unregister remote animations for organizer=%s uid=%d pid=%d",
      "level": "VERBOSE",
+78 −26
Original line number Diff line number Diff line
@@ -49,7 +49,9 @@ import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;

import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.common.ProtoLog;

import java.lang.annotation.Retention;
@@ -68,6 +70,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr

    private final ActivityTaskManagerService mAtmService;
    private final WindowManagerGlobalLock mGlobalLock;
    private final WindowOrganizerController mWindowOrganizerController;

    /**
     * A Map which manages the relationship between
     * {@link ITaskFragmentOrganizer} and {@link TaskFragmentOrganizerState}
@@ -82,9 +86,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr

    private final ArraySet<Task> mTmpTaskSet = new ArraySet<>();

    TaskFragmentOrganizerController(ActivityTaskManagerService atm) {
        mAtmService = atm;
    TaskFragmentOrganizerController(@NonNull ActivityTaskManagerService atm,
            @NonNull WindowOrganizerController windowOrganizerController) {
        mAtmService = requireNonNull(atm);
        mGlobalLock = atm.mGlobalLock;
        mWindowOrganizerController = requireNonNull(windowOrganizerController);
    }

    /**
@@ -131,6 +137,14 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        private final SparseArray<RemoteAnimationDefinition> mRemoteAnimationDefinitions =
                new SparseArray<>();

        /**
         * List of {@link TaskFragmentTransaction#getTransactionToken()} that have been sent to the
         * organizer. If the transaction is sent during a transition, the
         * {@link TransitionController} will wait until the transaction is finished.
         * @see #onTransactionFinished(IBinder)
         */
        private final List<IBinder> mRunningTransactions = new ArrayList<>();

        TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer, int pid, int uid) {
            mOrganizer = organizer;
            mOrganizerPid = pid;
@@ -176,6 +190,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                taskFragment.removeImmediately();
                mOrganizedTaskFragments.remove(taskFragment);
            }
            for (int i = mRunningTransactions.size() - 1; i >= 0; i--) {
                // Cleanup any running transaction to unblock the current transition.
                onTransactionFinished(mRunningTransactions.get(i));
            }
            mOrganizer.asBinder().unlinkToDeath(this, 0 /*flags*/);
        }

@@ -320,6 +338,40 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                    .setActivityIntent(activity.intent)
                    .setActivityToken(activityToken);
        }

        void dispatchTransaction(@NonNull TaskFragmentTransaction transaction) {
            if (transaction.isEmpty()) {
                return;
            }
            try {
                mOrganizer.onTransactionReady(transaction);
            } catch (RemoteException e) {
                Slog.d(TAG, "Exception sending TaskFragmentTransaction", e);
                return;
            }
            onTransactionStarted(transaction.getTransactionToken());
        }

        /** Called when the transaction is sent to the organizer. */
        void onTransactionStarted(@NonNull IBinder transactionToken) {
            if (!mWindowOrganizerController.getTransitionController().isCollecting()) {
                return;
            }
            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                    "Defer transition ready for TaskFragmentTransaction=%s", transactionToken);
            mRunningTransactions.add(transactionToken);
            mWindowOrganizerController.getTransitionController().deferTransitionReady();
        }

        /** Called when the transaction is finished. */
        void onTransactionFinished(@NonNull IBinder transactionToken) {
            if (!mRunningTransactions.remove(transactionToken)) {
                return;
            }
            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                    "Continue transition ready for TaskFragmentTransaction=%s", transactionToken);
            mWindowOrganizerController.getTransitionController().continueTransitionReady();
        }
    }

    @Nullable
@@ -336,7 +388,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
    }

    @Override
    public void registerOrganizer(ITaskFragmentOrganizer organizer) {
    public void registerOrganizer(@NonNull ITaskFragmentOrganizer organizer) {
        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        synchronized (mGlobalLock) {
@@ -354,7 +406,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
    }

    @Override
    public void unregisterOrganizer(ITaskFragmentOrganizer organizer) {
    public void unregisterOrganizer(@NonNull ITaskFragmentOrganizer organizer) {
        validateAndGetState(organizer);
        final int pid = Binder.getCallingPid();
        final long uid = Binder.getCallingUid();
@@ -372,8 +424,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
    }

    @Override
    public void registerRemoteAnimations(ITaskFragmentOrganizer organizer, int taskId,
            RemoteAnimationDefinition definition) {
    public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId,
            @NonNull RemoteAnimationDefinition definition) {
        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        synchronized (mGlobalLock) {
@@ -398,7 +450,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
    }

    @Override
    public void unregisterRemoteAnimations(ITaskFragmentOrganizer organizer, int taskId) {
    public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, int taskId) {
        final int pid = Binder.getCallingPid();
        final long uid = Binder.getCallingUid();
        synchronized (mGlobalLock) {
@@ -416,6 +468,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        }
    }

    @Override
    public void onTransactionHandled(@NonNull ITaskFragmentOrganizer organizer,
            @NonNull IBinder transactionToken, @NonNull WindowContainerTransaction wct) {
        synchronized (mGlobalLock) {
            // Keep the calling identity to avoid unsecure change.
            mWindowOrganizerController.applyTransaction(wct);
            final TaskFragmentOrganizerState state = validateAndGetState(organizer);
            state.onTransactionFinished(transactionToken);
        }
    }

    /**
     * Gets the {@link RemoteAnimationDefinition} set on the given organizer if exists. Returns
     * {@code null} if it doesn't, or if the organizer has activity(ies) embedded in untrusted mode.
@@ -775,13 +838,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        }
        final int organizerNum = mPendingTaskFragmentEvents.size();
        for (int i = 0; i < organizerNum; i++) {
            final ITaskFragmentOrganizer organizer = mTaskFragmentOrganizerState.get(
                    mPendingTaskFragmentEvents.keyAt(i)).mOrganizer;
            dispatchPendingEvents(organizer, mPendingTaskFragmentEvents.valueAt(i));
            final TaskFragmentOrganizerState state =
                    mTaskFragmentOrganizerState.get(mPendingTaskFragmentEvents.keyAt(i));
            dispatchPendingEvents(state, mPendingTaskFragmentEvents.valueAt(i));
        }
    }

    void dispatchPendingEvents(@NonNull ITaskFragmentOrganizer organizer,
    void dispatchPendingEvents(@NonNull TaskFragmentOrganizerState state,
            @NonNull List<PendingTaskFragmentEvent> pendingEvents) {
        if (pendingEvents.isEmpty()) {
            return;
@@ -817,7 +880,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                if (mTmpTaskSet.add(task)) {
                    // Make sure the organizer know about the Task config.
                    transaction.addChange(prepareChange(new PendingTaskFragmentEvent.Builder(
                            PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED, organizer)
                            PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED, state.mOrganizer)
                            .setTask(task)
                            .build()));
                }
@@ -825,7 +888,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
            transaction.addChange(prepareChange(event));
        }
        mTmpTaskSet.clear();
        dispatchTransactionInfo(organizer, transaction);
        state.dispatchTransaction(transaction);
        pendingEvents.removeAll(candidateEvents);
    }

@@ -855,6 +918,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
        }

        final ITaskFragmentOrganizer organizer = taskFragment.getTaskFragmentOrganizer();
        final TaskFragmentOrganizerState state = validateAndGetState(organizer);
        final TaskFragmentTransaction transaction = new TaskFragmentTransaction();
        // Make sure the organizer know about the Task config.
        transaction.addChange(prepareChange(new PendingTaskFragmentEvent.Builder(
@@ -862,22 +926,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
                .setTask(taskFragment.getTask())
                .build()));
        transaction.addChange(prepareChange(event));
        dispatchTransactionInfo(event.mTaskFragmentOrg, transaction);
        state.dispatchTransaction(transaction);
        mPendingTaskFragmentEvents.get(organizer.asBinder()).remove(event);
    }

    private void dispatchTransactionInfo(@NonNull ITaskFragmentOrganizer organizer,
            @NonNull TaskFragmentTransaction transaction) {
        if (transaction.isEmpty()) {
            return;
        }
        try {
            organizer.onTransactionReady(transaction);
        } catch (RemoteException e) {
            Slog.d(TAG, "Exception sending TaskFragmentTransaction", e);
        }
    }

    @Nullable
    private TaskFragmentTransaction.Change prepareChange(
            @NonNull PendingTaskFragmentEvent event) {
Loading