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

Commit 8c946d65 authored by Chris Li's avatar Chris Li
Browse files

Implement WCT#create/deleteTaskFragment

Also update setAdjacentRoots to accept TaskFragment.
Pass the WCT to WM Core. The implementation on WM Core side will be in a
separate cl.

Bug: 190433129
Test: N/A
Change-Id: I1ee8a7ba0a43e18e180c05a7fcf0467967564782
parent cf717a20
Loading
Loading
Loading
Loading
+93 −6
Original line number Diff line number Diff line
@@ -326,7 +326,8 @@ public final class WindowContainerTransaction implements Parcelable {

    /**
     * Sets to containers adjacent to each other. Containers below two visible adjacent roots will
     * be made invisible. This currently only applies to Task containers created by organizer.
     * be made invisible. This currently only applies to TaskFragment containers created by
     * organizer.
     * @param root1 the first root.
     * @param root2 the second root.
     */
@@ -386,7 +387,11 @@ public final class WindowContainerTransaction implements Parcelable {
    @NonNull
    public WindowContainerTransaction createTaskFragment(
            @NonNull TaskFragmentCreationParams taskFragmentOptions) {
        // TODO(b/190433129) add actual implementation
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT)
                        .setTaskFragmentCreationOptions(taskFragmentOptions)
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
    }

@@ -398,7 +403,11 @@ public final class WindowContainerTransaction implements Parcelable {
    @NonNull
    public WindowContainerTransaction deleteTaskFragment(
            @NonNull WindowContainerToken taskFragment) {
        // TODO(b/190433129) add actual implementation
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT)
                        .setContainer(taskFragment.asBinder())
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
    }

@@ -415,7 +424,14 @@ public final class WindowContainerTransaction implements Parcelable {
    public WindowContainerTransaction startActivityInTaskFragment(
            @NonNull IBinder fragmentToken, @NonNull Intent activityIntent,
            @Nullable Bundle activityOptions) {
        // TODO(b/190433129) add actual implementation
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(
                        HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT)
                        .setContainer(fragmentToken)
                        .setActivityIntent(activityIntent)
                        .setLaunchOptions(activityOptions)
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
    }

@@ -429,7 +445,13 @@ public final class WindowContainerTransaction implements Parcelable {
    @NonNull
    public WindowContainerTransaction reparentActivityToTaskFragment(
            @NonNull IBinder fragmentToken, @NonNull IBinder activityToken) {
        // TODO(b/190433129) add actual implementation
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(
                        HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT)
                        .setReparentContainer(fragmentToken)
                        .setContainer(activityToken)
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
    }

@@ -444,7 +466,12 @@ public final class WindowContainerTransaction implements Parcelable {
    public WindowContainerTransaction reparentChildren(
            @NonNull WindowContainerToken oldParent,
            @Nullable WindowContainerToken newParent) {
        // TODO(b/190433129) add actual implementation
        final HierarchyOp hierarchyOp =
                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN)
                        .setContainer(oldParent.asBinder())
                        .setReparentContainer(newParent.asBinder())
                        .build();
        mHierarchyOps.add(hierarchyOp);
        return this;
    }

@@ -776,6 +803,11 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4;
        public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5;
        public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6;
        public static final int HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT = 7;
        public static final int HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT = 8;
        public static final int HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 9;
        public static final int HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 10;
        public static final int HIERARCHY_OP_TYPE_REPARENT_CHILDREN = 11;

        // The following key(s) are for use with mLaunchOptions:
        // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -803,6 +835,13 @@ public final class WindowContainerTransaction implements Parcelable {
        @Nullable
        private Bundle mLaunchOptions;

        @Nullable
        private Intent mActivityIntent;

        // Used as options for WindowContainerTransaction#createTaskFragment().
        @Nullable
        private TaskFragmentCreationParams mTaskFragmentCreationOptions;

        public static HierarchyOp createForReparent(
                @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {
            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT)
@@ -879,6 +918,8 @@ public final class WindowContainerTransaction implements Parcelable {
            mWindowingModes = copy.mWindowingModes;
            mActivityTypes = copy.mActivityTypes;
            mLaunchOptions = copy.mLaunchOptions;
            mActivityIntent = copy.mActivityIntent;
            mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions;
        }

        protected HierarchyOp(Parcel in) {
@@ -889,6 +930,8 @@ public final class WindowContainerTransaction implements Parcelable {
            mWindowingModes = in.createIntArray();
            mActivityTypes = in.createIntArray();
            mLaunchOptions = in.readBundle();
            mActivityIntent = in.readTypedObject(Intent.CREATOR);
            mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR);
        }

        public int getType() {
@@ -931,6 +974,16 @@ public final class WindowContainerTransaction implements Parcelable {
            return mLaunchOptions;
        }

        @Nullable
        public Intent getActivityIntent() {
            return mActivityIntent;
        }

        @Nullable
        public TaskFragmentCreationParams getTaskFragmentCreationOptions() {
            return mTaskFragmentCreationOptions;
        }

        @Override
        public String toString() {
            switch (mType) {
@@ -955,6 +1008,19 @@ public final class WindowContainerTransaction implements Parcelable {
                case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
                    return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop
                            + "}";
                case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
                    return "{CreateTaskFragment: options=" + mTaskFragmentCreationOptions + "}";
                case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
                    return "{DeleteTaskFragment: taskFragment=" + mContainer + "}";
                case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                    return "{StartActivityInTaskFragment: fragmentToken=" + mContainer + " intent="
                            + mActivityIntent + " options=" + mLaunchOptions + "}";
                case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
                    return "{ReparentActivityToTaskFragment: fragmentToken=" + mReparent
                            + " activity=" + mContainer + "}";
                case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
                    return "{ReparentChildren: oldParent=" + mContainer + " newParent=" + mReparent
                            + "}";
                default:
                    return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
                            + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes
@@ -971,6 +1037,8 @@ public final class WindowContainerTransaction implements Parcelable {
            dest.writeIntArray(mWindowingModes);
            dest.writeIntArray(mActivityTypes);
            dest.writeBundle(mLaunchOptions);
            dest.writeTypedObject(mActivityIntent, flags);
            dest.writeTypedObject(mTaskFragmentCreationOptions, flags);
        }

        @Override
@@ -1011,6 +1079,12 @@ public final class WindowContainerTransaction implements Parcelable {
            @Nullable
            private Bundle mLaunchOptions;

            @Nullable
            private Intent mActivityIntent;

            @Nullable
            private TaskFragmentCreationParams mTaskFragmentCreationOptions;

            Builder(int type) {
                mType = type;
            }
@@ -1045,6 +1119,17 @@ public final class WindowContainerTransaction implements Parcelable {
                return this;
            }

            Builder setActivityIntent(@Nullable Intent activityIntent) {
                mActivityIntent = activityIntent;
                return this;
            }

            Builder setTaskFragmentCreationOptions(
                    @Nullable TaskFragmentCreationParams taskFragmentCreationOptions) {
                mTaskFragmentCreationOptions = taskFragmentCreationOptions;
                return this;
            }

            HierarchyOp build() {
                final HierarchyOp hierarchyOp = new HierarchyOp(mType);
                hierarchyOp.mContainer = mContainer;
@@ -1057,6 +1142,8 @@ public final class WindowContainerTransaction implements Parcelable {
                        : null;
                hierarchyOp.mToTop = mToTop;
                hierarchyOp.mLaunchOptions = mLaunchOptions;
                hierarchyOp.mActivityIntent = mActivityIntent;
                hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions;

                return hierarchyOp;
            }
+1 −14
Original line number Diff line number Diff line
@@ -602,18 +602,6 @@ class Task extends TaskFragment {
     */
    private boolean mForceNotOrganized;

    /**
     * This task was created by the task organizer which has the following implementations.
     * <ul>
     *     <lis>The task won't be removed when it is empty. Removal has to be an explicit request
     *     from the task organizer.</li>
     *     <li>Unlike other non-root tasks, it's direct children are visible to the task
     *     organizer for ordering purposes.</li>
     * </ul>
     */
    @VisibleForTesting
    boolean mCreatedByOrganizer;

    // Tracking cookie for the creation of this task.
    IBinder mLaunchCookie;

@@ -641,7 +629,7 @@ class Task extends TaskFragment {
            IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
            boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
            boolean _removeWithTaskOrganizer) {
        super(atmService);
        super(atmService, _createdByOrganizer);

        mTaskId = _taskId;
        mUserId = _userId;
@@ -693,7 +681,6 @@ class Task extends TaskFragment {
        mHandler = new ActivityTaskHandler(mTaskSupervisor.mLooper);
        mCurrentUser = mAtmService.mAmInternal.getCurrentUserId();

        mCreatedByOrganizer = _createdByOrganizer;
        mLaunchCookie = _launchCookie;
        mDeferTaskAppear = _deferTaskAppear;
        mRemoveWithTaskOrganizer = _removeWithTaskOrganizer;
+22 −1
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentInfo;

import com.android.internal.annotations.VisibleForTesting;
@@ -184,6 +185,25 @@ class TaskFragment extends WindowContainer<WindowContainer> {
    @Nullable
    private ActivityRecord mResumedActivity = null;

    /**
     * This TaskFragment was created by an organizer which has the following implementations.
     * <ul>
     *     <li>The TaskFragment won't be removed when it is empty. Removal has to be an explicit
     *     request from the organizer.</li>
     *     <li>If this fragment is a Task object then unlike other non-root tasks, it's direct
     *     children are visible to the organizer for ordering purposes.</li>
     *     <li>A TaskFragment can be created by {@link android.window.TaskFragmentOrganizer}, and
     *     a Task can be created by {@link android.window.TaskOrganizer}.</li>
     * </ul>
     */
    @VisibleForTesting
    boolean mCreatedByOrganizer;

    /** Organizer that organizing this TaskFragment. */
    // TODO(b/190433129) set the value when creating TaskFragment from WCT.
    @Nullable
    private ITaskFragmentOrganizer mTaskFragmentOrganizer;

    /** Client assigned unique token for this TaskFragment if this is created by an organizer. */
    // TODO(b/190433129) set the value when creating TaskFragment from WCT.
    @Nullable
@@ -245,12 +265,13 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        }
    }

    TaskFragment(ActivityTaskManagerService atmService) {
    TaskFragment(ActivityTaskManagerService atmService, boolean createdByOrganizer) {
        super(atmService.mWindowManager);

        mAtmService = atmService;
        mTaskSupervisor = atmService.mTaskSupervisor;
        mRootWindowContainer = mAtmService.mRootWindowContainer;
        mCreatedByOrganizer = createdByOrganizer;
    }

    void setAdjacentTaskFragment(TaskFragment taskFragment) {
+47 −3
Original line number Diff line number Diff line
@@ -17,12 +17,17 @@
package com.android.server.wm;

import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;

import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
@@ -34,6 +39,7 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -51,6 +57,7 @@ import android.window.ITaskOrganizerController;
import android.window.ITransitionPlayer;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
import android.window.TaskFragmentCreationParams;
import android.window.WindowContainerTransaction;

import com.android.internal.annotations.VisibleForTesting;
@@ -504,13 +511,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
            return effects;
        }

        final WindowContainer wc;
        final IBinder fragmentToken;
        switch (type) {
            case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT:
                effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
                break;
            case HIERARCHY_OP_TYPE_REORDER:
            case HIERARCHY_OP_TYPE_REPARENT:
                final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
                wc = WindowContainer.fromBinder(hop.getContainer());
                if (wc == null || !wc.isAttached()) {
                    Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                    break;
@@ -546,6 +555,40 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
                mService.startActivityFromRecents(taskId, launchOpts);
                break;
            case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
                final TaskFragmentCreationParams taskFragmentCreationOptions =
                        hop.getTaskFragmentCreationOptions();
                // TODO(b/190433129) add actual implementation on WM Core
                break;
            case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
                wc = WindowContainer.fromBinder(hop.getContainer());
                if (wc == null || !wc.isAttached()) {
                    Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                    break;
                }
                final TaskFragment taskFragment = wc.asTaskFragment();
                if (taskFragment == null || taskFragment.asTask() != null) {
                    throw new IllegalArgumentException(
                            "Can only delete organized TaskFragment, but not Task.");
                }
                // TODO(b/190433129) add actual implementation on WM Core
                break;
            case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
                fragmentToken = hop.getContainer();
                final Intent activityIntent = hop.getActivityIntent();
                final Bundle activityOptions = hop.getLaunchOptions();
                // TODO(b/190433129) add actual implementation on WM Core
                break;
            case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
                fragmentToken = hop.getNewParent();
                final ActivityRecord activity = ActivityRecord.forTokenLocked(hop.getContainer());
                // TODO(b/190433129) add actual implementation on WM Core
                break;
            case HIERARCHY_OP_TYPE_REPARENT_CHILDREN:
                final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer());
                final WindowContainer newParent = WindowContainer.fromBinder(hop.getNewParent());
                // TODO(b/190433129) add actual implementation on WM Core
                break;
        }
        return effects;
    }
@@ -707,8 +750,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
    }

    private int setAdjacentRootsHierarchyOp(WindowContainerTransaction.HierarchyOp hop) {
        final Task root1 = WindowContainer.fromBinder(hop.getContainer()).asTask();
        final Task root2 = WindowContainer.fromBinder(hop.getAdjacentRoot()).asTask();
        final TaskFragment root1 = WindowContainer.fromBinder(hop.getContainer()).asTaskFragment();
        final TaskFragment root2 =
                WindowContainer.fromBinder(hop.getAdjacentRoot()).asTaskFragment();
        if (!root1.mCreatedByOrganizer || !root2.mCreatedByOrganizer) {
            throw new IllegalArgumentException("setAdjacentRootsHierarchyOp: Not created by"
                    + " organizer root1=" + root1 + " root2=" + root2);