Merge "Report the failure back to the organizer" into sc-v2-dev
This commit is contained in:
@@ -490,9 +490,16 @@ public class ActivityStartController {
|
|||||||
return START_SUCCESS;
|
return START_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startActivityInTaskFragment(@NonNull TaskFragment taskFragment,
|
/**
|
||||||
|
* Starts an activity in the TaskFragment.
|
||||||
|
* @param taskFragment TaskFragment {@link TaskFragment} to start the activity in.
|
||||||
|
* @param activityIntent intent to start the activity.
|
||||||
|
* @param activityOptions ActivityOptions to start the activity with.
|
||||||
|
* @return the start result.
|
||||||
|
*/
|
||||||
|
int startActivityInTaskFragment(@NonNull TaskFragment taskFragment,
|
||||||
@NonNull Intent activityIntent, @Nullable Bundle activityOptions) {
|
@NonNull Intent activityIntent, @Nullable Bundle activityOptions) {
|
||||||
obtainStarter(activityIntent, "startActivityInTaskFragment")
|
return obtainStarter(activityIntent, "startActivityInTaskFragment")
|
||||||
.setActivityOptions(activityOptions)
|
.setActivityOptions(activityOptions)
|
||||||
.setInTaskFragment(taskFragment)
|
.setInTaskFragment(taskFragment)
|
||||||
.setCallingUid(Binder.getCallingUid())
|
.setCallingUid(Binder.getCallingUid())
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static android.window.TaskFragmentOrganizer.putExceptionInBundle;
|
||||||
|
|
||||||
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.WindowOrganizerController.configurationsAreEqualForOrganizer;
|
import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer;
|
||||||
|
|
||||||
@@ -23,6 +25,7 @@ import android.annotation.IntDef;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -190,6 +193,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
|
Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
|
||||||
|
Throwable exception) {
|
||||||
|
final Bundle exceptionBundle = putExceptionInBundle(exception);
|
||||||
|
try {
|
||||||
|
organizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Exception sending onTaskFragmentError callback", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -289,6 +302,14 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
state.removeTaskFragment(taskFragment);
|
state.removeTaskFragment(taskFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onTaskFragmentError(ITaskFragmentOrganizer organizer, IBinder errorCallbackToken,
|
||||||
|
Throwable exception) {
|
||||||
|
validateAndGetState(organizer);
|
||||||
|
PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent(organizer,
|
||||||
|
errorCallbackToken, exception, PendingTaskFragmentEvent.EVENT_ERROR);
|
||||||
|
mPendingTaskFragmentEvents.add(pendingEvent);
|
||||||
|
}
|
||||||
|
|
||||||
private void removeOrganizer(ITaskFragmentOrganizer organizer) {
|
private void removeOrganizer(ITaskFragmentOrganizer organizer) {
|
||||||
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
|
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
|
||||||
// remove all of the children of the organized TaskFragment
|
// remove all of the children of the organized TaskFragment
|
||||||
@@ -321,25 +342,45 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
static final int EVENT_VANISHED = 1;
|
static final int EVENT_VANISHED = 1;
|
||||||
static final int EVENT_INFO_CHANGED = 2;
|
static final int EVENT_INFO_CHANGED = 2;
|
||||||
static final int EVENT_PARENT_INFO_CHANGED = 3;
|
static final int EVENT_PARENT_INFO_CHANGED = 3;
|
||||||
|
static final int EVENT_ERROR = 4;
|
||||||
|
|
||||||
@IntDef(prefix = "EVENT_", value = {
|
@IntDef(prefix = "EVENT_", value = {
|
||||||
EVENT_APPEARED,
|
EVENT_APPEARED,
|
||||||
EVENT_VANISHED,
|
EVENT_VANISHED,
|
||||||
EVENT_INFO_CHANGED,
|
EVENT_INFO_CHANGED,
|
||||||
EVENT_PARENT_INFO_CHANGED
|
EVENT_PARENT_INFO_CHANGED,
|
||||||
|
EVENT_ERROR
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface EventType {}
|
public @interface EventType {}
|
||||||
|
|
||||||
@EventType
|
@EventType
|
||||||
final int mEventType;
|
private final int mEventType;
|
||||||
final TaskFragment mTaskFragment;
|
private final ITaskFragmentOrganizer mTaskFragmentOrg;
|
||||||
final ITaskFragmentOrganizer mTaskFragmentOrg;
|
private final TaskFragment mTaskFragment;
|
||||||
|
private final IBinder mErrorCallback;
|
||||||
|
private final Throwable mException;
|
||||||
|
|
||||||
PendingTaskFragmentEvent(TaskFragment taskFragment, ITaskFragmentOrganizer taskFragmentOrg,
|
private PendingTaskFragmentEvent(TaskFragment taskFragment,
|
||||||
|
ITaskFragmentOrganizer taskFragmentOrg, @EventType int eventType) {
|
||||||
|
this(taskFragment, taskFragmentOrg, null /* errorCallback */,
|
||||||
|
null /* exception */, eventType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingTaskFragmentEvent(ITaskFragmentOrganizer taskFragmentOrg,
|
||||||
|
IBinder errorCallback, Throwable exception, @EventType int eventType) {
|
||||||
|
this(null /* taskFragment */, taskFragmentOrg, errorCallback, exception,
|
||||||
|
eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingTaskFragmentEvent(TaskFragment taskFragment,
|
||||||
|
ITaskFragmentOrganizer taskFragmentOrg, IBinder errorCallback, Throwable exception,
|
||||||
@EventType int eventType) {
|
@EventType int eventType) {
|
||||||
mTaskFragment = taskFragment;
|
mTaskFragment = taskFragment;
|
||||||
mTaskFragmentOrg = taskFragmentOrg;
|
mTaskFragmentOrg = taskFragmentOrg;
|
||||||
|
mErrorCallback = errorCallback;
|
||||||
|
mException = exception;
|
||||||
mEventType = eventType;
|
mEventType = eventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,6 +448,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
break;
|
break;
|
||||||
case PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED:
|
case PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED:
|
||||||
state.onTaskFragmentParentInfoChanged(taskFragmentOrg, taskFragment);
|
state.onTaskFragmentParentInfoChanged(taskFragmentOrg, taskFragment);
|
||||||
|
break;
|
||||||
|
case PendingTaskFragmentEvent.EVENT_ERROR:
|
||||||
|
state.onTaskFragmentError(taskFragmentOrg, event.mErrorCallback,
|
||||||
|
event.mException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mPendingTaskFragmentEvents.clear();
|
mPendingTaskFragmentEvents.clear();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
|
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
|
||||||
|
import static android.app.ActivityManager.isStartResultSuccessful;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
|
||||||
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
|
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
|
||||||
@@ -44,6 +45,7 @@ import android.annotation.Nullable;
|
|||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@@ -369,7 +371,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
final boolean isInLockTaskMode = mService.isInLockTaskMode();
|
final boolean isInLockTaskMode = mService.isInLockTaskMode();
|
||||||
for (int i = 0; i < hopSize; ++i) {
|
for (int i = 0; i < hopSize; ++i) {
|
||||||
effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
|
effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
|
||||||
isInLockTaskMode, caller);
|
isInLockTaskMode, caller, t.getErrorCallbackToken(),
|
||||||
|
t.getTaskFragmentOrganizer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Queue-up bounds-change transactions for tasks which are now organized. Do
|
// Queue-up bounds-change transactions for tasks which are now organized. Do
|
||||||
@@ -525,7 +528,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
|
|
||||||
private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
|
private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
|
||||||
int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
|
int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
|
||||||
@Nullable CallerInfo caller) {
|
@Nullable CallerInfo caller, @Nullable IBinder errorCallbackToken,
|
||||||
|
@Nullable ITaskFragmentOrganizer organizer) {
|
||||||
final int type = hop.getType();
|
final int type = hop.getType();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
|
case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
|
||||||
@@ -652,7 +656,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
|
case HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT:
|
||||||
final TaskFragmentCreationParams taskFragmentCreationOptions =
|
final TaskFragmentCreationParams taskFragmentCreationOptions =
|
||||||
hop.getTaskFragmentCreationOptions();
|
hop.getTaskFragmentCreationOptions();
|
||||||
createTaskFragment(taskFragmentCreationOptions);
|
createTaskFragment(taskFragmentCreationOptions, errorCallbackToken);
|
||||||
break;
|
break;
|
||||||
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
|
case HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT:
|
||||||
wc = WindowContainer.fromBinder(hop.getContainer());
|
wc = WindowContainer.fromBinder(hop.getContainer());
|
||||||
@@ -665,28 +669,36 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can only delete organized TaskFragment, but not Task.");
|
"Can only delete organized TaskFragment, but not Task.");
|
||||||
}
|
}
|
||||||
deleteTaskFragment(taskFragment);
|
deleteTaskFragment(taskFragment, errorCallbackToken);
|
||||||
break;
|
break;
|
||||||
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
|
case HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT:
|
||||||
fragmentToken = hop.getContainer();
|
fragmentToken = hop.getContainer();
|
||||||
if (!mLaunchTaskFragments.containsKey(fragmentToken)) {
|
if (!mLaunchTaskFragments.containsKey(fragmentToken)) {
|
||||||
throw 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);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
final Intent activityIntent = hop.getActivityIntent();
|
final Intent activityIntent = hop.getActivityIntent();
|
||||||
final Bundle activityOptions = hop.getLaunchOptions();
|
final Bundle activityOptions = hop.getLaunchOptions();
|
||||||
mService.getActivityStartController()
|
final TaskFragment tf = mLaunchTaskFragments.get(fragmentToken);
|
||||||
.startActivityInTaskFragment(mLaunchTaskFragments.get(fragmentToken),
|
final int result = mService.getActivityStartController()
|
||||||
activityIntent, activityOptions);
|
.startActivityInTaskFragment(tf, activityIntent, activityOptions);
|
||||||
// TODO(b/189385246) : report the failure back to the organizer if the activity
|
if (!isStartResultSuccessful(result)) {
|
||||||
// start failed
|
final Throwable exception =
|
||||||
|
new ActivityNotFoundException("start activity in taskFragment failed");
|
||||||
|
sendTaskFragmentOperationFailure(tf.getTaskFragmentOrganizer(),
|
||||||
|
errorCallbackToken, exception);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
|
case HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT:
|
||||||
fragmentToken = hop.getNewParent();
|
fragmentToken = hop.getNewParent();
|
||||||
final ActivityRecord activity = ActivityRecord.forTokenLocked(hop.getContainer());
|
final ActivityRecord activity = ActivityRecord.forTokenLocked(hop.getContainer());
|
||||||
if (!mLaunchTaskFragments.containsKey(fragmentToken) || activity == null) {
|
if (!mLaunchTaskFragments.containsKey(fragmentToken) || activity == null) {
|
||||||
throw 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);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
activity.reparent(mLaunchTaskFragments.get(fragmentToken), POSITION_TOP);
|
activity.reparent(mLaunchTaskFragments.get(fragmentToken), POSITION_TOP);
|
||||||
break;
|
break;
|
||||||
@@ -700,7 +712,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
+ oldParent);
|
+ oldParent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reparentTaskFragment(oldParent, newParent);
|
reparentTaskFragment(oldParent, newParent, errorCallbackToken);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return effects;
|
return effects;
|
||||||
@@ -1076,17 +1088,25 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams) {
|
void createTaskFragment(@NonNull TaskFragmentCreationParams creationParams,
|
||||||
|
@Nullable IBinder errorCallbackToken) {
|
||||||
final ActivityRecord ownerActivity =
|
final ActivityRecord ownerActivity =
|
||||||
ActivityRecord.forTokenLocked(creationParams.getOwnerToken());
|
ActivityRecord.forTokenLocked(creationParams.getOwnerToken());
|
||||||
if (ownerActivity == null || ownerActivity.getTask() == null) {
|
if (ownerActivity == null || ownerActivity.getTask() == null) {
|
||||||
// TODO(b/189385246) : report the failure back to the organizer
|
final Throwable exception =
|
||||||
|
new IllegalArgumentException("Not allowed to operate with invalid ownerToken");
|
||||||
|
sendTaskFragmentOperationFailure(creationParams.getOrganizer(), errorCallbackToken,
|
||||||
|
exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The ownerActivity has to belong to the same app as the root Activity of the target Task.
|
// The ownerActivity has to belong to the same app as the root Activity of the target Task.
|
||||||
final ActivityRecord rootActivity = ownerActivity.getTask().getRootActivity();
|
final ActivityRecord rootActivity = ownerActivity.getTask().getRootActivity();
|
||||||
if (rootActivity.getUid() != ownerActivity.getUid()) {
|
if (rootActivity.getUid() != ownerActivity.getUid()) {
|
||||||
// TODO(b/189385246) : report the failure back to the organizer
|
final Throwable exception =
|
||||||
|
new IllegalArgumentException("Not allowed to operate with the ownerToken while "
|
||||||
|
+ "the root activity of the target task belong to the different app");
|
||||||
|
sendTaskFragmentOperationFailure(creationParams.getOrganizer(), errorCallbackToken,
|
||||||
|
exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final TaskFragment taskFragment = new TaskFragment(mService,
|
final TaskFragment taskFragment = new TaskFragment(mService,
|
||||||
@@ -1102,13 +1122,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reparentTaskFragment(@NonNull WindowContainer oldParent,
|
void reparentTaskFragment(@NonNull WindowContainer oldParent,
|
||||||
@Nullable WindowContainer newParent) {
|
@Nullable WindowContainer newParent, @Nullable IBinder errorCallbackToken) {
|
||||||
WindowContainer parent = newParent;
|
WindowContainer parent = newParent;
|
||||||
if (parent == null && oldParent.asTaskFragment() != null) {
|
if (parent == null && oldParent.asTaskFragment() != null) {
|
||||||
parent = oldParent.asTaskFragment().getTask();
|
parent = oldParent.asTaskFragment().getTask();
|
||||||
}
|
}
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
// TODO(b/189385246) : report the failure back to the organizer
|
final Throwable exception =
|
||||||
|
new IllegalArgumentException("Not allowed to operate with invalid container");
|
||||||
|
sendTaskFragmentOperationFailure(oldParent.asTaskFragment().getTaskFragmentOrganizer(),
|
||||||
|
errorCallbackToken, exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (oldParent.hasChild()) {
|
while (oldParent.hasChild()) {
|
||||||
@@ -1116,11 +1139,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteTaskFragment(@NonNull TaskFragment taskFragment) {
|
void deleteTaskFragment(@NonNull TaskFragment taskFragment,
|
||||||
|
@Nullable IBinder errorCallbackToken) {
|
||||||
final int index = mLaunchTaskFragments.indexOfValue(taskFragment);
|
final int index = mLaunchTaskFragments.indexOfValue(taskFragment);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
throw new IllegalArgumentException(
|
final Throwable exception =
|
||||||
"Not allowed to operate with invalid taskFragment");
|
new IllegalArgumentException("Not allowed to operate with invalid "
|
||||||
|
+ "taskFragment");
|
||||||
|
sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
|
||||||
|
errorCallbackToken, exception);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
mLaunchTaskFragments.removeAt(index);
|
mLaunchTaskFragments.removeAt(index);
|
||||||
taskFragment.removeImmediately();
|
taskFragment.removeImmediately();
|
||||||
@@ -1135,4 +1163,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
mUid = Binder.getCallingUid();
|
mUid = Binder.getCallingUid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendTaskFragmentOperationFailure(@NonNull ITaskFragmentOrganizer organizer,
|
||||||
|
@Nullable IBinder errorCallbackToken, @NonNull Throwable exception) {
|
||||||
|
if (organizer == null) {
|
||||||
|
throw new IllegalArgumentException("Not allowed to operate with invalid organizer");
|
||||||
|
}
|
||||||
|
mService.mTaskFragmentOrganizerController
|
||||||
|
.onTaskFragmentError(organizer, errorCallbackToken, exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.window.TaskFragmentOrganizer.putExceptionInBundle;
|
|
||||||
|
|
||||||
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;
|
||||||
import static com.android.server.wm.testing.Assert.assertThrows;
|
import static com.android.server.wm.testing.Assert.assertThrows;
|
||||||
@@ -35,7 +33,6 @@ import android.content.Intent;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
@@ -198,9 +195,11 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
public void testOnTaskFragmentError() throws RemoteException {
|
public void testOnTaskFragmentError() throws RemoteException {
|
||||||
final IBinder errorCallbackToken = new Binder();
|
final IBinder errorCallbackToken = new Binder();
|
||||||
final Throwable exception = new IllegalArgumentException("Test exception");
|
final Throwable exception = new IllegalArgumentException("Test exception");
|
||||||
final Bundle exceptionBundle = putExceptionInBundle(exception);
|
|
||||||
|
|
||||||
mIOrganizer.onTaskFragmentError(errorCallbackToken, exceptionBundle);
|
mController.registerOrganizer(mIOrganizer);
|
||||||
|
mController.onTaskFragmentError(mTaskFragment.getTaskFragmentOrganizer(),
|
||||||
|
errorCallbackToken, exception);
|
||||||
|
mController.dispatchPendingEvents();
|
||||||
|
|
||||||
verify(mOrganizer).onTaskFragmentError(eq(errorCallbackToken), eq(exception));
|
verify(mOrganizer).onTaskFragmentError(eq(errorCallbackToken), eq(exception));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user