diff options
| author | Chris Li <lihongyu@google.com> | 2021-07-12 17:24:41 -0700 |
|---|---|---|
| committer | Chris Li <lihongyu@google.com> | 2021-07-15 13:07:14 -0700 |
| commit | d5555da37a3a7f9508efee06b5c7abbb380af55d (patch) | |
| tree | b5b68f2d1250d8765801739fcab510c98546bab3 /core/java | |
| parent | 2f7eef8248746a16a6270ae527233303846420a2 (diff) | |
Allow TaskFragmentOrganizer to apply WCT without permission
TaskFragmentOrganizer will be used by regular apps without the
permission to manage Task. We are allow it to apply transactions if it
is operating on TaskFragment that is organized by itself.
Bug: 193191599
Test: atest WmTests:TaskFragmentOrganizerControllerTest
Change-Id: I82e5d49260680bd496ff184c6795ec817c65d858
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/window/DisplayAreaOrganizer.java | 2 | ||||
| -rw-r--r-- | core/java/android/window/TaskFragmentOrganizer.java | 13 | ||||
| -rw-r--r-- | core/java/android/window/TaskOrganizer.java | 1 | ||||
| -rw-r--r-- | core/java/android/window/WindowContainerTransaction.java | 51 | ||||
| -rw-r--r-- | core/java/android/window/WindowOrganizer.java | 19 |
5 files changed, 78 insertions, 8 deletions
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index e6746556fb67..6758a3b411a2 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -265,6 +265,7 @@ public class DisplayAreaOrganizer extends WindowOrganizer { } }; + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) private IDisplayAreaOrganizerController getController() { try { return getWindowOrganizerController().getDisplayAreaOrganizerController(); @@ -272,5 +273,4 @@ public class DisplayAreaOrganizer extends WindowOrganizer { return null; } } - } diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index 3b4d4e52c908..b252df7c72e9 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -120,6 +120,19 @@ public class TaskFragmentOrganizer extends WindowOrganizer { public void onTaskFragmentError( @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {} + @Override + public void applyTransaction(@NonNull WindowContainerTransaction t) { + t.setTaskFragmentOrganizer(mInterface); + super.applyTransaction(t); + } + + @Override + public int applySyncTransaction(@NonNull WindowContainerTransaction t, + @NonNull WindowContainerTransactionCallback callback) { + t.setTaskFragmentOrganizer(mInterface); + return super.applySyncTransaction(t, callback); + } + private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() { @Override public void onTaskFragmentAppeared(@NonNull TaskFragmentAppearedInfo taskFragmentInfo) { diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 8fa011028f44..6f250fc0ce7a 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -290,6 +290,7 @@ public class TaskOrganizer extends WindowOrganizer { } }; + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) private ITaskOrganizerController getController() { try { return getWindowOrganizerController().getTaskOrganizerController(); diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 9c512add3345..8735ed841ebc 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; /** * Represents a collection of operations on some WindowContainers that should be applied all at @@ -52,12 +53,16 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mErrorCallbackToken; + @Nullable + private ITaskFragmentOrganizer mTaskFragmentOrganizer; + public WindowContainerTransaction() {} private WindowContainerTransaction(Parcel in) { in.readMap(mChanges, null /* loader */); in.readList(mHierarchyOps, null /* loader */); mErrorCallbackToken = in.readStrongBinder(); + mTaskFragmentOrganizer = ITaskFragmentOrganizer.Stub.asInterface(in.readStrongBinder()); } private Change getOrCreateChange(IBinder token) { @@ -473,7 +478,7 @@ public final class WindowContainerTransaction implements Parcelable { final HierarchyOp hierarchyOp = new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN) .setContainer(oldParent.asBinder()) - .setReparentContainer(newParent.asBinder()) + .setReparentContainer(newParent != null ? newParent.asBinder() : null) .build(); mHierarchyOps.add(hierarchyOp); return this; @@ -497,6 +502,23 @@ public final class WindowContainerTransaction implements Parcelable { } /** + * Sets the {@link TaskFragmentOrganizer} that applies this {@link WindowContainerTransaction}. + * When this is set, the server side will not check for the permission of + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, but will ensure this WCT only + * contains operations that are allowed for this organizer, such as modifying TaskFragments that + * are organized by this organizer. + * @hide + */ + @NonNull + WindowContainerTransaction setTaskFragmentOrganizer(@NonNull ITaskFragmentOrganizer organizer) { + if (mTaskFragmentOrganizer != null) { + throw new IllegalStateException("Can't set multiple organizers for one transaction."); + } + mTaskFragmentOrganizer = organizer; + return this; + } + + /** * Merges another WCT into this one. * @param transfer When true, this will transfer everything from other potentially leaving * other in an unusable state. When false, other is left alone, but @@ -519,7 +541,17 @@ public final class WindowContainerTransaction implements Parcelable { } if (mErrorCallbackToken != null && other.mErrorCallbackToken != null && mErrorCallbackToken != other.mErrorCallbackToken) { - throw new IllegalArgumentException("Can't merge two WCT with different error token"); + throw new IllegalArgumentException("Can't merge two WCTs with different error token"); + } + final IBinder taskFragmentOrganizerAsBinder = mTaskFragmentOrganizer != null + ? mTaskFragmentOrganizer.asBinder() + : null; + final IBinder otherTaskFragmentOrganizerAsBinder = other.mTaskFragmentOrganizer != null + ? other.mTaskFragmentOrganizer.asBinder() + : null; + if (!Objects.equals(taskFragmentOrganizerAsBinder, otherTaskFragmentOrganizerAsBinder)) { + throw new IllegalArgumentException( + "Can't merge two WCTs from different TaskFragmentOrganizers"); } mErrorCallbackToken = mErrorCallbackToken != null ? mErrorCallbackToken @@ -547,11 +579,21 @@ public final class WindowContainerTransaction implements Parcelable { return mErrorCallbackToken; } + /** @hide */ + @Nullable + public ITaskFragmentOrganizer getTaskFragmentOrganizer() { + return mTaskFragmentOrganizer; + } + @Override @NonNull public String toString() { - return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps - + " errorCallbackToken=" + mErrorCallbackToken + " }"; + return "WindowContainerTransaction {" + + " changes = " + mChanges + + " hops = " + mHierarchyOps + + " errorCallbackToken=" + mErrorCallbackToken + + " taskFragmentOrganizer=" + mTaskFragmentOrganizer + + " }"; } @Override @@ -560,6 +602,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeMap(mChanges); dest.writeList(mHierarchyOps); dest.writeStrongBinder(mErrorCallbackToken); + dest.writeStrongInterface(mTaskFragmentOrganizer); } @Override diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java index 544d42240079..78dbebaf2738 100644 --- a/core/java/android/window/WindowOrganizer.java +++ b/core/java/android/window/WindowOrganizer.java @@ -36,9 +36,16 @@ public class WindowOrganizer { /** * Apply multiple WindowContainer operations at once. + * + * Note that using this API requires the caller to hold + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using + * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is + * created by itself. + * * @param t The transaction to apply. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS, + conditional = true) public void applyTransaction(@NonNull WindowContainerTransaction t) { try { if (!t.isEmpty()) { @@ -51,6 +58,12 @@ public class WindowOrganizer { /** * Apply multiple WindowContainer operations at once. + * + * Note that using this API requires the caller to hold + * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using + * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is + * created by itself. + * * @param t The transaction to apply. * @param callback This transaction will use the synchronization scheme described in * BLASTSyncEngine.java. The SurfaceControl transaction containing the effects of this @@ -58,7 +71,8 @@ public class WindowOrganizer { * @return An ID for the sync operation which will later be passed to transactionReady callback. * This lets the caller differentiate overlapping sync operations. */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS, + conditional = true) public int applySyncTransaction(@NonNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback) { try { @@ -123,7 +137,6 @@ public class WindowOrganizer { } } - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) IWindowOrganizerController getWindowOrganizerController() { return IWindowOrganizerControllerSingleton.get(); } |
