Merge "Implement ActivityEmbedding Shell transition animation with showBackdrop" into tm-qpr-dev
This commit is contained in:
@@ -20,6 +20,9 @@ import static android.view.WindowManager.TRANSIT_CHANGE;
|
|||||||
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
|
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
|
||||||
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
|
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
|
||||||
|
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -42,7 +45,6 @@ import com.android.wm.shell.transition.Transitions;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
/** To run the ActivityEmbedding animations. */
|
/** To run the ActivityEmbedding animations. */
|
||||||
class ActivityEmbeddingAnimationRunner {
|
class ActivityEmbeddingAnimationRunner {
|
||||||
@@ -85,7 +87,7 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
@NonNull Runnable animationFinishCallback) {
|
@NonNull Runnable animationFinishCallback) {
|
||||||
final List<ActivityEmbeddingAnimationAdapter> adapters =
|
final List<ActivityEmbeddingAnimationAdapter> adapters =
|
||||||
createAnimationAdapters(info, startTransaction);
|
createAnimationAdapters(info, startTransaction, finishTransaction);
|
||||||
long duration = 0;
|
long duration = 0;
|
||||||
for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
|
for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
|
||||||
duration = Math.max(duration, adapter.getDurationHint());
|
duration = Math.max(duration, adapter.getDurationHint());
|
||||||
@@ -129,7 +131,8 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<ActivityEmbeddingAnimationAdapter> createAnimationAdapters(
|
private List<ActivityEmbeddingAnimationAdapter> createAnimationAdapters(
|
||||||
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) {
|
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
|
||||||
|
@NonNull SurfaceControl.Transaction finishTransaction) {
|
||||||
boolean isChangeTransition = false;
|
boolean isChangeTransition = false;
|
||||||
for (TransitionInfo.Change change : info.getChanges()) {
|
for (TransitionInfo.Change change : info.getChanges()) {
|
||||||
if (change.hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW)) {
|
if (change.hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW)) {
|
||||||
@@ -145,23 +148,25 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
return createChangeAnimationAdapters(info, startTransaction);
|
return createChangeAnimationAdapters(info, startTransaction);
|
||||||
}
|
}
|
||||||
if (Transitions.isClosingType(info.getType())) {
|
if (Transitions.isClosingType(info.getType())) {
|
||||||
return createCloseAnimationAdapters(info);
|
return createCloseAnimationAdapters(info, startTransaction, finishTransaction);
|
||||||
}
|
}
|
||||||
return createOpenAnimationAdapters(info);
|
return createOpenAnimationAdapters(info, startTransaction, finishTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<ActivityEmbeddingAnimationAdapter> createOpenAnimationAdapters(
|
private List<ActivityEmbeddingAnimationAdapter> createOpenAnimationAdapters(
|
||||||
@NonNull TransitionInfo info) {
|
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
|
||||||
return createOpenCloseAnimationAdapters(info, true /* isOpening */,
|
@NonNull SurfaceControl.Transaction finishTransaction) {
|
||||||
mAnimationSpec::loadOpenAnimation);
|
return createOpenCloseAnimationAdapters(info, startTransaction, finishTransaction,
|
||||||
|
true /* isOpening */, mAnimationSpec::loadOpenAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<ActivityEmbeddingAnimationAdapter> createCloseAnimationAdapters(
|
private List<ActivityEmbeddingAnimationAdapter> createCloseAnimationAdapters(
|
||||||
@NonNull TransitionInfo info) {
|
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
|
||||||
return createOpenCloseAnimationAdapters(info, false /* isOpening */,
|
@NonNull SurfaceControl.Transaction finishTransaction) {
|
||||||
mAnimationSpec::loadCloseAnimation);
|
return createOpenCloseAnimationAdapters(info, startTransaction, finishTransaction,
|
||||||
|
false /* isOpening */, mAnimationSpec::loadCloseAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,8 +175,9 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<ActivityEmbeddingAnimationAdapter> createOpenCloseAnimationAdapters(
|
private List<ActivityEmbeddingAnimationAdapter> createOpenCloseAnimationAdapters(
|
||||||
@NonNull TransitionInfo info, boolean isOpening,
|
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
|
||||||
@NonNull BiFunction<TransitionInfo.Change, Rect, Animation> animationProvider) {
|
@NonNull SurfaceControl.Transaction finishTransaction, boolean isOpening,
|
||||||
|
@NonNull AnimationProvider animationProvider) {
|
||||||
// We need to know if the change window is only a partial of the whole animation screen.
|
// We need to know if the change window is only a partial of the whole animation screen.
|
||||||
// If so, we will need to adjust it to make the whole animation screen looks like one.
|
// If so, we will need to adjust it to make the whole animation screen looks like one.
|
||||||
final List<TransitionInfo.Change> openingChanges = new ArrayList<>();
|
final List<TransitionInfo.Change> openingChanges = new ArrayList<>();
|
||||||
@@ -194,7 +200,8 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
final List<ActivityEmbeddingAnimationAdapter> adapters = new ArrayList<>();
|
final List<ActivityEmbeddingAnimationAdapter> adapters = new ArrayList<>();
|
||||||
for (TransitionInfo.Change change : openingChanges) {
|
for (TransitionInfo.Change change : openingChanges) {
|
||||||
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
|
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
|
||||||
change, animationProvider, openingWholeScreenBounds);
|
info, change, startTransaction, finishTransaction, animationProvider,
|
||||||
|
openingWholeScreenBounds);
|
||||||
if (isOpening) {
|
if (isOpening) {
|
||||||
adapter.overrideLayer(offsetLayer++);
|
adapter.overrideLayer(offsetLayer++);
|
||||||
}
|
}
|
||||||
@@ -202,7 +209,8 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
}
|
}
|
||||||
for (TransitionInfo.Change change : closingChanges) {
|
for (TransitionInfo.Change change : closingChanges) {
|
||||||
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
|
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
|
||||||
change, animationProvider, closingWholeScreenBounds);
|
info, change, startTransaction, finishTransaction, animationProvider,
|
||||||
|
closingWholeScreenBounds);
|
||||||
if (!isOpening) {
|
if (!isOpening) {
|
||||||
adapter.overrideLayer(offsetLayer++);
|
adapter.overrideLayer(offsetLayer++);
|
||||||
}
|
}
|
||||||
@@ -213,10 +221,18 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private ActivityEmbeddingAnimationAdapter createOpenCloseAnimationAdapter(
|
private ActivityEmbeddingAnimationAdapter createOpenCloseAnimationAdapter(
|
||||||
@NonNull TransitionInfo.Change change,
|
@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
|
||||||
@NonNull BiFunction<TransitionInfo.Change, Rect, Animation> animationProvider,
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
@NonNull Rect wholeAnimationBounds) {
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
final Animation animation = animationProvider.apply(change, wholeAnimationBounds);
|
@NonNull AnimationProvider animationProvider, @NonNull Rect wholeAnimationBounds) {
|
||||||
|
final Animation animation = animationProvider.get(info, change, wholeAnimationBounds);
|
||||||
|
// We may want to show a background color for open/close transition.
|
||||||
|
final int backgroundColor = getTransitionBackgroundColorIfSet(info, change, animation,
|
||||||
|
0 /* defaultColor */);
|
||||||
|
if (backgroundColor != 0) {
|
||||||
|
addBackgroundToTransition(info.getRootLeash(), backgroundColor, startTransaction,
|
||||||
|
finishTransaction);
|
||||||
|
}
|
||||||
return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(),
|
return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(),
|
||||||
wholeAnimationBounds);
|
wholeAnimationBounds);
|
||||||
}
|
}
|
||||||
@@ -322,4 +338,10 @@ class ActivityEmbeddingAnimationRunner {
|
|||||||
return ScreenshotUtils.takeScreenshot(t, screenshotChange.getLeash(),
|
return ScreenshotUtils.takeScreenshot(t, screenshotChange.getLeash(),
|
||||||
animationChange.getLeash(), cropBounds, Integer.MAX_VALUE);
|
animationChange.getLeash(), cropBounds, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** To provide an {@link Animation} based on the transition infos. */
|
||||||
|
private interface AnimationProvider {
|
||||||
|
Animation get(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
|
||||||
|
@NonNull Rect animationBounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package com.android.wm.shell.activityembedding;
|
package com.android.wm.shell.activityembedding;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -33,7 +36,6 @@ import android.window.TransitionInfo;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.internal.R;
|
|
||||||
import com.android.internal.policy.TransitionAnimation;
|
import com.android.internal.policy.TransitionAnimation;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
@@ -175,16 +177,20 @@ class ActivityEmbeddingAnimationSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Animation loadOpenAnimation(@NonNull TransitionInfo.Change change,
|
Animation loadOpenAnimation(@NonNull TransitionInfo info,
|
||||||
@NonNull Rect wholeAnimationBounds) {
|
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
|
||||||
final boolean isEnter = Transitions.isOpeningType(change.getMode());
|
final boolean isEnter = Transitions.isOpeningType(change.getMode());
|
||||||
final Animation animation;
|
final Animation animation;
|
||||||
// TODO(b/207070762):
|
// TODO(b/207070762): Implement edgeExtension version
|
||||||
// 1. Implement clearTop version: R.anim.task_fragment_clear_top_close_enter/exit
|
if (shouldShowBackdrop(info, change)) {
|
||||||
// 2. Implement edgeExtension version
|
|
||||||
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
||||||
? R.anim.task_fragment_open_enter
|
? com.android.internal.R.anim.task_fragment_clear_top_open_enter
|
||||||
: R.anim.task_fragment_open_exit);
|
: com.android.internal.R.anim.task_fragment_clear_top_open_exit);
|
||||||
|
} else {
|
||||||
|
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
||||||
|
? com.android.internal.R.anim.task_fragment_open_enter
|
||||||
|
: com.android.internal.R.anim.task_fragment_open_exit);
|
||||||
|
}
|
||||||
// Use the whole animation bounds instead of the change bounds, so that when multiple change
|
// Use the whole animation bounds instead of the change bounds, so that when multiple change
|
||||||
// targets are opening at the same time, the animation applied to each will be the same.
|
// targets are opening at the same time, the animation applied to each will be the same.
|
||||||
// Otherwise, we may see gap between the activities that are launching together.
|
// Otherwise, we may see gap between the activities that are launching together.
|
||||||
@@ -195,16 +201,20 @@ class ActivityEmbeddingAnimationSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Animation loadCloseAnimation(@NonNull TransitionInfo.Change change,
|
Animation loadCloseAnimation(@NonNull TransitionInfo info,
|
||||||
@NonNull Rect wholeAnimationBounds) {
|
@NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
|
||||||
final boolean isEnter = Transitions.isOpeningType(change.getMode());
|
final boolean isEnter = Transitions.isOpeningType(change.getMode());
|
||||||
final Animation animation;
|
final Animation animation;
|
||||||
// TODO(b/207070762):
|
// TODO(b/207070762): Implement edgeExtension version
|
||||||
// 1. Implement clearTop version: R.anim.task_fragment_clear_top_close_enter/exit
|
if (shouldShowBackdrop(info, change)) {
|
||||||
// 2. Implement edgeExtension version
|
|
||||||
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
||||||
? R.anim.task_fragment_close_enter
|
? com.android.internal.R.anim.task_fragment_clear_top_close_enter
|
||||||
: R.anim.task_fragment_close_exit);
|
: com.android.internal.R.anim.task_fragment_clear_top_close_exit);
|
||||||
|
} else {
|
||||||
|
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
|
||||||
|
? com.android.internal.R.anim.task_fragment_close_enter
|
||||||
|
: com.android.internal.R.anim.task_fragment_close_exit);
|
||||||
|
}
|
||||||
// Use the whole animation bounds instead of the change bounds, so that when multiple change
|
// Use the whole animation bounds instead of the change bounds, so that when multiple change
|
||||||
// targets are closing at the same time, the animation applied to each will be the same.
|
// targets are closing at the same time, the animation applied to each will be the same.
|
||||||
// Otherwise, we may see gap between the activities that are finishing together.
|
// Otherwise, we may see gap between the activities that are finishing together.
|
||||||
@@ -213,4 +223,11 @@ class ActivityEmbeddingAnimationSpec {
|
|||||||
animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
|
animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
|
||||||
return animation;
|
return animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldShowBackdrop(@NonNull TransitionInfo info,
|
||||||
|
@NonNull TransitionInfo.Change change) {
|
||||||
|
final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE,
|
||||||
|
mTransitionAnimation);
|
||||||
|
return a != null && a.getShowBackdrop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,11 @@ package com.android.wm.shell.transition;
|
|||||||
|
|
||||||
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
|
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
|
||||||
import static android.app.ActivityOptions.ANIM_CUSTOM;
|
import static android.app.ActivityOptions.ANIM_CUSTOM;
|
||||||
import static android.app.ActivityOptions.ANIM_FROM_STYLE;
|
|
||||||
import static android.app.ActivityOptions.ANIM_NONE;
|
import static android.app.ActivityOptions.ANIM_NONE;
|
||||||
import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
|
import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
|
||||||
import static android.app.ActivityOptions.ANIM_SCALE_UP;
|
import static android.app.ActivityOptions.ANIM_SCALE_UP;
|
||||||
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
|
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
|
||||||
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
|
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||||
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
||||||
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
|
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
|
||||||
@@ -43,7 +41,6 @@ import static android.view.WindowManager.TRANSIT_OPEN;
|
|||||||
import static android.view.WindowManager.TRANSIT_RELAUNCH;
|
import static android.view.WindowManager.TRANSIT_RELAUNCH;
|
||||||
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
import static android.view.WindowManager.transitTypeToString;
|
|
||||||
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
|
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
|
||||||
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
|
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
|
||||||
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
|
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
|
||||||
@@ -59,6 +56,10 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
|
|||||||
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
|
||||||
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
|
||||||
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
|
||||||
|
import static com.android.wm.shell.transition.TransitionAnimationHelper.sDisableCustomTaskAnimationProperty;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@@ -74,7 +75,6 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
@@ -84,7 +84,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.SystemProperties;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.view.Choreographer;
|
import android.view.Choreographer;
|
||||||
@@ -122,21 +121,6 @@ import java.util.function.Consumer;
|
|||||||
public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
||||||
private static final int MAX_ANIMATION_DURATION = 3000;
|
private static final int MAX_ANIMATION_DURATION = 3000;
|
||||||
|
|
||||||
/**
|
|
||||||
* Restrict ability of activities overriding transition animation in a way such that
|
|
||||||
* an activity can do it only when the transition happens within a same task.
|
|
||||||
*
|
|
||||||
* @see android.app.Activity#overridePendingTransition(int, int)
|
|
||||||
*/
|
|
||||||
private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
|
|
||||||
"persist.wm.disable_custom_task_animation";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
|
|
||||||
*/
|
|
||||||
static boolean sDisableCustomTaskAnimationProperty =
|
|
||||||
SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true);
|
|
||||||
|
|
||||||
private final TransactionPool mTransactionPool;
|
private final TransactionPool mTransactionPool;
|
||||||
private final DisplayController mDisplayController;
|
private final DisplayController mDisplayController;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -431,22 +415,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
cornerRadius = 0;
|
cornerRadius = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.getShowBackdrop()) {
|
backgroundColorForTransition = getTransitionBackgroundColorIfSet(info, change, a,
|
||||||
if (info.getAnimationOptions().getBackgroundColor() != 0) {
|
backgroundColorForTransition);
|
||||||
// If available use the background color provided through AnimationOptions
|
|
||||||
backgroundColorForTransition =
|
|
||||||
info.getAnimationOptions().getBackgroundColor();
|
|
||||||
} else if (a.getBackdropColor() != 0) {
|
|
||||||
// Otherwise fallback on the background color provided through the animation
|
|
||||||
// definition.
|
|
||||||
backgroundColorForTransition = a.getBackdropColor();
|
|
||||||
} else if (change.getBackgroundColor() != 0) {
|
|
||||||
// Otherwise default to the window's background color if provided through
|
|
||||||
// the theme as the background color for the animation - the top most window
|
|
||||||
// with a valid background color and showBackground set takes precedence.
|
|
||||||
backgroundColorForTransition = change.getBackgroundColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean delayedEdgeExtension = false;
|
boolean delayedEdgeExtension = false;
|
||||||
if (!isTask && a.hasExtension()) {
|
if (!isTask && a.hasExtension()) {
|
||||||
@@ -668,29 +638,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
return edgeExtensionLayer;
|
return edgeExtensionLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBackgroundToTransition(
|
|
||||||
@NonNull SurfaceControl rootLeash,
|
|
||||||
@ColorInt int color,
|
|
||||||
@NonNull SurfaceControl.Transaction startTransaction,
|
|
||||||
@NonNull SurfaceControl.Transaction finishTransaction
|
|
||||||
) {
|
|
||||||
final Color bgColor = Color.valueOf(color);
|
|
||||||
final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() };
|
|
||||||
|
|
||||||
final SurfaceControl animationBackgroundSurface = new SurfaceControl.Builder()
|
|
||||||
.setName("Animation Background")
|
|
||||||
.setParent(rootLeash)
|
|
||||||
.setColorLayer()
|
|
||||||
.setOpaque(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
startTransaction
|
|
||||||
.setLayer(animationBackgroundSurface, Integer.MIN_VALUE)
|
|
||||||
.setColor(animationBackgroundSurface, colorArray)
|
|
||||||
.show(animationBackgroundSurface);
|
|
||||||
finishTransaction.remove(animationBackgroundSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
|
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
|
||||||
@@ -704,9 +651,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Animation loadAnimation(TransitionInfo info, TransitionInfo.Change change,
|
private Animation loadAnimation(@NonNull TransitionInfo info,
|
||||||
int wallpaperTransit) {
|
@NonNull TransitionInfo.Change change, int wallpaperTransit) {
|
||||||
Animation a = null;
|
Animation a;
|
||||||
|
|
||||||
final int type = info.getType();
|
final int type = info.getType();
|
||||||
final int flags = info.getFlags();
|
final int flags = info.getFlags();
|
||||||
@@ -717,12 +664,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
final boolean isTask = change.getTaskInfo() != null;
|
final boolean isTask = change.getTaskInfo() != null;
|
||||||
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
|
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
|
||||||
final int overrideType = options != null ? options.getType() : ANIM_NONE;
|
final int overrideType = options != null ? options.getType() : ANIM_NONE;
|
||||||
final boolean canCustomContainer = isTask ? !sDisableCustomTaskAnimationProperty : true;
|
final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty;
|
||||||
final Rect endBounds = Transitions.isClosingType(changeMode)
|
final Rect endBounds = Transitions.isClosingType(changeMode)
|
||||||
? mRotator.getEndBoundsInStartRotation(change)
|
? mRotator.getEndBoundsInStartRotation(change)
|
||||||
: change.getEndAbsBounds();
|
: change.getEndAbsBounds();
|
||||||
final boolean isDream =
|
|
||||||
isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
|
|
||||||
|
|
||||||
if (info.isKeyguardGoingAway()) {
|
if (info.isKeyguardGoingAway()) {
|
||||||
a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
|
a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
|
||||||
@@ -763,87 +708,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
// This received a transferred starting window, so don't animate
|
// This received a transferred starting window, so don't animate
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
int animAttr = 0;
|
a = loadAttributeAnimation(info, change, wallpaperTransit, mTransitionAnimation);
|
||||||
boolean translucent = false;
|
|
||||||
if (isDream) {
|
|
||||||
if (type == TRANSIT_OPEN) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
|
|
||||||
} else if (type == TRANSIT_CLOSE) {
|
|
||||||
animAttr = enter
|
|
||||||
? 0
|
|
||||||
: R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
|
|
||||||
}
|
|
||||||
} else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
|
|
||||||
} else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
|
|
||||||
} else if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
|
|
||||||
} else if (wallpaperTransit == WALLPAPER_TRANSITION_CLOSE) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
|
|
||||||
} else if (type == TRANSIT_OPEN) {
|
|
||||||
// We will translucent open animation for translucent activities and tasks. Choose
|
|
||||||
// WindowAnimation_activityOpenEnterAnimation and set translucent here, then
|
|
||||||
// TransitionAnimation loads appropriate animation later.
|
|
||||||
if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
|
|
||||||
translucent = true;
|
|
||||||
}
|
|
||||||
if (isTask && !translucent) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_taskOpenEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_taskOpenExitAnimation;
|
|
||||||
} else {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_activityOpenEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_activityOpenExitAnimation;
|
|
||||||
}
|
|
||||||
} else if (type == TRANSIT_TO_FRONT) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_taskToFrontEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_taskToFrontExitAnimation;
|
|
||||||
} else if (type == TRANSIT_CLOSE) {
|
|
||||||
if (isTask) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_taskCloseEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_taskCloseExitAnimation;
|
|
||||||
} else {
|
|
||||||
if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
|
|
||||||
translucent = true;
|
|
||||||
}
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_activityCloseEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_activityCloseExitAnimation;
|
|
||||||
}
|
|
||||||
} else if (type == TRANSIT_TO_BACK) {
|
|
||||||
animAttr = enter
|
|
||||||
? R.styleable.WindowAnimation_taskToBackEnterAnimation
|
|
||||||
: R.styleable.WindowAnimation_taskToBackExitAnimation;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animAttr != 0) {
|
|
||||||
if (overrideType == ANIM_FROM_STYLE && canCustomContainer) {
|
|
||||||
a = mTransitionAnimation
|
|
||||||
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
|
|
||||||
animAttr, translucent);
|
|
||||||
} else {
|
|
||||||
a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
|
||||||
"loadAnimation: anim=%s animAttr=0x%x type=%s isEntrance=%b", a, animAttr,
|
|
||||||
transitTypeToString(type),
|
|
||||||
enter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.wm.shell.transition;
|
||||||
|
|
||||||
|
import static android.app.ActivityOptions.ANIM_FROM_STYLE;
|
||||||
|
import static android.app.ActivityOptions.ANIM_NONE;
|
||||||
|
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
|
||||||
|
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||||
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
|
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||||
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
|
import static android.view.WindowManager.transitTypeToString;
|
||||||
|
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
|
||||||
|
|
||||||
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
|
||||||
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
|
||||||
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
|
||||||
|
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
|
||||||
|
|
||||||
|
import android.annotation.ColorInt;
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.SystemProperties;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.window.TransitionInfo;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
import com.android.internal.policy.TransitionAnimation;
|
||||||
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
|
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||||
|
|
||||||
|
/** The helper class that provides methods for adding styles to transition animations. */
|
||||||
|
public class TransitionAnimationHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restrict ability of activities overriding transition animation in a way such that
|
||||||
|
* an activity can do it only when the transition happens within a same task.
|
||||||
|
*
|
||||||
|
* @see android.app.Activity#overridePendingTransition(int, int)
|
||||||
|
*/
|
||||||
|
private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
|
||||||
|
"persist.wm.disable_custom_task_animation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
|
||||||
|
*/
|
||||||
|
static final boolean sDisableCustomTaskAnimationProperty =
|
||||||
|
SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true);
|
||||||
|
|
||||||
|
/** Loads the animation that is defined through attribute id for the given transition. */
|
||||||
|
@Nullable
|
||||||
|
public static Animation loadAttributeAnimation(@NonNull TransitionInfo info,
|
||||||
|
@NonNull TransitionInfo.Change change, int wallpaperTransit,
|
||||||
|
@NonNull TransitionAnimation transitionAnimation) {
|
||||||
|
final int type = info.getType();
|
||||||
|
final int changeMode = change.getMode();
|
||||||
|
final int changeFlags = change.getFlags();
|
||||||
|
final boolean enter = Transitions.isOpeningType(changeMode);
|
||||||
|
final boolean isTask = change.getTaskInfo() != null;
|
||||||
|
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
|
||||||
|
final int overrideType = options != null ? options.getType() : ANIM_NONE;
|
||||||
|
final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty;
|
||||||
|
final boolean isDream =
|
||||||
|
isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
|
||||||
|
int animAttr = 0;
|
||||||
|
boolean translucent = false;
|
||||||
|
if (isDream) {
|
||||||
|
if (type == TRANSIT_OPEN) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
|
||||||
|
} else if (type == TRANSIT_CLOSE) {
|
||||||
|
animAttr = enter
|
||||||
|
? 0
|
||||||
|
: R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
|
||||||
|
}
|
||||||
|
} else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
|
||||||
|
} else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
|
||||||
|
} else if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
|
||||||
|
} else if (wallpaperTransit == WALLPAPER_TRANSITION_CLOSE) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
|
||||||
|
} else if (type == TRANSIT_OPEN) {
|
||||||
|
// We will translucent open animation for translucent activities and tasks. Choose
|
||||||
|
// WindowAnimation_activityOpenEnterAnimation and set translucent here, then
|
||||||
|
// TransitionAnimation loads appropriate animation later.
|
||||||
|
if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
|
||||||
|
translucent = true;
|
||||||
|
}
|
||||||
|
if (isTask && !translucent) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_taskOpenEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_taskOpenExitAnimation;
|
||||||
|
} else {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_activityOpenEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_activityOpenExitAnimation;
|
||||||
|
}
|
||||||
|
} else if (type == TRANSIT_TO_FRONT) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_taskToFrontEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_taskToFrontExitAnimation;
|
||||||
|
} else if (type == TRANSIT_CLOSE) {
|
||||||
|
if (isTask) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_taskCloseEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_taskCloseExitAnimation;
|
||||||
|
} else {
|
||||||
|
if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
|
||||||
|
translucent = true;
|
||||||
|
}
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_activityCloseEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_activityCloseExitAnimation;
|
||||||
|
}
|
||||||
|
} else if (type == TRANSIT_TO_BACK) {
|
||||||
|
animAttr = enter
|
||||||
|
? R.styleable.WindowAnimation_taskToBackEnterAnimation
|
||||||
|
: R.styleable.WindowAnimation_taskToBackExitAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Animation a = null;
|
||||||
|
if (animAttr != 0) {
|
||||||
|
if (overrideType == ANIM_FROM_STYLE && canCustomContainer) {
|
||||||
|
a = transitionAnimation
|
||||||
|
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
|
||||||
|
animAttr, translucent);
|
||||||
|
} else {
|
||||||
|
a = transitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||||
|
"loadAnimation: anim=%s animAttr=0x%x type=%s isEntrance=%b", a, animAttr,
|
||||||
|
transitTypeToString(type),
|
||||||
|
enter);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the background {@link ColorInt} for the given transition animation if it is set.
|
||||||
|
*
|
||||||
|
* @param defaultColor {@link ColorInt} to return if there is no background color specified by
|
||||||
|
* the given transition animation.
|
||||||
|
*/
|
||||||
|
@ColorInt
|
||||||
|
public static int getTransitionBackgroundColorIfSet(@NonNull TransitionInfo info,
|
||||||
|
@NonNull TransitionInfo.Change change, @NonNull Animation a,
|
||||||
|
@ColorInt int defaultColor) {
|
||||||
|
if (!a.getShowBackdrop()) {
|
||||||
|
return defaultColor;
|
||||||
|
}
|
||||||
|
if (info.getAnimationOptions() != null
|
||||||
|
&& info.getAnimationOptions().getBackgroundColor() != 0) {
|
||||||
|
// If available use the background color provided through AnimationOptions
|
||||||
|
return info.getAnimationOptions().getBackgroundColor();
|
||||||
|
} else if (a.getBackdropColor() != 0) {
|
||||||
|
// Otherwise fallback on the background color provided through the animation
|
||||||
|
// definition.
|
||||||
|
return a.getBackdropColor();
|
||||||
|
} else if (change.getBackgroundColor() != 0) {
|
||||||
|
// Otherwise default to the window's background color if provided through
|
||||||
|
// the theme as the background color for the animation - the top most window
|
||||||
|
// with a valid background color and showBackground set takes precedence.
|
||||||
|
return change.getBackgroundColor();
|
||||||
|
}
|
||||||
|
return defaultColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given {@code backgroundColor} as the background color to the transition animation.
|
||||||
|
*/
|
||||||
|
public static void addBackgroundToTransition(@NonNull SurfaceControl rootLeash,
|
||||||
|
@ColorInt int backgroundColor, @NonNull SurfaceControl.Transaction startTransaction,
|
||||||
|
@NonNull SurfaceControl.Transaction finishTransaction) {
|
||||||
|
if (backgroundColor == 0) {
|
||||||
|
// No background color.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Color bgColor = Color.valueOf(backgroundColor);
|
||||||
|
final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() };
|
||||||
|
final SurfaceControl animationBackgroundSurface = new SurfaceControl.Builder()
|
||||||
|
.setName("Animation Background")
|
||||||
|
.setParent(rootLeash)
|
||||||
|
.setColorLayer()
|
||||||
|
.setOpaque(true)
|
||||||
|
.build();
|
||||||
|
startTransaction
|
||||||
|
.setLayer(animationBackgroundSurface, Integer.MIN_VALUE)
|
||||||
|
.setColor(animationBackgroundSurface, colorArray)
|
||||||
|
.show(animationBackgroundSurface);
|
||||||
|
finishTransaction.remove(animationBackgroundSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user