diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 6c6e547d9ef8e..df670f46903e2 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3202,6 +3202,59 @@ package android.window { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public final class TaskFragmentAppearedInfo implements android.os.Parcelable { + method @NonNull public android.view.SurfaceControl getLeash(); + method @NonNull public android.window.TaskFragmentInfo getTaskFragmentInfo(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public final class TaskFragmentCreationParams implements android.os.Parcelable { + method @NonNull public android.os.IBinder getFragmentToken(); + method @NonNull public android.graphics.Rect getInitialBounds(); + method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizer(); + method @NonNull public android.os.IBinder getOwnerToken(); + method public int getWindowingMode(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public static final class TaskFragmentCreationParams.Builder { + ctor public TaskFragmentCreationParams.Builder(@NonNull android.window.TaskFragmentOrganizerToken, @NonNull android.os.IBinder, @NonNull android.os.IBinder); + method @NonNull public android.window.TaskFragmentCreationParams build(); + method @NonNull public android.window.TaskFragmentCreationParams.Builder setInitialBounds(@NonNull android.graphics.Rect); + method @NonNull public android.window.TaskFragmentCreationParams.Builder setWindowingMode(int); + } + + public final class TaskFragmentInfo implements android.os.Parcelable { + method public boolean equalsForTaskFragmentOrganizer(@Nullable android.window.TaskFragmentInfo); + method @NonNull public java.util.List getActivities(); + method @NonNull public android.content.res.Configuration getConfiguration(); + method @NonNull public android.os.IBinder getFragmentToken(); + method @NonNull public android.graphics.Point getPositionInParent(); + method @NonNull public android.window.WindowContainerToken getToken(); + method public int getWindowingMode(); + method public boolean hasRunningActivity(); + method public boolean isEmpty(); + method public boolean isVisible(); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public class TaskFragmentOrganizer extends android.window.WindowOrganizer { + ctor public TaskFragmentOrganizer(@NonNull java.util.concurrent.Executor); + method @NonNull public java.util.concurrent.Executor getExecutor(); + method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); + method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentAppearedInfo); + method public void onTaskFragmentError(@NonNull android.os.IBinder, @NonNull Throwable); + method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); + method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); + method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); + method @CallSuper public void registerOrganizer(); + method @CallSuper public void unregisterOrganizer(); + } + + public final class TaskFragmentOrganizerToken implements android.os.Parcelable { + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public class TaskOrganizer extends android.window.WindowOrganizer { ctor public TaskOrganizer(); method @BinderThread public void addStartingWindow(@NonNull android.window.StartingWindowInfo, @NonNull android.os.IBinder); @@ -3230,9 +3283,13 @@ package android.window { public final class WindowContainerTransaction implements android.os.Parcelable { ctor public WindowContainerTransaction(); + method @NonNull public android.window.WindowContainerTransaction createTaskFragment(@NonNull android.window.TaskFragmentCreationParams); + method @NonNull public android.window.WindowContainerTransaction deleteTaskFragment(@NonNull android.window.WindowContainerToken); method public int describeContents(); method @NonNull public android.window.WindowContainerTransaction reorder(@NonNull android.window.WindowContainerToken, boolean); method @NonNull public android.window.WindowContainerTransaction reparent(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, boolean); + method @NonNull public android.window.WindowContainerTransaction reparentActivityToTaskFragment(@NonNull android.os.IBinder, @NonNull android.os.IBinder); + method @NonNull public android.window.WindowContainerTransaction reparentChildren(@NonNull android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken); method @NonNull public android.window.WindowContainerTransaction reparentTasks(@Nullable android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, @Nullable int[], @Nullable int[], boolean); method @NonNull public android.window.WindowContainerTransaction scheduleFinishEnterPip(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect); method @NonNull public android.window.WindowContainerTransaction setActivityWindowingMode(@NonNull android.window.WindowContainerToken, int); @@ -3240,12 +3297,14 @@ package android.window { method @NonNull public android.window.WindowContainerTransaction setAppBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect); method @NonNull public android.window.WindowContainerTransaction setBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect); method @NonNull public android.window.WindowContainerTransaction setBoundsChangeTransaction(@NonNull android.window.WindowContainerToken, @NonNull android.view.SurfaceControl.Transaction); + method @NonNull public android.window.WindowContainerTransaction setErrorCallbackToken(@NonNull android.os.IBinder); method @NonNull public android.window.WindowContainerTransaction setFocusable(@NonNull android.window.WindowContainerToken, boolean); method @NonNull public android.window.WindowContainerTransaction setHidden(@NonNull android.window.WindowContainerToken, boolean); method @NonNull public android.window.WindowContainerTransaction setLaunchRoot(@NonNull android.window.WindowContainerToken, @Nullable int[], @Nullable int[]); method @NonNull public android.window.WindowContainerTransaction setScreenSizeDp(@NonNull android.window.WindowContainerToken, int, int); method @NonNull public android.window.WindowContainerTransaction setSmallestScreenWidthDp(@NonNull android.window.WindowContainerToken, int); method @NonNull public android.window.WindowContainerTransaction setWindowingMode(@NonNull android.window.WindowContainerToken, int); + method @NonNull public android.window.WindowContainerTransaction startActivityInTaskFragment(@NonNull android.os.IBinder, @NonNull android.os.IBinder, @NonNull android.content.Intent, @Nullable android.os.Bundle); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } diff --git a/core/java/android/window/TaskFragmentAppearedInfo.java b/core/java/android/window/TaskFragmentAppearedInfo.java index 234b30c0662c2..89d9a9508a713 100644 --- a/core/java/android/window/TaskFragmentAppearedInfo.java +++ b/core/java/android/window/TaskFragmentAppearedInfo.java @@ -17,6 +17,7 @@ package android.window; import android.annotation.NonNull; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; import android.view.SurfaceControl; @@ -25,6 +26,7 @@ import android.view.SurfaceControl; * Data object for the TaskFragment info provided when a TaskFragment is presented to an organizer. * @hide */ +@TestApi public final class TaskFragmentAppearedInfo implements Parcelable { @NonNull @@ -33,16 +35,19 @@ public final class TaskFragmentAppearedInfo implements Parcelable { @NonNull private final SurfaceControl mLeash; + /** @hide */ public TaskFragmentAppearedInfo( @NonNull TaskFragmentInfo taskFragmentInfo, @NonNull SurfaceControl leash) { mTaskFragmentInfo = taskFragmentInfo; mLeash = leash; } + @NonNull public TaskFragmentInfo getTaskFragmentInfo() { return mTaskFragmentInfo; } + @NonNull public SurfaceControl getLeash() { return mLeash; } @@ -52,6 +57,7 @@ public final class TaskFragmentAppearedInfo implements Parcelable { mLeash = in.readTypedObject(SurfaceControl.CREATOR); } + /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeTypedObject(mTaskFragmentInfo, flags); @@ -79,6 +85,7 @@ public final class TaskFragmentAppearedInfo implements Parcelable { + "}"; } + /** @hide */ @Override public int describeContents() { return 0; diff --git a/core/java/android/window/TaskFragmentCreationParams.java b/core/java/android/window/TaskFragmentCreationParams.java index e4d6a6c07835c..81ab7836435d8 100644 --- a/core/java/android/window/TaskFragmentCreationParams.java +++ b/core/java/android/window/TaskFragmentCreationParams.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WindowingMode; import android.annotation.NonNull; +import android.annotation.TestApi; import android.graphics.Rect; import android.os.IBinder; import android.os.Parcel; @@ -29,11 +30,12 @@ import android.os.Parcelable; * Data object for options to create TaskFragment with. * @hide */ +@TestApi public final class TaskFragmentCreationParams implements Parcelable { /** The organizer that will organize this TaskFragment. */ @NonNull - private final ITaskFragmentOrganizer mOrganizer; + private final TaskFragmentOrganizerToken mOrganizer; /** * Unique token assigned from the client organizer to identify the {@link TaskFragmentInfo} when @@ -58,25 +60,29 @@ public final class TaskFragmentCreationParams implements Parcelable { private int mWindowingMode = WINDOWING_MODE_UNDEFINED; private TaskFragmentCreationParams( - @NonNull ITaskFragmentOrganizer organizer, @NonNull IBinder fragmentToken, - @NonNull IBinder ownerToken) { + @NonNull TaskFragmentOrganizerToken organizer, + @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) { mOrganizer = organizer; mFragmentToken = fragmentToken; mOwnerToken = ownerToken; } - public ITaskFragmentOrganizer getOrganizer() { + @NonNull + public TaskFragmentOrganizerToken getOrganizer() { return mOrganizer; } + @NonNull public IBinder getFragmentToken() { return mFragmentToken; } + @NonNull public IBinder getOwnerToken() { return mOwnerToken; } + @NonNull public Rect getInitialBounds() { return mInitialBounds; } @@ -87,16 +93,17 @@ public final class TaskFragmentCreationParams implements Parcelable { } private TaskFragmentCreationParams(Parcel in) { - mOrganizer = ITaskFragmentOrganizer.Stub.asInterface(in.readStrongBinder()); + mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in); mFragmentToken = in.readStrongBinder(); mOwnerToken = in.readStrongBinder(); mInitialBounds.readFromParcel(in); mWindowingMode = in.readInt(); } + /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeStrongInterface(mOrganizer); + mOrganizer.writeToParcel(dest, flags); dest.writeStrongBinder(mFragmentToken); dest.writeStrongBinder(mOwnerToken); mInitialBounds.writeToParcel(dest, flags); @@ -128,16 +135,17 @@ public final class TaskFragmentCreationParams implements Parcelable { + "}"; } + /** @hide */ @Override public int describeContents() { return 0; } /** Builder to construct the options to create TaskFragment with. */ - public static class Builder { + public static final class Builder { @NonNull - private final ITaskFragmentOrganizer mOrganizer; + private final TaskFragmentOrganizerToken mOrganizer; @NonNull private final IBinder mFragmentToken; @@ -151,26 +159,29 @@ public final class TaskFragmentCreationParams implements Parcelable { @WindowingMode private int mWindowingMode = WINDOWING_MODE_UNDEFINED; - public Builder(@NonNull ITaskFragmentOrganizer organizer, @NonNull IBinder fragmentToken, - @NonNull IBinder ownerToken) { + public Builder(@NonNull TaskFragmentOrganizerToken organizer, + @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) { mOrganizer = organizer; mFragmentToken = fragmentToken; mOwnerToken = ownerToken; } /** Sets the initial bounds for the TaskFragment. */ + @NonNull public Builder setInitialBounds(@NonNull Rect bounds) { mInitialBounds.set(bounds); return this; } /** Sets the initial windowing mode for the TaskFragment. */ + @NonNull public Builder setWindowingMode(@WindowingMode int windowingMode) { mWindowingMode = windowingMode; return this; } /** Constructs the options to create TaskFragment with. */ + @NonNull public TaskFragmentCreationParams build() { final TaskFragmentCreationParams result = new TaskFragmentCreationParams( mOrganizer, mFragmentToken, mOwnerToken); diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java index fe25e5726110b..dac420b6190df 100644 --- a/core/java/android/window/TaskFragmentInfo.java +++ b/core/java/android/window/TaskFragmentInfo.java @@ -22,6 +22,7 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.content.res.Configuration; import android.graphics.Point; import android.os.IBinder; @@ -35,6 +36,7 @@ import java.util.List; * Stores information about a particular TaskFragment. * @hide */ +@TestApi public final class TaskFragmentInfo implements Parcelable { /** @@ -63,11 +65,13 @@ public final class TaskFragmentInfo implements Parcelable { * List of Activity tokens that are children of this TaskFragment. It only contains Activities * that belong to the organizer process for security. */ + @NonNull private final List mActivities = new ArrayList<>(); /** Relative position of the fragment's top left corner in the parent container. */ private final Point mPositionInParent; + /** @hide */ public TaskFragmentInfo( @NonNull IBinder fragmentToken, @NonNull WindowContainerToken token, @NonNull Configuration configuration, boolean isEmpty, boolean hasRunningActivity, @@ -82,14 +86,17 @@ public final class TaskFragmentInfo implements Parcelable { mPositionInParent = requireNonNull(positionInParent); } + @NonNull public IBinder getFragmentToken() { return mFragmentToken; } + @NonNull public WindowContainerToken getToken() { return mToken; } + @NonNull public Configuration getConfiguration() { return mConfiguration; } @@ -106,6 +113,7 @@ public final class TaskFragmentInfo implements Parcelable { return mIsVisible; } + @NonNull public List getActivities() { return mActivities; } @@ -151,6 +159,7 @@ public final class TaskFragmentInfo implements Parcelable { mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR)); } + /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeStrongBinder(mFragmentToken); @@ -189,6 +198,7 @@ public final class TaskFragmentInfo implements Parcelable { + "}"; } + /** @hide */ @Override public int describeContents() { return 0; diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index b252df7c72e9b..f22f0b231ec9d 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -18,6 +18,7 @@ package android.window; import android.annotation.CallSuper; import android.annotation.NonNull; +import android.annotation.TestApi; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; @@ -26,9 +27,10 @@ import android.os.RemoteException; import java.util.concurrent.Executor; /** - * Interface for WindowManager to delegate control of {@link com.android.server.wm.TaskFragment}. + * Interface for WindowManager to delegate control of {@code TaskFragment}. * @hide */ +@TestApi public class TaskFragmentOrganizer extends WindowOrganizer { /** @@ -39,6 +41,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { /** * Creates a {@link Bundle} with an exception that can be passed to * {@link ITaskFragmentOrganizer#onTaskFragmentError}. + * @hide */ public static Bundle putExceptionInBundle(@NonNull Throwable exception) { final Bundle exceptionBundle = new Bundle(); @@ -126,6 +129,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer { super.applyTransaction(t); } + // Suppress the lint because it is not a registration method. + @SuppressWarnings("ExecutorRegistration") @Override public int applySyncTransaction(@NonNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback) { @@ -169,8 +174,11 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } }; - public ITaskFragmentOrganizer getIOrganizer() { - return mInterface; + private final TaskFragmentOrganizerToken mToken = new TaskFragmentOrganizerToken(mInterface); + + @NonNull + public TaskFragmentOrganizerToken getOrganizerToken() { + return mToken; } private ITaskFragmentOrganizerController getController() { diff --git a/core/java/android/window/TaskFragmentOrganizerToken.java b/core/java/android/window/TaskFragmentOrganizerToken.java new file mode 100644 index 0000000000000..d5216a6444d96 --- /dev/null +++ b/core/java/android/window/TaskFragmentOrganizerToken.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 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.annotation.TestApi; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Interface to communicate between window manager and {@link TaskFragmentOrganizer}. + *

+ * Window manager will dispatch TaskFragment information updates via this interface. + * It is necessary because {@link ITaskFragmentOrganizer} aidl interface can not be used as a + * {@link TestApi}. + * @hide + */ +@TestApi +public final class TaskFragmentOrganizerToken implements Parcelable { + private final ITaskFragmentOrganizer mRealToken; + + TaskFragmentOrganizerToken(ITaskFragmentOrganizer realToken) { + mRealToken = realToken; + } + + /** @hide */ + public IBinder asBinder() { + return mRealToken.asBinder(); + } + + /** @hide */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongInterface(mRealToken); + } + + /** @hide */ + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Creator CREATOR = + new Creator() { + @Override + public TaskFragmentOrganizerToken createFromParcel(Parcel in) { + final ITaskFragmentOrganizer realToken = + ITaskFragmentOrganizer.Stub.asInterface(in.readStrongBinder()); + // The TaskFragmentOrganizerToken may be null for TaskOrganizer or + // DisplayAreaOrganizer. + if (realToken == null) { + return null; + } + return new TaskFragmentOrganizerToken(realToken); + } + + @Override + public TaskFragmentOrganizerToken[] newArray(int size) { + return new TaskFragmentOrganizerToken[size]; + } + }; + + @Override + public int hashCode() { + return mRealToken.asBinder().hashCode(); + } + + @Override + public String toString() { + return "TaskFragmentOrganizerToken{" + mRealToken + "}"; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof TaskFragmentOrganizerToken)) { + return false; + } + return mRealToken.asBinder() == ((TaskFragmentOrganizerToken) obj).asBinder(); + } +} diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 380032b83db6c..a735bbc88e36e 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -410,7 +410,6 @@ public final class WindowContainerTransaction implements Parcelable { /** * Creates a new TaskFragment with the given options. * @param taskFragmentOptions the options used to create the TaskFragment. - * @hide */ @NonNull public WindowContainerTransaction createTaskFragment( @@ -426,7 +425,6 @@ public final class WindowContainerTransaction implements Parcelable { /** * Deletes an existing TaskFragment. Any remaining activities below it will be destroyed. * @param taskFragment the TaskFragment to be removed. - * @hide */ @NonNull public WindowContainerTransaction deleteTaskFragment( @@ -447,7 +445,6 @@ public final class WindowContainerTransaction implements Parcelable { * @param activityIntent intent to start the activity. * @param activityOptions ActivityOptions to start the activity with. * @see android.content.Context#startActivity(Intent, Bundle). - * @hide */ @NonNull public WindowContainerTransaction startActivityInTaskFragment( @@ -470,7 +467,6 @@ public final class WindowContainerTransaction implements Parcelable { * @param fragmentToken client assigned unique token to create TaskFragment with specified in * {@link TaskFragmentCreationParams#getFragmentToken()}. * @param activityToken activity to be reparented. - * @hide */ @NonNull public WindowContainerTransaction reparentActivityToTaskFragment( @@ -490,7 +486,6 @@ public final class WindowContainerTransaction implements Parcelable { * @param oldParent children of this TaskFragment will be reparented. * @param newParent the new parent TaskFragment to move the children to. If {@code null}, the * children will be moved to the leaf Task. - * @hide */ @NonNull public WindowContainerTransaction reparentChildren( @@ -535,7 +530,6 @@ public final class WindowContainerTransaction implements Parcelable { * @param errorCallbackToken client provided token that will be passed back as parameter in * the callback if there is an error on the server side. * @see ITaskFragmentOrganizer#onTaskFragmentError - * @hide */ @NonNull public WindowContainerTransaction setErrorCallbackToken(@NonNull IBinder errorCallbackToken) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java index d84554b59c2aa..27bd53d6b98d8 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/organizer/JetpackTaskFragmentOrganizer.java @@ -187,7 +187,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { } return new TaskFragmentCreationParams.Builder( - getIOrganizer(), + getOrganizerToken(), fragmentToken, ownerToken) .setInitialBounds(bounds) diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index ba13546bed2f9..57317228454e8 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -86,6 +86,7 @@ import android.view.DisplayInfo; import android.view.SurfaceControl; import android.window.ITaskFragmentOrganizer; import android.window.TaskFragmentInfo; +import android.window.TaskFragmentOrganizerToken; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; @@ -285,8 +286,8 @@ class TaskFragment extends WindowContainer { taskFragment.mAdjacentTaskFragment = this; } - void setTaskFragmentOrganizer(ITaskFragmentOrganizer organizer, int pid) { - mTaskFragmentOrganizer = organizer; + void setTaskFragmentOrganizer(TaskFragmentOrganizerToken organizer, int pid) { + mTaskFragmentOrganizer = ITaskFragmentOrganizer.Stub.asInterface(organizer.asBinder()); mTaskFragmentOrganizerPid = pid; } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 0be21cbd1bcee..abf8afa8d3e04 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -1109,11 +1109,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub @Nullable IBinder errorCallbackToken) { final ActivityRecord ownerActivity = ActivityRecord.forTokenLocked(creationParams.getOwnerToken()); + final ITaskFragmentOrganizer organizer = ITaskFragmentOrganizer.Stub.asInterface( + creationParams.getOrganizer().asBinder()); + if (ownerActivity == null || ownerActivity.getTask() == null) { final Throwable exception = new IllegalArgumentException("Not allowed to operate with invalid ownerToken"); - sendTaskFragmentOperationFailure(creationParams.getOrganizer(), errorCallbackToken, - exception); + sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); return; } // The ownerActivity has to belong to the same app as the root Activity of the target Task. @@ -1122,8 +1124,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub final Throwable exception = new IllegalArgumentException("Not allowed to operate with the ownerToken while " + "the root activity of the target task belong to the different app"); - sendTaskFragmentOperationFailure(creationParams.getOrganizer(), errorCallbackToken, - exception); + sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); return; } final TaskFragment taskFragment = new TaskFragment(mService, diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index f83f1cf0ad1b2..c35f317029612 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -41,6 +41,7 @@ import android.window.ITaskFragmentOrganizer; import android.window.TaskFragmentCreationParams; import android.window.TaskFragmentInfo; import android.window.TaskFragmentOrganizer; +import android.window.TaskFragmentOrganizerToken; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransactionCallback; @@ -62,6 +63,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { private TaskFragmentOrganizerController mController; private TaskFragmentOrganizer mOrganizer; + private TaskFragmentOrganizerToken mOrganizerToken; private ITaskFragmentOrganizer mIOrganizer; private TaskFragment mTaskFragment; private TaskFragmentInfo mTaskFragmentInfo; @@ -73,7 +75,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { public void setup() { mController = mWm.mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController; mOrganizer = new TaskFragmentOrganizer(Runnable::run); - mIOrganizer = mOrganizer.getIOrganizer(); + mOrganizerToken = mOrganizer.getOrganizerToken(); + mIOrganizer = ITaskFragmentOrganizer.Stub.asInterface(mOrganizerToken.asBinder()); mTaskFragmentInfo = mock(TaskFragmentInfo.class); mFragmentToken = new Binder(); mTaskFragment = @@ -235,7 +238,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { }); // Allow transaction to change a TaskFragment created by the organizer. - mTaskFragment.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); + mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); } @@ -257,7 +260,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { }); // Allow transaction to change a TaskFragment created by the organizer. - mTaskFragment.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); + mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); } @@ -280,7 +283,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { }); // Allow transaction to change a TaskFragment created by the organizer. - mTaskFragment.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); + mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); } @@ -306,8 +309,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { }); // Allow transaction to change a TaskFragment created by the organizer. - mTaskFragment.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); - taskFragment2.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); + mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); + taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); } @@ -317,7 +320,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mOrganizer.applyTransaction(mTransaction); // Allow organizer to create TaskFragment and start/reparent activity to TaskFragment. - mTransaction.createTaskFragment(mock(TaskFragmentCreationParams.class)); + final TaskFragmentCreationParams mockParams = mock(TaskFragmentCreationParams.class); + doReturn(mOrganizerToken).when(mockParams).getOrganizer(); + mTransaction.createTaskFragment(mockParams); mTransaction.startActivityInTaskFragment( mFragmentToken, null /* callerToken */, new Intent(), null /* activityOptions */); mTransaction.reparentActivityToTaskFragment(mFragmentToken, mock(IBinder.class)); @@ -352,7 +357,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { }); // Allow transaction to change a TaskFragment created by the organizer. - mTaskFragment.setTaskFragmentOrganizer(mIOrganizer, 10 /* pid */); + mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); }