Loading core/api/test-current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3326,7 +3326,7 @@ package android.window { method @NonNull public java.util.concurrent.Executor getExecutor(); method @NonNull public java.util.concurrent.Executor getExecutor(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentError(@NonNull android.os.IBinder, @NonNull Throwable); method public void onTaskFragmentError(@NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable); method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); Loading core/java/android/window/ITaskFragmentOrganizer.aidl +4 −3 Original line number Original line Diff line number Diff line Loading @@ -45,10 +45,11 @@ oneway interface ITaskFragmentOrganizer { * * * @param errorCallbackToken Token set through {@link * @param errorCallbackToken Token set through {@link * WindowContainerTransaction#setErrorCallbackToken(IBinder)} * WindowContainerTransaction#setErrorCallbackToken(IBinder)} * @param exceptionBundle Bundle containing the exception. Should be created with * @param errorBundle Bundle containing the exception, operation type and TaskFragmentInfo * {@link TaskFragmentOrganizer#putExceptionInBundle}. * if any. Should be created with * {@link TaskFragmentOrganizer#putErrorInfoInBundle}. */ */ void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle); void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle errorBundle); /** /** * Called when an Activity is reparented to the Task with organized TaskFragment. For example, * Called when an Activity is reparented to the Task with organized TaskFragment. For example, Loading core/java/android/window/TaskFragmentOrganizer.java +30 −11 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.window; import android.annotation.CallSuper; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.content.Intent; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Configuration; Loading @@ -39,16 +40,23 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}. * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}. */ */ private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception"; private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception"; private static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; private static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; /** /** * Creates a {@link Bundle} with an exception that can be passed to * Creates a {@link Bundle} with an exception, operation type and TaskFragmentInfo (if any) * {@link ITaskFragmentOrganizer#onTaskFragmentError}. * that can be passed to {@link ITaskFragmentOrganizer#onTaskFragmentError}. * @hide * @hide */ */ public static Bundle putExceptionInBundle(@NonNull Throwable exception) { public static @NonNull Bundle putErrorInfoInBundle(@NonNull Throwable exception, final Bundle exceptionBundle = new Bundle(); @Nullable TaskFragmentInfo info, int opType) { exceptionBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception); final Bundle errorBundle = new Bundle(); return exceptionBundle; errorBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception); if (info != null) { errorBundle.putParcelable(KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, info); } errorBundle.putInt(KEY_ERROR_CALLBACK_OP_TYPE, opType); return errorBundle; } } /** /** Loading Loading @@ -150,10 +158,15 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * * * @param errorCallbackToken token set in * @param errorCallbackToken token set in * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} * {@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. * @param exception exception from the server side. */ */ public void onTaskFragmentError( public void onTaskFragmentError( @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {} @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, * Called when an Activity is reparented to the Task with organized TaskFragment. For example, Loading Loading @@ -217,10 +230,16 @@ public class TaskFragmentOrganizer extends WindowOrganizer { @Override @Override public void onTaskFragmentError( public void onTaskFragmentError( @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) { @NonNull IBinder errorCallbackToken, @NonNull Bundle errorBundle) { mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError( mExecutor.execute(() -> { errorCallbackToken, final TaskFragmentInfo info = errorBundle.getParcelable( (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class))); KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class); TaskFragmentOrganizer.this.onTaskFragmentError( errorCallbackToken, info, errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE), (Throwable) errorBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class)); }); } } @Override @Override Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -72,6 +72,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { @NonNull Configuration parentConfig); @NonNull Configuration parentConfig); void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent, void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken); @NonNull IBinder activityToken); void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType); } } /** /** Loading Loading @@ -323,4 +324,18 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken); mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken); } } } } @Override public void onTaskFragmentError(@NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo, int opType, @NonNull Throwable exception) { if (taskFragmentInfo != null) { final IBinder fragmentToken = taskFragmentInfo.getFragmentToken(); mFragmentInfos.put(fragmentToken, taskFragmentInfo); } if (mCallback != null) { mCallback.onTaskFragmentError(taskFragmentInfo, opType); } } } } libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,8 @@ package androidx.window.extensions.embedding; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_SUCCESS; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -296,6 +298,37 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } } } @Override public void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType) { synchronized (mLock) { switch (opType) { case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: { final TaskFragmentContainer container; if (taskFragmentInfo != null) { container = getContainer(taskFragmentInfo.getFragmentToken()); } else { container = null; } if (container == null) { break; } // Update the latest taskFragmentInfo and perform necessary clean-up container.setInfo(taskFragmentInfo); container.clearPendingAppearedActivities(); if (container.isEmpty()) { mPresenter.cleanupContainer(container, false /* shouldFinishDependent */); } break; } default: Log.e(TAG, "onTaskFragmentError: taskFragmentInfo = " + taskFragmentInfo + ", opType = " + opType); } } } /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */ /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */ private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) { private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) { for (int i = mTaskContainers.size() - 1; i >= 0; i--) { for (int i = mTaskContainers.size() - 1; i >= 0; i--) { Loading Loading
core/api/test-current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -3326,7 +3326,7 @@ package android.window { method @NonNull public java.util.concurrent.Executor getExecutor(); method @NonNull public java.util.concurrent.Executor getExecutor(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); method @NonNull public android.window.TaskFragmentOrganizerToken getOrganizerToken(); method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentAppeared(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentError(@NonNull android.os.IBinder, @NonNull Throwable); method public void onTaskFragmentError(@NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable); method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); Loading
core/java/android/window/ITaskFragmentOrganizer.aidl +4 −3 Original line number Original line Diff line number Diff line Loading @@ -45,10 +45,11 @@ oneway interface ITaskFragmentOrganizer { * * * @param errorCallbackToken Token set through {@link * @param errorCallbackToken Token set through {@link * WindowContainerTransaction#setErrorCallbackToken(IBinder)} * WindowContainerTransaction#setErrorCallbackToken(IBinder)} * @param exceptionBundle Bundle containing the exception. Should be created with * @param errorBundle Bundle containing the exception, operation type and TaskFragmentInfo * {@link TaskFragmentOrganizer#putExceptionInBundle}. * if any. Should be created with * {@link TaskFragmentOrganizer#putErrorInfoInBundle}. */ */ void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle); void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle errorBundle); /** /** * Called when an Activity is reparented to the Task with organized TaskFragment. For example, * Called when an Activity is reparented to the Task with organized TaskFragment. For example, Loading
core/java/android/window/TaskFragmentOrganizer.java +30 −11 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.window; import android.annotation.CallSuper; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.content.Intent; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Configuration; Loading @@ -39,16 +40,23 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}. * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}. */ */ private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception"; private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception"; private static final String KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO = "task_fragment_info"; private static final String KEY_ERROR_CALLBACK_OP_TYPE = "operation_type"; /** /** * Creates a {@link Bundle} with an exception that can be passed to * Creates a {@link Bundle} with an exception, operation type and TaskFragmentInfo (if any) * {@link ITaskFragmentOrganizer#onTaskFragmentError}. * that can be passed to {@link ITaskFragmentOrganizer#onTaskFragmentError}. * @hide * @hide */ */ public static Bundle putExceptionInBundle(@NonNull Throwable exception) { public static @NonNull Bundle putErrorInfoInBundle(@NonNull Throwable exception, final Bundle exceptionBundle = new Bundle(); @Nullable TaskFragmentInfo info, int opType) { exceptionBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception); final Bundle errorBundle = new Bundle(); return exceptionBundle; errorBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception); if (info != null) { errorBundle.putParcelable(KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, info); } errorBundle.putInt(KEY_ERROR_CALLBACK_OP_TYPE, opType); return errorBundle; } } /** /** Loading Loading @@ -150,10 +158,15 @@ public class TaskFragmentOrganizer extends WindowOrganizer { * * * @param errorCallbackToken token set in * @param errorCallbackToken token set in * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} * {@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. * @param exception exception from the server side. */ */ public void onTaskFragmentError( public void onTaskFragmentError( @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {} @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, * Called when an Activity is reparented to the Task with organized TaskFragment. For example, Loading Loading @@ -217,10 +230,16 @@ public class TaskFragmentOrganizer extends WindowOrganizer { @Override @Override public void onTaskFragmentError( public void onTaskFragmentError( @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) { @NonNull IBinder errorCallbackToken, @NonNull Bundle errorBundle) { mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError( mExecutor.execute(() -> { errorCallbackToken, final TaskFragmentInfo info = errorBundle.getParcelable( (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class))); KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class); TaskFragmentOrganizer.this.onTaskFragmentError( errorCallbackToken, info, errorBundle.getInt(KEY_ERROR_CALLBACK_OP_TYPE), (Throwable) errorBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION, java.lang.Throwable.class)); }); } } @Override @Override Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -72,6 +72,7 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { @NonNull Configuration parentConfig); @NonNull Configuration parentConfig); void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent, void onActivityReparentToTask(int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken); @NonNull IBinder activityToken); void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType); } } /** /** Loading Loading @@ -323,4 +324,18 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken); mCallback.onActivityReparentToTask(taskId, activityIntent, activityToken); } } } } @Override public void onTaskFragmentError(@NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo, int opType, @NonNull Throwable exception) { if (taskFragmentInfo != null) { final IBinder fragmentToken = taskFragmentInfo.getFragmentToken(); mFragmentInfos.put(fragmentToken, taskFragmentInfo); } if (mCallback != null) { mCallback.onTaskFragmentError(taskFragmentInfo, opType); } } } }
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,8 @@ package androidx.window.extensions.embedding; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_SUCCESS; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -296,6 +298,37 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } } } } @Override public void onTaskFragmentError(@Nullable TaskFragmentInfo taskFragmentInfo, int opType) { synchronized (mLock) { switch (opType) { case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT: { final TaskFragmentContainer container; if (taskFragmentInfo != null) { container = getContainer(taskFragmentInfo.getFragmentToken()); } else { container = null; } if (container == null) { break; } // Update the latest taskFragmentInfo and perform necessary clean-up container.setInfo(taskFragmentInfo); container.clearPendingAppearedActivities(); if (container.isEmpty()) { mPresenter.cleanupContainer(container, false /* shouldFinishDependent */); } break; } default: Log.e(TAG, "onTaskFragmentError: taskFragmentInfo = " + taskFragmentInfo + ", opType = " + opType); } } } /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */ /** Called on receiving {@link #onTaskFragmentVanished(TaskFragmentInfo)} for cleanup. */ private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) { private void cleanupTaskFragment(@NonNull IBinder taskFragmentToken) { for (int i = mTaskContainers.size() - 1; i >= 0; i--) { for (int i = mTaskContainers.size() - 1; i >= 0; i--) { Loading