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

Commit 397b1509 authored by Jeff Chang's avatar Jeff Chang
Browse files

Embedded Activities in TaskFragments

- Adding TaskFragments into the leaf Task to embed activities when
  activity started to the side.
- Delete TaskFragment
- Reparent TaskFragments

Bug: 189385246
Bug: 190433129
Test: wm presubmit and have test case in updating CL.
Change-Id: I7e7f5109457dd083d3b148d3ce676ad9aa5ad89f
parent cb977a8e
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.WindowingMode;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Parcel;
@@ -39,13 +38,6 @@ public final class TaskFragmentInfo implements Parcelable {
    @NonNull
    private final IBinder mFragmentToken;

    /**
     * The component name of the initial root activity of this TaskFragment, which will be used
     * to configure the relationships for TaskFragments.
     */
    @NonNull
    private final ComponentName mInitialComponentName;

    @NonNull
    private final WindowContainerToken mToken;

@@ -59,14 +51,12 @@ public final class TaskFragmentInfo implements Parcelable {
    private final boolean mIsVisible;

    public TaskFragmentInfo(
            @NonNull IBinder fragmentToken, @NonNull ComponentName initialComponentName,
            @NonNull WindowContainerToken token, @NonNull Configuration configuration,
            boolean isEmpty, boolean isVisible) {
        if (fragmentToken == null || initialComponentName == null) {
            @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token,
            @NonNull Configuration configuration, boolean isEmpty, boolean isVisible) {
        if (fragmentToken == null) {
            throw new IllegalArgumentException("Invalid TaskFragmentInfo.");
        }
        mFragmentToken = fragmentToken;
        mInitialComponentName = initialComponentName;
        mToken = token;
        mConfiguration.setTo(configuration);
        mIsEmpty = isEmpty;
@@ -77,10 +67,6 @@ public final class TaskFragmentInfo implements Parcelable {
        return mFragmentToken;
    }

    public ComponentName getInitialComponentName() {
        return mInitialComponentName;
    }

    public WindowContainerToken getToken() {
        return mToken;
    }
@@ -112,7 +98,6 @@ public final class TaskFragmentInfo implements Parcelable {
        }

        return mFragmentToken.equals(that.mFragmentToken)
                && mInitialComponentName.equals(that.mInitialComponentName)
                && mToken.equals(that.mToken)
                && mIsEmpty == that.mIsEmpty
                && mIsVisible == that.mIsVisible
@@ -121,7 +106,6 @@ public final class TaskFragmentInfo implements Parcelable {

    private TaskFragmentInfo(Parcel in) {
        mFragmentToken = in.readStrongBinder();
        mInitialComponentName = in.readTypedObject(ComponentName.CREATOR);
        mToken = in.readTypedObject(WindowContainerToken.CREATOR);
        mConfiguration.readFromParcel(in);
        mIsEmpty = in.readBoolean();
@@ -131,7 +115,6 @@ public final class TaskFragmentInfo implements Parcelable {
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeStrongBinder(mFragmentToken);
        dest.writeTypedObject(mInitialComponentName, flags);
        dest.writeTypedObject(mToken, flags);
        mConfiguration.writeToParcel(dest, flags);
        dest.writeBoolean(mIsEmpty);
@@ -156,7 +139,6 @@ public final class TaskFragmentInfo implements Parcelable {
    public String toString() {
        return "TaskFragmentInfo{"
                + " fragmentToken=" + mFragmentToken
                + " initialComponentName=" + mInitialComponentName
                + " token=" + mToken
                + " isEmpty=" + mIsEmpty
                + " isVisible=" + mIsVisible
+12 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
@@ -38,6 +39,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
@@ -488,6 +490,16 @@ public class ActivityStartController {
        return START_SUCCESS;
    }

    void startActivityInTaskFragment(@NonNull TaskFragment taskFragment,
            @NonNull Intent activityIntent, @Nullable Bundle activityOptions) {
        obtainStarter(activityIntent, "startActivityInTaskFragment")
                .setActivityOptions(activityOptions)
                .setInTaskFragment(taskFragment)
                .setCallingUid(Binder.getCallingUid())
                .setCallingPid(Binder.getCallingPid())
                .execute();
    }

    void registerRemoteAnimationForNextActivityStart(String packageName,
            RemoteAnimationAdapter adapter) {
        mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
+31 −5
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ class ActivityStarter {
    private int mPreferredWindowingMode;

    private Task mInTask;
    private TaskFragment mInTaskFragment;
    @VisibleForTesting
    boolean mAddingToTask;
    private Task mReuseTask;
@@ -342,6 +343,7 @@ class ActivityStarter {
        boolean avoidMoveToFront;
        ActivityRecord[] outActivity;
        Task inTask;
        TaskFragment inTaskFragment;
        String reason;
        ProfilerInfo profilerInfo;
        Configuration globalConfig;
@@ -392,6 +394,7 @@ class ActivityStarter {
            componentSpecified = false;
            outActivity = null;
            inTask = null;
            inTaskFragment = null;
            reason = null;
            profilerInfo = null;
            globalConfig = null;
@@ -407,7 +410,7 @@ class ActivityStarter {
        /**
         * Adopts all values from passed in request.
         */
        void set(Request request) {
        void set(@NonNull Request request) {
            caller = request.caller;
            intent = request.intent;
            intentGrants = request.intentGrants;
@@ -432,6 +435,7 @@ class ActivityStarter {
            componentSpecified = request.componentSpecified;
            outActivity = request.outActivity;
            inTask = request.inTask;
            inTaskFragment = request.inTaskFragment;
            reason = request.reason;
            profilerInfo = request.profilerInfo;
            globalConfig = request.globalConfig;
@@ -574,6 +578,7 @@ class ActivityStarter {
        mPreferredWindowingMode = starter.mPreferredWindowingMode;

        mInTask = starter.mInTask;
        mInTaskFragment = starter.mInTaskFragment;
        mAddingToTask = starter.mAddingToTask;
        mReuseTask = starter.mReuseTask;

@@ -835,6 +840,7 @@ class ActivityStarter {
        final int startFlags = request.startFlags;
        final SafeActivityOptions options = request.activityOptions;
        Task inTask = request.inTask;
        mInTaskFragment = request.inTaskFragment;

        int err = ActivityManager.START_SUCCESS;
        // Pull the optional Ephemeral Installer-only bundle out of the options early.
@@ -2204,6 +2210,7 @@ class ActivityStarter {
        mPreferredWindowingMode = WINDOWING_MODE_UNDEFINED;

        mInTask = null;
        mInTaskFragment = null;
        mAddingToTask = false;
        mReuseTask = null;

@@ -2691,11 +2698,23 @@ class ActivityStarter {
        mIntentDelivered = true;
    }

    private void addOrReparentStartingActivity(Task parent, String reason) {
        if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
            parent.addChild(mStartActivity);
    private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
        TaskFragment newParent = task;
        if (mInTaskFragment != null) {
            // mInTaskFragment is created and added to the leaf task by task fragment organizer's
            // request. If the task was resolved and different than mInTaskFragment, reparent the
            // task to mInTaskFragment for embedding.
            if (mInTaskFragment.getTask() != task) {
                task.reparent(mInTaskFragment, POSITION_TOP);
            } else {
            mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
                newParent = mInTaskFragment;
            }
        }
        if (mStartActivity.getTaskFragment() == null
                || mStartActivity.getTaskFragment() == newParent) {
            newParent.addChild(mStartActivity, POSITION_TOP);
        } else {
            mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
        }
    }

@@ -2927,6 +2946,11 @@ class ActivityStarter {
        return this;
    }

    ActivityStarter setInTaskFragment(TaskFragment taskFragment) {
        mRequest.inTaskFragment = taskFragment;
        return this;
    }

    ActivityStarter setWaitResult(WaitResult result) {
        mRequest.waitResult = result;
        return this;
@@ -3010,5 +3034,7 @@ class ActivityStarter {
        pw.print(mDoResume);
        pw.print(" mAddingToTask=");
        pw.println(mAddingToTask);
        pw.print(" mInTaskFragment=");
        pw.println(mInTaskFragment);
    }
}
+1 −3
Original line number Diff line number Diff line
@@ -629,7 +629,7 @@ class Task extends TaskFragment {
            IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
            boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
            boolean _removeWithTaskOrganizer) {
        super(atmService, _createdByOrganizer);
        super(atmService, null /* fragmentToken */, _createdByOrganizer);

        mTaskId = _taskId;
        mUserId = _userId;
@@ -643,7 +643,6 @@ class Task extends TaskFragment {
                : new PersistedTaskSnapshotData();
        // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
        setOrientation(SCREEN_ORIENTATION_UNSET);
        mRemoteToken = new RemoteToken(this);
        affinityIntent = _affinityIntent;
        affinity = _affinity;
        rootAffinity = _rootAffinity;
@@ -4986,7 +4985,6 @@ class Task extends TaskFragment {
        // Slot the activity into the history root task and proceed
        ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s "
                        + "callers: %s", r, task, new RuntimeException("here").fillInStackTrace());
        task.positionChildAtTop(r);

        // The transition animation and starting window are not needed if {@code allowMoveToFront}
        // is false, because the activity won't be visible.
+23 −15
Original line number Diff line number Diff line
@@ -74,7 +74,6 @@ import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.ResumeActivityItem;
import android.content.ComponentName;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.IBinder;
@@ -155,6 +154,9 @@ class TaskFragment extends WindowContainer<WindowContainer> {
     */
    int mMinHeight;

    /** Avoid reentrant of {@link #removeImmediately()}. */
    private boolean mRemoving;

    // The TaskFragment that adjacent to this one.
    private TaskFragment mAdjacentTaskFragment;

@@ -196,23 +198,13 @@ class TaskFragment extends WindowContainer<WindowContainer> {
    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
    private IBinder mFragmentToken;

    /**
     * The component name of the root activity that initiated this TaskFragment, which will be used
     * to configure the relationships for TaskFragments.
     */
    // TODO(b/190433129) set the value when creating TaskFragment from WCT.
    @Nullable
    private ComponentName mInitialComponentName;

    private final Rect mTmpInsets = new Rect();
    private final Rect mTmpBounds = new Rect();
    private final Rect mTmpFullBounds = new Rect();
@@ -260,15 +252,18 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        }
    }

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

        mAtmService = atmService;
        mTaskSupervisor = atmService.mTaskSupervisor;
        mTaskSupervisor = mAtmService.mTaskSupervisor;
        mRootWindowContainer = mAtmService.mRootWindowContainer;
        mCreatedByOrganizer = createdByOrganizer;
        mTaskFragmentOrganizerController =
                mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController;
        mFragmentToken = fragmentToken;
        mRemoteToken = new RemoteToken(this);
    }

    void setAdjacentTaskFragment(TaskFragment taskFragment) {
@@ -276,6 +271,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        taskFragment.mAdjacentTaskFragment = this;
    }

    void setTaskFragmentOrganizer(ITaskFragmentOrganizer organizer) {
        mTaskFragmentOrganizer = organizer;
    }

    TaskFragment getAdjacentTaskFragment() {
        return mAdjacentTaskFragment;
    }
@@ -1981,7 +1980,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        }
    }

    // TODO(b/190433129) call when TaskFragment is removed from WCT#deleteTaskFragment
    private void sendTaskFragmentVanished() {
        if (mTaskFragmentOrganizer != null) {
            mTaskFragmentOrganizerController.onTaskFragmentVanished(mTaskFragmentOrganizer, this);
@@ -1995,7 +1993,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
    TaskFragmentInfo getTaskFragmentInfo() {
        return new TaskFragmentInfo(
                mFragmentToken,
                mInitialComponentName,
                mRemoteToken.toWindowContainerToken(),
                getConfiguration(),
                getChildCount() == 0,
@@ -2026,6 +2023,17 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        mMinHeight = minHeight;
    }

    @Override
    void removeImmediately() {
        if (mRemoving) {
            return;
        }
        mRemoving = true;
        super.removeImmediately();
        sendTaskFragmentVanished();
        mRemoving = false;
    }

    boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll,
            boolean dumpClient, String dumpPackage, final boolean needSep, Runnable header) {
        boolean printed = false;
Loading