Merge "Revert "Use queue to defer all task events""

This commit is contained in:
Evan Rosky
2021-01-15 00:08:16 +00:00
committed by Android (Google) Code Review
8 changed files with 85 additions and 411 deletions

View File

@@ -262,6 +262,12 @@ public class ShellTaskOrganizer extends TaskOrganizer {
synchronized (mLock) {
ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId);
final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);
if (data == null) {
// TODO(b/171749427): It means onTaskInfoChanged send before onTaskAppeared or
// after onTaskVanished, it should be fixed in controller side.
return;
}
final TaskListener oldListener = getTaskListener(data.getTaskInfo());
final TaskListener newListener = getTaskListener(taskInfo);
mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash()));

View File

@@ -41,12 +41,12 @@ public class PipUiEventLogger {
}
public void setTaskInfo(TaskInfo taskInfo) {
if (taskInfo != null && taskInfo.topActivity != null) {
mPackageName = taskInfo.topActivity.getPackageName();
mPackageUid = getUid(mPackageName, taskInfo.userId);
} else {
if (taskInfo == null) {
mPackageName = null;
mPackageUid = INVALID_PACKAGE_UID;
} else {
mPackageName = taskInfo.topActivity.getPackageName();
mPackageUid = getUid(mPackageName, taskInfo.userId);
}
}

View File

@@ -1005,7 +1005,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
private void updateThemeColors() {
if (mScrimBehind == null) return;
int background = Utils.getColorAttr(mScrimBehind.getContext(),
android.R.attr.colorBackgroundFloating).getDefaultColor();
int accent = Utils.getColorAccent(mScrimBehind.getContext()).getDefaultColor();

View File

@@ -862,9 +862,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
}
}
// Send any pending task-info changes that were queued-up during a layout deferment
mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
checkAppTransitionReady(surfacePlacer);
@@ -1017,6 +1014,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mWmService.scheduleAnimationLocked();
// Send any pending task-info changes that were queued-up during a layout deferment
mWmService.mAtmService.mTaskOrganizerController.dispatchPendingTaskInfoChanges();
if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");
}

View File

@@ -4992,6 +4992,7 @@ class Task extends WindowContainer<WindowContainer> {
}
} else {
// No longer managed by any organizer.
mTaskAppearedSent = false;
setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, false /* set */);
if (mCreatedByOrganizer) {
removeImmediately("setTaskOrganizer");
@@ -5016,6 +5017,11 @@ class Task extends WindowContainer<WindowContainer> {
* @return {@code true} if task organizer changed.
*/
boolean updateTaskOrganizerState(boolean forceUpdate, boolean skipTaskAppeared) {
if (getSurfaceControl() == null) {
// Can't call onTaskAppeared without a surfacecontrol, so defer this until after one
// is created.
return false;
}
if (!canBeOrganized()) {
return setTaskOrganizer(null);
}
@@ -5025,10 +5031,6 @@ class Task extends WindowContainer<WindowContainer> {
final ITaskOrganizer organizer = controller.getTaskOrganizer(windowingMode);
if (!forceUpdate && mTaskOrganizer == organizer) {
return false;
} else if (organizer != null && getSurfaceControl() == null) {
// Can't call onTaskAppeared without a surfacecontrol, so defer this until after one
// is created.
return false;
}
return setTaskOrganizer(organizer, skipTaskAppeared);
}
@@ -7669,7 +7671,7 @@ class Task extends WindowContainer<WindowContainer> {
void dispatchTaskInfoChangedIfNeeded(boolean force) {
if (isOrganized()) {
mAtmService.mTaskOrganizerController.onTaskInfoChanged(this, force);
mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, force);
}
}

View File

@@ -151,23 +151,27 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task appeared taskId=%d", task.mTaskId);
final boolean visible = task.isVisible();
final RunningTaskInfo taskInfo = task.getTaskInfo();
try {
mTaskOrganizer.onTaskAppeared(taskInfo, prepareLeash(task, visible,
"TaskOrganizerController.onTaskAppeared"));
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskAppeared callback", e);
}
mDeferTaskOrgCallbacksConsumer.accept(() -> {
try {
mTaskOrganizer.onTaskAppeared(taskInfo, prepareLeash(task, visible,
"TaskOrganizerController.onTaskAppeared"));
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskAppeared callback", e);
}
});
}
void onTaskVanished(Task task) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task vanished taskId=%d", task.mTaskId);
final RunningTaskInfo taskInfo = task.getTaskInfo();
try {
mTaskOrganizer.onTaskVanished(taskInfo);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskVanished callback", e);
}
mDeferTaskOrgCallbacksConsumer.accept(() -> {
try {
mTaskOrganizer.onTaskVanished(taskInfo);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskVanished callback", e);
}
});
}
void onTaskInfoChanged(Task task, ActivityManager.RunningTaskInfo taskInfo) {
@@ -176,18 +180,20 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
return;
}
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task info changed taskId=%d", task.mTaskId);
if (!task.isOrganized()) {
// This is safe to ignore if the task is no longer organized
return;
}
try {
// Purposely notify of task info change immediately instead of deferring (like
// appear and vanish) to allow info changes (such as new PIP params) to flow
// without waiting.
mTaskOrganizer.onTaskInfoChanged(taskInfo);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskInfoChanged callback", e);
}
mDeferTaskOrgCallbacksConsumer.accept(() -> {
if (!task.isOrganized()) {
// This is safe to ignore if the task is no longer organized
return;
}
try {
// Purposely notify of task info change immediately instead of deferring (like
// appear and vanish) to allow info changes (such as new PIP params) to flow
// without waiting.
mTaskOrganizer.onTaskInfoChanged(taskInfo);
} catch (RemoteException e) {
Slog.e(TAG, "Exception sending onTaskInfoChanged callback", e);
}
});
}
void onBackPressedOnTaskRoot(Task task) {
@@ -197,15 +203,17 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
// Skip if the task has not yet received taskAppeared().
return;
}
if (!task.isOrganized()) {
// This is safe to ignore if the task is no longer organized
return;
}
try {
mTaskOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
} catch (Exception e) {
Slog.e(TAG, "Exception sending onBackPressedOnTaskRoot callback", e);
}
mDeferTaskOrgCallbacksConsumer.accept(() -> {
if (!task.isOrganized()) {
// This is safe to ignore if the task is no longer organized
return;
}
try {
mTaskOrganizer.onBackPressedOnTaskRoot(task.getTaskInfo());
} catch (Exception e) {
Slog.e(TAG, "Exception sending onBackPressedOnTaskRoot callback", e);
}
});
}
}
@@ -250,34 +258,28 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
return mOrganizer.prepareLeash(t, t.isVisible(), reason);
}
private boolean addTask(Task t) {
if (t.mTaskAppearedSent) {
return false;
}
void addTask(Task t) {
if (t.mTaskAppearedSent) return;
if (!mOrganizedTasks.contains(t)) {
mOrganizedTasks.add(t);
}
if (t.taskAppearedReady()) {
t.mTaskAppearedSent = true;
return true;
mOrganizer.onTaskAppeared(t);
}
return false;
}
private boolean removeTask(Task t) {
mOrganizedTasks.remove(t);
mInterceptBackPressedOnRootTasks.remove(t.mTaskId);
void removeTask(Task t) {
if (t.mTaskAppearedSent) {
if (t.getSurfaceControl() != null) {
t.migrateToNewSurfaceControl();
}
t.mTaskAppearedSent = false;
return true;
mOrganizer.onTaskVanished(t);
}
return false;
mOrganizedTasks.remove(t);
mInterceptBackPressedOnRootTasks.remove(t.mTaskId);
}
void dispose() {
@@ -289,7 +291,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
while (!mOrganizedTasks.isEmpty()) {
final Task t = mOrganizedTasks.get(0);
if (!t.updateTaskOrganizerState(true /* forceUpdate */)) {
TaskOrganizerController.this.onTaskVanished(mOrganizer.mTaskOrganizer, t);
removeTask(t);
}
}
@@ -303,33 +305,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
}
static class PendingTaskEvent {
static final int EVENT_APPEARED = 0;
static final int EVENT_VANISHED = 1;
static final int EVENT_INFO_CHANGED = 2;
static final int EVENT_ROOT_BACK_PRESSED = 3;
final int mEventType;
final Task mTask;
final ITaskOrganizer mTaskOrg;
boolean mForce;
PendingTaskEvent(Task task, int event) {
this(task, task.mTaskOrganizer, event);
}
PendingTaskEvent(Task task, ITaskOrganizer taskOrg, int eventType) {
mTask = task;
mTaskOrg = taskOrg;
mEventType = eventType;
}
boolean isLifecycleEvent() {
return mEventType == EVENT_APPEARED || mEventType == EVENT_VANISHED
|| mEventType == EVENT_INFO_CHANGED;
}
}
private final ActivityTaskManagerService mService;
private final WindowManagerGlobalLock mGlobalLock;
@@ -337,8 +312,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
private final LinkedList<ITaskOrganizer> mTaskOrganizers = new LinkedList<>();
private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
// Pending task events due to layout deferred.
private final ArrayList<PendingTaskEvent> mPendingTaskEvents = new ArrayList<>();
private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
// Set of organized tasks (by taskId) that dispatch back pressed to their organizers
private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet();
@@ -363,12 +337,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
public void setDeferTaskOrgCallbacksConsumer(Consumer<Runnable> consumer) {
mDeferTaskOrgCallbacksConsumer = consumer;
}
@VisibleForTesting
ArrayList<PendingTaskEvent> getPendingEventList() {
return mPendingTaskEvents;
}
/**
* Register a TaskOrganizer to manage tasks as they enter the a supported windowing mode.
*/
@@ -474,33 +442,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
void onTaskAppeared(ITaskOrganizer organizer, Task task) {
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
if (state != null && state.addTask(task)) {
PendingTaskEvent pending = getPendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED);
if (pending == null) {
pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_APPEARED);
mPendingTaskEvents.add(pending);
}
}
state.addTask(task);
}
void onTaskVanished(ITaskOrganizer organizer, Task task) {
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
if (state != null && state.removeTask(task)) {
for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) {
PendingTaskEvent entry = mPendingTaskEvents.get(i);
if (task.mTaskId == entry.mTask.mTaskId) {
// This task will vanished so remove all pending event of it.
mPendingTaskEvents.remove(i);
if (entry.mEventType == PendingTaskEvent.EVENT_APPEARED) {
// If task still not appeared, ignore this callback.
return;
}
}
}
PendingTaskEvent pending =
new PendingTaskEvent(task, organizer, PendingTaskEvent.EVENT_VANISHED);
mPendingTaskEvents.add(pending);
if (state != null) {
state.removeTask(task);
}
}
@@ -570,76 +518,30 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
}
}
void dispatchPendingEvents() {
if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()
|| mPendingTaskEvents.isEmpty()) {
void dispatchPendingTaskInfoChanges() {
if (mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
return;
}
for (int i = 0, n = mPendingTaskEvents.size(); i < n; i++) {
PendingTaskEvent event = mPendingTaskEvents.get(i);
final Task task = event.mTask;
final TaskOrganizerState state;
switch (event.mEventType) {
case PendingTaskEvent.EVENT_APPEARED:
state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder());
if (state != null && task.taskAppearedReady()) {
state.mOrganizer.onTaskAppeared(task);
}
break;
case PendingTaskEvent.EVENT_VANISHED:
state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder());
if (state != null) {
state.mOrganizer.onTaskVanished(task);
}
break;
case PendingTaskEvent.EVENT_INFO_CHANGED:
dispatchTaskInfoChanged(event.mTask, event.mForce);
break;
case PendingTaskEvent.EVENT_ROOT_BACK_PRESSED:
state = mTaskOrganizerStates.get(event.mTaskOrg.asBinder());
if (state != null) {
state.mOrganizer.onBackPressedOnTaskRoot(task);
}
break;
}
for (int i = 0, n = mPendingTaskInfoChanges.size(); i < n; ++i) {
dispatchTaskInfoChanged(mPendingTaskInfoChanges.get(i), false /* force */);
}
mPendingTaskEvents.clear();
mPendingTaskInfoChanges.clear();
}
void onTaskInfoChanged(Task task, boolean force) {
if (!task.mTaskAppearedSent) {
// Skip if task still not appeared.
void dispatchTaskInfoChanged(Task task, boolean force) {
if (!force && mService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
// Defer task info reporting while layout is deferred. This is because layout defer
// blocks tend to do lots of re-ordering which can mess up animations in receivers.
mPendingTaskInfoChanges.remove(task);
mPendingTaskInfoChanges.add(task);
return;
}
// Defer task info reporting while layout is deferred. This is because layout defer
// blocks tend to do lots of re-ordering which can mess up animations in receivers.
PendingTaskEvent pending = getPendingLifecycleTaskEvent(task);
if (pending == null) {
pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_INFO_CHANGED);
} else {
if (pending.mEventType != PendingTaskEvent.EVENT_INFO_CHANGED) {
// If queued event is appeared, it means task still not appeared so ignore
// this info changed. If queued event is vanished, it means task should
// will vanished early so do not need this info changed.
return;
}
// Remove and add for re-ordering.
mPendingTaskEvents.remove(pending);
}
pending.mForce = force;
mPendingTaskEvents.add(pending);
}
private void dispatchTaskInfoChanged(Task task, boolean force) {
RunningTaskInfo lastInfo = mLastSentTaskInfos.get(task);
if (mTmpTaskInfo == null) {
mTmpTaskInfo = new RunningTaskInfo();
}
mTmpTaskInfo.configuration.unset();
task.fillTaskInfo(mTmpTaskInfo);
boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo);
if (!changed) {
int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration);
@@ -802,48 +704,11 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
return false;
}
PendingTaskEvent pendingVanished =
getPendingTaskEvent(task, PendingTaskEvent.EVENT_VANISHED);
if (pendingVanished != null) {
// This task will vanish before this callback so just ignore.
return false;
}
PendingTaskEvent pending = getPendingTaskEvent(
task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED);
if (pending == null) {
pending = new PendingTaskEvent(task, PendingTaskEvent.EVENT_ROOT_BACK_PRESSED);
} else {
// Pending already exist, remove and add for re-ordering.
mPendingTaskEvents.remove(pending);
}
mPendingTaskEvents.add(pending);
final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder());
state.mOrganizer.onBackPressedOnTaskRoot(task);
return true;
}
@Nullable
private PendingTaskEvent getPendingTaskEvent(Task task, int type) {
for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) {
PendingTaskEvent entry = mPendingTaskEvents.get(i);
if (task.mTaskId == entry.mTask.mTaskId && type == entry.mEventType) {
return entry;
}
}
return null;
}
@VisibleForTesting
@Nullable
PendingTaskEvent getPendingLifecycleTaskEvent(Task task) {
for (int i = mPendingTaskEvents.size() - 1; i >= 0; i--) {
PendingTaskEvent entry = mPendingTaskEvents.get(i);
if (task.mTaskId == entry.mTask.mTaskId && entry.isLifecycleEvent()) {
return entry;
}
}
return null;
}
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.print(prefix); pw.println("TaskOrganizerController:");

View File

@@ -222,7 +222,6 @@ public class WindowAnimator {
mService.destroyPreservedSurfaceLocked();
mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
executeAfterPrepareSurfacesRunnables();
if (DEBUG_WINDOW_TRACE) {

View File

@@ -80,8 +80,6 @@ import android.window.WindowContainerTransaction;
import androidx.test.filters.SmallTest;
import com.android.server.wm.TaskOrganizerController.PendingTaskEvent;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -152,14 +150,10 @@ public class WindowOrganizerTests extends WindowTestsBase {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
stack.removeImmediately();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskVanished(any());
}
@@ -168,21 +162,15 @@ public class WindowOrganizerTests extends WindowTestsBase {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack, false);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, never())
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
stack.setHasBeenVisible(true);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertTrue(stack.getHasBeenVisible());
verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
stack.removeImmediately();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskVanished(any());
}
@@ -207,16 +195,12 @@ public class WindowOrganizerTests extends WindowTestsBase {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack, false /* fakeDraw */);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, never())
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
assertTrue(stack.isOrganized());
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertTaskVanished(organizer, false /* expectVanished */, stack);
assertFalse(stack.isOrganized());
}
@@ -226,16 +210,11 @@ public class WindowOrganizerTests extends WindowTestsBase {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
assertTrue(stack.isOrganized());
stack.setTaskOrganizer(null);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskVanished(any());
assertFalse(stack.isOrganized());
}
@@ -245,16 +224,11 @@ public class WindowOrganizerTests extends WindowTestsBase {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
assertTrue(stack.isOrganized());
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertTaskVanished(organizer, true /* expectVanished */, stack);
assertFalse(stack.isOrganized());
}
@@ -269,8 +243,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
final Task task3 = createTask(stack3);
final ArrayList<TaskAppearedInfo> existingTasks = new ArrayList<>();
final ITaskOrganizer organizer = registerMockOrganizer(existingTasks);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
// verify that tasks are returned and taskAppeared is not called
assertContainsTasks(existingTasks, stack, stack2, stack3);
@@ -282,8 +254,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Now we replace the registration and verify the new organizer receives existing tasks
final ArrayList<TaskAppearedInfo> existingTasks2 = new ArrayList<>();
final ITaskOrganizer organizer2 = registerMockOrganizer(existingTasks2);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertContainsTasks(existingTasks2, stack, stack2, stack3);
verify(organizer2, times(0)).onTaskAppeared(any(RunningTaskInfo.class),
any(SurfaceControl.class));
@@ -295,8 +265,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Now we unregister the second one, the first one should automatically be reregistered
// so we verify that it's now seeing changes.
mWm.mAtmService.mTaskOrganizerController.unregisterTaskOrganizer(organizer2);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(3))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
assertTaskVanished(organizer2, true /* expectVanished */, stack, stack2, stack3);
@@ -631,8 +599,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
Task task = mWm.mAtmService.mTaskOrganizerController.createRootTask(
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
RunningTaskInfo info1 = task.getTaskInfo();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
lastReportedTiles.clear();
called[0] = false;
@@ -707,8 +673,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
Task task2 = mWm.mAtmService.mTaskOrganizerController.createRootTask(
mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, null);
RunningTaskInfo info2 = task2.getTaskInfo();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
final int initialRootTaskCount = mWm.mAtmService.mTaskOrganizerController.getRootTasks(
mDisplayContent.mDisplayId, null /* activityTypes */).size();
@@ -892,8 +856,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
.setAspectRatio(new Rational(3, 4)).build();
mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2);
waitUntilHandlersIdle();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
assertNotNull(o.mChangedInfo);
assertNotNull(o.mChangedInfo.pictureInPictureParams);
final Rational ratio = o.mChangedInfo.pictureInPictureParams.getAspectRatioRational();
@@ -933,24 +895,16 @@ public class WindowOrganizerTests extends WindowTestsBase {
stack.setTaskOrganizer(organizer);
// setHasBeenVisible was already called once by the set-up code.
stack.setHasBeenVisible(true);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(1))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
stack.setTaskOrganizer(null);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(1)).onTaskVanished(any());
stack.setTaskOrganizer(organizer);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(2))
.onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
stack.removeImmediately();
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(2)).onTaskVanished(any());
}
@@ -969,8 +923,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Verify a back pressed does not call the organizer
mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, never()).onBackPressedOnTaskRoot(any());
// Enable intercepting back
@@ -979,8 +931,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Verify now that the back press does call the organizer
mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
// Disable intercepting back
@@ -989,8 +939,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
// Verify now that the back press no longer calls the organizer
mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
// Ensure events dispatch to organizer.
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
}
@@ -1071,151 +1019,6 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertTrue(task2.isOrganized());
}
@Test
public void testAppearDeferThenInfoChange() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
final Task task = createTask(stack);
final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_APPEARED, pendingEvents.get(0).mEventType);
assertEquals("TestDescription",
pendingEvents.get(0).mTask.getTaskInfo().taskDescription.getLabel());
}
@Test
public void testAppearDeferThenVanish() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
final Task task = createTask(stack);
stack.removeImmediately();
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(0, pendingEvents.size());
}
@Test
public void testInfoChangeDeferMultiple() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType);
assertEquals("TestDescription",
pendingEvents.get(0).mTask.getTaskInfo().taskDescription.getLabel());
record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription2"));
waitUntilHandlersIdle();
pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_INFO_CHANGED, pendingEvents.get(0).mEventType);
assertEquals("TestDescription2",
pendingEvents.get(0).mTask.getTaskInfo().taskDescription.getLabel());
}
@Test
public void testInfoChangDeferThenVanish() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
stack.removeImmediately();
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
assertEquals("TestDescription",
pendingEvents.get(0).mTask.getTaskInfo().taskDescription.getLabel());
}
@Test
public void testVanishDeferThenInfoChange() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
stack.removeImmediately();
stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
}
@Test
public void testVanishDeferThenBackOnRoot() {
final ITaskOrganizer organizer = registerMockOrganizer();
final Task stack = createStack();
final Task task = createTask(stack);
final ActivityRecord record = createActivityRecord(stack.mDisplayContent, task);
// Assume layout defer
mWm.mWindowPlacerLocked.deferLayout();
stack.removeImmediately();
mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(record.token);
waitUntilHandlersIdle();
ArrayList<PendingTaskEvent> pendingEvents = getTaskPendingEvent(stack);
assertEquals(1, pendingEvents.size());
assertEquals(PendingTaskEvent.EVENT_VANISHED, pendingEvents.get(0).mEventType);
}
private ArrayList<PendingTaskEvent> getTaskPendingEvent(Task task) {
ArrayList<PendingTaskEvent> total =
mWm.mAtmService.mTaskOrganizerController.getPendingEventList();
ArrayList<PendingTaskEvent> result = new ArrayList();
for (int i = 0; i < total.size(); i++) {
PendingTaskEvent entry = total.get(i);
if (entry.mTask.mTaskId == task.mTaskId) {
result.add(entry);
}
}
return result;
}
/**
* Verifies that task vanished is called for a specific task.
*/