/********************************************************************************
** Copyright (C), 2023-2123, Oplus Mobile Comm Corp., Ltd
** All rights reserved.
**
** File: - OplusInterruptTransitionManager.java
** Description:
** Manager of interrupt transition
**
** Version: 1.0
** Date: 2024-02-04
** Author: LiYichen@ANDROID.WMS
** TAG: OPLUS_FEATURE_INTERRUPT_TRANSITION
** ------------------------------- Revision History: ----------------------------
** <author> <data> <version> <desc>
** ------------------------------------------------------------------------------
** LiYichen@ANDROID.WMS 2024-02-04 1.0 Create this module
********************************************************************************/
package com.oplus.transition;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Log;
import android.view.Surface;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.animation.Animation;
import android.window.RemoteTransition;
import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.recents.RecentsTransitionHandler;
//import com.android.wm.shell.transition.RecentsMixedTransition;
import com.android.wm.shell.transition.DefaultTransitionHandler;
import com.android.wm.shell.transition.RemoteTransitionHandler;
import android.window.RemoteTransition;
import com.android.wm.shell.transition.TransitionAnimationUtil;
import com.android.wm.shell.transition.TransitionLog;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.util.ReflectionUtils;
import com.android.wm.shell.shared.TransitionUtil;
import android.view.IRecentsAnimationController;
import android.window.WindowOrganizer;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_NONE;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
import static com.oplus.content.OplusIntent.OPLUS_FLAG_POCKET_STUDIO_CANVAS;
import static com.oplus.wrapper.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
import com.oplus.content.OplusFeatureConfigManager;
import com.oplus.splitscreen.ReflectionHelper;
import com.oplus.uifirst.OplusUIFirstManager;
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class OplusInterruptTransitionManager {
public static final String TAG = "OplusInterruptTransitionManager";
public static final String OPLUS_FEATURE_INTERRUPT_TRANSITION = "oplus.software.support_blockable_animation";
public static final boolean DEBUG_INTERRUPT_TRANSITION_PROP = SystemProperties.getBoolean(
"persist.wm.debug.interrupt_transition", false);
public static final boolean ENABLE_INTERRUPT_TRANSITION = DEBUG_INTERRUPT_TRANSITION_PROP
|| OplusFeatureConfigManager.getInstance().hasFeature(OPLUS_FEATURE_INTERRUPT_TRANSITION);
private static final String EXT = "mExt";
private static final String GET_EXTENDED_INFO = "getExtendedInfo";
private static final String SET_RECENTS_CONTROLLER = "setRecentsController";
private static final String TASKFRAGMENT = "TaskFragment";
private static final String GET_PARENT_LEASH_FOR_BG_COLOR = "getParentLeashForBgColor";
private static final String SET_IS_BAL_ALLOW = "setIsBalAllow";
private static final String SET_IS_REMOTE_FROM_LAUNCHER = "setIsRemoteFromLauncher";
private static final String IS_OPLUS_ANIM_RES = "isOplusAnimRes";
private static final String GET_AVOID_INTERCEPT_KEY_EVENT_TO_HOME = "getAvoidInterceptKeyEventToHome";
private static final String SET_MERGE_BACK_ANIMATION_TO_RECENTS = "setMergeBackAnimationToRecents";
private static final String KEY_HAS_FIX_ROTATION_LEASH = "has-fix-rotation-leash";
private static final String GET_TASK_NOT_IN_RECENT_ON_EXTINFO = "getTaskNotInRecent";
private static final String SET_IS_TASK_NOT_IN_RECENTS = "setIsTaskNotInRecents";
private static final String GET_IS_TASK_NOT_IN_RECENTS = "getIsTaskNotInRecents";
private static final String GET_REQUEST_TRANSITION_TASK_ID = "getRequestTransitionTaskId";
private static final String SET_REQUEST_TRANSITION_TASK_ID = "setRequestTransitionTaskId";
private static final String GET_IS_FROM_HOME = "getIsFromHome";
private static final String GET_IS_BAL_ALLOW = "getIsBalAllow";
private static final String GET_IS_FROM_OVERLAY = "getIsFromOverlay";
private static final String IS_ASSIST_SCREEN_SHOWING = "isAssistScreenShowing";
private static final String PKG_LAUNCHER = "com.android.launcher";
private static final int OPLUS_MIRAGE_DISPLAY = 10000;
private static final int OPLUS_MIRAGE_TVDISPLAY = 2020;
public static final int INTERRUPT_TRACK = 10;
private static final int STATE_NEW_TASK = 1;
private static volatile OplusInterruptTransitionManager sInstance;
private Transitions mTransitions;
private boolean mRemoteInterrupt;
private boolean mRecentFinishToHome;
private long mRecentFinishSeqId;
private boolean mIsLandScapeExitScene;
private IBinder mRemoteTransitionToken;
public static OplusInterruptTransitionManager getInstance() {
if (sInstance == null) {
synchronized (OplusInterruptTransitionManager.class) {
if (sInstance == null) {
sInstance = new OplusInterruptTransitionManager();
}
}
}
return sInstance;
}
public void init(Transitions transitions) {
mTransitions = transitions;
}
public boolean isRemoteInterrupt() {
if (!ENABLE_INTERRUPT_TRANSITION) {
return false;
}
return mRemoteInterrupt;
}
public void setInterrupt(boolean interrupt) {
mRemoteInterrupt = interrupt;
}
public void resetRemoteInterrupt() {
if (isRemoteInterrupt()) {
setInterrupt(false);
}
}
public void setRecentFinishToHome(boolean toHome) {
mRecentFinishToHome = toHome;
}
public boolean isRecentFinishToHome() {
return mRecentFinishToHome;
}
public void continueRecents(Transitions.ActiveTransition playing,
Transitions.ActiveTransition ready,
RecentsTransitionHandler recentsHandler, WindowOrganizer organizer) {
if (recentsHandler == null) {
return;
}
RecentsTransitionHandler.RecentsController recentsController =
recentsHandler.getRecentController(ready.mToken);
TransitionLog.always("continueRecent track.mActiveTransition: " + ready + ", controller: " + recentsController);
if (recentsController != null) {
ArrayList<Integer> readyTaskIds = getChangeTaskIds(ready.mInfo);
recentsController.setTmpRemote(playing);
TransitionInfo remoteInfo = recentsController.getTmpRemote().mInfo;
for (TransitionInfo.Change change : remoteInfo.getChanges()) {
// avoid flick when recent finish, because remote will apply earlier
if (change == null || change.getLeash() == null || !change.getLeash().isValid()) {
continue;
}
if ((change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT)
&& !change.getLeash().toString().contains(TASKFRAGMENT)) {
recentsController.getTmpRemote().mFinishT.hide(change.getLeash());
if (change.getTaskInfo() != null
&& change.getTaskInfo().topActivityType != ACTIVITY_TYPE_HOME
&& !readyTaskIds.contains(change.getTaskInfo().taskId)) {
ready.mStartT.hide(change.getLeash());
TransitionLog.always("The change: " + change + " of remote transiton "
+ "don't participate recents, so hide task surface");
}
}
}
}
setInterrupt(true);
notifyRemoteInterrupt(playing.mToken, ready.mToken, organizer);
}
private ArrayList<Integer> getChangeTaskIds(TransitionInfo info) {
ArrayList<Integer> taskIds = new ArrayList<>();
for (TransitionInfo.Change change : info.getChanges()) {
if (change.getTaskInfo() != null) {
taskIds.add(change.getTaskInfo().taskId);
}
}
return taskIds;
}
public void finishTmpRemoteTransition(Transitions.ActiveTransition active,
SurfaceControl.Transaction finishT,
RecentsTransitionHandler recentsTransitionHandler,
WindowContainerTransaction wct,
ArrayList<Transitions.TransitionObserver> observers,
ShellTaskOrganizer organizer) {
if (recentsTransitionHandler == null || recentsTransitionHandler.getRecentController(active.mToken) == null) {
return;
}
Transitions.ActiveTransition tmpRemote = recentsTransitionHandler.getRecentController(active.mToken).getTmpRemote();
if (tmpRemote == null) {
return;
}
boolean isRecentToHome = OplusRemoteInterruptManager.ReflectionHelper.isRecentFinishToHome(wct);
long seqId = OplusRemoteInterruptManager.ReflectionHelper.getRecentFinishSeq(wct);
TransitionLog.always("finishTmpRemoteTransition " + tmpRemote
+ ", wct=" + wct + ", isRecentToHome=" + isRecentToHome + ", seqId=" + seqId);
for (int i = 0; i < observers.size(); ++i) {
observers.get(i).onTransitionFinished(tmpRemote.mToken, tmpRemote.mAborted);
}
if (tmpRemote.mMerged != null) {
for (int iM = 0; iM < tmpRemote.mMerged.size(); ++iM) {
final Transitions.ActiveTransition toMerge = tmpRemote.mMerged.get(iM);
if (toMerge.mStartT != null) {
finishT.merge(toMerge.mStartT);
}
if (toMerge.mFinishT != null) {
finishT.merge(toMerge.mFinishT);
}
}
}
WindowContainerTransaction tmpWCT = new WindowContainerTransaction();
OplusRemoteInterruptManager.ReflectionHelper.recordRecentFinishState(tmpWCT, isRecentToHome, seqId);
tmpRemote.mInfo.releaseAnimSurfaces();
//#ifdef OPLUS_TRANSITION_BUGFIX 7004238
//#songchunlong@ANDROID.WMS, 2024/03/06, Modify for finishTransition async ux binder
//Jun.Gao@ANDROID.WMS, 2024/10/29, Modify for using sdk interface set async binder ux
OplusUIFirstManager.getInstance().setBinderThreadUxFlag(-1, 1);
//#endif /* OPLUS_TRANSITION_BUGFIX */
organizer.finishTransition(tmpRemote.mToken, tmpWCT);
if (tmpRemote.mMerged != null) {
for (int iM = 0; iM < tmpRemote.mMerged.size(); ++iM) {
Transitions.ActiveTransition merged = tmpRemote.mMerged.get(iM);
organizer.finishTransition(merged.mToken, tmpWCT /* wct */);
merged.mInfo.releaseAnimSurfaces();
}
tmpRemote.mMerged.clear();
}
recentsTransitionHandler.getRecentController(active.mToken).setTmpRemote(null);
}
public void reorderHomeWhenFinish(int state, WindowContainerToken launcherTask, int track,
WindowContainerTransaction wct) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
setRecentFinishToHome(true);
if (state == STATE_NEW_TASK && launcherTask != null && !nextWillCloseLauncher(track)) {
TransitionLog.always("recents reorderHomeWhenFinish");
wct.reorder(launcherTask, true /* toTop */);
}
}
public boolean showOpenTaskInFinishIfNeeded(int trackId, WindowContainerToken openTaskToken,
IBinder transitionTokenMergeRecents) {
if (openTaskToken == null || transitionTokenMergeRecents == null) {
return true;
}
Transitions.ActiveTransition readyTransition = mTransitions.nextReadyTransition(trackId);
if (readyTransition != null && readyTransition.mInfo != null && readyTransition.mToken.equals(transitionTokenMergeRecents)) {
boolean remoteFromLaunch = mTransitions.isRemoteOpenRequestedFrom(readyTransition.mToken, "QuickstepLaunch");
TransitionInfo readyInfo = readyTransition.mInfo;
if (remoteFromLaunch && readyInfo.getChanges().stream().anyMatch(change -> openTaskToken.equals(change.getContainer()))) {
TransitionLog.always("readyTransiton: " + readyTransition + " don't merge into recents, but task:"
+ openTaskToken + " add to openingtask, so don't show it when recents finish");
return false;
}
}
return true;
}
private boolean nextWillCloseLauncher(int trackId) {
if (trackId < 0) {
return false;
}
Transitions.ActiveTransition ready = mTransitions.nextReadyTransition(trackId);
if (ready != null && ready.mInfo != null) {
TransitionInfo info = ready.mInfo;
List<TransitionInfo.Change> changes = info.getChanges();
// #ifdef OPLUS_FEATURE_INTERRUPT_TRANSITION
// Qin.Ding@ANDROID.WMS 2024/05/27, add for almid:7350478, 7367404, 7360883
if (changes.size() <= 2 && info.getType() == TRANSIT_OPEN) {
TransitionInfo.Change change = changes.get(0);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo != null && taskInfo.getActivityType() != ACTIVITY_TYPE_HOME
&& !TransitionUtil.isClosingType(change.getMode())
&& !change.hasFlags(FLAG_TRANSLUCENT)) {
boolean isFromOverlay = OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_IS_FROM_OVERLAY, null);
if ((changes.size() == 2 && isFromOverlay)
|| changes.size() == 1) {
TransitionLog.always("nextWillCloseLauncher, Prevent reorder launcherTask, changes.size=" + changes.size());
return true;
}
}
}
// #endif /*OPLUS_FEATURE_INTERRUPT_TRANSITION*/
for (int i = 0; i < changes.size(); i ++) {
TransitionInfo.Change change = changes.get(i);
if (change.getTaskInfo() != null
&& change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME
&& TransitionUtil.isClosingType(change.getMode())) {
return true;
}
}
}
return false;
}
// #ifdef OPLUS_FEATURE_ANIMATION
// Qin.Ding@ANDROID.WMS 2024/07/06, Modify for almid:7502858, 7532587
public boolean skipMergeIntoRecentsIfNeed(TransitionInfo info, IBinder mergedToken, WindowContainerToken recentsTask,
RecentsTransitionHandler.RecentsController controller) {
//#ifdef OPLUS_FEATURE_INTERRUPT_TRANSITION
//LiYichen@ANDROID.WMS 2024/4/19, Add for interrupt transition
if (null == recentsTask) {
controller.cancel("cancel_by_interrupt");
TransitionLog.always(TAG + " skip merge into recents, when recentsTask is null");
return true;
}
//#endif /*OPLUS_FEATURE_INTERRUPT_TRANSITION*/
boolean isRemoteOpenFromSysUI = mTransitions.isRemoteOpenRequestedFrom(mergedToken, "SysUIPluginLaunch");
if (isRemoteOpenFromSysUI) {
TransitionLog.always(TAG + " skip merge into recents, when remote open debugname is SysUIPluginLaunch");
return true;
}
if (OplusTransitionReflectionHelper.methodInvokeOnExt(info, GET_IS_FROM_OVERLAY, null)) {
TransitionLog.always(TAG + " skip merge into recents, when open from overlay");
return true;
}
//add for ps 7822096
if (skipMergeIntoRecentsForCanvas(info, controller)) {
controller.cancel("cancel_by_canvas");
TransitionLog.always(TAG + " skip merge into recents, when canvas switch");
return true;
}
return false;
}
// #endif /* OPLUS_FEATURE_ANIMATION */
private boolean skipMergeIntoRecentsForCanvas(TransitionInfo mergeInfo,
RecentsTransitionHandler.RecentsController controller) {
TransitionInfo playingInfo = (controller == null) ? null : controller.getPlayingTransitionInfo();
if (controller == null || mergeInfo == null || playingInfo == null) {
return false;
}
boolean isCanvasSwitch = false;
boolean hasToFrontCanvasInMergeInfo = false;
boolean hasToBackHomeInMergeInfo = false;
boolean hasToBackCanvasInPlayingInfo = false;
boolean hasToFrontHomeInPlayingInfo = false;
boolean hasSameEmbeddedChildren = false;
int mergeCanvasTaskId = -1;
int playingCanvasTaskId = -1;
List<Integer> mergeTaskIdList = null;
List<Integer> playingTaskIdList = null;
for (int i = 0; i < mergeInfo.getChanges().size(); ++i) {
final TransitionInfo.Change change = mergeInfo.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo == null) {
continue;
}
if (isCanvasTask(taskInfo) && change.getMode() == WindowManager.TRANSIT_TO_FRONT) {
mergeCanvasTaskId = taskInfo.taskId;
hasToFrontCanvasInMergeInfo = true;
mergeTaskIdList = ReflectionHelper.FlexibleWindowManager_getEmbeddedChildren(taskInfo.taskId);
}
if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME && change.getMode() == TRANSIT_TO_BACK) {
hasToBackHomeInMergeInfo = true;
}
}
for (int i = 0; i < playingInfo.getChanges().size(); ++i) {
final TransitionInfo.Change change = playingInfo.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo == null) {
continue;
}
if (isCanvasTask(taskInfo) && change.getMode() == WindowManager.TRANSIT_TO_BACK) {
playingCanvasTaskId = taskInfo.taskId;
hasToBackCanvasInPlayingInfo = true;
playingTaskIdList = ReflectionHelper.FlexibleWindowManager_getEmbeddedChildren(taskInfo.taskId);
}
if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME && change.getMode() == TRANSIT_TO_FRONT) {
hasToFrontHomeInPlayingInfo = true;
}
}
if (mergeTaskIdList == null || mergeTaskIdList.isEmpty() || playingTaskIdList == null || playingTaskIdList.isEmpty()) {
return false;
}
if (mergeCanvasTaskId == playingCanvasTaskId || mergeCanvasTaskId == -1 || playingCanvasTaskId == -1) {
return false;
}
isCanvasSwitch = hasToFrontCanvasInMergeInfo && hasToBackHomeInMergeInfo
&& hasToBackCanvasInPlayingInfo && hasToFrontHomeInPlayingInfo;
hasSameEmbeddedChildren = mergeTaskIdList.retainAll(playingTaskIdList);
return isCanvasSwitch && hasSameEmbeddedChildren;
}
private boolean isCanvasTask(@NonNull ActivityManager.RunningTaskInfo task) {
return task != null && (TransitionAnimationUtil.getOplusFlags(
task.baseIntent) & OPLUS_FLAG_POCKET_STUDIO_CANVAS) != 0;
}
public boolean ifMergeIntoRemote(TransitionInfo info, SurfaceControl.Transaction t,
Transitions.TransitionFinishCallback finishCallback,
boolean mergedIsNotRemote) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return false;
}
if (normalTaskLevelSamePkgName(info)) {
// merged into remote
TransitionLog.always(TAG + " transition " + info.getDebugId() + "have same packagename and "
+ "only normal task level, merge into remote.");
finishCallback.onTransitionFinished(null);
return true;
}
for (TransitionInfo.Change change : info.getChanges()) {
// if changes have a task, skip
if (change.getTaskInfo() != null) {
return false;
}
}
if (isPureLauncherTransition(info)) {
return false;
}
if (isLargeSmallScreenSwitchAnim(info)) {
TransitionLog.always(TAG + " transition " + info.getDebugId() + " isLargeSmallScreenSwitchAnim, do not merge into remote.");
return false;
}
boolean needMergeRemote = false;
for (TransitionInfo.Change change : info.getChanges()) {
// if changes are activity, need to be merged into remote
if (change.getTaskInfo() == null && !change.hasFlags(TransitionInfo.FLAG_IS_WALLPAPER)) {
needMergeRemote = true;
}
// update alpha after setupStartState
if (TransitionUtil.isOpeningType(info.getType())
&& TransitionUtil.isOpeningType(change.getMode())) {
t.setAlpha(change.getLeash(), 1);
}
}
if (needMergeRemote && mergedIsNotRemote) {
// apply startT in advance
t.apply();
t.clear();
// merged into remote
TransitionLog.debug("remote mergeAnimation, " + info.getDebugId() + " merged into remote");
finishCallback.onTransitionFinished(null);
return true;
}
return false;
}
private boolean normalTaskLevelSamePkgName(TransitionInfo info) {
if (info == null) {
return false;
}
boolean hasSamePackage = true;
String taskPackageName = null;
boolean hasNoAnimFlag = false;
boolean hasNoneFlagInOpenType = false;
for (TransitionInfo.Change change : info.getChanges()) {
if (change.getTaskInfo() == null) {
return false;
}
if (change.getTaskInfo().realActivity != null) {
if (change.hasFlags(FLAG_NO_ANIMATION)) {
hasNoAnimFlag = true;
}
if (info.getType() == TRANSIT_OPEN
&& change.getMode() == TRANSIT_CLOSE
&& change.getFlags() == FLAG_NONE) {
hasNoneFlagInOpenType = true;
}
String changePackageName = change.getTaskInfo().realActivity.getPackageName();
if (PKG_LAUNCHER.equals(changePackageName)) {
return false;
}
if (taskPackageName == null) {
taskPackageName = changePackageName;
} else if (!taskPackageName.equals(changePackageName)) {
hasSamePackage = false;
}
}
}
return hasSamePackage && (hasNoAnimFlag || hasNoneFlagInOpenType);
}
public static boolean isLargeSmallScreenSwitchAnim(TransitionInfo info) {
if (info.getType() == TRANSIT_CHANGE) {
for (TransitionInfo.Change change : info.getChanges()) {
if (change.hasFlags(FLAG_IS_DISPLAY)
&& change.getStartRotation() == change.getEndRotation()) {
return true;
}
}
}
return false;
}
public boolean isPureLauncherTransition(TransitionInfo info) {
boolean isPureLauncherTransition = true;
for (TransitionInfo.Change change : info.getChanges()) {
if (!change.getLeash().toString().contains("com.android.launcher")
|| (change.getMode() != TRANSIT_OPEN && change.getMode() != TRANSIT_TO_BACK)) {
isPureLauncherTransition = false;
}
}
return isPureLauncherTransition;
}
public void hookRecentsMerge(TransitionInfo mergeInfo, SurfaceControl.Transaction t,
RemoteAnimationTarget[] appearedTargets, IBinder mergedToken) {
fixStartTOnRecentsMerge(mergeInfo, t, appearedTargets);
adjustAppearedTargets(appearedTargets, mergeInfo, mergedToken);
addFlagInRecentOnRemoteTargets(mergeInfo, appearedTargets);
}
private void fixStartTOnRecentsMerge(TransitionInfo mergeInfo, SurfaceControl.Transaction t,
RemoteAnimationTarget[] appearedTargets) {
if (mergeInfo == null) {
return;
}
if (appearedTargets == null) {
for (TransitionInfo.Change change : mergeInfo.getChanges()) {
setAlphaForOpenActivityIfNeeded(mergeInfo, change, t);
setPositionForFixRotation(mergeInfo, change, t);
}
}
}
private void adjustAppearedTargets(RemoteAnimationTarget[] appearedTargets, TransitionInfo info, IBinder mergedToken) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
if (appearedTargets == null || info == null) {
return;
}
boolean isBalAllow = OplusTransitionReflectionHelper.methodInvokeOnExt(info, GET_IS_BAL_ALLOW, null);
boolean isRemoteFromLauncher = mTransitions.isRemoteOpenRequestedFrom(mergedToken, "QuickstepLaunch");
for (RemoteAnimationTarget appearedTarget : appearedTargets) {
if (appearedTarget.mode == MODE_OPENING && appearedTarget.taskInfo.topActivityType == ACTIVITY_TYPE_STANDARD) {
if (isBalAllow && !isRemoteFromLauncher) {
OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget, SET_IS_BAL_ALLOW,
new Class<?>[]{boolean.class}, true);
TransitionLog.debug("set remoteTarget: " + appearedTarget + " is balallow");
} else if (isRemoteFromLauncher) {
OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget, SET_IS_REMOTE_FROM_LAUNCHER,
new Class<?>[]{boolean.class}, true);
}
}
}
}
private void setAlphaForOpenActivityIfNeeded(TransitionInfo info, TransitionInfo.Change change,
SurfaceControl.Transaction t) {
int mode = change.getMode();
boolean openMode = (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT);
if (openMode && TransitionUtil.isOpeningType(info.getType())
&& (change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0
&& change.getTaskInfo() == null) {
TransitionLog.debug("set alpha 1 of activity:" + change);
t.setAlpha(change.getLeash(), 1);
}
}
private void setPositionForFixRotation(TransitionInfo mergeInfo, TransitionInfo.Change change,
SurfaceControl.Transaction t) {
if (change.getStartRotation() == change.getEndRotation()) {
return;
}
Bundle b = OplusTransitionReflectionHelper.getWindowInfoBundleFromChange(change);
if (b != null && b.getBoolean(KEY_HAS_FIX_ROTATION_LEASH, false)) {
final SurfaceControl leash = change.getLeash();
if (!TransitionInfo.isIndependent(change, mergeInfo)) {
return;
}
boolean hasParent = change.getParent() != null;
final int rootIdx = TransitionUtil.rootIndexFor(change, mergeInfo);
if (!hasParent) {
t.setPosition(leash,
change.getStartAbsBounds().left - mergeInfo.getRoot(rootIdx).getOffset().x,
change.getStartAbsBounds().top - mergeInfo.getRoot(rootIdx).getOffset().y);
TransitionLog.debug("set position for " + change + ", when has fix rotation");
}
}
}
public void sendRecentsController(IBinder transition, RecentsTransitionHandler handler,
TransitionInfo info) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
if (handler != null) {
RecentsTransitionHandler.RecentsController recentsController =
handler.getRecentController(transition);
if (recentsController != null) {
setRecentsController(info, recentsController);
TransitionLog.debug("sendRecentsController, info:" + info);
}
}
}
private static void setRecentsController(TransitionInfo info,
RecentsTransitionHandler.RecentsController recentsController) {
if (info == null || recentsController == null) {
return;
}
try {
Field ext = info.getClass().getDeclaredField(EXT);
ext.setAccessible(true);
Object infoExt = ext.get(info);
if (infoExt != null) {
Method getExtendedInfo = infoExt.getClass().getDeclaredMethod(GET_EXTENDED_INFO);
getExtendedInfo.setAccessible(true);
Object extendedInfo = getExtendedInfo.invoke(infoExt);
if (extendedInfo != null) {
Method setRecentsController = extendedInfo.getClass().getDeclaredMethod(SET_RECENTS_CONTROLLER,
IRecentsAnimationController.class);
setRecentsController.setAccessible(true);
setRecentsController.invoke(extendedInfo, recentsController);
}
}
} catch (Exception e) {
Log.e(TAG, "setRecentsController error : " + e);
}
}
public RemoteAnimationTarget initTargetWithTaskLeash(TransitionInfo.Change change, int layer,
TransitionInfo mergeInfo,
SurfaceControl.Transaction t,
ArrayMap<SurfaceControl, SurfaceControl> leashMap,
TransitionInfo recentInfo) {
// We are receiving new opening leaf tasks, so convert to onTasksAppeared.
final RemoteAnimationTarget target = TransitionUtil.newTarget(
change, layer, mergeInfo, t, leashMap);
// reparent into the original `mInfo` since that's where we are animating.
final int rootIdx = TransitionUtil.rootIndexFor(change, recentInfo);
t.reparent(target.leash, recentInfo.getRoot(rootIdx).getLeash());
t.setLayer(target.leash, layer);
// Hide the animation leash, let listener show it.
t.hide(target.leash);
return target;
}
//#ifdef OPLUS_FEATURE_INTERRUPT_TRANSITION
//wenguangyu@Android.WMS, 2024/01/19, add for notify transitions state to WmCore
public void notifyTransitionRemoveTask(IBinder playingToken, boolean isRecentsPlaying,
IBinder mergedToken, TransitionInfo mergedInfo,
int removeTaskId, WindowOrganizer organizer) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
if (playingToken == null || mergedToken == null || mergedInfo == null || !isRecentsPlaying) {
return;
}
/*if (OplusRemoteInterruptManager.ReflectionHelper.getIsFromHome(mergedInfo)) {
notifyStartCompleted(mergedInfo, mergedAborted, organizer);
}
playing.mHandler.updateFinishT(playing.mToken, merged.mFinishT);*/
organizer.notifyTransitionRemoveTask(playingToken, mergedToken, removeTaskId);
}
public void notifyTransitionMerged(IBinder playing, IBinder merged, boolean isRecentsPlaying,
WindowOrganizer organizer) {
if (!ENABLE_INTERRUPT_TRANSITION || playing == null || merged == null || !isRecentsPlaying) {
return;
}
organizer.notifyTransitionMerged(playing, merged);
}
/**
* first start remote transition, then start recents transition and trigger interrupt scene
* @param playing remote transition token
* @param merged recents transition token
* @param organizer WindowOrgnaizer object
*/
public void notifyRemoteInterrupt(IBinder playing, IBinder merged, WindowOrganizer organizer) {
organizer.notifyRemoteInterrupt(playing, merged);
}
private void notifyStartCompleted(TransitionInfo info, boolean abort, WindowOrganizer organizer) {
if (TransitionUtil.isOpeningType(info.getType())) {
ActivityManager.RunningTaskInfo runningTaskInfo = null;
for (int i = 0; i < info.getChanges().size(); i++) {
TransitionInfo.Change change = info.getChanges().get(i);
ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo != null) {
if (runningTaskInfo != null) {
break;
} else if (TransitionUtil.isOpeningType(change.getMode())
&& taskInfo.isVisibleRequested
&& taskInfo.topActivityType != ACTIVITY_TYPE_HOME) {
runningTaskInfo = taskInfo;
}
}
}
if (runningTaskInfo != null) {
organizer.notifyStartCompleted(runningTaskInfo.token, abort);
}
}
}
//#endif /*OPLUS_FEATURE_INTERRUPT_TRANSITION*/
//#ifdef OPLUS_FEATURE_SHELL_TRANSITION
//Guochunlin@ANDROID.WMS 2024/02/08, Add to notify launcher
private boolean isLandAppOpen(TransitionInfo info) {
if (info != null) {
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
int endFixedRotation = change.getEndFixedRotation();
if (info.getType() == TRANSIT_OPEN
&& (endFixedRotation == Surface.ROTATION_90 || endFixedRotation == Surface.ROTATION_270)) {
TransitionLog.debug("isLandAppOpen: endFixedRotation = " + endFixedRotation);
return true;
}
}
}
return false;
}
public boolean isLandScapeExitScene(IBinder token, Transitions.TransitionHandler handler,
ShellTaskOrganizer organizer,
RemoteTransitionHandler remoteTransitionHandler,
TransitionInfo info, Context context) {
if (handler == null || context == null) {
return false;
}
boolean isRecentsAnimation = (handler instanceof RecentsTransitionHandler);
/*if (!isRecentsAnimation && (handler instanceof RecentsMixedTransition)) {
RecentsMixedTransition recentsMixedTransition = (RecentsMixedTransition) handler;
isRecentsAnimation = recentsMixedTransition.isAnimateRecentsDuringSplit();
}*/
boolean isRemoteAnimation = false;
boolean isChangeAnimationFromLandToPort = false;
if (!isRecentsAnimation) {
isRemoteAnimation = (info.getType() == TRANSIT_OPEN) && (mRemoteTransitionToken == token);
isChangeAnimationFromLandToPort = (info.getType() == TRANSIT_CHANGE) && isChangeAnimationFromLandToPort(info);
}
if (isRecentsAnimation || isRemoteAnimation || isChangeAnimationFromLandToPort) {
TransitionLog.always("isRecentsAnimation is: " + isRecentsAnimation + " isRemoteAnimation " + isRemoteAnimation);
int currentRotation = context.getResources().getConfiguration()
.windowConfiguration.getRotation();
boolean isLandScape = (currentRotation == Surface.ROTATION_90
|| currentRotation == Surface.ROTATION_270)
|| isLandAppOpen(info);
if (isChangeAnimationFromLandToPort && mIsLandScapeExitScene) {
mIsLandScapeExitScene = false;
TransitionLog.always("isLandScapeExitScene and mIsLandScapeExitScene is: " + mIsLandScapeExitScene
+ ", change animation from land to port, notify launcher to cancel listener");
organizer.onLandScapeSceneExit(true);
return true;
}
if (isLandScape) {
mIsLandScapeExitScene = true;
TransitionLog.always("isLandScapeExitScene and mIsLandScapeExitScene is: " + mIsLandScapeExitScene);
return true;
} else if (isRecentsAnimation) {
mIsLandScapeExitScene = false;
TransitionLog.always("isLandScapeExitScene and mIsLandScapeExitScene is: " + mIsLandScapeExitScene
+ ", notify launcher to cancel listener");
organizer.onLandScapeSceneExit(false);
return false;
}
}
return false;
}
private boolean isChangeAnimationFromLandToPort(TransitionInfo info) {
if (info != null && info.getType() == TRANSIT_CHANGE) {
for (TransitionInfo.Change change : info.getChanges()) {
if (change.getMode() == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) {
int startRotation = change.getStartRotation();
int endRotation = change.getEndRotation();
boolean fromLand = (startRotation == Surface.ROTATION_90
|| startRotation == Surface.ROTATION_270);
boolean toPort = (endRotation == Surface.ROTATION_0
|| endRotation == Surface.ROTATION_180);
return fromLand && toPort;
}
}
}
return false;
}
public boolean notifyLauncherStartActivity(TransitionInfo info, ShellTaskOrganizer organizer,
IBinder transitionToken,
RemoteTransitionHandler remoteTransitionHandler) {
if (mIsLandScapeExitScene) {
if (info.getType() == TRANSIT_CHANGE || isRotationChange(info)) {
TransitionLog.always("Transition Change excuted by last landscape application and transition type is: " + info.getType());
mIsLandScapeExitScene = false;
organizer.onLandScapeSceneExit(true);
return true;
} else {
ArrayMap<IBinder, RemoteTransition> requestedRemotes = remoteTransitionHandler.getRequestedRemotes();
boolean isOpenRemote = (info.getType() == TRANSIT_OPEN) && (requestedRemotes != null)
&& (requestedRemotes.get(transitionToken) != null);
if (isOpenRemote) {
mIsLandScapeExitScene = false;
TransitionLog.always("reset mIsLandScapeExitScene");
return true;
}
}
}
return false;
}
private boolean isRotationChange(TransitionInfo info) {
if (info != null && info.getType() == TRANSIT_PIP) {
for (TransitionInfo.Change change : info.getChanges()) {
if (change.getMode() == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) {
int startRotation = change.getStartRotation();
int endRotation = change.getEndRotation();
TransitionLog.always("isRotationChange and startRotation: " + startRotation + " endRotation: " + endRotation);
return startRotation != endRotation;
}
}
}
return false;
}
public void setRemoteTransitionToken(IBinder token) {
mRemoteTransitionToken = token;
}
public boolean keyBackPressWithAvoidQuickBack(TransitionInfo info) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return false;
}
return (boolean) OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_AVOID_INTERCEPT_KEY_EVENT_TO_HOME, null) || isBackToHome(info);
}
private boolean isBackToHome(TransitionInfo info) {
if (null == info || null == info.getChanges()) {
return false;
}
final int numChanges = info.getChanges().size();
boolean isHomeToFront = false;
boolean isOpeningAppToClose = false;
if (numChanges == 2 && info.getType() == WindowManager.TRANSIT_CLOSE) {
for (int i = numChanges - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (null == change) {
return false;
}
if (change.getMode() == WindowManager.TRANSIT_TO_FRONT
&& change.getTaskInfo() != null
&& change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME) {
TransitionLog.debug("isHomeToFront");
isHomeToFront = true;
} else if (change.getMode() == WindowManager.TRANSIT_CLOSE) {
TransitionLog.debug("isOpeningAppToClose");
isOpeningAppToClose = true;
}
}
}
return isHomeToFront && isOpeningAppToClose;
}
//#endif /*OPLUS_FEATURE_SHELL_TRANSITION*/
public void updateMergeRemoteTaskVisible(TransitionInfo mergeInfo,
SurfaceControl.Transaction finishT) {
if (isRecentFinishToHome() && finishT != null && (mergeInfo.getType() == TRANSIT_OPEN
// hewei add for ALM: 7130945
|| mergeInfo.getType() == TRANSIT_TO_FRONT)) {
TransitionLog.always("not apply merge finishT");
for (TransitionInfo.Change change : mergeInfo.getChanges()) {
if (change.getEndDisplayId() >= OPLUS_MIRAGE_DISPLAY || change.getEndDisplayId() == OPLUS_MIRAGE_TVDISPLAY
|| change.getLeash() == null || !change.getLeash().isValid()) {
continue;
}
if (TransitionUtil.isOpeningType(change.getMode())
|| change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_MOVED_TO_TOP) != 0) {
if ((change.getTaskInfo() != null && change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME)
|| (change.getActivityComponent() != null)) {
finishT.hide(change.getLeash());
}
}
if (TransitionUtil.isClosingType(change.getMode()) && change.getTaskInfo() != null
&& change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME) {
finishT.show(change.getLeash());
}
}
}
}
public void applyStartTransactionOnAbortIfNeed(@NonNull Transitions.ActiveTransition playing,
@NonNull Transitions.ActiveTransition ready) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
if (playing.mHandler != null && !(playing.mHandler instanceof DefaultTransitionHandler)
&& ready.mStartT != null && ready.mInfo.getChanges().size() > 0) {
// add for alm 8129143
if (ready.mInfo != null && ready.mInfo.getType() == TRANSIT_OPEN) {
for (TransitionInfo.Change change : ready.mInfo.getChanges()) {
if (change.hasAllFlags(FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT | FLAG_IS_BEHIND_STARTING_WINDOW)
&& change.getStartRotation() != change.getEndRotation()) {
TransitionLog.always("Do not apply startT before merge");
return;
}
}
}
ready.mStartT.apply();
TransitionLog.always("apply startT of aborted " + ready + "; before merged into " + playing);
}
}
//#ifdef OPLUS_FEATURE_INTERRUPT_TRANSITION
//Guochunlin@ANDROID.WMS 2024/5/11, Add for bug 7265043
public boolean isToHomeAnimation(TransitionInfo mergeInfo, TransitionInfo recentsInfo) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return false;
}
List<TransitionInfo.Change> changes = mergeInfo.getChanges();
Transitions.ActiveTransition activeTransition = mTransitions.getActiveTransition(recentsInfo.getTrack());
if (mergeInfo.getType() == TRANSIT_TO_BACK && changes.size() == 1
&& activeTransition != null && activeTransition.mMerged != null) {
TransitionInfo.Change change = changes.get(0);
if (change.getTaskInfo() != null && change.getMode() == TRANSIT_TO_BACK) {
return true;
}
}
//Pusam.Huang@ANDROID.WMS 2024/09/23, Add for bug 7940700, begin.
if (mergeInfo.getType() == TRANSIT_CLOSE && changes.size() == 1 && activeTransition != null) {
TransitionInfo.Change change = changes.get(0);
if (change.getTaskInfo() != null && change.getMode() == TRANSIT_CLOSE) {
return true;
}
}
//2024/09/23, Add for bug 7940700, end.
boolean onlyHomeToFront = false;
for (TransitionInfo.Change change : changes) {
if (change.getTaskInfo() != null && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME
&& (TransitionUtil.isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
onlyHomeToFront = true;
} else if (TransitionUtil.isOpeningType(change.getMode())) {
onlyHomeToFront = false;
break;
}
}
return onlyHomeToFront;
}
public void addFlagInRecentOnRemoteTargets(TransitionInfo info, RemoteAnimationTarget[] appearedTargets) {
if (info == null || appearedTargets == null) {
return;
}
for (int i = 0; i < appearedTargets.length; i++) {
RemoteAnimationTarget appearedTarget = appearedTargets[i];
if (appearedTarget != null && appearedTarget.mode != MODE_CLOSING) {
boolean taskNotInRecents = (boolean) OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_TASK_NOT_IN_RECENT_ON_EXTINFO, null);
if (taskNotInRecents) {
OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget, SET_IS_TASK_NOT_IN_RECENTS,
new Class<?>[]{boolean.class}, true);
TransitionLog.always("Appeared opening task " + appearedTarget.taskId
+ " is not in recents, notify remote to close recents anim, notInRecent = "
+ OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget,
GET_IS_TASK_NOT_IN_RECENTS, null));
}
int requestTransitionTaskId = (int) OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_REQUEST_TRANSITION_TASK_ID, null);
if (requestTransitionTaskId != -1) {
OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget, SET_REQUEST_TRANSITION_TASK_ID,
new Class<?>[]{int.class}, requestTransitionTaskId);
TransitionLog.always("Appeared opening task " + appearedTarget.taskId
+ " set request transition task id "
+ OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTarget,
GET_REQUEST_TRANSITION_TASK_ID, null));
}
}
}
}
/*
*construct a closing remoteAnimationTarget to notify launcher by onTasksAppeared
*/
public void constructCloseRemoteAnimationTarget(RemoteAnimationTarget[] appearedTargets,
ArrayList<TransitionInfo.Change> closingTasks) {
if (closingTasks != null && closingTasks.size() == 1) {
final TransitionInfo.Change change = closingTasks.get(0);
ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
appearedTargets[0] = new RemoteAnimationTarget(taskInfo.taskId /* taskId */, -1,
null, false /* isTranslucent */, null /* clipRect */,
null /* contentInsets */, -1 /* prefixOrderIndex */,
null /* position */, null,
null, taskInfo.configuration.windowConfiguration,
false, null /* startLeash */,
null /* startBounds */, taskInfo /* taskInfo */, false /* allowEnterPip */);
OplusTransitionReflectionHelper.methodInvokeOnExt(appearedTargets[0],
SET_MERGE_BACK_ANIMATION_TO_RECENTS, new Class<?>[]{boolean.class}, true);
TransitionLog.debug("setMergeBackAnimationToRecents true");
}
}
//#endif /*OPLUS_FEATURE_INTERRUPT_TRANSITION*/
public void hideMergedToRecentsTask(TransitionInfo info, int taskId) {
if (info == null || taskId <= 0) {
return;
}
Transitions.ActiveTransition active = mTransitions.getActiveTransition(info.getTrack());
if (active != null && active.mHandler instanceof RecentsTransitionHandler && active.mMerged != null) {
int size = active.mMerged.size();
for (int i = size - 1; i >= 0; i--) {
final Transitions.ActiveTransition toMerge = active.mMerged.get(i);
for (TransitionInfo.Change change : toMerge.mInfo.getChanges()) {
if (change == null || change.getLeash() == null || !change.getLeash().isValid()) {
continue;
}
int mode = change.getMode();
if (change.getTaskInfo() != null
&& change.getTaskInfo().taskId == taskId
&& (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
toMerge.mFinishT.hide(change.getLeash());
TransitionLog.always("hide closing task: " + change.getLeash()
+ "in transition: " + toMerge.mInfo.getDebugId());
return;
}
}
}
}
}
public SurfaceControl adjustLeashAtRecentStart(TransitionInfo.Change change,
SurfaceControl.Transaction t,
ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
SurfaceControl leash = change.getLeash();
t.setAlpha(change.getLeash(), 1);
t.show(change.getLeash());
if (leashMap != null) {
leashMap.put(change.getLeash(), leash);
}
return leash;
}
public int getBgColorForActivityTransition(TransitionInfo info, TransitionInfo.Change change, Animation a) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return 0;
}
int bgColor = 0;
final Context uiContext = ActivityThread.currentActivityThread()
.getSystemUiContext();
bgColor = uiContext.getColor(com.android.internal.R.color.overview_background);
bgColor = getTransitionBackgroundColorIfSet(info, change, a, bgColor);
return bgColor;
}
public void addBackgroundColorOnTask(TransitionInfo info,
SurfaceControl.Transaction startTransaction,
SurfaceControl.Transaction finishTransaction) {
if (!ENABLE_INTERRUPT_TRANSITION) {
return;
}
boolean isOplusAnimRes = OplusTransitionReflectionHelper
.methodInvokeOnExt(info, IS_OPLUS_ANIM_RES, null);
boolean isSupportType = info.getType() == TRANSIT_OPEN || info.getType() == TRANSIT_CLOSE;
final Color bgColor = Color.valueOf(Color.BLACK);
final float[] colorArray = new float[]{bgColor.red(), bgColor.green(), bgColor.blue()};
final SurfaceControl parentSC = OplusTransitionReflectionHelper
.methodInvokeOnExt(info, GET_PARENT_LEASH_FOR_BG_COLOR, null);
if (parentSC == null || !isSupportType) {
return;
}
for (int i = 0; i < info.getRootCount(); ++i) {
final SurfaceControl.Builder colorLayerBuilder = new SurfaceControl.Builder()
.setName("activity-level-anim-background")
.setCallsite("DefaultTransitionHandler")
.setColorLayer();
colorLayerBuilder.setParent(parentSC);
TransitionLog.always("addBackgroundColorOnTask bgColor=" + bgColor
+ ", parentSC=" + parentSC
+ ", isOplusAnimRes=" + isOplusAnimRes
+ ", info=" + info
+ ", colorLayerBuilder=" + colorLayerBuilder);
final SurfaceControl backgroundSurface = colorLayerBuilder.build();
startTransaction.setColor(backgroundSurface, colorArray)
.setLayer(backgroundSurface, Integer.MIN_VALUE)
.show(backgroundSurface);
finishTransaction.remove(backgroundSurface);
}
}
public boolean isRemoteReadyMergeToRecents(IBinder token, String debugName) {
if (ENABLE_INTERRUPT_TRANSITION) {
return mTransitions.isRemoteOpenRequestedFrom(token, debugName);
}
return false;
}
public boolean ifInvokeCallBackInInterrupt(boolean onlyHomeToFront, RemoteAnimationTarget[] appearedTargets,
IBinder mergedToken, TransitionInfo info) {
if (mergedToken == null || info == null) {
return false;
}
boolean isRemoteFromSystemUi = mTransitions.isRemoteOpenRequestedFrom(mergedToken, "SysUILaunch");
boolean isRemoteFromLauncher = mTransitions.isRemoteOpenRequestedFrom(mergedToken, "QuickstepLaunch");
boolean isBalAllow = OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_IS_BAL_ALLOW, null);
boolean isFromOverlay = OplusTransitionReflectionHelper.methodInvokeOnExt(info,
GET_IS_FROM_OVERLAY, null);
boolean isAssistScreenShowing = OplusTransitionReflectionHelper.methodInvokeOnExt(info,
IS_ASSIST_SCREEN_SHOWING, null);
boolean notRemoteT = !isRemoteFromLauncher && !isRemoteFromSystemUi;
boolean specialScenes = !isBalAllow && !isFromOverlay && !isAssistScreenShowing;
return !onlyHomeToFront && (appearedTargets == null || (notRemoteT && specialScenes));
}
}
解析以上写好的类的方法与含义