Loading core/api/test-current.txt +45 −6 Original line number Diff line number Diff line Loading @@ -3343,20 +3343,59 @@ package android.window { 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 onActivityReparentedToTask(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.Intent, @NonNull android.os.IBinder); method public void onTaskFragmentAppeared(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentError(@NonNull android.window.WindowContainerTransaction, @NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable); method public void onTaskFragmentInfoChanged(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentParentInfoChanged(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.res.Configuration); method public void onTaskFragmentVanished(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTransactionReady(@NonNull android.window.TaskFragmentTransaction); method @CallSuper public void registerOrganizer(); method @CallSuper public void unregisterOrganizer(); field public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; field public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; field public static final String KEY_ERROR_CALLBACK_THROWABLE = "fragment_throwable"; } public final class TaskFragmentOrganizerToken implements android.os.Parcelable { field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentOrganizerToken> CREATOR; } public final class TaskFragmentTransaction implements android.os.Parcelable { ctor public TaskFragmentTransaction(); method public void addChange(@Nullable android.window.TaskFragmentTransaction.Change); method public int describeContents(); method @NonNull public java.util.List<android.window.TaskFragmentTransaction.Change> getChanges(); method @NonNull public android.os.IBinder getTransactionToken(); method public boolean isEmpty(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentTransaction> CREATOR; field public static final int TYPE_ACTIVITY_REPARENTED_TO_TASK = 6; // 0x6 field public static final int TYPE_TASK_FRAGMENT_APPEARED = 1; // 0x1 field public static final int TYPE_TASK_FRAGMENT_ERROR = 5; // 0x5 field public static final int TYPE_TASK_FRAGMENT_INFO_CHANGED = 2; // 0x2 field public static final int TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED = 4; // 0x4 field public static final int TYPE_TASK_FRAGMENT_VANISHED = 3; // 0x3 } public static final class TaskFragmentTransaction.Change implements android.os.Parcelable { ctor public TaskFragmentTransaction.Change(int); method public int describeContents(); method @Nullable public android.content.Intent getActivityIntent(); method @Nullable public android.os.IBinder getActivityToken(); method @NonNull public android.os.Bundle getErrorBundle(); method @Nullable public android.os.IBinder getErrorCallbackToken(); method @Nullable public android.content.res.Configuration getTaskConfiguration(); method @Nullable public android.window.TaskFragmentInfo getTaskFragmentInfo(); method @Nullable public android.os.IBinder getTaskFragmentToken(); method public int getTaskId(); method public int getType(); method @NonNull public android.window.TaskFragmentTransaction.Change setActivityIntent(@NonNull android.content.Intent); method @NonNull public android.window.TaskFragmentTransaction.Change setActivityToken(@NonNull android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setErrorBundle(@NonNull android.os.Bundle); method @NonNull public android.window.TaskFragmentTransaction.Change setErrorCallbackToken(@Nullable android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskConfiguration(@NonNull android.content.res.Configuration); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskFragmentInfo(@NonNull android.window.TaskFragmentInfo); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskFragmentToken(@NonNull android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskId(int); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentTransaction.Change> CREATOR; } public class TaskOrganizer extends android.window.WindowOrganizer { ctor public TaskOrganizer(); method @BinderThread public void copySplashScreenView(int); Loading core/java/android/window/TaskFragmentOrganizer.java +4 −144 Original line number Diff line number Diff line Loading @@ -20,12 +20,6 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED; 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_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; Loading @@ -35,8 +29,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.app.WindowConfiguration; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading @@ -55,21 +47,18 @@ public class TaskFragmentOrganizer extends WindowOrganizer { /** * Key to the {@link Throwable} in {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_THROWABLE = "fragment_throwable"; /** * Key to the {@link TaskFragmentInfo} in * {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; /** * Key to the {@link WindowContainerTransaction.HierarchyOp} in * {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; Loading Loading @@ -195,7 +184,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * Routes to {@link ITaskFragmentOrganizerController#applyTransaction} instead of * {@link IWindowOrganizerController#applyTransaction} for the different transition options. * * @see #applyTransaction(WindowContainerTransaction, int, boolean, boolean) * @see #applyTransaction(WindowContainerTransaction, int, boolean) */ @Override public void applyTransaction(@NonNull WindowContainerTransaction wct) { Loading Loading @@ -273,143 +262,14 @@ public class TaskFragmentOrganizer extends WindowOrganizer { return TRANSIT_CHANGE; } /** * Called when a TaskFragment is created and organized by this organizer. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is created. */ public void onTaskFragmentAppeared(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when the status of an organized TaskFragment is changed. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is changed. */ public void onTaskFragmentInfoChanged(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when an organized TaskFragment is removed. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is removed. */ public void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when the parent leaf Task of organized TaskFragments is changed. * When the leaf Task is changed, the organizer may want to update the TaskFragments in one * transaction. * * For case like screen size change, it will trigger onTaskFragmentParentInfoChanged with new * Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override * bounds. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskId Id of the parent Task that is changed. * @param parentConfig Config of the parent Task. */ public void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct, int taskId, @NonNull Configuration parentConfig) {} /** * Called when the {@link WindowContainerTransaction} created with * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param errorCallbackToken token set in * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} * @param taskFragmentInfo The {@link TaskFragmentInfo}. This could be {@code null} if no * TaskFragment created. * @param opType The {@link WindowContainerTransaction.HierarchyOp} of the failed * transaction operation. * @param exception exception from the server side. */ public void onTaskFragmentError(@NonNull WindowContainerTransaction wct, @NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo, int opType, @NonNull Throwable exception) {} /** * Called when an Activity is reparented to the Task with organized TaskFragment. For example, * when an Activity enters and then exits Picture-in-picture, it will be reparented back to its * original Task. In this case, we need to notify the organizer so that it can check if the * Activity matches any split rule. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskId The Task that the activity is reparented to. * @param activityIntent The intent that the activity is original launched with. * @param activityToken If the activity belongs to the same process as the organizer, this * will be the actual activity token; if the activity belongs to a * different process, the server will generate a temporary token that * the organizer can use to reparent the activity through * {@link WindowContainerTransaction} if needed. */ public void onActivityReparentedToTask(@NonNull WindowContainerTransaction wct, int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken) {} /** * Called when the transaction is ready so that the organizer can update the TaskFragments based * on the changes in transaction. * @hide */ public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) { // TODO(b/240519866): move to SplitController#onTransactionReady to make sure the whole // transaction is handled in one sync block. Keep the implementation below to keep CTS // compatibility. Remove in the next release. final WindowContainerTransaction wct = new WindowContainerTransaction(); final List<TaskFragmentTransaction.Change> changes = transaction.getChanges(); for (TaskFragmentTransaction.Change change : changes) { final int taskId = change.getTaskId(); switch (change.getType()) { case TYPE_TASK_FRAGMENT_APPEARED: onTaskFragmentAppeared(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_INFO_CHANGED: onTaskFragmentInfoChanged(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_VANISHED: onTaskFragmentVanished(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED: onTaskFragmentParentInfoChanged(wct, taskId, change.getTaskConfiguration()); break; case TYPE_TASK_FRAGMENT_ERROR: final Bundle errorBundle = change.getErrorBundle(); onTaskFragmentError( wct, change.getErrorCallbackToken(), errorBundle.getParcelable( KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class), errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE), errorBundle.getSerializable(KEY_ERROR_CALLBACK_THROWABLE, java.lang.Throwable.class)); break; case TYPE_ACTIVITY_REPARENTED_TO_TASK: onActivityReparentedToTask( wct, change.getTaskId(), change.getActivityIntent(), change.getActivityToken()); break; default: throw new IllegalArgumentException( "Unknown TaskFragmentEvent=" + change.getType()); } } // Notify the server, and the server should apply the WindowContainerTransaction. onTransactionHandled(transaction.getTransactionToken(), wct, getTransitionType(wct), false /* shouldApplyIndependently */); // Notify the server to finish the transaction. onTransactionHandled(transaction.getTransactionToken(), new WindowContainerTransaction(), TRANSIT_NONE, false /* shouldApplyIndependently */); } private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() { Loading core/java/android/window/TaskFragmentTransaction.java +17 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static java.util.Objects.requireNonNull; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.content.Intent; import android.content.res.Configuration; import android.os.Binder; Loading @@ -40,6 +42,7 @@ import java.util.List; * @see TaskFragmentTransaction.Change * @hide */ @TestApi public final class TaskFragmentTransaction implements Parcelable { /** Unique token to represent this transaction. */ Loading @@ -63,6 +66,7 @@ public final class TaskFragmentTransaction implements Parcelable { dest.writeTypedList(mChanges); } @NonNull public IBinder getTransactionToken() { return mTransactionToken; } Loading Loading @@ -105,6 +109,7 @@ public final class TaskFragmentTransaction implements Parcelable { return 0; } @NonNull public static final Creator<TaskFragmentTransaction> CREATOR = new Creator<>() { @Override public TaskFragmentTransaction createFromParcel(Parcel in) { Loading Loading @@ -218,24 +223,28 @@ public final class TaskFragmentTransaction implements Parcelable { } /** The change is related to the TaskFragment created with this unique token. */ @NonNull public Change setTaskFragmentToken(@NonNull IBinder taskFragmentToken) { mTaskFragmentToken = requireNonNull(taskFragmentToken); return this; } /** Info of the embedded TaskFragment. */ @NonNull public Change setTaskFragmentInfo(@NonNull TaskFragmentInfo info) { mTaskFragmentInfo = requireNonNull(info); return this; } /** Task id the parent Task. */ @NonNull public Change setTaskId(int taskId) { mTaskId = taskId; return this; } /** Configuration of the parent Task. */ @NonNull public Change setTaskConfiguration(@NonNull Configuration configuration) { mTaskConfiguration = requireNonNull(configuration); return this; Loading @@ -246,6 +255,7 @@ public final class TaskFragmentTransaction implements Parcelable { * from the {@link TaskFragmentOrganizer}, it may come with an error callback token to * report back. */ @NonNull public Change setErrorCallbackToken(@Nullable IBinder errorCallbackToken) { mErrorCallbackToken = errorCallbackToken; return this; Loading @@ -255,6 +265,7 @@ public final class TaskFragmentTransaction implements Parcelable { * Bundle with necessary info about the failure operation of * {@link #TYPE_TASK_FRAGMENT_ERROR}. */ @NonNull public Change setErrorBundle(@NonNull Bundle errorBundle) { mErrorBundle = requireNonNull(errorBundle); return this; Loading @@ -264,6 +275,7 @@ public final class TaskFragmentTransaction implements Parcelable { * Intent of the activity that is reparented to the Task for * {@link #TYPE_ACTIVITY_REPARENTED_TO_TASK}. */ @NonNull public Change setActivityIntent(@NonNull Intent intent) { mActivityIntent = requireNonNull(intent); return this; Loading @@ -276,6 +288,7 @@ public final class TaskFragmentTransaction implements Parcelable { * a temporary token that the organizer can use to reparent the activity through * {@link WindowContainerTransaction} if needed. */ @NonNull public Change setActivityToken(@NonNull IBinder activityToken) { mActivityToken = requireNonNull(activityToken); return this; Loading Loading @@ -310,11 +323,12 @@ public final class TaskFragmentTransaction implements Parcelable { return mErrorCallbackToken; } @Nullable @NonNull public Bundle getErrorBundle() { return mErrorBundle; return mErrorBundle != null ? mErrorBundle : Bundle.EMPTY; } @SuppressLint("IntentBuilderName") // This is not creating new Intent. @Nullable public Intent getActivityIntent() { return mActivityIntent; Loading @@ -335,6 +349,7 @@ public final class TaskFragmentTransaction implements Parcelable { return 0; } @NonNull public static final Creator<Change> CREATOR = new Creator<>() { @Override public Change createFromParcel(Parcel in) { Loading Loading
core/api/test-current.txt +45 −6 Original line number Diff line number Diff line Loading @@ -3343,20 +3343,59 @@ package android.window { 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 onActivityReparentedToTask(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.Intent, @NonNull android.os.IBinder); method public void onTaskFragmentAppeared(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentError(@NonNull android.window.WindowContainerTransaction, @NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable); method public void onTaskFragmentInfoChanged(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentParentInfoChanged(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.res.Configuration); method public void onTaskFragmentVanished(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo); method public void onTransactionReady(@NonNull android.window.TaskFragmentTransaction); method @CallSuper public void registerOrganizer(); method @CallSuper public void unregisterOrganizer(); field public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; field public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; field public static final String KEY_ERROR_CALLBACK_THROWABLE = "fragment_throwable"; } public final class TaskFragmentOrganizerToken implements android.os.Parcelable { field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentOrganizerToken> CREATOR; } public final class TaskFragmentTransaction implements android.os.Parcelable { ctor public TaskFragmentTransaction(); method public void addChange(@Nullable android.window.TaskFragmentTransaction.Change); method public int describeContents(); method @NonNull public java.util.List<android.window.TaskFragmentTransaction.Change> getChanges(); method @NonNull public android.os.IBinder getTransactionToken(); method public boolean isEmpty(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentTransaction> CREATOR; field public static final int TYPE_ACTIVITY_REPARENTED_TO_TASK = 6; // 0x6 field public static final int TYPE_TASK_FRAGMENT_APPEARED = 1; // 0x1 field public static final int TYPE_TASK_FRAGMENT_ERROR = 5; // 0x5 field public static final int TYPE_TASK_FRAGMENT_INFO_CHANGED = 2; // 0x2 field public static final int TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED = 4; // 0x4 field public static final int TYPE_TASK_FRAGMENT_VANISHED = 3; // 0x3 } public static final class TaskFragmentTransaction.Change implements android.os.Parcelable { ctor public TaskFragmentTransaction.Change(int); method public int describeContents(); method @Nullable public android.content.Intent getActivityIntent(); method @Nullable public android.os.IBinder getActivityToken(); method @NonNull public android.os.Bundle getErrorBundle(); method @Nullable public android.os.IBinder getErrorCallbackToken(); method @Nullable public android.content.res.Configuration getTaskConfiguration(); method @Nullable public android.window.TaskFragmentInfo getTaskFragmentInfo(); method @Nullable public android.os.IBinder getTaskFragmentToken(); method public int getTaskId(); method public int getType(); method @NonNull public android.window.TaskFragmentTransaction.Change setActivityIntent(@NonNull android.content.Intent); method @NonNull public android.window.TaskFragmentTransaction.Change setActivityToken(@NonNull android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setErrorBundle(@NonNull android.os.Bundle); method @NonNull public android.window.TaskFragmentTransaction.Change setErrorCallbackToken(@Nullable android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskConfiguration(@NonNull android.content.res.Configuration); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskFragmentInfo(@NonNull android.window.TaskFragmentInfo); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskFragmentToken(@NonNull android.os.IBinder); method @NonNull public android.window.TaskFragmentTransaction.Change setTaskId(int); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.window.TaskFragmentTransaction.Change> CREATOR; } public class TaskOrganizer extends android.window.WindowOrganizer { ctor public TaskOrganizer(); method @BinderThread public void copySplashScreenView(int); Loading
core/java/android/window/TaskFragmentOrganizer.java +4 −144 Original line number Diff line number Diff line Loading @@ -20,12 +20,6 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.window.TaskFragmentTransaction.TYPE_ACTIVITY_REPARENTED_TO_TASK; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_APPEARED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_ERROR; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED; 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_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; Loading @@ -35,8 +29,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.app.WindowConfiguration; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading @@ -55,21 +47,18 @@ public class TaskFragmentOrganizer extends WindowOrganizer { /** * Key to the {@link Throwable} in {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_THROWABLE = "fragment_throwable"; /** * Key to the {@link TaskFragmentInfo} in * {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; /** * Key to the {@link WindowContainerTransaction.HierarchyOp} in * {@link TaskFragmentTransaction.Change#getErrorBundle()}. * @hide */ public static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; Loading Loading @@ -195,7 +184,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * Routes to {@link ITaskFragmentOrganizerController#applyTransaction} instead of * {@link IWindowOrganizerController#applyTransaction} for the different transition options. * * @see #applyTransaction(WindowContainerTransaction, int, boolean, boolean) * @see #applyTransaction(WindowContainerTransaction, int, boolean) */ @Override public void applyTransaction(@NonNull WindowContainerTransaction wct) { Loading Loading @@ -273,143 +262,14 @@ public class TaskFragmentOrganizer extends WindowOrganizer { return TRANSIT_CHANGE; } /** * Called when a TaskFragment is created and organized by this organizer. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is created. */ public void onTaskFragmentAppeared(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when the status of an organized TaskFragment is changed. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is changed. */ public void onTaskFragmentInfoChanged(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when an organized TaskFragment is removed. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskFragmentInfo Info of the TaskFragment that is removed. */ public void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentInfo taskFragmentInfo) {} /** * Called when the parent leaf Task of organized TaskFragments is changed. * When the leaf Task is changed, the organizer may want to update the TaskFragments in one * transaction. * * For case like screen size change, it will trigger onTaskFragmentParentInfoChanged with new * Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override * bounds. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskId Id of the parent Task that is changed. * @param parentConfig Config of the parent Task. */ public void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct, int taskId, @NonNull Configuration parentConfig) {} /** * Called when the {@link WindowContainerTransaction} created with * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param errorCallbackToken token set in * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} * @param taskFragmentInfo The {@link TaskFragmentInfo}. This could be {@code null} if no * TaskFragment created. * @param opType The {@link WindowContainerTransaction.HierarchyOp} of the failed * transaction operation. * @param exception exception from the server side. */ public void onTaskFragmentError(@NonNull WindowContainerTransaction wct, @NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo, int opType, @NonNull Throwable exception) {} /** * Called when an Activity is reparented to the Task with organized TaskFragment. For example, * when an Activity enters and then exits Picture-in-picture, it will be reparented back to its * original Task. In this case, we need to notify the organizer so that it can check if the * Activity matches any split rule. * * @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No * need to call {@link #applyTransaction} as it will be applied by the caller. * @param taskId The Task that the activity is reparented to. * @param activityIntent The intent that the activity is original launched with. * @param activityToken If the activity belongs to the same process as the organizer, this * will be the actual activity token; if the activity belongs to a * different process, the server will generate a temporary token that * the organizer can use to reparent the activity through * {@link WindowContainerTransaction} if needed. */ public void onActivityReparentedToTask(@NonNull WindowContainerTransaction wct, int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken) {} /** * Called when the transaction is ready so that the organizer can update the TaskFragments based * on the changes in transaction. * @hide */ public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) { // TODO(b/240519866): move to SplitController#onTransactionReady to make sure the whole // transaction is handled in one sync block. Keep the implementation below to keep CTS // compatibility. Remove in the next release. final WindowContainerTransaction wct = new WindowContainerTransaction(); final List<TaskFragmentTransaction.Change> changes = transaction.getChanges(); for (TaskFragmentTransaction.Change change : changes) { final int taskId = change.getTaskId(); switch (change.getType()) { case TYPE_TASK_FRAGMENT_APPEARED: onTaskFragmentAppeared(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_INFO_CHANGED: onTaskFragmentInfoChanged(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_VANISHED: onTaskFragmentVanished(wct, change.getTaskFragmentInfo()); break; case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED: onTaskFragmentParentInfoChanged(wct, taskId, change.getTaskConfiguration()); break; case TYPE_TASK_FRAGMENT_ERROR: final Bundle errorBundle = change.getErrorBundle(); onTaskFragmentError( wct, change.getErrorCallbackToken(), errorBundle.getParcelable( KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class), errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE), errorBundle.getSerializable(KEY_ERROR_CALLBACK_THROWABLE, java.lang.Throwable.class)); break; case TYPE_ACTIVITY_REPARENTED_TO_TASK: onActivityReparentedToTask( wct, change.getTaskId(), change.getActivityIntent(), change.getActivityToken()); break; default: throw new IllegalArgumentException( "Unknown TaskFragmentEvent=" + change.getType()); } } // Notify the server, and the server should apply the WindowContainerTransaction. onTransactionHandled(transaction.getTransactionToken(), wct, getTransitionType(wct), false /* shouldApplyIndependently */); // Notify the server to finish the transaction. onTransactionHandled(transaction.getTransactionToken(), new WindowContainerTransaction(), TRANSIT_NONE, false /* shouldApplyIndependently */); } private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() { Loading
core/java/android/window/TaskFragmentTransaction.java +17 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static java.util.Objects.requireNonNull; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.content.Intent; import android.content.res.Configuration; import android.os.Binder; Loading @@ -40,6 +42,7 @@ import java.util.List; * @see TaskFragmentTransaction.Change * @hide */ @TestApi public final class TaskFragmentTransaction implements Parcelable { /** Unique token to represent this transaction. */ Loading @@ -63,6 +66,7 @@ public final class TaskFragmentTransaction implements Parcelable { dest.writeTypedList(mChanges); } @NonNull public IBinder getTransactionToken() { return mTransactionToken; } Loading Loading @@ -105,6 +109,7 @@ public final class TaskFragmentTransaction implements Parcelable { return 0; } @NonNull public static final Creator<TaskFragmentTransaction> CREATOR = new Creator<>() { @Override public TaskFragmentTransaction createFromParcel(Parcel in) { Loading Loading @@ -218,24 +223,28 @@ public final class TaskFragmentTransaction implements Parcelable { } /** The change is related to the TaskFragment created with this unique token. */ @NonNull public Change setTaskFragmentToken(@NonNull IBinder taskFragmentToken) { mTaskFragmentToken = requireNonNull(taskFragmentToken); return this; } /** Info of the embedded TaskFragment. */ @NonNull public Change setTaskFragmentInfo(@NonNull TaskFragmentInfo info) { mTaskFragmentInfo = requireNonNull(info); return this; } /** Task id the parent Task. */ @NonNull public Change setTaskId(int taskId) { mTaskId = taskId; return this; } /** Configuration of the parent Task. */ @NonNull public Change setTaskConfiguration(@NonNull Configuration configuration) { mTaskConfiguration = requireNonNull(configuration); return this; Loading @@ -246,6 +255,7 @@ public final class TaskFragmentTransaction implements Parcelable { * from the {@link TaskFragmentOrganizer}, it may come with an error callback token to * report back. */ @NonNull public Change setErrorCallbackToken(@Nullable IBinder errorCallbackToken) { mErrorCallbackToken = errorCallbackToken; return this; Loading @@ -255,6 +265,7 @@ public final class TaskFragmentTransaction implements Parcelable { * Bundle with necessary info about the failure operation of * {@link #TYPE_TASK_FRAGMENT_ERROR}. */ @NonNull public Change setErrorBundle(@NonNull Bundle errorBundle) { mErrorBundle = requireNonNull(errorBundle); return this; Loading @@ -264,6 +275,7 @@ public final class TaskFragmentTransaction implements Parcelable { * Intent of the activity that is reparented to the Task for * {@link #TYPE_ACTIVITY_REPARENTED_TO_TASK}. */ @NonNull public Change setActivityIntent(@NonNull Intent intent) { mActivityIntent = requireNonNull(intent); return this; Loading @@ -276,6 +288,7 @@ public final class TaskFragmentTransaction implements Parcelable { * a temporary token that the organizer can use to reparent the activity through * {@link WindowContainerTransaction} if needed. */ @NonNull public Change setActivityToken(@NonNull IBinder activityToken) { mActivityToken = requireNonNull(activityToken); return this; Loading Loading @@ -310,11 +323,12 @@ public final class TaskFragmentTransaction implements Parcelable { return mErrorCallbackToken; } @Nullable @NonNull public Bundle getErrorBundle() { return mErrorBundle; return mErrorBundle != null ? mErrorBundle : Bundle.EMPTY; } @SuppressLint("IntentBuilderName") // This is not creating new Intent. @Nullable public Intent getActivityIntent() { return mActivityIntent; Loading @@ -335,6 +349,7 @@ public final class TaskFragmentTransaction implements Parcelable { return 0; } @NonNull public static final Creator<Change> CREATOR = new Creator<>() { @Override public Change createFromParcel(Parcel in) { Loading