Merge "Allow TaskFragmentOrganizer to set remote animation" into sc-v2-dev
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package android.window;
|
package android.window;
|
||||||
|
|
||||||
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.window.ITaskFragmentOrganizer;
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -30,4 +31,17 @@ interface ITaskFragmentOrganizerController {
|
|||||||
* Unregisters a previously registered TaskFragmentOrganizer.
|
* Unregisters a previously registered TaskFragmentOrganizer.
|
||||||
*/
|
*/
|
||||||
void unregisterOrganizer(in ITaskFragmentOrganizer organizer);
|
void unregisterOrganizer(in ITaskFragmentOrganizer organizer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers remote animations per transition type for the organizer. It will override the
|
||||||
|
* animations if the transition only contains windows that belong to the organized
|
||||||
|
* TaskFragments.
|
||||||
|
*/
|
||||||
|
void registerRemoteAnimations(in ITaskFragmentOrganizer organizer,
|
||||||
|
in RemoteAnimationDefinition definition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters remote animations per transition type for the organizer.
|
||||||
|
*/
|
||||||
|
void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ 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.view.RemoteAnimationDefinition;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -90,6 +91,34 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers remote animations per transition type for the organizer. It will override the
|
||||||
|
* animations if the transition only contains windows that belong to the organized
|
||||||
|
* TaskFragments.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@CallSuper
|
||||||
|
public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) {
|
||||||
|
try {
|
||||||
|
getController().registerRemoteAnimations(mInterface, definition);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters remote animations per transition type for the organizer.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@CallSuper
|
||||||
|
public void unregisterRemoteAnimations() {
|
||||||
|
try {
|
||||||
|
getController().unregisterRemoteAnimations(mInterface);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Called when a TaskFragment is created and organized by this organizer. */
|
/** Called when a TaskFragment is created and organized by this organizer. */
|
||||||
public void onTaskFragmentAppeared(
|
public void onTaskFragmentAppeared(
|
||||||
@NonNull TaskFragmentAppearedInfo taskFragmentAppearedInfo) {}
|
@NonNull TaskFragmentAppearedInfo taskFragmentAppearedInfo) {}
|
||||||
|
|||||||
@@ -1261,6 +1261,12 @@
|
|||||||
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
|
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
|
||||||
"at": "com\/android\/server\/wm\/Transition.java"
|
"at": "com\/android\/server\/wm\/Transition.java"
|
||||||
},
|
},
|
||||||
|
"-702650156": {
|
||||||
|
"message": "Override with TaskFragment remote animation for transit=%s",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_APP_TRANSITIONS",
|
||||||
|
"at": "com\/android\/server\/wm\/AppTransitionController.java"
|
||||||
|
},
|
||||||
"-701167286": {
|
"-701167286": {
|
||||||
"message": "applyAnimation: transit=%s, enter=%b, wc=%s",
|
"message": "applyAnimation: transit=%s, enter=%b, wc=%s",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
@@ -1789,6 +1795,12 @@
|
|||||||
"group": "WM_DEBUG_STATES",
|
"group": "WM_DEBUG_STATES",
|
||||||
"at": "com\/android\/server\/wm\/TaskFragment.java"
|
"at": "com\/android\/server\/wm\/TaskFragment.java"
|
||||||
},
|
},
|
||||||
|
"-70719599": {
|
||||||
|
"message": "Unregister remote animations for organizer=%s uid=%d pid=%d",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"-55185509": {
|
"-55185509": {
|
||||||
"message": "setFocusedTask: taskId=%d touchedActivity=%s",
|
"message": "setFocusedTask: taskId=%d touchedActivity=%s",
|
||||||
"level": "DEBUG",
|
"level": "DEBUG",
|
||||||
@@ -2941,6 +2953,12 @@
|
|||||||
"group": "WM_ERROR",
|
"group": "WM_ERROR",
|
||||||
"at": "com\/android\/server\/wm\/WindowManagerService.java"
|
"at": "com\/android\/server\/wm\/WindowManagerService.java"
|
||||||
},
|
},
|
||||||
|
"1210037962": {
|
||||||
|
"message": "Register remote animations for organizer=%s uid=%d pid=%d",
|
||||||
|
"level": "VERBOSE",
|
||||||
|
"group": "WM_DEBUG_WINDOW_ORGANIZER",
|
||||||
|
"at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
|
||||||
|
},
|
||||||
"1219600119": {
|
"1219600119": {
|
||||||
"message": "addWindow: win=%s Callers=%s",
|
"message": "addWindow: win=%s Callers=%s",
|
||||||
"level": "DEBUG",
|
"level": "DEBUG",
|
||||||
|
|||||||
@@ -2595,6 +2595,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
return task != null ? task.getOrganizedTask() : null;
|
return task != null ? task.getOrganizedTask() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the organized parent {@link TaskFragment}. */
|
||||||
|
@Nullable
|
||||||
|
TaskFragment getOrganizedTaskFragment() {
|
||||||
|
final TaskFragment parent = getTaskFragment();
|
||||||
|
return parent != null ? parent.getOrganizedTaskFragment() : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
TaskDisplayArea getDisplayArea() {
|
TaskDisplayArea getDisplayArea() {
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ import android.view.WindowManager.TransitionFlags;
|
|||||||
import android.view.WindowManager.TransitionOldType;
|
import android.view.WindowManager.TransitionOldType;
|
||||||
import android.view.WindowManager.TransitionType;
|
import android.view.WindowManager.TransitionType;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
@@ -233,7 +234,11 @@ public class AppTransitionController {
|
|||||||
final ActivityRecord topChangingApp =
|
final ActivityRecord topChangingApp =
|
||||||
getTopApp(mDisplayContent.mChangingContainers, false /* ignoreHidden */);
|
getTopApp(mDisplayContent.mChangingContainers, false /* ignoreHidden */);
|
||||||
final WindowManager.LayoutParams animLp = getAnimLp(animLpActivity);
|
final WindowManager.LayoutParams animLp = getAnimLp(animLpActivity);
|
||||||
overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
|
|
||||||
|
// Check if there is any override
|
||||||
|
if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) {
|
||||||
|
overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean voiceInteraction = containsVoiceInteraction(mDisplayContent.mOpeningApps)
|
final boolean voiceInteraction = containsVoiceInteraction(mDisplayContent.mOpeningApps)
|
||||||
|| containsVoiceInteraction(mDisplayContent.mOpeningApps);
|
|| containsVoiceInteraction(mDisplayContent.mOpeningApps);
|
||||||
@@ -483,6 +488,7 @@ public class AppTransitionController {
|
|||||||
return TYPE_NONE;
|
return TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private static WindowManager.LayoutParams getAnimLp(ActivityRecord activity) {
|
private static WindowManager.LayoutParams getAnimLp(ActivityRecord activity) {
|
||||||
final WindowState mainWindow = activity != null ? activity.findMainWindow() : null;
|
final WindowState mainWindow = activity != null ? activity.findMainWindow() : null;
|
||||||
return mainWindow != null ? mainWindow.mAttrs : null;
|
return mainWindow != null ? mainWindow.mAttrs : null;
|
||||||
@@ -505,6 +511,61 @@ public class AppTransitionController {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the pending transition with the remote animation defined by the
|
||||||
|
* {@link ITaskFragmentOrganizer} if all windows in the transition are children of
|
||||||
|
* {@link TaskFragment} that are organized by the same organizer.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the transition is overridden.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean overrideWithTaskFragmentRemoteAnimation(@TransitionOldType int transit,
|
||||||
|
ArraySet<Integer> activityTypes) {
|
||||||
|
final ArrayList<WindowContainer> allWindows = new ArrayList<>();
|
||||||
|
allWindows.addAll(mDisplayContent.mClosingApps);
|
||||||
|
allWindows.addAll(mDisplayContent.mOpeningApps);
|
||||||
|
allWindows.addAll(mDisplayContent.mChangingContainers);
|
||||||
|
|
||||||
|
// Find the common TaskFragmentOrganizer of all windows.
|
||||||
|
ITaskFragmentOrganizer organizer = null;
|
||||||
|
for (int i = allWindows.size() - 1; i >= 0; i--) {
|
||||||
|
final ActivityRecord r = getAppFromContainer(allWindows.get(i));
|
||||||
|
if (r == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final TaskFragment organizedTaskFragment = r.getOrganizedTaskFragment();
|
||||||
|
final ITaskFragmentOrganizer curOrganizer = organizedTaskFragment != null
|
||||||
|
? organizedTaskFragment.getTaskFragmentOrganizer()
|
||||||
|
: null;
|
||||||
|
if (curOrganizer == null) {
|
||||||
|
// All windows must below an organized TaskFragment.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (organizer == null) {
|
||||||
|
organizer = curOrganizer;
|
||||||
|
} else if (!organizer.asBinder().equals(curOrganizer.asBinder())) {
|
||||||
|
// They must be controlled by the same organizer.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final RemoteAnimationDefinition definition = organizer != null
|
||||||
|
? mDisplayContent.mAtmService.mTaskFragmentOrganizerController
|
||||||
|
.getRemoteAnimationDefinition(organizer)
|
||||||
|
: null;
|
||||||
|
final RemoteAnimationAdapter adapter = definition != null
|
||||||
|
? definition.getAdapter(transit, activityTypes)
|
||||||
|
: null;
|
||||||
|
if (adapter == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(adapter);
|
||||||
|
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
|
||||||
|
"Override with TaskFragment remote animation for transit=%s",
|
||||||
|
AppTransition.appTransitionOldToString(transit));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the pending transition with the remote animation defined for the transition in the
|
* Overrides the pending transition with the remote animation defined for the transition in the
|
||||||
* set of defined remote animations in the app window token.
|
* set of defined remote animations in the app window token.
|
||||||
@@ -524,13 +585,14 @@ public class AppTransitionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ActivityRecord getAppFromContainer(WindowContainer wc) {
|
static ActivityRecord getAppFromContainer(WindowContainer wc) {
|
||||||
return wc.asTask() != null ? wc.asTask().getTopNonFinishingActivity()
|
return wc.asTaskFragment() != null ? wc.asTaskFragment().getTopNonFinishingActivity()
|
||||||
: wc.asActivityRecord();
|
: wc.asActivityRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The window token that determines the animation theme.
|
* @return The window token that determines the animation theme.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private ActivityRecord findAnimLayoutParamsToken(@TransitionOldType int transit,
|
private ActivityRecord findAnimLayoutParamsToken(@TransitionOldType int transit,
|
||||||
ArraySet<Integer> activityTypes) {
|
ArraySet<Integer> activityTypes) {
|
||||||
ActivityRecord result;
|
ActivityRecord result;
|
||||||
@@ -543,7 +605,7 @@ public class AppTransitionController {
|
|||||||
w -> w.getRemoteAnimationDefinition() != null
|
w -> w.getRemoteAnimationDefinition() != null
|
||||||
&& w.getRemoteAnimationDefinition().hasTransition(transit, activityTypes));
|
&& w.getRemoteAnimationDefinition().hasTransition(transit, activityTypes));
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return getAppFromContainer(result);
|
return result;
|
||||||
}
|
}
|
||||||
result = lookForHighestTokenWithFilter(closingApps, openingApps, changingApps,
|
result = lookForHighestTokenWithFilter(closingApps, openingApps, changingApps,
|
||||||
w -> w.fillsParent() && w.findMainWindow() != null);
|
w -> w.fillsParent() && w.findMainWindow() != null);
|
||||||
|
|||||||
@@ -2095,7 +2095,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@VisibleForTesting
|
|
||||||
ITaskFragmentOrganizer getTaskFragmentOrganizer() {
|
ITaskFragmentOrganizer getTaskFragmentOrganizer() {
|
||||||
return mTaskFragmentOrganizer;
|
return mTaskFragmentOrganizer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.os.IBinder;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.window.ITaskFragmentOrganizer;
|
import android.window.ITaskFragmentOrganizer;
|
||||||
import android.window.ITaskFragmentOrganizerController;
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
@@ -81,6 +82,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs =
|
private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs =
|
||||||
new WeakHashMap<>();
|
new WeakHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see android.window.TaskFragmentOrganizer#registerRemoteAnimations(
|
||||||
|
* RemoteAnimationDefinition)
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private RemoteAnimationDefinition mRemoteAnimationDefinition;
|
||||||
|
|
||||||
TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer) {
|
TaskFragmentOrganizerState(ITaskFragmentOrganizer organizer) {
|
||||||
mOrganizer = organizer;
|
mOrganizer = organizer;
|
||||||
try {
|
try {
|
||||||
@@ -245,6 +253,61 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerRemoteAnimations(ITaskFragmentOrganizer organizer,
|
||||||
|
RemoteAnimationDefinition definition) {
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
|
final int uid = Binder.getCallingUid();
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
|
"Register remote animations for organizer=%s uid=%d pid=%d",
|
||||||
|
organizer.asBinder(), uid, pid);
|
||||||
|
final TaskFragmentOrganizerState organizerState =
|
||||||
|
mTaskFragmentOrganizerState.get(organizer.asBinder());
|
||||||
|
if (organizerState == null) {
|
||||||
|
throw new IllegalStateException("The organizer hasn't been registered.");
|
||||||
|
}
|
||||||
|
if (organizerState.mRemoteAnimationDefinition != null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"The organizer has already registered remote animations="
|
||||||
|
+ organizerState.mRemoteAnimationDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
definition.setCallingPidUid(pid, uid);
|
||||||
|
organizerState.mRemoteAnimationDefinition = definition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterRemoteAnimations(ITaskFragmentOrganizer organizer) {
|
||||||
|
final int pid = Binder.getCallingPid();
|
||||||
|
final long uid = Binder.getCallingUid();
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
|
||||||
|
"Unregister remote animations for organizer=%s uid=%d pid=%d",
|
||||||
|
organizer.asBinder(), uid, pid);
|
||||||
|
final TaskFragmentOrganizerState organizerState =
|
||||||
|
mTaskFragmentOrganizerState.get(organizer.asBinder());
|
||||||
|
if (organizerState == null) {
|
||||||
|
Slog.e(TAG, "The organizer hasn't been registered.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
organizerState.mRemoteAnimationDefinition = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the {@link RemoteAnimationDefinition} set on the given organizer if exists. */
|
||||||
|
@Nullable
|
||||||
|
public RemoteAnimationDefinition getRemoteAnimationDefinition(
|
||||||
|
ITaskFragmentOrganizer organizer) {
|
||||||
|
synchronized (mGlobalLock) {
|
||||||
|
final TaskFragmentOrganizerState organizerState =
|
||||||
|
mTaskFragmentOrganizerState.get(organizer.asBinder());
|
||||||
|
return organizerState != null ? organizerState.mRemoteAnimationDefinition : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) {
|
void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment taskFragment) {
|
||||||
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
|
final TaskFragmentOrganizerState state = validateAndGetState(organizer);
|
||||||
if (!state.addTaskFragment(taskFragment)) {
|
if (!state.addTaskFragment(taskFragment)) {
|
||||||
|
|||||||
@@ -26,15 +26,19 @@ import static android.view.WindowManager.TRANSIT_CLOSE;
|
|||||||
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
|
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
|
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
|
||||||
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
|
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.doCallRealMethod;
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -47,6 +51,8 @@ import android.view.RemoteAnimationAdapter;
|
|||||||
import android.view.RemoteAnimationDefinition;
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.window.ITaskFragmentOrganizer;
|
||||||
|
import android.window.TaskFragmentOrganizer;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
@@ -737,4 +743,38 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
|||||||
mAppTransitionController.getRemoteAnimationOverride(
|
mAppTransitionController.getRemoteAnimationOverride(
|
||||||
activity, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet<Integer>()));
|
activity, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet<Integer>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRemoteAnimationOverrideTaskFragmentOrganizer() {
|
||||||
|
// TaskFragmentOrganizer registers remote animation.
|
||||||
|
final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run);
|
||||||
|
final ITaskFragmentOrganizer iOrganizer =
|
||||||
|
ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder());
|
||||||
|
final RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
|
||||||
|
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
|
||||||
|
new TestRemoteAnimationRunner(), 10, 1);
|
||||||
|
definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter);
|
||||||
|
mAtm.mTaskFragmentOrganizerController.registerOrganizer(iOrganizer);
|
||||||
|
mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition);
|
||||||
|
|
||||||
|
// Create a TaskFragment with embedded activity.
|
||||||
|
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
|
||||||
|
.setParentTask(createTask(mDisplayContent))
|
||||||
|
.createActivityCount(1)
|
||||||
|
.setOrganizer(organizer)
|
||||||
|
.build();
|
||||||
|
final ActivityRecord activity = taskFragment.getTopMostActivity();
|
||||||
|
activity.allDrawn = true;
|
||||||
|
spyOn(mDisplayContent.mAppTransition);
|
||||||
|
|
||||||
|
// Prepare a transition for TaskFragment.
|
||||||
|
mDisplayContent.mAppTransition.prepareAppTransition(TRANSIT_CHANGE, 0);
|
||||||
|
mDisplayContent.mOpeningApps.add(activity);
|
||||||
|
mDisplayContent.mChangingContainers.add(taskFragment);
|
||||||
|
mDisplayContent.mAppTransitionController.handleAppTransitionReady();
|
||||||
|
|
||||||
|
// Check if the transition has been overridden.
|
||||||
|
verify(mDisplayContent.mAppTransition)
|
||||||
|
.overridePendingAppTransitionRemote(adapter, false /* sync */);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
|||||||
import static com.android.server.wm.testing.Assert.assertThrows;
|
import static com.android.server.wm.testing.Assert.assertThrows;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@@ -36,6 +37,7 @@ import android.os.Binder;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.window.ITaskFragmentOrganizer;
|
import android.window.ITaskFragmentOrganizer;
|
||||||
import android.window.TaskFragmentCreationParams;
|
import android.window.TaskFragmentCreationParams;
|
||||||
@@ -70,6 +72,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
private IBinder mFragmentToken;
|
private IBinder mFragmentToken;
|
||||||
private WindowContainerTransaction mTransaction;
|
private WindowContainerTransaction mTransaction;
|
||||||
private WindowContainerToken mFragmentWindowToken;
|
private WindowContainerToken mFragmentWindowToken;
|
||||||
|
private RemoteAnimationDefinition mDefinition;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -83,6 +86,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
new TaskFragment(mAtm, mFragmentToken, true /* createdByOrganizer */);
|
new TaskFragment(mAtm, mFragmentToken, true /* createdByOrganizer */);
|
||||||
mTransaction = new WindowContainerTransaction();
|
mTransaction = new WindowContainerTransaction();
|
||||||
mFragmentWindowToken = mTaskFragment.mRemoteToken.toWindowContainerToken();
|
mFragmentWindowToken = mTaskFragment.mRemoteToken.toWindowContainerToken();
|
||||||
|
mDefinition = new RemoteAnimationDefinition();
|
||||||
|
|
||||||
spyOn(mController);
|
spyOn(mController);
|
||||||
spyOn(mOrganizer);
|
spyOn(mOrganizer);
|
||||||
@@ -207,6 +211,18 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
|||||||
verify(mOrganizer).onTaskFragmentError(eq(errorCallbackToken), eq(exception));
|
verify(mOrganizer).onTaskFragmentError(eq(errorCallbackToken), eq(exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegisterRemoteAnimations() {
|
||||||
|
mController.registerOrganizer(mIOrganizer);
|
||||||
|
mController.registerRemoteAnimations(mIOrganizer, mDefinition);
|
||||||
|
|
||||||
|
assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer));
|
||||||
|
|
||||||
|
mController.unregisterRemoteAnimations(mIOrganizer);
|
||||||
|
|
||||||
|
assertNull(mController.getRemoteAnimationDefinition(mIOrganizer));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWindowContainerTransaction_setTaskFragmentOrganizer() {
|
public void testWindowContainerTransaction_setTaskFragmentOrganizer() {
|
||||||
mOrganizer.applyTransaction(mTransaction);
|
mOrganizer.applyTransaction(mTransaction);
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.app.IApplicationThread;
|
import android.app.IApplicationThread;
|
||||||
@@ -100,6 +101,7 @@ import android.view.WindowManager;
|
|||||||
import android.view.WindowManager.DisplayImePolicy;
|
import android.view.WindowManager.DisplayImePolicy;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.StartingWindowInfo;
|
import android.window.StartingWindowInfo;
|
||||||
|
import android.window.TaskFragmentOrganizer;
|
||||||
import android.window.TransitionInfo;
|
import android.window.TransitionInfo;
|
||||||
import android.window.TransitionRequestInfo;
|
import android.window.TransitionRequestInfo;
|
||||||
|
|
||||||
@@ -1135,6 +1137,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
|||||||
private boolean mCreateParentTask;
|
private boolean mCreateParentTask;
|
||||||
private boolean mCreateEmbeddedTask;
|
private boolean mCreateEmbeddedTask;
|
||||||
private int mCreateActivityCount = 0;
|
private int mCreateActivityCount = 0;
|
||||||
|
@Nullable
|
||||||
|
private TaskFragmentOrganizer mOrganizer;
|
||||||
|
|
||||||
TaskFragmentBuilder(ActivityTaskManagerService service) {
|
TaskFragmentBuilder(ActivityTaskManagerService service) {
|
||||||
mAtm = service;
|
mAtm = service;
|
||||||
@@ -1161,11 +1165,16 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TaskFragmentBuilder setOrganizer(@Nullable TaskFragmentOrganizer organizer) {
|
||||||
|
mOrganizer = organizer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
TaskFragment build() {
|
TaskFragment build() {
|
||||||
SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);
|
SystemServicesTestRule.checkHoldsLock(mAtm.mGlobalLock);
|
||||||
|
|
||||||
final TaskFragment taskFragment = new TaskFragment(mAtm, null /* fragmentToken */,
|
final TaskFragment taskFragment = new TaskFragment(mAtm, null /* fragmentToken */,
|
||||||
false /* createdByOrganizer */);
|
mOrganizer != null);
|
||||||
if (mParentTask == null && mCreateParentTask) {
|
if (mParentTask == null && mCreateParentTask) {
|
||||||
mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
|
mParentTask = new TaskBuilder(mAtm.mTaskSupervisor).build();
|
||||||
}
|
}
|
||||||
@@ -1183,6 +1192,10 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
|||||||
taskFragment.addChild(activity);
|
taskFragment.addChild(activity);
|
||||||
mCreateActivityCount--;
|
mCreateActivityCount--;
|
||||||
}
|
}
|
||||||
|
if (mOrganizer != null) {
|
||||||
|
taskFragment.setTaskFragmentOrganizer(
|
||||||
|
mOrganizer.getOrganizerToken(), 10000 /* pid */);
|
||||||
|
}
|
||||||
return taskFragment;
|
return taskFragment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user