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

Commit 3589fb90 authored by Charles Chen's avatar Charles Chen
Browse files

Add TaskFragmentParentInfo

This CL adds a TaskFragmentParentInfo class and extends
onTaskFragmentParentInfoChanged to dispatch display ID and
visibility of the parent Task.
It makes SplitController able to track visibility and display
changes and used to update SplitContainers if there's a folding
state change.

Test: atest SplitControllerTest TaskFragmentOrganizerControllerTest
Bug: 243609832
Bug: 207494880

Change-Id: If3d5db621b20d4005ce0b60e46ac98e1d1e962e3
parent 894d5160
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -188,6 +188,10 @@ public final class TaskFragmentInfo implements Parcelable {
    /**
    /**
     * Returns {@code true} if the parameters that are important for task fragment organizers are
     * Returns {@code true} if the parameters that are important for task fragment organizers are
     * equal between this {@link TaskFragmentInfo} and {@param that}.
     * equal between this {@link TaskFragmentInfo} and {@param that}.
     * Note that this method is usually called with
     * {@link com.android.server.wm.WindowOrganizerController#configurationsAreEqualForOrganizer(
     * Configuration, Configuration)} to determine if this {@link TaskFragmentInfo} should
     * be dispatched to the client.
     */
     */
    public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) {
    public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) {
        if (that == null) {
        if (that == null) {
+23 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

/**
 * The information about the parent Task of a particular TaskFragment
 * @hide
 */
parcelable TaskFragmentParentInfo;
 No newline at end of file
+130 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * The information about the parent Task of a particular TaskFragment
 * @hide
 */
public class TaskFragmentParentInfo implements Parcelable {
    @NonNull
    private final Configuration mConfiguration = new Configuration();

    private final int mDisplayId;

    private final boolean mVisibleRequested;

    public TaskFragmentParentInfo(@NonNull Configuration configuration, int displayId,
            boolean visibleRequested) {
        mConfiguration.setTo(configuration);
        mDisplayId = displayId;
        mVisibleRequested = visibleRequested;
    }

    public TaskFragmentParentInfo(@NonNull TaskFragmentParentInfo info) {
        mConfiguration.setTo(info.getConfiguration());
        mDisplayId = info.mDisplayId;
        mVisibleRequested = info.mVisibleRequested;
    }

    /** The {@link Configuration} of the parent Task */
    @NonNull
    public Configuration getConfiguration() {
        return mConfiguration;
    }

    /**
     * The display ID of the parent Task. {@link android.view.Display#INVALID_DISPLAY} means the
     * Task is detached from previously associated display.
     */
    public int getDisplayId() {
        return mDisplayId;
    }

    /** Whether the parent Task is requested to be visible or not */
    public boolean isVisibleRequested() {
        return mVisibleRequested;
    }

    /**
     * Returns {@code true} if the parameters which are important for task fragment
     * organizers are equal between this {@link TaskFragmentParentInfo} and {@code that}.
     * Note that this method is usually called with
     * {@link com.android.server.wm.WindowOrganizerController#configurationsAreEqualForOrganizer(
     * Configuration, Configuration)} to determine if this {@link TaskFragmentParentInfo} should
     * be dispatched to the client.
     */
    public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentParentInfo that) {
        if (that == null) {
            return false;
        }
        return getWindowingMode() == that.getWindowingMode() && mDisplayId == that.mDisplayId
                && mVisibleRequested == that.mVisibleRequested;
    }

    @WindowConfiguration.WindowingMode
    private int getWindowingMode() {
        return mConfiguration.windowConfiguration.getWindowingMode();
    }

    @Override
    public String toString() {
        return TaskFragmentParentInfo.class.getSimpleName() + ":{"
                + "config=" + mConfiguration
                + ", displayId=" + mDisplayId
                + ", visibleRequested=" + mVisibleRequested
                + "}";
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        mConfiguration.writeToParcel(dest, flags);
        dest.writeInt(mDisplayId);
        dest.writeBoolean(mVisibleRequested);
    }

    private TaskFragmentParentInfo(Parcel in) {
        mConfiguration.readFromParcel(in);
        mDisplayId = in.readInt();
        mVisibleRequested = in.readBoolean();
    }

    public static final Creator<TaskFragmentParentInfo> CREATOR =
            new Creator<TaskFragmentParentInfo>() {
                @Override
                public TaskFragmentParentInfo createFromParcel(Parcel in) {
                    return new TaskFragmentParentInfo(in);
                }

                @Override
                public TaskFragmentParentInfo[] newArray(int size) {
                    return new TaskFragmentParentInfo[size];
                }
            };

    @Override
    public int describeContents() {
        return 0;
    }
}
+28 −8
Original line number Original line Diff line number Diff line
@@ -171,10 +171,6 @@ public final class TaskFragmentTransaction implements Parcelable {
        /** @see #setTaskId(int) */
        /** @see #setTaskId(int) */
        private int mTaskId;
        private int mTaskId;


        /** @see #setTaskConfiguration(Configuration) */
        @Nullable
        private Configuration mTaskConfiguration;

        /** @see #setErrorCallbackToken(IBinder) */
        /** @see #setErrorCallbackToken(IBinder) */
        @Nullable
        @Nullable
        private IBinder mErrorCallbackToken;
        private IBinder mErrorCallbackToken;
@@ -191,6 +187,9 @@ public final class TaskFragmentTransaction implements Parcelable {
        @Nullable
        @Nullable
        private IBinder mActivityToken;
        private IBinder mActivityToken;


        @Nullable
        private TaskFragmentParentInfo mTaskFragmentParentInfo;

        public Change(@ChangeType int type) {
        public Change(@ChangeType int type) {
            mType = type;
            mType = type;
        }
        }
@@ -200,11 +199,11 @@ public final class TaskFragmentTransaction implements Parcelable {
            mTaskFragmentToken = in.readStrongBinder();
            mTaskFragmentToken = in.readStrongBinder();
            mTaskFragmentInfo = in.readTypedObject(TaskFragmentInfo.CREATOR);
            mTaskFragmentInfo = in.readTypedObject(TaskFragmentInfo.CREATOR);
            mTaskId = in.readInt();
            mTaskId = in.readInt();
            mTaskConfiguration = in.readTypedObject(Configuration.CREATOR);
            mErrorCallbackToken = in.readStrongBinder();
            mErrorCallbackToken = in.readStrongBinder();
            mErrorBundle = in.readBundle(TaskFragmentTransaction.class.getClassLoader());
            mErrorBundle = in.readBundle(TaskFragmentTransaction.class.getClassLoader());
            mActivityIntent = in.readTypedObject(Intent.CREATOR);
            mActivityIntent = in.readTypedObject(Intent.CREATOR);
            mActivityToken = in.readStrongBinder();
            mActivityToken = in.readStrongBinder();
            mTaskFragmentParentInfo = in.readTypedObject(TaskFragmentParentInfo.CREATOR);
        }
        }


        @Override
        @Override
@@ -213,11 +212,11 @@ public final class TaskFragmentTransaction implements Parcelable {
            dest.writeStrongBinder(mTaskFragmentToken);
            dest.writeStrongBinder(mTaskFragmentToken);
            dest.writeTypedObject(mTaskFragmentInfo, flags);
            dest.writeTypedObject(mTaskFragmentInfo, flags);
            dest.writeInt(mTaskId);
            dest.writeInt(mTaskId);
            dest.writeTypedObject(mTaskConfiguration, flags);
            dest.writeStrongBinder(mErrorCallbackToken);
            dest.writeStrongBinder(mErrorCallbackToken);
            dest.writeBundle(mErrorBundle);
            dest.writeBundle(mErrorBundle);
            dest.writeTypedObject(mActivityIntent, flags);
            dest.writeTypedObject(mActivityIntent, flags);
            dest.writeStrongBinder(mActivityToken);
            dest.writeStrongBinder(mActivityToken);
            dest.writeTypedObject(mTaskFragmentParentInfo, flags);
        }
        }


        /** The change is related to the TaskFragment created with this unique token. */
        /** The change is related to the TaskFragment created with this unique token. */
@@ -241,10 +240,10 @@ public final class TaskFragmentTransaction implements Parcelable {
            return this;
            return this;
        }
        }


        // TODO(b/241043377): Keep this API to prevent @TestApi changes. Remove in the next release.
        /** Configuration of the parent Task. */
        /** Configuration of the parent Task. */
        @NonNull
        @NonNull
        public Change setTaskConfiguration(@NonNull Configuration configuration) {
        public Change setTaskConfiguration(@NonNull Configuration configuration) {
            mTaskConfiguration = requireNonNull(configuration);
            return this;
            return this;
        }
        }


@@ -292,6 +291,19 @@ public final class TaskFragmentTransaction implements Parcelable {
            return this;
            return this;
        }
        }


        // TODO(b/241043377): Hide this API to prevent @TestApi changes. Remove in the next release.
        /**
         * Sets info of the parent Task of the embedded TaskFragment.
         * @see TaskFragmentParentInfo
         *
         * @hide pending unhide
         */
        @NonNull
        public Change setTaskFragmentParentInfo(@NonNull TaskFragmentParentInfo info) {
            mTaskFragmentParentInfo = requireNonNull(info);
            return this;
        }

        @ChangeType
        @ChangeType
        public int getType() {
        public int getType() {
            return mType;
            return mType;
@@ -311,9 +323,10 @@ public final class TaskFragmentTransaction implements Parcelable {
            return mTaskId;
            return mTaskId;
        }
        }


        // TODO(b/241043377): Keep this API to prevent @TestApi changes. Remove in the next release.
        @Nullable
        @Nullable
        public Configuration getTaskConfiguration() {
        public Configuration getTaskConfiguration() {
            return mTaskConfiguration;
            return mTaskFragmentParentInfo.getConfiguration();
        }
        }


        @Nullable
        @Nullable
@@ -337,6 +350,13 @@ public final class TaskFragmentTransaction implements Parcelable {
            return mActivityToken;
            return mActivityToken;
        }
        }


        // TODO(b/241043377): Hide this API to prevent @TestApi changes. Remove in the next release.
        /** @hide pending unhide */
        @Nullable
        public TaskFragmentParentInfo getTaskFragmentParentInfo() {
            return mTaskFragmentParentInfo;
        }

        @Override
        @Override
        public String toString() {
        public String toString() {
            return "Change{ type=" + mType + " }";
            return "Change{ type=" + mType + " }";
+7 −3
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ import android.util.Pair;
import android.util.Size;
import android.util.Size;
import android.util.SparseArray;
import android.util.SparseArray;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentParentInfo;
import android.window.TaskFragmentTransaction;
import android.window.TaskFragmentTransaction;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransaction;


@@ -191,7 +192,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
                        onTaskFragmentVanished(wct, info);
                        onTaskFragmentVanished(wct, info);
                        break;
                        break;
                    case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED:
                    case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED:
                        onTaskFragmentParentInfoChanged(wct, taskId, change.getTaskConfiguration());
                        onTaskFragmentParentInfoChanged(wct, taskId,
                                change.getTaskFragmentParentInfo());
                        break;
                        break;
                    case TYPE_TASK_FRAGMENT_ERROR:
                    case TYPE_TASK_FRAGMENT_ERROR:
                        final Bundle errorBundle = change.getErrorBundle();
                        final Bundle errorBundle = change.getErrorBundle();
@@ -346,12 +348,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
     *
     *
     * @param wct   The {@link WindowContainerTransaction} to make any changes with if needed.
     * @param wct   The {@link WindowContainerTransaction} to make any changes with if needed.
     * @param taskId    Id of the parent Task that is changed.
     * @param taskId    Id of the parent Task that is changed.
     * @param parentConfig  Config of the parent Task.
     * @param parentInfo  {@link TaskFragmentParentInfo} of the parent Task.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct,
    void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct,
            int taskId, @NonNull Configuration parentConfig) {
            int taskId, @NonNull TaskFragmentParentInfo parentInfo) {
        // TODO(b/241043111): handles displayId and visibility here.
        final Configuration parentConfig = parentInfo.getConfiguration();
        onTaskConfigurationChanged(taskId, parentConfig);
        onTaskConfigurationChanged(taskId, parentConfig);
        if (isInPictureInPicture(parentConfig)) {
        if (isInPictureInPicture(parentConfig)) {
            // No need to update presentation in PIP until the Task exit PIP.
            // No need to update presentation in PIP until the Task exit PIP.
Loading