Apply TaskFragmentOrganizer changes in one WCT (2/2)

Before, when receive TaskFragment transaction, we apply changes in
multiple WindowContainerTransactions. Now, update to apply all changes
in one WCT for the whole TaskFragment transaction.

Bug: 240519866
Test: pass existing
Change-Id: I943d6232ff226ed6f67367fa9b7f73e1f861de64
This commit is contained in:
Chris Li
2022-08-02 16:08:37 +08:00
parent 5eb053047b
commit 87cc485c6a
4 changed files with 90 additions and 126 deletions

View File

@@ -3333,11 +3333,12 @@ package android.window {
ctor public TaskFragmentOrganizer(@NonNull java.util.concurrent.Executor); ctor public TaskFragmentOrganizer(@NonNull java.util.concurrent.Executor);
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 onActivityReparentedToTask(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.Intent, @NonNull android.os.IBinder);
method public void onTaskFragmentError(@NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable); method public void onTaskFragmentAppeared(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo);
method public void onTaskFragmentInfoChanged(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentError(@NonNull android.window.WindowContainerTransaction, @NonNull android.os.IBinder, @Nullable android.window.TaskFragmentInfo, int, @NonNull Throwable);
method public void onTaskFragmentParentInfoChanged(@NonNull android.os.IBinder, @NonNull android.content.res.Configuration); method public void onTaskFragmentInfoChanged(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo);
method public void onTaskFragmentVanished(@NonNull android.window.TaskFragmentInfo); method public void onTaskFragmentParentInfoChanged(@NonNull android.window.WindowContainerTransaction, int, @NonNull android.content.res.Configuration);
method public void onTaskFragmentVanished(@NonNull android.window.WindowContainerTransaction, @NonNull android.window.TaskFragmentInfo);
method @CallSuper public void registerOrganizer(); method @CallSuper public void registerOrganizer();
method @CallSuper public void unregisterOrganizer(); method @CallSuper public void unregisterOrganizer();
} }

View File

@@ -26,16 +26,15 @@ import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED
import android.annotation.CallSuper; import android.annotation.CallSuper;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SuppressLint;
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;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.SparseArray;
import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationDefinition;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -74,12 +73,6 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
*/ */
private final Executor mExecutor; private final Executor mExecutor;
// TODO(b/240519866): doing so to keep CTS compatibility. Remove in the next release.
/** Map from Task id to client tokens of TaskFragments in the Task. */
private final SparseArray<List<IBinder>> mTaskIdToFragmentTokens = new SparseArray<>();
/** Map from Task id to Task configuration. */
private final SparseArray<Configuration> mTaskIdToConfigurations = new SparseArray<>();
public TaskFragmentOrganizer(@NonNull Executor executor) { public TaskFragmentOrganizer(@NonNull Executor executor) {
mExecutor = executor; mExecutor = executor;
} }
@@ -150,35 +143,32 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
/** /**
* Called when a TaskFragment is created and organized by this organizer. * Called when a TaskFragment is created and organized by this organizer.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param taskFragmentInfo Info of the TaskFragment that is created. * @param taskFragmentInfo Info of the TaskFragment that is created.
*/ */
public void onTaskFragmentAppeared(@NonNull TaskFragmentInfo taskFragmentInfo) {} public void onTaskFragmentAppeared(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentInfo taskFragmentInfo) {}
/** /**
* Called when the status of an organized TaskFragment is changed. * Called when the status of an organized TaskFragment is changed.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param taskFragmentInfo Info of the TaskFragment that is changed. * @param taskFragmentInfo Info of the TaskFragment that is changed.
*/ */
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) {} public void onTaskFragmentInfoChanged(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentInfo taskFragmentInfo) {}
/** /**
* Called when an organized TaskFragment is removed. * Called when an organized TaskFragment is removed.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param taskFragmentInfo Info of the TaskFragment that is removed. * @param taskFragmentInfo Info of the TaskFragment that is removed.
*/ */
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) {} public void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct,
@NonNull TaskFragmentInfo taskFragmentInfo) {}
/**
* Called when the parent leaf Task of organized TaskFragments is changed.
* When the leaf Task is changed, the organizer may want to update the TaskFragments in one
* transaction.
*
* For case like screen size change, it will trigger onTaskFragmentParentInfoChanged with new
* Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override
* bounds.
*/
public void onTaskFragmentParentInfoChanged(
@NonNull IBinder fragmentToken, @NonNull Configuration parentConfig) {}
/** /**
* Called when the parent leaf Task of organized TaskFragments is changed. * Called when the parent leaf Task of organized TaskFragments is changed.
@@ -189,25 +179,20 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override * Task bounds, but may not trigger onTaskFragmentInfoChanged because there can be an override
* bounds. * bounds.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param taskId Id of the parent Task that is changed. * @param taskId Id of the parent Task that is changed.
* @param parentConfig Config of the parent Task. * @param parentConfig Config of the parent Task.
* @hide
*/ */
public void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig) { public void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct, int taskId,
// TODO(b/240519866): doing so to keep CTS compatibility. Remove in the next release. @NonNull Configuration parentConfig) {}
final List<IBinder> tokens = mTaskIdToFragmentTokens.get(taskId);
if (tokens == null || tokens.isEmpty()) {
return;
}
for (int i = tokens.size() - 1; i >= 0; i--) {
onTaskFragmentParentInfoChanged(tokens.get(i), parentConfig);
}
}
/** /**
* Called when the {@link WindowContainerTransaction} created with * Called when the {@link WindowContainerTransaction} created with
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side. * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param errorCallbackToken token set in * @param errorCallbackToken token set in
* {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
* @param taskFragmentInfo The {@link TaskFragmentInfo}. This could be {@code null} if no * @param taskFragmentInfo The {@link TaskFragmentInfo}. This could be {@code null} if no
@@ -216,7 +201,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* transaction operation. * transaction operation.
* @param exception exception from the server side. * @param exception exception from the server side.
*/ */
public void onTaskFragmentError( public void onTaskFragmentError(@NonNull WindowContainerTransaction wct,
@NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo, @NonNull IBinder errorCallbackToken, @Nullable TaskFragmentInfo taskFragmentInfo,
int opType, @NonNull Throwable exception) {} int opType, @NonNull Throwable exception) {}
@@ -226,6 +211,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* original Task. In this case, we need to notify the organizer so that it can check if the * original Task. In this case, we need to notify the organizer so that it can check if the
* Activity matches any split rule. * Activity matches any split rule.
* *
* @param wct The {@link WindowContainerTransaction} to make any changes with if needed. No
* need to call {@link #applyTransaction} as it will be applied by the caller.
* @param taskId The Task that the activity is reparented to. * @param taskId The Task that the activity is reparented to.
* @param activityIntent The intent that the activity is original launched with. * @param activityIntent The intent that the activity is original launched with.
* @param activityToken If the activity belongs to the same process as the organizer, this * @param activityToken If the activity belongs to the same process as the organizer, this
@@ -233,61 +220,41 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
* different process, the server will generate a temporary token that * different process, the server will generate a temporary token that
* the organizer can use to reparent the activity through * the organizer can use to reparent the activity through
* {@link WindowContainerTransaction} if needed. * {@link WindowContainerTransaction} if needed.
* @hide
*/ */
public void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent, public void onActivityReparentedToTask(@NonNull WindowContainerTransaction wct,
@NonNull IBinder activityToken) {} int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken) {}
/** /**
* Called when the transaction is ready so that the organizer can update the TaskFragments based * Called when the transaction is ready so that the organizer can update the TaskFragments based
* on the changes in transaction. * on the changes in transaction.
* Note: {@link WindowOrganizer#applyTransaction} permission requirement is conditional for
* {@link TaskFragmentOrganizer}.
* @see com.android.server.wm.WindowOrganizerController#enforceTaskPermission
* @hide * @hide
*/ */
@SuppressLint("AndroidFrameworkRequiresPermission")
public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) { public void onTransactionReady(@NonNull TaskFragmentTransaction transaction) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
final List<TaskFragmentTransaction.Change> changes = transaction.getChanges(); final List<TaskFragmentTransaction.Change> changes = transaction.getChanges();
for (TaskFragmentTransaction.Change change : changes) { for (TaskFragmentTransaction.Change change : changes) {
// TODO(b/240519866): apply all changes in one WCT.
final int taskId = change.getTaskId(); final int taskId = change.getTaskId();
switch (change.getType()) { switch (change.getType()) {
case TYPE_TASK_FRAGMENT_APPEARED: case TYPE_TASK_FRAGMENT_APPEARED:
// TODO(b/240519866): doing so to keep CTS compatibility. Remove in the next onTaskFragmentAppeared(wct, change.getTaskFragmentInfo());
// release.
if (!mTaskIdToFragmentTokens.contains(taskId)) {
mTaskIdToFragmentTokens.put(taskId, new ArrayList<>());
}
mTaskIdToFragmentTokens.get(taskId).add(change.getTaskFragmentToken());
onTaskFragmentParentInfoChanged(change.getTaskFragmentToken(),
mTaskIdToConfigurations.get(taskId));
onTaskFragmentAppeared(change.getTaskFragmentInfo());
break; break;
case TYPE_TASK_FRAGMENT_INFO_CHANGED: case TYPE_TASK_FRAGMENT_INFO_CHANGED:
onTaskFragmentInfoChanged(change.getTaskFragmentInfo()); onTaskFragmentInfoChanged(wct, change.getTaskFragmentInfo());
break; break;
case TYPE_TASK_FRAGMENT_VANISHED: case TYPE_TASK_FRAGMENT_VANISHED:
// TODO(b/240519866): doing so to keep CTS compatibility. Remove in the next onTaskFragmentVanished(wct, change.getTaskFragmentInfo());
// release.
if (mTaskIdToFragmentTokens.contains(taskId)) {
final List<IBinder> tokens = mTaskIdToFragmentTokens.get(taskId);
tokens.remove(change.getTaskFragmentToken());
if (tokens.isEmpty()) {
mTaskIdToFragmentTokens.remove(taskId);
mTaskIdToConfigurations.remove(taskId);
}
}
onTaskFragmentVanished(change.getTaskFragmentInfo());
break; break;
case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED: case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED:
// TODO(b/240519866): doing so to keep CTS compatibility. Remove in the next onTaskFragmentParentInfoChanged(wct, taskId, change.getTaskConfiguration());
// release.
mTaskIdToConfigurations.put(taskId, change.getTaskConfiguration());
onTaskFragmentParentInfoChanged(taskId, change.getTaskConfiguration());
break; break;
case TYPE_TASK_FRAGMENT_ERROR: case TYPE_TASK_FRAGMENT_ERROR:
final Bundle errorBundle = change.getErrorBundle(); final Bundle errorBundle = change.getErrorBundle();
onTaskFragmentError( onTaskFragmentError(
wct,
change.getErrorCallbackToken(), change.getErrorCallbackToken(),
errorBundle.getParcelable( errorBundle.getParcelable(
KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class), KEY_ERROR_CALLBACK_TASK_FRAGMENT_INFO, TaskFragmentInfo.class),
@@ -297,6 +264,7 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
break; break;
case TYPE_ACTIVITY_REPARENTED_TO_TASK: case TYPE_ACTIVITY_REPARENTED_TO_TASK:
onActivityReparentedToTask( onActivityReparentedToTask(
wct,
change.getTaskId(), change.getTaskId(),
change.getActivityIntent(), change.getActivityIntent(),
change.getActivityToken()); change.getActivityToken());
@@ -306,6 +274,8 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
"Unknown TaskFragmentEvent=" + change.getType()); "Unknown TaskFragmentEvent=" + change.getType());
} }
} }
// TODO(b/240519866): notify TaskFragmentOrganizerController that the transition is done.
applyTransaction(wct);
} }
@Override @Override

View File

@@ -271,56 +271,49 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
} }
@Override @Override
public void onTaskFragmentAppeared(@NonNull TaskFragmentInfo taskFragmentInfo) { public void onTaskFragmentAppeared(@NonNull WindowContainerTransaction wct,
final WindowContainerTransaction wct = new WindowContainerTransaction(); @NonNull TaskFragmentInfo taskFragmentInfo) {
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken(); final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
mFragmentInfos.put(fragmentToken, taskFragmentInfo); mFragmentInfos.put(fragmentToken, taskFragmentInfo);
mCallback.onTaskFragmentAppeared(wct, taskFragmentInfo); mCallback.onTaskFragmentAppeared(wct, taskFragmentInfo);
applyTransaction(wct);
} }
@Override @Override
public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo taskFragmentInfo) { public void onTaskFragmentInfoChanged(@NonNull WindowContainerTransaction wct,
final WindowContainerTransaction wct = new WindowContainerTransaction(); @NonNull TaskFragmentInfo taskFragmentInfo) {
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken(); final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
mFragmentInfos.put(fragmentToken, taskFragmentInfo); mFragmentInfos.put(fragmentToken, taskFragmentInfo);
mCallback.onTaskFragmentInfoChanged(wct, taskFragmentInfo); mCallback.onTaskFragmentInfoChanged(wct, taskFragmentInfo);
applyTransaction(wct);
} }
@Override @Override
public void onTaskFragmentVanished(@NonNull TaskFragmentInfo taskFragmentInfo) { public void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct,
final WindowContainerTransaction wct = new WindowContainerTransaction(); @NonNull TaskFragmentInfo taskFragmentInfo) {
mFragmentInfos.remove(taskFragmentInfo.getFragmentToken()); mFragmentInfos.remove(taskFragmentInfo.getFragmentToken());
mCallback.onTaskFragmentVanished(wct, taskFragmentInfo); mCallback.onTaskFragmentVanished(wct, taskFragmentInfo);
applyTransaction(wct);
} }
@Override @Override
public void onTaskFragmentParentInfoChanged(int taskId, @NonNull Configuration parentConfig) { public void onTaskFragmentParentInfoChanged(@NonNull WindowContainerTransaction wct,
final WindowContainerTransaction wct = new WindowContainerTransaction(); int taskId, @NonNull Configuration parentConfig) {
mCallback.onTaskFragmentParentInfoChanged(wct, taskId, parentConfig); mCallback.onTaskFragmentParentInfoChanged(wct, taskId, parentConfig);
applyTransaction(wct);
} }
@Override @Override
public void onActivityReparentedToTask(int taskId, @NonNull Intent activityIntent, public void onActivityReparentedToTask(@NonNull WindowContainerTransaction wct,
@NonNull IBinder activityToken) { int taskId, @NonNull Intent activityIntent, @NonNull IBinder activityToken) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mCallback.onActivityReparentedToTask(wct, taskId, activityIntent, activityToken); mCallback.onActivityReparentedToTask(wct, taskId, activityIntent, activityToken);
applyTransaction(wct);
} }
@Override @Override
public void onTaskFragmentError(@NonNull IBinder errorCallbackToken, public void onTaskFragmentError(@NonNull WindowContainerTransaction wct,
@NonNull IBinder errorCallbackToken,
@Nullable TaskFragmentInfo taskFragmentInfo, @Nullable TaskFragmentInfo taskFragmentInfo,
int opType, @NonNull Throwable exception) { int opType, @NonNull Throwable exception) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (taskFragmentInfo != null) { if (taskFragmentInfo != null) {
final IBinder fragmentToken = taskFragmentInfo.getFragmentToken(); final IBinder fragmentToken = taskFragmentInfo.getFragmentToken();
mFragmentInfos.put(fragmentToken, taskFragmentInfo); mFragmentInfos.put(fragmentToken, taskFragmentInfo);
} }
mCallback.onTaskFragmentError(wct, taskFragmentInfo, opType); mCallback.onTaskFragmentError(wct, taskFragmentInfo, opType);
applyTransaction(wct);
} }
} }

View File

@@ -158,7 +158,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentAppeared(any()); verify(mOrganizer, never()).onTaskFragmentAppeared(any(), any());
// Send callback when the TaskFragment is attached. // Send callback when the TaskFragment is attached.
setupMockParent(mTaskFragment, mTask); setupMockParent(mTaskFragment, mTask);
@@ -166,7 +166,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentAppeared(any()); verify(mOrganizer).onTaskFragmentAppeared(any(), any());
} }
@Test @Test
@@ -179,13 +179,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment); mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
// Call onTaskFragmentAppeared first. // Call onTaskFragmentAppeared first.
mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentAppeared(any()); verify(mOrganizer).onTaskFragmentAppeared(any(), any());
// No callback if the info is not changed. // No callback if the info is not changed.
doReturn(true).when(mTaskFragmentInfo).equalsForTaskFragmentOrganizer(any()); doReturn(true).when(mTaskFragmentInfo).equalsForTaskFragmentOrganizer(any());
@@ -195,7 +195,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment); mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
// Trigger callback if the info is changed. // Trigger callback if the info is changed.
doReturn(false).when(mTaskFragmentInfo).equalsForTaskFragmentOrganizer(any()); doReturn(false).when(mTaskFragmentInfo).equalsForTaskFragmentOrganizer(any());
@@ -204,7 +204,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment); mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(eq(mTaskFragmentInfo)); verify(mOrganizer).onTaskFragmentInfoChanged(any(), eq(mTaskFragmentInfo));
} }
@Test @Test
@@ -215,7 +215,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentVanished(any()); verify(mOrganizer).onTaskFragmentVanished(any(), any());
} }
@Test @Test
@@ -228,10 +228,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentAppeared(any()); verify(mOrganizer, never()).onTaskFragmentAppeared(any(), any());
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(anyInt(), any()); verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(any(), anyInt(), any());
verify(mOrganizer).onTaskFragmentVanished(eq(mTaskFragmentInfo)); verify(mOrganizer).onTaskFragmentVanished(any(), eq(mTaskFragmentInfo));
// Not trigger onTaskFragmentInfoChanged. // Not trigger onTaskFragmentInfoChanged.
// Call onTaskFragmentAppeared before calling onTaskFragmentInfoChanged. // Call onTaskFragmentAppeared before calling onTaskFragmentInfoChanged.
@@ -244,10 +244,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mController.onTaskFragmentVanished(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentAppeared(any()); verify(mOrganizer, never()).onTaskFragmentAppeared(any(), any());
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(anyInt(), any()); verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(any(), anyInt(), any());
verify(mOrganizer).onTaskFragmentVanished(eq(mTaskFragmentInfo)); verify(mOrganizer).onTaskFragmentVanished(any(), eq(mTaskFragmentInfo));
} }
@Test @Test
@@ -260,7 +260,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentParentInfoChanged(eq(mTask.mTaskId), any()); verify(mOrganizer).onTaskFragmentParentInfoChanged(any(), eq(mTask.mTaskId), any());
// No extra callback if the info is not changed. // No extra callback if the info is not changed.
clearInvocations(mOrganizer); clearInvocations(mOrganizer);
@@ -269,7 +269,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(anyInt(), any()); verify(mOrganizer, never()).onTaskFragmentParentInfoChanged(any(), anyInt(), any());
// Trigger callback if the size is changed. // Trigger callback if the size is changed.
mTask.getConfiguration().smallestScreenWidthDp = 100; mTask.getConfiguration().smallestScreenWidthDp = 100;
@@ -277,7 +277,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentParentInfoChanged(eq(mTask.mTaskId), any()); verify(mOrganizer).onTaskFragmentParentInfoChanged(any(), eq(mTask.mTaskId), any());
// Trigger callback if the windowing mode is changed. // Trigger callback if the windowing mode is changed.
clearInvocations(mOrganizer); clearInvocations(mOrganizer);
@@ -286,7 +286,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment); mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentParentInfoChanged(eq(mTask.mTaskId), any()); verify(mOrganizer).onTaskFragmentParentInfoChanged(any(), eq(mTask.mTaskId), any());
} }
@Test @Test
@@ -298,7 +298,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mErrorToken, null /* taskFragment */, -1 /* opType */, exception); mErrorToken, null /* taskFragment */, -1 /* opType */, exception);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), eq(null), eq(-1), verify(mOrganizer).onTaskFragmentError(any(), eq(mErrorToken), eq(null), eq(-1),
eq(exception)); eq(exception));
} }
@@ -318,14 +318,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.onActivityReparentedToTask(activity); mController.onActivityReparentedToTask(activity);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onActivityReparentedToTask(anyInt(), any(), any()); verify(mOrganizer, never()).onActivityReparentedToTask(any(), anyInt(), any(), any());
// Notify organizer if it was embedded before entered Pip. // Notify organizer if it was embedded before entered Pip.
activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer; activity.mLastTaskFragmentOrganizerBeforePip = mIOrganizer;
mController.onActivityReparentedToTask(activity); mController.onActivityReparentedToTask(activity);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onActivityReparentedToTask(eq(task.mTaskId), eq(activity.intent), verify(mOrganizer).onActivityReparentedToTask(any(), eq(task.mTaskId), eq(activity.intent),
eq(activity.token)); eq(activity.token));
// Notify organizer if there is any embedded in the Task. // Notify organizer if there is any embedded in the Task.
@@ -341,7 +341,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, times(2)) verify(mOrganizer, times(2))
.onActivityReparentedToTask(eq(task.mTaskId), eq(activity.intent), .onActivityReparentedToTask(any(), eq(task.mTaskId), eq(activity.intent),
eq(activity.token)); eq(activity.token));
} }
@@ -371,7 +371,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
// Allow organizer to reparent activity in other process using the temporary token. // Allow organizer to reparent activity in other process using the temporary token.
verify(mOrganizer).onActivityReparentedToTask(eq(task.mTaskId), eq(activity.intent), verify(mOrganizer).onActivityReparentedToTask(any(), eq(task.mTaskId), eq(activity.intent),
token.capture()); token.capture());
final IBinder temporaryToken = token.getValue(); final IBinder temporaryToken = token.getValue();
assertNotEquals(activity.token, temporaryToken); assertNotEquals(activity.token, temporaryToken);
@@ -801,7 +801,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
// Verifies that event was not sent // Verifies that event was not sent
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
} }
@Test @Test
@@ -827,7 +827,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
// Verifies that event was not sent // Verifies that event was not sent
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
// Mock the task becomes visible, and activity resumed // Mock the task becomes visible, and activity resumed
doReturn(true).when(task).shouldBeVisible(any()); doReturn(true).when(task).shouldBeVisible(any());
@@ -835,7 +835,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
// Verifies that event is sent. // Verifies that event is sent.
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(any()); verify(mOrganizer).onTaskFragmentInfoChanged(any(), any());
} }
/** /**
@@ -869,7 +869,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
reset(mOrganizer); reset(mOrganizer);
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment); mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(any()); verify(mOrganizer).onTaskFragmentInfoChanged(any(), any());
} }
/** /**
@@ -887,8 +887,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
.createActivityCount(1) .createActivityCount(1)
.build(); .build();
final ActivityRecord embeddedActivity = taskFragment.getTopNonFinishingActivity(); final ActivityRecord embeddedActivity = taskFragment.getTopNonFinishingActivity();
// Add another activity in the Task so that it always contains a non-finishing activitiy. // Add another activity in the Task so that it always contains a non-finishing activity.
final ActivityRecord nonEmbeddedActivity = createActivityRecord(task); createActivityRecord(task);
assertTrue(task.shouldBeVisible(null)); assertTrue(task.shouldBeVisible(null));
// Dispatch pending info changed event from creating the activity // Dispatch pending info changed event from creating the activity
@@ -896,21 +896,21 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
taskFragment.mTaskFragmentAppearedSent = true; taskFragment.mTaskFragmentAppearedSent = true;
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment); mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(any()); verify(mOrganizer).onTaskFragmentInfoChanged(any(), any());
// Verify the info changed callback is not called when the task is invisible // Verify the info changed callback is not called when the task is invisible
reset(mOrganizer); reset(mOrganizer);
doReturn(false).when(task).shouldBeVisible(any()); doReturn(false).when(task).shouldBeVisible(any());
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment); mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer, never()).onTaskFragmentInfoChanged(any()); verify(mOrganizer, never()).onTaskFragmentInfoChanged(any(), any());
// Finish the embedded activity, and verify the info changed callback is called because the // Finish the embedded activity, and verify the info changed callback is called because the
// TaskFragment is becoming empty. // TaskFragment is becoming empty.
embeddedActivity.finishing = true; embeddedActivity.finishing = true;
mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment); mController.onTaskFragmentInfoChanged(mIOrganizer, taskFragment);
mController.dispatchPendingEvents(); mController.dispatchPendingEvents();
verify(mOrganizer).onTaskFragmentInfoChanged(any()); verify(mOrganizer).onTaskFragmentInfoChanged(any(), any());
} }
/** /**
@@ -1020,7 +1020,7 @@ 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(), verify(mOrganizer).onTaskFragmentError(any(), eq(mErrorToken), any(),
eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT), eq(HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT),
any(SecurityException.class)); any(SecurityException.class));
} }
@@ -1059,7 +1059,7 @@ 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(), verify(mOrganizer).onTaskFragmentError(any(), eq(mErrorToken), any(),
eq(HIERARCHY_OP_TYPE_REPARENT_CHILDREN), any(SecurityException.class)); eq(HIERARCHY_OP_TYPE_REPARENT_CHILDREN), any(SecurityException.class));
} }