Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +89 −36 Original line number Diff line number Diff line Loading @@ -826,24 +826,26 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius, @Nullable Rect clipRect, boolean isActivity) { final DefaultAnimationAdapter adapter = new DefaultAnimationAdapter(anim, leash, position, clipRect, cornerRadius, isActivity); buildSurfaceAnimation(animations, anim, finishCallback, pool, mainExecutor, adapter); } /** Builds an animator for the surface and adds it to the `animations` list. */ static void buildSurfaceAnimation(@NonNull ArrayList<Animator> animations, @NonNull Animation anim, @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull AnimationAdapter updateListener) { final SurfaceControl.Transaction transaction = pool.acquire(); updateListener.setTransaction(transaction); final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); final Transformation transformation = new Transformation(); final float[] matrix = new float[9]; // Animation length is already expected to be scaled. va.overrideDurationScale(1.0f); va.setDuration(anim.computeDurationHint()); final ValueAnimator.AnimatorUpdateListener updateListener = animation -> { final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix, position, cornerRadius, clipRect, isActivity); }; va.addUpdateListener(updateListener); final Runnable finisher = () -> { applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix, position, cornerRadius, clipRect, isActivity); updateListener.onAnimationUpdate(va); pool.release(transaction); mainExecutor.execute(() -> { Loading Loading @@ -1007,37 +1009,88 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { || animType == ANIM_FROM_STYLE; } private static void applyTransformation(long time, SurfaceControl.Transaction t, SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix, Point position, float cornerRadius, @Nullable Rect immutableClipRect, /** The animation adapter for buildSurfaceAnimation. */ abstract static class AnimationAdapter implements ValueAnimator.AnimatorUpdateListener { @NonNull final SurfaceControl mLeash; @NonNull SurfaceControl.Transaction mTransaction; private Choreographer mChoreographer; AnimationAdapter(@NonNull SurfaceControl leash) { mLeash = leash; } void setTransaction(@NonNull SurfaceControl.Transaction transaction) { mTransaction = transaction; } @Override public void onAnimationUpdate(@NonNull ValueAnimator animator) { applyTransformation(animator); if (mChoreographer == null) { mChoreographer = Choreographer.getInstance(); } mTransaction.setFrameTimelineVsync(mChoreographer.getVsyncId()); mTransaction.apply(); } abstract void applyTransformation(@NonNull ValueAnimator animator); } private static class DefaultAnimationAdapter extends AnimationAdapter { final Transformation mTransformation = new Transformation(); final float[] mMatrix = new float[9]; @NonNull final Animation mAnim; @Nullable final Point mPosition; @Nullable final Rect mClipRect; final float mCornerRadius; final boolean mIsActivity; DefaultAnimationAdapter(@NonNull Animation anim, @NonNull SurfaceControl leash, @Nullable Point position, @Nullable Rect clipRect, float cornerRadius, boolean isActivity) { tmpTransformation.clear(); anim.getTransformation(time, tmpTransformation); super(leash); mAnim = anim; mPosition = (position != null && (position.x != 0 || position.y != 0)) ? position : null; mClipRect = (clipRect != null && !clipRect.isEmpty()) ? clipRect : null; mCornerRadius = cornerRadius; mIsActivity = isActivity; } @Override void applyTransformation(@NonNull ValueAnimator animator) { final long currentPlayTime = Math.min(animator.getDuration(), animator.getCurrentPlayTime()); final Transformation transformation = mTransformation; final SurfaceControl.Transaction t = mTransaction; final SurfaceControl leash = mLeash; transformation.clear(); mAnim.getTransformation(currentPlayTime, transformation); if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() && anim.getExtensionEdges() != 0x0 && isActivity) { t.setEdgeExtensionEffect(leash, anim.getExtensionEdges()); && mIsActivity && mAnim.getExtensionEdges() != 0) { t.setEdgeExtensionEffect(leash, mAnim.getExtensionEdges()); } if (position != null) { tmpTransformation.getMatrix().postTranslate(position.x, position.y); if (mPosition != null) { transformation.getMatrix().postTranslate(mPosition.x, mPosition.y); } t.setMatrix(leash, tmpTransformation.getMatrix(), matrix); t.setAlpha(leash, tmpTransformation.getAlpha()); t.setMatrix(leash, transformation.getMatrix(), mMatrix); t.setAlpha(leash, transformation.getAlpha()); final Rect clipRect = immutableClipRect == null ? null : new Rect(immutableClipRect); Insets extensionInsets = Insets.min(tmpTransformation.getInsets(), Insets.NONE); if (!extensionInsets.equals(Insets.NONE) && clipRect != null && !clipRect.isEmpty()) { // Clip out any overflowing edge extension if (mClipRect != null) { Rect clipRect = mClipRect; final Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE); if (!extensionInsets.equals(Insets.NONE)) { // Clip out any overflowing edge extension. clipRect = new Rect(mClipRect); clipRect.inset(extensionInsets); t.setCrop(leash, clipRect); } if (anim.hasRoundedCorners() && cornerRadius > 0 && clipRect != null) { // We can only apply rounded corner if a crop is set if (mCornerRadius > 0 && mAnim.hasRoundedCorners()) { // Rounded corner can only be applied if a crop is set. t.setCrop(leash, clipRect); t.setCornerRadius(leash, cornerRadius); t.setCornerRadius(leash, mCornerRadius); } } } t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); t.apply(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +89 −36 Original line number Diff line number Diff line Loading @@ -826,24 +826,26 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius, @Nullable Rect clipRect, boolean isActivity) { final DefaultAnimationAdapter adapter = new DefaultAnimationAdapter(anim, leash, position, clipRect, cornerRadius, isActivity); buildSurfaceAnimation(animations, anim, finishCallback, pool, mainExecutor, adapter); } /** Builds an animator for the surface and adds it to the `animations` list. */ static void buildSurfaceAnimation(@NonNull ArrayList<Animator> animations, @NonNull Animation anim, @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull AnimationAdapter updateListener) { final SurfaceControl.Transaction transaction = pool.acquire(); updateListener.setTransaction(transaction); final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); final Transformation transformation = new Transformation(); final float[] matrix = new float[9]; // Animation length is already expected to be scaled. va.overrideDurationScale(1.0f); va.setDuration(anim.computeDurationHint()); final ValueAnimator.AnimatorUpdateListener updateListener = animation -> { final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix, position, cornerRadius, clipRect, isActivity); }; va.addUpdateListener(updateListener); final Runnable finisher = () -> { applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix, position, cornerRadius, clipRect, isActivity); updateListener.onAnimationUpdate(va); pool.release(transaction); mainExecutor.execute(() -> { Loading Loading @@ -1007,37 +1009,88 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { || animType == ANIM_FROM_STYLE; } private static void applyTransformation(long time, SurfaceControl.Transaction t, SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix, Point position, float cornerRadius, @Nullable Rect immutableClipRect, /** The animation adapter for buildSurfaceAnimation. */ abstract static class AnimationAdapter implements ValueAnimator.AnimatorUpdateListener { @NonNull final SurfaceControl mLeash; @NonNull SurfaceControl.Transaction mTransaction; private Choreographer mChoreographer; AnimationAdapter(@NonNull SurfaceControl leash) { mLeash = leash; } void setTransaction(@NonNull SurfaceControl.Transaction transaction) { mTransaction = transaction; } @Override public void onAnimationUpdate(@NonNull ValueAnimator animator) { applyTransformation(animator); if (mChoreographer == null) { mChoreographer = Choreographer.getInstance(); } mTransaction.setFrameTimelineVsync(mChoreographer.getVsyncId()); mTransaction.apply(); } abstract void applyTransformation(@NonNull ValueAnimator animator); } private static class DefaultAnimationAdapter extends AnimationAdapter { final Transformation mTransformation = new Transformation(); final float[] mMatrix = new float[9]; @NonNull final Animation mAnim; @Nullable final Point mPosition; @Nullable final Rect mClipRect; final float mCornerRadius; final boolean mIsActivity; DefaultAnimationAdapter(@NonNull Animation anim, @NonNull SurfaceControl leash, @Nullable Point position, @Nullable Rect clipRect, float cornerRadius, boolean isActivity) { tmpTransformation.clear(); anim.getTransformation(time, tmpTransformation); super(leash); mAnim = anim; mPosition = (position != null && (position.x != 0 || position.y != 0)) ? position : null; mClipRect = (clipRect != null && !clipRect.isEmpty()) ? clipRect : null; mCornerRadius = cornerRadius; mIsActivity = isActivity; } @Override void applyTransformation(@NonNull ValueAnimator animator) { final long currentPlayTime = Math.min(animator.getDuration(), animator.getCurrentPlayTime()); final Transformation transformation = mTransformation; final SurfaceControl.Transaction t = mTransaction; final SurfaceControl leash = mLeash; transformation.clear(); mAnim.getTransformation(currentPlayTime, transformation); if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() && anim.getExtensionEdges() != 0x0 && isActivity) { t.setEdgeExtensionEffect(leash, anim.getExtensionEdges()); && mIsActivity && mAnim.getExtensionEdges() != 0) { t.setEdgeExtensionEffect(leash, mAnim.getExtensionEdges()); } if (position != null) { tmpTransformation.getMatrix().postTranslate(position.x, position.y); if (mPosition != null) { transformation.getMatrix().postTranslate(mPosition.x, mPosition.y); } t.setMatrix(leash, tmpTransformation.getMatrix(), matrix); t.setAlpha(leash, tmpTransformation.getAlpha()); t.setMatrix(leash, transformation.getMatrix(), mMatrix); t.setAlpha(leash, transformation.getAlpha()); final Rect clipRect = immutableClipRect == null ? null : new Rect(immutableClipRect); Insets extensionInsets = Insets.min(tmpTransformation.getInsets(), Insets.NONE); if (!extensionInsets.equals(Insets.NONE) && clipRect != null && !clipRect.isEmpty()) { // Clip out any overflowing edge extension if (mClipRect != null) { Rect clipRect = mClipRect; final Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE); if (!extensionInsets.equals(Insets.NONE)) { // Clip out any overflowing edge extension. clipRect = new Rect(mClipRect); clipRect.inset(extensionInsets); t.setCrop(leash, clipRect); } if (anim.hasRoundedCorners() && cornerRadius > 0 && clipRect != null) { // We can only apply rounded corner if a crop is set if (mCornerRadius > 0 && mAnim.hasRoundedCorners()) { // Rounded corner can only be applied if a crop is set. t.setCrop(leash, clipRect); t.setCornerRadius(leash, cornerRadius); t.setCornerRadius(leash, mCornerRadius); } } } t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); t.apply(); } }