Merge "Sending TaskFragmentInfo and operation type in #onTaskFragmentError" into tm-qpr-dev
This commit is contained in:
@@ -3350,7 +3350,8 @@ 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 @Deprecated 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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,10 +159,33 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
* @param errorCallbackToken token set in
|
* @param errorCallbackToken token set in
|
||||||
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
|
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
|
||||||
* @param exception exception from the server side.
|
* @param exception exception from the server side.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #onTaskFragmentError(IBinder, TaskFragmentInfo, int, Throwable)}
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void onTaskFragmentError(
|
public void onTaskFragmentError(
|
||||||
@NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}
|
@NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the {@link WindowContainerTransaction} created with
|
||||||
|
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side.
|
||||||
|
*
|
||||||
|
* @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 IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo,
|
||||||
|
int opType, @NonNull Throwable exception) {
|
||||||
|
// Doing so to keep compatibility. This will be removed in the next release.
|
||||||
|
onTaskFragmentError(errorCallbackToken, 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,
|
||||||
* when an Activity enters and then exits Picture-in-picture, it will be reparented back to its
|
* when an Activity enters and then exits Picture-in-picture, it will be reparented back to its
|
||||||
@@ -217,10 +248,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)));
|
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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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--) {
|
||||||
|
|||||||
@@ -193,6 +193,11 @@ class TaskFragmentContainer {
|
|||||||
mPendingAppearedActivities.remove(pendingAppearedActivity);
|
mPendingAppearedActivities.remove(pendingAppearedActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearPendingAppearedActivities() {
|
||||||
|
mPendingAppearedActivities.clear();
|
||||||
|
mPendingAppearedIntent = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
Intent getPendingAppearedIntent() {
|
Intent getPendingAppearedIntent() {
|
||||||
return mPendingAppearedIntent;
|
return mPendingAppearedIntent;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
|
||||||
@@ -3015,6 +3016,7 @@ class ActivityStarter {
|
|||||||
if (taskFragment.isOrganized()) {
|
if (taskFragment.isOrganized()) {
|
||||||
mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
|
mService.mWindowOrganizerController.sendTaskFragmentOperationFailure(
|
||||||
taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
|
taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken,
|
||||||
|
taskFragment, HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT,
|
||||||
new SecurityException(errMsg));
|
new SecurityException(errMsg));
|
||||||
} else {
|
} else {
|
||||||
// If the taskFragment is not organized, just dump error message as warning logs.
|
// If the taskFragment is not organized, just dump error message as warning logs.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.window.TaskFragmentOrganizer.putExceptionInBundle;
|
import static android.window.TaskFragmentOrganizer.putErrorInfoInBundle;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
|
||||||
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
|
import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED;
|
||||||
@@ -214,12 +214,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTaskFragmentError(IBinder errorCallbackToken, Throwable exception) {
|
void onTaskFragmentError(IBinder errorCallbackToken, @Nullable TaskFragment taskFragment,
|
||||||
|
int opType, Throwable exception) {
|
||||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
"Sending TaskFragment error exception=%s", exception.toString());
|
"Sending TaskFragment error exception=%s", exception.toString());
|
||||||
final Bundle exceptionBundle = putExceptionInBundle(exception);
|
final TaskFragmentInfo info =
|
||||||
|
taskFragment != null ? taskFragment.getTaskFragmentInfo() : null;
|
||||||
|
final Bundle errorBundle = putErrorInfoInBundle(exception, info, opType);
|
||||||
try {
|
try {
|
||||||
mOrganizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
|
mOrganizer.onTaskFragmentError(errorCallbackToken, errorBundle);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
|
Slog.d(TAG, "Exception sending onTaskFragmentError callback", e);
|
||||||
}
|
}
|
||||||
@@ -462,13 +465,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
|
void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
|
||||||
Throwable exception) {
|
TaskFragment taskFragment, int opType, Throwable exception) {
|
||||||
validateAndGetState(organizer);
|
validateAndGetState(organizer);
|
||||||
Slog.w(TAG, "onTaskFragmentError ", exception);
|
Slog.w(TAG, "onTaskFragmentError ", exception);
|
||||||
final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
|
final PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent.Builder(
|
||||||
PendingTaskFragmentEvent.EVENT_ERROR, organizer)
|
PendingTaskFragmentEvent.EVENT_ERROR, organizer)
|
||||||
.setErrorCallbackToken(errorCallbackToken)
|
.setErrorCallbackToken(errorCallbackToken)
|
||||||
|
.setTaskFragment(taskFragment)
|
||||||
.setException(exception)
|
.setException(exception)
|
||||||
|
.setOpType(opType)
|
||||||
.build();
|
.build();
|
||||||
mPendingTaskFragmentEvents.add(pendingEvent);
|
mPendingTaskFragmentEvents.add(pendingEvent);
|
||||||
// Make sure the error event will be dispatched if there are no other changes.
|
// Make sure the error event will be dispatched if there are no other changes.
|
||||||
@@ -567,19 +572,22 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
// Set when the event is deferred due to the host task is invisible. The defer time will
|
// Set when the event is deferred due to the host task is invisible. The defer time will
|
||||||
// be the last active time of the host task.
|
// be the last active time of the host task.
|
||||||
private long mDeferTime;
|
private long mDeferTime;
|
||||||
|
private int mOpType;
|
||||||
|
|
||||||
private PendingTaskFragmentEvent(@EventType int eventType,
|
private PendingTaskFragmentEvent(@EventType int eventType,
|
||||||
ITaskFragmentOrganizer taskFragmentOrg,
|
ITaskFragmentOrganizer taskFragmentOrg,
|
||||||
@Nullable TaskFragment taskFragment,
|
@Nullable TaskFragment taskFragment,
|
||||||
@Nullable IBinder errorCallbackToken,
|
@Nullable IBinder errorCallbackToken,
|
||||||
@Nullable Throwable exception,
|
@Nullable Throwable exception,
|
||||||
@Nullable ActivityRecord activity) {
|
@Nullable ActivityRecord activity,
|
||||||
|
int opType) {
|
||||||
mEventType = eventType;
|
mEventType = eventType;
|
||||||
mTaskFragmentOrg = taskFragmentOrg;
|
mTaskFragmentOrg = taskFragmentOrg;
|
||||||
mTaskFragment = taskFragment;
|
mTaskFragment = taskFragment;
|
||||||
mErrorCallbackToken = errorCallbackToken;
|
mErrorCallbackToken = errorCallbackToken;
|
||||||
mException = exception;
|
mException = exception;
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
|
mOpType = opType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -610,6 +618,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
private Throwable mException;
|
private Throwable mException;
|
||||||
@Nullable
|
@Nullable
|
||||||
private ActivityRecord mActivity;
|
private ActivityRecord mActivity;
|
||||||
|
private int mOpType;
|
||||||
|
|
||||||
Builder(@EventType int eventType, ITaskFragmentOrganizer taskFragmentOrg) {
|
Builder(@EventType int eventType, ITaskFragmentOrganizer taskFragmentOrg) {
|
||||||
mEventType = eventType;
|
mEventType = eventType;
|
||||||
@@ -636,9 +645,14 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Builder setOpType(int opType) {
|
||||||
|
mOpType = opType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
PendingTaskFragmentEvent build() {
|
PendingTaskFragmentEvent build() {
|
||||||
return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
|
return new PendingTaskFragmentEvent(mEventType, mTaskFragmentOrg, mTaskFragment,
|
||||||
mErrorCallbackToken, mException, mActivity);
|
mErrorCallbackToken, mException, mActivity, mOpType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -667,6 +681,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldSendEventWhenTaskInvisible(@NonNull PendingTaskFragmentEvent event) {
|
private boolean shouldSendEventWhenTaskInvisible(@NonNull PendingTaskFragmentEvent event) {
|
||||||
|
if (event.mEventType == PendingTaskFragmentEvent.EVENT_ERROR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
final TaskFragmentOrganizerState state =
|
final TaskFragmentOrganizerState state =
|
||||||
mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
|
mTaskFragmentOrganizerState.get(event.mTaskFragmentOrg.asBinder());
|
||||||
final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
|
final TaskFragmentInfo lastInfo = state.mLastSentTaskFragmentInfos.get(event.mTaskFragment);
|
||||||
@@ -757,7 +775,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
state.onTaskFragmentParentInfoChanged(taskFragment);
|
state.onTaskFragmentParentInfoChanged(taskFragment);
|
||||||
break;
|
break;
|
||||||
case PendingTaskFragmentEvent.EVENT_ERROR:
|
case PendingTaskFragmentEvent.EVENT_ERROR:
|
||||||
state.onTaskFragmentError(event.mErrorCallbackToken, event.mException);
|
state.onTaskFragmentError(event.mErrorCallbackToken, taskFragment, event.mOpType,
|
||||||
|
event.mException);
|
||||||
break;
|
break;
|
||||||
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
|
case PendingTaskFragmentEvent.EVENT_ACTIVITY_REPARENT_TO_TASK:
|
||||||
state.onActivityReparentToTask(event.mActivity);
|
state.onActivityReparentToTask(event.mActivity);
|
||||||
|
|||||||
@@ -765,7 +765,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
bottomActivity)) {
|
bottomActivity)) {
|
||||||
Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
|
Slog.w(TAG, "Skip removing TaskFragment due in lock task mode.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
|
||||||
new IllegalStateException(
|
taskFragment, type, new IllegalStateException(
|
||||||
"Not allow to delete task fragment in lock task mode."));
|
"Not allow to delete task fragment in lock task mode."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -779,13 +779,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (tf == null) {
|
if (tf == null) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to operate with invalid fragment token");
|
"Not allowed to operate with invalid fragment token");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tf.isEmbeddedTaskFragmentInPip()) {
|
if (tf.isEmbeddedTaskFragmentInPip()) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to start activity in PIP TaskFragment");
|
"Not allowed to start activity in PIP TaskFragment");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final Intent activityIntent = hop.getActivityIntent();
|
final Intent activityIntent = hop.getActivityIntent();
|
||||||
@@ -795,7 +797,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
hop.getCallingActivity(), caller.mUid, caller.mPid,
|
hop.getCallingActivity(), caller.mUid, caller.mPid,
|
||||||
errorCallbackToken);
|
errorCallbackToken);
|
||||||
if (!isStartResultSuccessful(result)) {
|
if (!isStartResultSuccessful(result)) {
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken,
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf, type,
|
||||||
convertStartFailureToThrowable(result, activityIntent));
|
convertStartFailureToThrowable(result, activityIntent));
|
||||||
} else {
|
} else {
|
||||||
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
effects |= TRANSACT_EFFECTS_LIFECYCLE;
|
||||||
@@ -816,25 +818,29 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (parent == null || activity == null) {
|
if (parent == null || activity == null) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to operate with invalid fragment token or activity.");
|
"Not allowed to operate with invalid fragment token or activity.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (parent.isEmbeddedTaskFragmentInPip()) {
|
if (parent.isEmbeddedTaskFragmentInPip()) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to reparent activity to PIP TaskFragment");
|
"Not allowed to reparent activity to PIP TaskFragment");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
|
if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) {
|
||||||
final Throwable exception = new SecurityException(
|
final Throwable exception = new SecurityException(
|
||||||
"The task fragment is not allowed to embed the given activity.");
|
"The task fragment is not allowed to embed the given activity.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (parent.getTask() != activity.getTask()) {
|
if (parent.getTask() != activity.getTask()) {
|
||||||
final Throwable exception = new SecurityException("The reparented activity is"
|
final Throwable exception = new SecurityException("The reparented activity is"
|
||||||
+ " not in the same Task as the target TaskFragment.");
|
+ " not in the same Task as the target TaskFragment.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, parent, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,14 +860,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (tf1 == null || (adjacentFragmentToken != null && tf2 == null)) {
|
if (tf1 == null || (adjacentFragmentToken != null && tf2 == null)) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to set adjacent on invalid fragment tokens");
|
"Not allowed to set adjacent on invalid fragment tokens");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tf1.isEmbeddedTaskFragmentInPip()
|
if (tf1.isEmbeddedTaskFragmentInPip()
|
||||||
|| (tf2 != null && tf2.isEmbeddedTaskFragmentInPip())) {
|
|| (tf2 != null && tf2.isEmbeddedTaskFragmentInPip())) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to set adjacent on TaskFragment in PIP Task");
|
"Not allowed to set adjacent on TaskFragment in PIP Task");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, tf1, type,
|
||||||
|
exception);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tf1.setAdjacentTaskFragment(tf2);
|
tf1.setAdjacentTaskFragment(tf2);
|
||||||
@@ -1109,7 +1117,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
+ taskFragment.getBounds() + " does not satisfy minimum dimensions:"
|
+ taskFragment.getBounds() + " does not satisfy minimum dimensions:"
|
||||||
+ minDimensions + " " + reason);
|
+ minDimensions + " " + reason);
|
||||||
sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
|
sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
|
||||||
errorCallbackToken, exception);
|
errorCallbackToken, taskFragment, -1 /* opType */, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1662,13 +1670,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (ownerActivity == null || ownerActivity.getTask() == null) {
|
if (ownerActivity == null || ownerActivity.getTask() == null) {
|
||||||
final Throwable exception =
|
final Throwable exception =
|
||||||
new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
|
new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
|
||||||
|
HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ownerActivity.isResizeable()) {
|
if (!ownerActivity.isResizeable()) {
|
||||||
final IllegalArgumentException exception = new IllegalArgumentException("Not allowed"
|
final IllegalArgumentException exception = new IllegalArgumentException("Not allowed"
|
||||||
+ " to operate with non-resizable owner Activity");
|
+ " to operate with non-resizable owner Activity");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
|
||||||
|
HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The ownerActivity has to belong to the same app as the target Task.
|
// The ownerActivity has to belong to the same app as the target Task.
|
||||||
@@ -1678,13 +1688,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
final Throwable exception =
|
final Throwable exception =
|
||||||
new SecurityException("Not allowed to operate with the ownerToken while "
|
new SecurityException("Not allowed to operate with the ownerToken while "
|
||||||
+ "the root activity of the target task belong to the different app");
|
+ "the root activity of the target task belong to the different app");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
|
||||||
|
HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ownerTask.inPinnedWindowingMode()) {
|
if (ownerTask.inPinnedWindowingMode()) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to create TaskFragment in PIP Task");
|
"Not allowed to create TaskFragment in PIP Task");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, null /* taskFragment */,
|
||||||
|
HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TaskFragment taskFragment = new TaskFragment(mService,
|
final TaskFragment taskFragment = new TaskFragment(mService,
|
||||||
@@ -1712,7 +1724,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (newParentTF == null) {
|
if (newParentTF == null) {
|
||||||
final Throwable exception =
|
final Throwable exception =
|
||||||
new IllegalArgumentException("Not allowed to operate with invalid container");
|
new IllegalArgumentException("Not allowed to operate with invalid container");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
|
||||||
|
HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (newParentTF.getTaskFragmentOrganizer() != null) {
|
if (newParentTF.getTaskFragmentOrganizer() != null) {
|
||||||
@@ -1723,20 +1736,23 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
if (isEmbeddingDisallowed) {
|
if (isEmbeddingDisallowed) {
|
||||||
final Throwable exception = new SecurityException(
|
final Throwable exception = new SecurityException(
|
||||||
"The new parent is not allowed to embed the activities.");
|
"The new parent is not allowed to embed the activities.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
|
||||||
|
HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newParentTF.isEmbeddedTaskFragmentInPip() || oldParent.isEmbeddedTaskFragmentInPip()) {
|
if (newParentTF.isEmbeddedTaskFragmentInPip() || oldParent.isEmbeddedTaskFragmentInPip()) {
|
||||||
final Throwable exception = new SecurityException(
|
final Throwable exception = new SecurityException(
|
||||||
"Not allow to reparent in TaskFragment in PIP Task.");
|
"Not allow to reparent in TaskFragment in PIP Task.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
|
||||||
|
HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (newParentTF.getTask() != oldParent.getTask()) {
|
if (newParentTF.getTask() != oldParent.getTask()) {
|
||||||
final Throwable exception = new SecurityException(
|
final Throwable exception = new SecurityException(
|
||||||
"The new parent is not in the same Task as the old parent.");
|
"The new parent is not in the same Task as the old parent.");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, newParentTF,
|
||||||
|
HIERARCHY_OP_TYPE_REPARENT_CHILDREN, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (oldParent.hasChild()) {
|
while (oldParent.hasChild()) {
|
||||||
@@ -1751,7 +1767,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
final Throwable exception =
|
final Throwable exception =
|
||||||
new IllegalArgumentException("Not allowed to operate with invalid "
|
new IllegalArgumentException("Not allowed to operate with invalid "
|
||||||
+ "taskFragment");
|
+ "taskFragment");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
|
||||||
|
HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (taskFragment.isEmbeddedTaskFragmentInPip()
|
if (taskFragment.isEmbeddedTaskFragmentInPip()
|
||||||
@@ -1760,7 +1777,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
&& taskFragment.getTopNonFinishingActivity() != null) {
|
&& taskFragment.getTopNonFinishingActivity() != null) {
|
||||||
final Throwable exception = new IllegalArgumentException(
|
final Throwable exception = new IllegalArgumentException(
|
||||||
"Not allowed to delete TaskFragment in PIP Task");
|
"Not allowed to delete TaskFragment in PIP Task");
|
||||||
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
|
sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment,
|
||||||
|
HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT, exception);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mLaunchTaskFragments.removeAt(index);
|
mLaunchTaskFragments.removeAt(index);
|
||||||
@@ -1788,12 +1806,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
|
void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
|
||||||
@Nullable IBinder errorCallbackToken, @NonNull Throwable exception) {
|
@Nullable IBinder errorCallbackToken, @Nullable TaskFragment taskFragment, int opType,
|
||||||
|
@NonNull Throwable exception) {
|
||||||
if (organizer == null) {
|
if (organizer == null) {
|
||||||
throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
|
throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
|
||||||
}
|
}
|
||||||
mService.mTaskFragmentOrganizerController
|
mService.mTaskFragmentOrganizerController
|
||||||
.onTaskFragmentError(organizer, errorCallbackToken, exception);
|
.onTaskFragmentError(organizer, errorCallbackToken, taskFragment, opType,
|
||||||
|
exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Throwable convertStartFailureToThrowable(int result, Intent intent) {
|
private Throwable convertStartFailureToThrowable(int result, Intent intent) {
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ package com.android.server.wm;
|
|||||||
|
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||||
|
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;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
|
||||||
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||||
@@ -237,10 +243,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
|
|
||||||
mController.registerOrganizer(mIOrganizer);
|
mController.registerOrganizer(mIOrganizer);
|
||||||
mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
|
mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
|
||||||
mErrorToken, exception);
|
mErrorToken, null /* taskFragment */, -1 /* opType */, exception);
|
||||||
mController.dispatchPendingEvents();
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(exception));
|
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(null), eq(-1), eq(exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -604,7 +610,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
verify(mAtm.getActivityStartController(), never()).startActivityInTaskFragment(any(), any(),
|
verify(mAtm.getActivityStartController(), never()).startActivityInTaskFragment(any(), any(),
|
||||||
any(), any(), anyInt(), anyInt(), any());
|
any(), any(), anyInt(), anyInt(), any());
|
||||||
verify(mAtm.mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
verify(mAtm.mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
||||||
eq(mErrorToken), any(IllegalArgumentException.class));
|
eq(mErrorToken), eq(mTaskFragment),
|
||||||
|
eq(HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT),
|
||||||
|
any(IllegalArgumentException.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -619,7 +627,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
mWindowOrganizerController.applyTransaction(mTransaction);
|
mWindowOrganizerController.applyTransaction(mTransaction);
|
||||||
|
|
||||||
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
||||||
eq(mErrorToken), any(IllegalArgumentException.class));
|
eq(mErrorToken), eq(mTaskFragment),
|
||||||
|
eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
|
||||||
|
any(IllegalArgumentException.class));
|
||||||
assertNull(activity.getOrganizedTaskFragment());
|
assertNull(activity.getOrganizedTaskFragment());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,7 +645,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
mWindowOrganizerController.applyTransaction(mTransaction);
|
mWindowOrganizerController.applyTransaction(mTransaction);
|
||||||
|
|
||||||
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
||||||
eq(mErrorToken), any(IllegalArgumentException.class));
|
eq(mErrorToken), eq(mTaskFragment),
|
||||||
|
eq(HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS),
|
||||||
|
any(IllegalArgumentException.class));
|
||||||
verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
|
verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,7 +666,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
mWindowOrganizerController.applyTransaction(mTransaction);
|
mWindowOrganizerController.applyTransaction(mTransaction);
|
||||||
|
|
||||||
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
||||||
eq(mErrorToken), any(IllegalArgumentException.class));
|
eq(mErrorToken), eq(null), eq(HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT),
|
||||||
|
any(IllegalArgumentException.class));
|
||||||
assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken));
|
assertNull(mWindowOrganizerController.getTaskFragment(fragmentToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +682,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
mWindowOrganizerController.applyTransaction(mTransaction);
|
mWindowOrganizerController.applyTransaction(mTransaction);
|
||||||
|
|
||||||
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
|
||||||
eq(mErrorToken), any(IllegalArgumentException.class));
|
eq(mErrorToken), eq(mTaskFragment), eq(HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT),
|
||||||
|
any(IllegalArgumentException.class));
|
||||||
assertNotNull(mWindowOrganizerController.getTaskFragment(mFragmentToken));
|
assertNotNull(mWindowOrganizerController.getTaskFragment(mFragmentToken));
|
||||||
|
|
||||||
// Allow organizer to delete empty TaskFragment for cleanup.
|
// Allow organizer to delete empty TaskFragment for cleanup.
|
||||||
@@ -931,7 +945,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
// The pending event will be dispatched on the handler (from requestTraversal).
|
// The pending event will be dispatched on the handler (from requestTraversal).
|
||||||
waitHandlerIdle(mWm.mAnimationHandler);
|
waitHandlerIdle(mWm.mAnimationHandler);
|
||||||
|
|
||||||
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
|
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
|
||||||
|
eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
|
||||||
|
any(SecurityException.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -968,7 +984,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
// The pending event will be dispatched on the handler (from requestTraversal).
|
// The pending event will be dispatched on the handler (from requestTraversal).
|
||||||
waitHandlerIdle(mWm.mAnimationHandler);
|
waitHandlerIdle(mWm.mAnimationHandler);
|
||||||
|
|
||||||
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
|
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(),
|
||||||
|
eq(HIERARCHY_OP_TYPE_REPARENT_CHILDREN), any(SecurityException.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user