diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index b0d0f163446a8..4ccd486b48132 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -732,6 +732,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { WindowOrganizerController mWindowOrganizerController; TaskOrganizerController mTaskOrganizerController; + TaskFragmentOrganizerController mTaskFragmentOrganizerController; @Nullable private BackgroundActivityStartCallback mBackgroundActivityStartCallback; @@ -805,6 +806,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED); mWindowOrganizerController = new WindowOrganizerController(this); mTaskOrganizerController = mWindowOrganizerController.mTaskOrganizerController; + mTaskFragmentOrganizerController = + mWindowOrganizerController.mTaskFragmentOrganizerController; } public void onSystemReady() { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 0b80bae71ab83..12afbacba9257 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -853,6 +853,7 @@ class RootWindowContainer extends WindowContainer // Send any pending task-info changes that were queued-up during a layout deferment mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); + mWmService.mAtmService.mTaskFragmentOrganizerController.dispatchPendingEvents(); mWmService.mSyncEngine.onSurfacePlacement(); mWmService.mAnimator.executeAfterPrepareSurfacesRunnables(); diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 12ad634fb6b80..e9f4b5b6cf610 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -82,6 +82,7 @@ import android.util.DisplayMetrics; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; +import android.view.SurfaceControl; import android.window.ITaskFragmentOrganizer; import android.window.TaskFragmentInfo; @@ -160,6 +161,11 @@ class TaskFragment extends WindowContainer { // The TaskFragment that adjacent to this one. private TaskFragment mAdjacentTaskFragment; + /** + * Prevents duplicate calls to onTaskAppeared. + */ + boolean mTaskFragmentAppearedSent; + /** * When we are in the process of pausing an activity, before starting the * next one, this variable holds the activity that is currently being paused. @@ -1970,18 +1976,24 @@ class TaskFragment extends WindowContainer { @Override public void onConfigurationChanged(Configuration newParentConfig) { super.onConfigurationChanged(newParentConfig); + sendTaskFragmentInfoChanged(); + } + @Override + void setSurfaceControl(SurfaceControl sc) { + super.setSurfaceControl(sc); + // If the TaskFragmentOrganizer was set before we created the SurfaceControl, we need to + // emit the callbacks now. + sendTaskFragmentAppeared(); + } + + void sendTaskFragmentInfoChanged() { if (mTaskFragmentOrganizer != null) { - // Parent config may have changed. The controller will check if there is any important - // config change for the organizer. - mTaskFragmentOrganizerController - .onTaskFragmentParentInfoChanged(mTaskFragmentOrganizer, this); mTaskFragmentOrganizerController .onTaskFragmentInfoChanged(mTaskFragmentOrganizer, this); } } - // TODO(b/190433129) call when TaskFragment is created from WCT#createTaskFragment private void sendTaskFragmentAppeared() { if (mTaskFragmentOrganizer != null) { mTaskFragmentOrganizerController.onTaskFragmentAppeared(mTaskFragmentOrganizer, this); diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index 56d29dee7b458..496ecdedcaf71 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -19,6 +19,8 @@ package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; +import android.annotation.IntDef; +import android.annotation.Nullable; import android.content.res.Configuration; import android.os.Binder; import android.os.IBinder; @@ -33,6 +35,8 @@ import android.window.TaskFragmentInfo; import com.android.internal.protolog.common.ProtoLog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Map; import java.util.WeakHashMap; @@ -45,16 +49,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr private final ActivityTaskManagerService mAtmService; private final WindowManagerGlobalLock mGlobalLock; - private final Map mLastSentTaskFragmentInfos = - new WeakHashMap<>(); - private final Map mLastSentTaskFragmentParentConfigs = - new WeakHashMap<>(); /** * A Map which manages the relationship between * {@link ITaskFragmentOrganizer} and {@link TaskFragmentOrganizerState} */ - private final ArrayMap mTaskFragmentOrganizerControllers = + private final ArrayMap mTaskFragmentOrganizerState = new ArrayMap<>(); + /** + * A List which manages the TaskFragment pending event {@link PendingTaskFragmentEvent} + */ + private final ArrayList mPendingTaskFragmentEvents = + new ArrayList<>(); TaskFragmentOrganizerController(ActivityTaskManagerService atm) { mAtmService = atm; @@ -65,11 +70,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr * A class to manage {@link ITaskFragmentOrganizer} and its organized * {@link TaskFragment TaskFragments}. */ - private class TaskFragmentController implements IBinder.DeathRecipient { + private class TaskFragmentOrganizerState implements IBinder.DeathRecipient { private final ArrayList mOrganizedTaskFragments = new ArrayList<>(); private final ITaskFragmentOrganizer mOrganizer; + private final Map mLastSentTaskFragmentInfos = + new WeakHashMap<>(); + private final Map mLastSentTaskFragmentParentConfigs = + new WeakHashMap<>(); - TaskFragmentController(ITaskFragmentOrganizer organizer) { + TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer) { mOrganizer = organizer; try { mOrganizer.asBinder().linkToDeath(this, 0 /*flags*/); @@ -85,10 +94,18 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } - void addTaskFragment(TaskFragment taskFragment) { - if (!mOrganizedTaskFragments.contains(taskFragment)) { - mOrganizedTaskFragments.add(taskFragment); + /** + * @return {@code true} if taskFragment is organized and not sent the appeared event before. + */ + boolean addTaskFragment(TaskFragment taskFragment) { + if (taskFragment.mTaskFragmentAppearedSent) { + return false; } + if (mOrganizedTaskFragments.contains(taskFragment)) { + return false; + } + mOrganizedTaskFragments.add(taskFragment); + return true; } void removeTaskFragment(TaskFragment taskFragment) { @@ -100,6 +117,79 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr mOrganizedTaskFragments.clear(); mOrganizer.asBinder().unlinkToDeath(this, 0 /*flags*/); } + + void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName()); + final TaskFragmentInfo info = tf.getTaskFragmentInfo(); + final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), + "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); + try { + organizer.onTaskFragmentAppeared( + new TaskFragmentAppearedInfo(info, outSurfaceControl)); + mLastSentTaskFragmentInfos.put(tf, info); + tf.mTaskFragmentAppearedSent = true; + } catch (RemoteException e) { + Slog.e(TAG, "Exception sending onTaskFragmentAppeared callback", e); + } + onTaskFragmentParentInfoChanged(organizer, tf); + } + + void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName()); + try { + organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo()); + } catch (RemoteException e) { + Slog.e(TAG, "Exception sending onTaskFragmentVanished callback", e); + } + tf.mTaskFragmentAppearedSent = false; + mLastSentTaskFragmentInfos.remove(tf); + mLastSentTaskFragmentParentConfigs.remove(tf); + } + + void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { + // Parent config may have changed. The controller will check if there is any important + // config change for the organizer. + onTaskFragmentParentInfoChanged(organizer, tf); + + // Check if the info is different from the last reported info. + final TaskFragmentInfo info = tf.getTaskFragmentInfo(); + final TaskFragmentInfo lastInfo = mLastSentTaskFragmentInfos.get(tf); + if (info.equalsForTaskFragmentOrganizer(lastInfo) && configurationsAreEqualForOrganizer( + info.getConfiguration(), lastInfo.getConfiguration())) { + return; + } + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", + tf.getName()); + try { + organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); + mLastSentTaskFragmentInfos.put(tf, info); + } catch (RemoteException e) { + Slog.e(TAG, "Exception sending onTaskFragmentInfoChanged callback", e); + } + } + + void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { + // Check if the parent info is different from the last reported parent info. + if (tf.getParent() == null || tf.getParent().asTask() == null) { + mLastSentTaskFragmentParentConfigs.remove(tf); + return; + } + final Task parent = tf.getParent().asTask(); + final Configuration parentConfig = parent.getConfiguration(); + final Configuration lastParentConfig = mLastSentTaskFragmentParentConfigs.get(tf); + if (configurationsAreEqualForOrganizer(parentConfig, lastParentConfig)) { + return; + } + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, + "TaskFragment parent info changed name=%s parentTaskId=%d", + tf.getName(), parent.mTaskId); + try { + organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig); + mLastSentTaskFragmentParentConfigs.put(tf, new Configuration(parentConfig)); + } catch (RemoteException e) { + Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e); + } + } } @Override @@ -110,18 +200,18 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task fragment organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); - if (mTaskFragmentOrganizerControllers.containsKey(organizer.asBinder())) { + if (mTaskFragmentOrganizerState.containsKey(organizer.asBinder())) { throw new IllegalStateException( "Replacing existing organizer currently unsupported"); } - mTaskFragmentOrganizerControllers.put(organizer.asBinder(), - new TaskFragmentController(organizer)); + mTaskFragmentOrganizerState.put(organizer.asBinder(), + new TaskFragmentOrganizerState(organizer)); } } @Override public void unregisterOrganizer(ITaskFragmentOrganizer organizer) { - validateAndGetController(organizer); + validateAndGetState(organizer); final int pid = Binder.getCallingPid(); final long uid = Binder.getCallingUid(); synchronized (mGlobalLock) { @@ -132,88 +222,78 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } - void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { - final TaskFragmentController controller = validateAndGetController(organizer); - - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName()); - final TaskFragmentInfo info = tf.getTaskFragmentInfo(); - final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), - "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); - controller.addTaskFragment(tf); - try { - organizer.onTaskFragmentAppeared( - new TaskFragmentAppearedInfo(info, outSurfaceControl)); - mLastSentTaskFragmentInfos.put(tf, info); - } catch (RemoteException e) { - Slog.e(TAG, "Exception sending onTaskFragmentAppeared callback", e); + void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { + final TaskFragmentOrganizerState state = validateAndGetState(organizer); + if (!state.addTaskFragment(taskFragment)) { + return; + } + PendingTaskFragmentEvent pendingEvent = getPendingTaskFragmentEvent(taskFragment, + PendingTaskFragmentEvent.EVENT_APPEARED); + if (pendingEvent == null) { + pendingEvent = new PendingTaskFragmentEvent(taskFragment, organizer, + PendingTaskFragmentEvent.EVENT_APPEARED); + mPendingTaskFragmentEvents.add(pendingEvent); } } - void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { - validateAndGetController(organizer); - - // Check if the info is different from the last reported info. - final TaskFragmentInfo info = tf.getTaskFragmentInfo(); - final TaskFragmentInfo lastInfo = mLastSentTaskFragmentInfos.get(tf); - if (info.equalsForTaskFragmentOrganizer(lastInfo) && configurationsAreEqualForOrganizer( - info.getConfiguration(), lastInfo.getConfiguration())) { - return; - } - - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName()); - try { - organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); - mLastSentTaskFragmentInfos.put(tf, info); - } catch (RemoteException e) { - Slog.e(TAG, "Exception sending onTaskFragmentInfoChanged callback", e); - } + void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { + handleTaskFragmentInfoChanged(organizer, taskFragment, + PendingTaskFragmentEvent.EVENT_INFO_CHANGED); } - void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { - final TaskFragmentController controller = validateAndGetController(organizer); - - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName()); - try { - organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo()); - } catch (RemoteException e) { - Slog.e(TAG, "Exception sending onTaskFragmentVanished callback", e); - } - mLastSentTaskFragmentInfos.remove(tf); - mLastSentTaskFragmentParentConfigs.remove(tf); - controller.removeTaskFragment(tf); + void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, + TaskFragment taskFragment) { + handleTaskFragmentInfoChanged(organizer, taskFragment, + PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED); } - void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { - validateAndGetController(organizer); - - // Check if the parent info is different from the last reported parent info. - if (tf.getParent() == null || tf.getParent().asTask() == null) { - mLastSentTaskFragmentParentConfigs.remove(tf); + private void handleTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, + TaskFragment taskFragment, int eventType) { + validateAndGetState(organizer); + if (!taskFragment.mTaskFragmentAppearedSent) { + // Skip if TaskFragment still not appeared. return; } - final Task parent = tf.getParent().asTask(); - final Configuration parentConfig = parent.getConfiguration(); - final Configuration lastParentConfig = mLastSentTaskFragmentParentConfigs.get(tf); - if (configurationsAreEqualForOrganizer(parentConfig, lastParentConfig)) { + PendingTaskFragmentEvent pendingEvent = getLastPendingLifecycleEvent(taskFragment); + if (pendingEvent == null) { + pendingEvent = new PendingTaskFragmentEvent(taskFragment, organizer, eventType); + } else { + if (pendingEvent.mEventType == PendingTaskFragmentEvent.EVENT_VANISHED) { + // Skipped the info changed event if vanished event is pending. + return; + } + // Remove and add for re-ordering. + mPendingTaskFragmentEvents.remove(pendingEvent); + } + mPendingTaskFragmentEvents.add(pendingEvent); + } + + void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) { + final TaskFragmentOrganizerState state = validateAndGetState(organizer); + for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) { + PendingTaskFragmentEvent entry = mPendingTaskFragmentEvents.get(i); + if (taskFragment == entry.mTaskFragment) { + mPendingTaskFragmentEvents.remove(i); + if (entry.mEventType == PendingTaskFragmentEvent.EVENT_APPEARED) { + // If taskFragment appeared callback is pending, ignore the vanished request. + return; + } + } + } + if (!taskFragment.mTaskFragmentAppearedSent) { return; } - - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, - "TaskFragment parent info changed name=%s parentTaskId=%d", - tf.getName(), parent.mTaskId); - try { - organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig); - mLastSentTaskFragmentParentConfigs.put(tf, new Configuration(parentConfig)); - } catch (RemoteException e) { - Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e); - } + PendingTaskFragmentEvent pendingEvent = new PendingTaskFragmentEvent(taskFragment, + organizer, PendingTaskFragmentEvent.EVENT_VANISHED); + mPendingTaskFragmentEvents.add(pendingEvent); + state.removeTaskFragment(taskFragment); } private void removeOrganizer(ITaskFragmentOrganizer organizer) { - final TaskFragmentController controller = validateAndGetController(organizer); + final TaskFragmentOrganizerState state = validateAndGetState(organizer); // remove all of the children of the organized TaskFragment - controller.dispose(); - mTaskFragmentOrganizerControllers.remove(organizer.asBinder()); + state.dispose(); + mTaskFragmentOrganizerState.remove(organizer.asBinder()); } /** @@ -222,13 +302,113 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr * we wouldn't register {@link DeathRecipient} for the organizer, and might not remove the * {@link TaskFragment} after the organizer process died. */ - private TaskFragmentController validateAndGetController(ITaskFragmentOrganizer organizer) { - final TaskFragmentController controller = - mTaskFragmentOrganizerControllers.get(organizer.asBinder()); - if (controller == null) { + private TaskFragmentOrganizerState validateAndGetState(ITaskFragmentOrganizer organizer) { + final TaskFragmentOrganizerState state = + mTaskFragmentOrganizerState.get(organizer.asBinder()); + if (state == null) { throw new IllegalArgumentException( "TaskFragmentOrganizer has not been registered. Organizer=" + organizer); } - return controller; + return state; + } + + /** + * A class to store {@link ITaskFragmentOrganizer} and its organized + * {@link TaskFragment TaskFragments} with different pending event request. + */ + private static class PendingTaskFragmentEvent { + static final int EVENT_APPEARED = 0; + static final int EVENT_VANISHED = 1; + static final int EVENT_INFO_CHANGED = 2; + static final int EVENT_PARENT_INFO_CHANGED = 3; + + @IntDef(prefix = "EVENT_", value = { + EVENT_APPEARED, + EVENT_VANISHED, + EVENT_INFO_CHANGED, + EVENT_PARENT_INFO_CHANGED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EventType {} + + @EventType + final int mEventType; + final TaskFragment mTaskFragment; + final ITaskFragmentOrganizer mTaskFragmentOrg; + + PendingTaskFragmentEvent(TaskFragment taskFragment, ITaskFragmentOrganizer taskFragmentOrg, + @EventType int eventType) { + mTaskFragment = taskFragment; + mTaskFragmentOrg = taskFragmentOrg; + mEventType = eventType; + } + + /** + * @return {@code true} if the pending event is related with taskFragment created, vanished + * and information changed. + */ + boolean isLifecycleEvent() { + switch (mEventType) { + case EVENT_APPEARED: + case EVENT_VANISHED: + case EVENT_INFO_CHANGED: + case EVENT_PARENT_INFO_CHANGED: + return true; + default: + return false; + } + } + } + + @Nullable + private PendingTaskFragmentEvent getLastPendingLifecycleEvent(TaskFragment tf) { + for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) { + PendingTaskFragmentEvent entry = mPendingTaskFragmentEvents.get(i); + if (tf == entry.mTaskFragment && entry.isLifecycleEvent()) { + return entry; + } + } + return null; + } + + @Nullable + private PendingTaskFragmentEvent getPendingTaskFragmentEvent(TaskFragment taskFragment, + int type) { + for (int i = mPendingTaskFragmentEvents.size() - 1; i >= 0; i--) { + PendingTaskFragmentEvent entry = mPendingTaskFragmentEvents.get(i); + if (taskFragment == entry.mTaskFragment && type == entry.mEventType) { + return entry; + } + } + return null; + } + + void dispatchPendingEvents() { + if (mAtmService.mWindowManager.mWindowPlacerLocked.isLayoutDeferred() + || mPendingTaskFragmentEvents.isEmpty()) { + return; + } + for (int i = 0, n = mPendingTaskFragmentEvents.size(); i < n; i++) { + PendingTaskFragmentEvent event = mPendingTaskFragmentEvents.get(i); + final ITaskFragmentOrganizer taskFragmentOrg = event.mTaskFragmentOrg; + final TaskFragment taskFragment = event.mTaskFragment; + final TaskFragmentOrganizerState state = + mTaskFragmentOrganizerState.get(taskFragmentOrg.asBinder()); + if (state == null) continue; + switch (event.mEventType) { + case PendingTaskFragmentEvent.EVENT_APPEARED: + state.onTaskFragmentAppeared(taskFragmentOrg, taskFragment); + break; + case PendingTaskFragmentEvent.EVENT_VANISHED: + state.onTaskFragmentVanished(taskFragmentOrg, taskFragment); + break; + case PendingTaskFragmentEvent.EVENT_INFO_CHANGED: + state.onTaskFragmentInfoChanged(taskFragmentOrg, taskFragment); + break; + case PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED: + state.onTaskFragmentParentInfoChanged(taskFragmentOrg, taskFragment); + } + } + mPendingTaskFragmentEvents.clear(); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 6bd8ad27342a4..d5e653bdba7eb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -102,6 +102,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mController.registerOrganizer(mIOrganizer); mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer).onTaskFragmentAppeared(any()); } @@ -110,6 +111,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { public void testOnTaskFragmentInfoChanged() { mController.registerOrganizer(mIOrganizer); mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); // No callback if the info is not changed. doReturn(true).when(mTaskFragmentInfo).equalsForTaskFragmentOrganizer(any()); @@ -117,6 +119,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mController.onTaskFragmentInfoChanged(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); @@ -125,6 +128,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mController.onTaskFragmentInfoChanged(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer).onTaskFragmentInfoChanged(mTaskFragmentInfo); } @@ -133,7 +137,9 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { public void testOnTaskFragmentVanished() { mController.registerOrganizer(mIOrganizer); + mTaskFragment.mTaskFragmentAppearedSent = true; mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer).onTaskFragmentVanished(any()); } @@ -148,8 +154,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { doReturn(parentConfig).when(parent).getConfiguration(); doReturn(parent).when(parent).asTask(); + mTaskFragment.mTaskFragmentAppearedSent = true; mController.onTaskFragmentParentInfoChanged( mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer).onTaskFragmentParentInfoChanged(eq(mFragmentToken), any()); @@ -158,6 +166,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mController.onTaskFragmentParentInfoChanged( mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(any(), any()); @@ -166,6 +175,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mController.onTaskFragmentParentInfoChanged( mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); + mController.dispatchPendingEvents(); verify(mOrganizer).onTaskFragmentParentInfoChanged(eq(mFragmentToken), any()); }