Loading libs/WindowManager/Shell/res/drawable/desktop_mode_resize_veil_background.xmldeleted 100644 → 0 +0 −20 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2023 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. --> <shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@android:color/white" /> </shape> libs/WindowManager/Shell/res/layout/desktop_mode_resize_veil.xml +3 −4 Original line number Diff line number Diff line Loading @@ -16,13 +16,12 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/desktop_mode_resize_veil_background"> android:layout_height="match_parent"> <ImageView android:id="@+id/veil_application_icon" android:layout_width="96dp" android:layout_height="96dp" android:layout_width="@dimen/desktop_mode_resize_veil_icon_size" android:layout_height="@dimen/desktop_mode_resize_veil_icon_size" android:layout_gravity="center" android:contentDescription="@string/app_icon_text" /> </FrameLayout> No newline at end of file libs/WindowManager/Shell/res/values/dimen.xml +3 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,9 @@ <!-- The radius of the caption menu shadow. --> <dimen name="desktop_mode_handle_menu_shadow_radius">2dp</dimen> <!-- The size of the icon shown in the resize veil. --> <dimen name="desktop_mode_resize_veil_icon_size">96dp</dimen> <dimen name="freeform_resize_handle">15dp</dimen> <dimen name="freeform_resize_corner">44dp</dimen> Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +1 −1 Original line number Diff line number Diff line Loading @@ -451,7 +451,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * until a resize event calls showResizeVeil below. */ void createResizeVeil() { mResizeVeil = new ResizeVeil(mContext, mAppIconDrawable, mTaskInfo, mResizeVeil = new ResizeVeil(mContext, mAppIconDrawable, mTaskInfo, mTaskSurface, mSurfaceControlBuilderSupplier, mDisplay, mSurfaceControlTransactionSupplier); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java +118 −42 Original line number Diff line number Diff line Loading @@ -23,13 +23,16 @@ import android.annotation.ColorRes; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.Display; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceSession; import android.view.View; import android.view.WindowManager; import android.view.WindowlessWindowManager; Loading @@ -37,6 +40,7 @@ import android.widget.ImageView; import android.window.TaskConstants; import com.android.wm.shell.R; import com.android.wm.shell.common.SurfaceUtils; import java.util.function.Supplier; Loading @@ -45,19 +49,36 @@ import java.util.function.Supplier; */ public class ResizeVeil { private static final int RESIZE_ALPHA_DURATION = 100; private static final int VEIL_CONTAINER_LAYER = TaskConstants.TASK_CHILD_LAYER_RESIZE_VEIL; /** The background is a child of the veil container layer and goes at the bottom. */ private static final int VEIL_BACKGROUND_LAYER = 0; /** The icon is a child of the veil container layer and goes in front of the background. */ private static final int VEIL_ICON_LAYER = 1; private final Context mContext; private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier; private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier; private final SurfaceSession mSurfaceSession = new SurfaceSession(); private final Drawable mAppIcon; private ImageView mIconView; private int mIconSize; private SurfaceControl mParentSurface; /** A container surface to host the veil background and icon child surfaces. */ private SurfaceControl mVeilSurface; /** A color surface for the veil background. */ private SurfaceControl mBackgroundSurface; /** A surface that hosts a windowless window with the app icon. */ private SurfaceControl mIconSurface; private final RunningTaskInfo mTaskInfo; private SurfaceControlViewHost mViewHost; private final Display mDisplay; private ValueAnimator mVeilAnimator; public ResizeVeil(Context context, Drawable appIcon, RunningTaskInfo taskInfo, SurfaceControl taskSurface, Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Display display, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { mContext = context; Loading @@ -65,6 +86,7 @@ public class ResizeVeil { mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier; mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier; mTaskInfo = taskInfo; mParentSurface = taskSurface; mDisplay = display; setupResizeVeil(); } Loading @@ -73,34 +95,44 @@ public class ResizeVeil { * Create the veil in its default invisible state. */ private void setupResizeVeil() { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get(); mVeilSurface = builder mVeilSurface = mSurfaceControlBuilderSupplier.get() .setContainerLayer() .setName("Resize veil of Task=" + mTaskInfo.taskId) .setHidden(true) .setParent(mParentSurface) .setCallsite("ResizeVeil#setupResizeVeil") .build(); mBackgroundSurface = SurfaceUtils.makeColorLayer(mVeilSurface, "Resize veil background of Task=" + mTaskInfo.taskId, mSurfaceSession); mIconSurface = mSurfaceControlBuilderSupplier.get() .setName("Resize veil icon of Task= " + mTaskInfo.taskId) .setContainerLayer() .setParent(mVeilSurface) .setHidden(true) .setCallsite("ResizeVeil#setupResizeVeil") .build(); View v = LayoutInflater.from(mContext) .inflate(R.layout.desktop_mode_resize_veil, null); t.setPosition(mVeilSurface, 0, 0) .setLayer(mVeilSurface, TaskConstants.TASK_CHILD_LAYER_RESIZE_VEIL) .apply(); Rect taskBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); mIconSize = mContext.getResources() .getDimensionPixelSize(R.dimen.desktop_mode_resize_veil_icon_size); final View root = LayoutInflater.from(mContext) .inflate(R.layout.desktop_mode_resize_veil, null /* root */); mIconView = root.findViewById(R.id.veil_application_icon); mIconView.setImageDrawable(mAppIcon); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(taskBounds.width(), taskBounds.height(), new WindowManager.LayoutParams( mIconSize, mIconSize, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); lp.setTitle("Resize veil of Task=" + mTaskInfo.taskId); lp.setTitle("Resize veil icon window of Task=" + mTaskInfo.taskId); lp.setTrustedOverlay(); WindowlessWindowManager windowManager = new WindowlessWindowManager(mTaskInfo.configuration, mVeilSurface, null /* hostInputToken */); mViewHost = new SurfaceControlViewHost(mContext, mDisplay, windowManager, "ResizeVeil"); mViewHost.setView(v, lp); mIconView = mViewHost.getView().findViewById(R.id.veil_application_icon); mIconView.setImageDrawable(mAppIcon); final WindowlessWindowManager wwm = new WindowlessWindowManager(mTaskInfo.configuration, mIconSurface, null /* hostInputToken */); mViewHost = new SurfaceControlViewHost(mContext, mDisplay, wwm, "ResizeVeil"); mViewHost.setView(root, lp); } /** Loading @@ -120,46 +152,74 @@ public class ResizeVeil { mParentSurface = parentSurface; } int backgroundColorId = getBackgroundColorId(); mViewHost.getView().setBackgroundColor(mContext.getColor(backgroundColorId)); t.show(mVeilSurface); t.setLayer(mVeilSurface, VEIL_CONTAINER_LAYER); t.setLayer(mIconSurface, VEIL_ICON_LAYER); t.setLayer(mBackgroundSurface, VEIL_BACKGROUND_LAYER); t.setColor(mBackgroundSurface, Color.valueOf(mContext.getColor(getBackgroundColorId())).getComponents()); relayout(taskBounds, t); if (fadeIn) { cancelAnimation(); final SurfaceControl.Transaction veilAnimT = mSurfaceControlTransactionSupplier.get(); mVeilAnimator = new ValueAnimator(); mVeilAnimator.setFloatValues(0f, 1f); mVeilAnimator.setDuration(RESIZE_ALPHA_DURATION); mVeilAnimator.addUpdateListener(animation -> { t.setAlpha(mVeilSurface, mVeilAnimator.getAnimatedFraction()); t.apply(); veilAnimT.setAlpha(mBackgroundSurface, mVeilAnimator.getAnimatedFraction()); veilAnimT.apply(); }); mVeilAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { veilAnimT.show(mBackgroundSurface) .setAlpha(mBackgroundSurface, 0) .apply(); } @Override public void onAnimationEnd(Animator animation) { t.setAlpha(mVeilSurface, 1); t.apply(); veilAnimT.setAlpha(mBackgroundSurface, 1).apply(); } }); final SurfaceControl.Transaction iconAnimT = mSurfaceControlTransactionSupplier.get(); final ValueAnimator iconAnimator = new ValueAnimator(); iconAnimator.setFloatValues(0f, 1f); iconAnimator.setDuration(RESIZE_ALPHA_DURATION); iconAnimator.addUpdateListener(animation -> { mIconView.setAlpha(animation.getAnimatedFraction()); iconAnimT.setAlpha(mIconSurface, animation.getAnimatedFraction()); iconAnimT.apply(); }); iconAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { iconAnimT.show(mIconSurface) .setAlpha(mIconSurface, 0) .apply(); } @Override public void onAnimationEnd(Animator animation) { iconAnimT.setAlpha(mIconSurface, 1).apply(); } }); // Let the animators show it with the correct alpha value once the animation starts. t.hide(mIconSurface); t.hide(mBackgroundSurface); t.apply(); t.show(mVeilSurface) .addTransactionCommittedListener( mContext.getMainExecutor(), () -> { mVeilAnimator.start(); iconAnimator.start(); }) .setAlpha(mVeilSurface, 0); } else { // Show the veil immediately at full opacity. t.show(mVeilSurface).setAlpha(mVeilSurface, 1); // Show the veil immediately. t.show(mIconSurface); t.show(mBackgroundSurface); t.setAlpha(mIconSurface, 1); t.setAlpha(mBackgroundSurface, 1); t.apply(); } mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t); } /** Loading @@ -175,8 +235,9 @@ public class ResizeVeil { * @param newBounds bounds to update veil to. */ private void relayout(Rect newBounds, SurfaceControl.Transaction t) { mViewHost.relayout(newBounds.width(), newBounds.height()); t.setWindowCrop(mVeilSurface, newBounds.width(), newBounds.height()); final PointF iconPosition = calculateAppIconPosition(newBounds); t.setPosition(mIconSurface, iconPosition.x, iconPosition.y); t.setPosition(mParentSurface, newBounds.left, newBounds.top); t.setWindowCrop(mParentSurface, newBounds.width(), newBounds.height()); } Loading Loading @@ -204,7 +265,7 @@ public class ResizeVeil { mVeilAnimator.end(); } relayout(newBounds, t); mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t); t.apply(); } /** Loading @@ -217,14 +278,16 @@ public class ResizeVeil { mVeilAnimator.setDuration(RESIZE_ALPHA_DURATION); mVeilAnimator.addUpdateListener(animation -> { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); t.setAlpha(mVeilSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.setAlpha(mBackgroundSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.setAlpha(mIconSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.apply(); }); mVeilAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); t.hide(mVeilSurface); t.hide(mBackgroundSurface); t.hide(mIconSurface); t.apply(); } }); Loading @@ -242,6 +305,11 @@ public class ResizeVeil { } } private PointF calculateAppIconPosition(Rect parentBounds) { return new PointF((float) parentBounds.width() / 2 - (float) mIconSize / 2, (float) parentBounds.height() / 2 - (float) mIconSize / 2); } private void cancelAnimation() { if (mVeilAnimator != null) { mVeilAnimator.removeAllUpdateListeners(); Loading @@ -260,11 +328,19 @@ public class ResizeVeil { mViewHost.release(); mViewHost = null; } if (mVeilSurface != null) { final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); if (mBackgroundSurface != null) { t.remove(mBackgroundSurface); mBackgroundSurface = null; } if (mIconSurface != null) { t.remove(mIconSurface); mIconSurface = null; } if (mVeilSurface != null) { t.remove(mVeilSurface); mVeilSurface = null; t.apply(); } t.apply(); } } Loading
libs/WindowManager/Shell/res/drawable/desktop_mode_resize_veil_background.xmldeleted 100644 → 0 +0 −20 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2023 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. --> <shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@android:color/white" /> </shape>
libs/WindowManager/Shell/res/layout/desktop_mode_resize_veil.xml +3 −4 Original line number Diff line number Diff line Loading @@ -16,13 +16,12 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/desktop_mode_resize_veil_background"> android:layout_height="match_parent"> <ImageView android:id="@+id/veil_application_icon" android:layout_width="96dp" android:layout_height="96dp" android:layout_width="@dimen/desktop_mode_resize_veil_icon_size" android:layout_height="@dimen/desktop_mode_resize_veil_icon_size" android:layout_gravity="center" android:contentDescription="@string/app_icon_text" /> </FrameLayout> No newline at end of file
libs/WindowManager/Shell/res/values/dimen.xml +3 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,9 @@ <!-- The radius of the caption menu shadow. --> <dimen name="desktop_mode_handle_menu_shadow_radius">2dp</dimen> <!-- The size of the icon shown in the resize veil. --> <dimen name="desktop_mode_resize_veil_icon_size">96dp</dimen> <dimen name="freeform_resize_handle">15dp</dimen> <dimen name="freeform_resize_corner">44dp</dimen> Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +1 −1 Original line number Diff line number Diff line Loading @@ -451,7 +451,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * until a resize event calls showResizeVeil below. */ void createResizeVeil() { mResizeVeil = new ResizeVeil(mContext, mAppIconDrawable, mTaskInfo, mResizeVeil = new ResizeVeil(mContext, mAppIconDrawable, mTaskInfo, mTaskSurface, mSurfaceControlBuilderSupplier, mDisplay, mSurfaceControlTransactionSupplier); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java +118 −42 Original line number Diff line number Diff line Loading @@ -23,13 +23,16 @@ import android.annotation.ColorRes; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.Display; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceSession; import android.view.View; import android.view.WindowManager; import android.view.WindowlessWindowManager; Loading @@ -37,6 +40,7 @@ import android.widget.ImageView; import android.window.TaskConstants; import com.android.wm.shell.R; import com.android.wm.shell.common.SurfaceUtils; import java.util.function.Supplier; Loading @@ -45,19 +49,36 @@ import java.util.function.Supplier; */ public class ResizeVeil { private static final int RESIZE_ALPHA_DURATION = 100; private static final int VEIL_CONTAINER_LAYER = TaskConstants.TASK_CHILD_LAYER_RESIZE_VEIL; /** The background is a child of the veil container layer and goes at the bottom. */ private static final int VEIL_BACKGROUND_LAYER = 0; /** The icon is a child of the veil container layer and goes in front of the background. */ private static final int VEIL_ICON_LAYER = 1; private final Context mContext; private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier; private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier; private final SurfaceSession mSurfaceSession = new SurfaceSession(); private final Drawable mAppIcon; private ImageView mIconView; private int mIconSize; private SurfaceControl mParentSurface; /** A container surface to host the veil background and icon child surfaces. */ private SurfaceControl mVeilSurface; /** A color surface for the veil background. */ private SurfaceControl mBackgroundSurface; /** A surface that hosts a windowless window with the app icon. */ private SurfaceControl mIconSurface; private final RunningTaskInfo mTaskInfo; private SurfaceControlViewHost mViewHost; private final Display mDisplay; private ValueAnimator mVeilAnimator; public ResizeVeil(Context context, Drawable appIcon, RunningTaskInfo taskInfo, SurfaceControl taskSurface, Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Display display, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { mContext = context; Loading @@ -65,6 +86,7 @@ public class ResizeVeil { mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier; mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier; mTaskInfo = taskInfo; mParentSurface = taskSurface; mDisplay = display; setupResizeVeil(); } Loading @@ -73,34 +95,44 @@ public class ResizeVeil { * Create the veil in its default invisible state. */ private void setupResizeVeil() { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get(); mVeilSurface = builder mVeilSurface = mSurfaceControlBuilderSupplier.get() .setContainerLayer() .setName("Resize veil of Task=" + mTaskInfo.taskId) .setHidden(true) .setParent(mParentSurface) .setCallsite("ResizeVeil#setupResizeVeil") .build(); mBackgroundSurface = SurfaceUtils.makeColorLayer(mVeilSurface, "Resize veil background of Task=" + mTaskInfo.taskId, mSurfaceSession); mIconSurface = mSurfaceControlBuilderSupplier.get() .setName("Resize veil icon of Task= " + mTaskInfo.taskId) .setContainerLayer() .setParent(mVeilSurface) .setHidden(true) .setCallsite("ResizeVeil#setupResizeVeil") .build(); View v = LayoutInflater.from(mContext) .inflate(R.layout.desktop_mode_resize_veil, null); t.setPosition(mVeilSurface, 0, 0) .setLayer(mVeilSurface, TaskConstants.TASK_CHILD_LAYER_RESIZE_VEIL) .apply(); Rect taskBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); mIconSize = mContext.getResources() .getDimensionPixelSize(R.dimen.desktop_mode_resize_veil_icon_size); final View root = LayoutInflater.from(mContext) .inflate(R.layout.desktop_mode_resize_veil, null /* root */); mIconView = root.findViewById(R.id.veil_application_icon); mIconView.setImageDrawable(mAppIcon); final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(taskBounds.width(), taskBounds.height(), new WindowManager.LayoutParams( mIconSize, mIconSize, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); lp.setTitle("Resize veil of Task=" + mTaskInfo.taskId); lp.setTitle("Resize veil icon window of Task=" + mTaskInfo.taskId); lp.setTrustedOverlay(); WindowlessWindowManager windowManager = new WindowlessWindowManager(mTaskInfo.configuration, mVeilSurface, null /* hostInputToken */); mViewHost = new SurfaceControlViewHost(mContext, mDisplay, windowManager, "ResizeVeil"); mViewHost.setView(v, lp); mIconView = mViewHost.getView().findViewById(R.id.veil_application_icon); mIconView.setImageDrawable(mAppIcon); final WindowlessWindowManager wwm = new WindowlessWindowManager(mTaskInfo.configuration, mIconSurface, null /* hostInputToken */); mViewHost = new SurfaceControlViewHost(mContext, mDisplay, wwm, "ResizeVeil"); mViewHost.setView(root, lp); } /** Loading @@ -120,46 +152,74 @@ public class ResizeVeil { mParentSurface = parentSurface; } int backgroundColorId = getBackgroundColorId(); mViewHost.getView().setBackgroundColor(mContext.getColor(backgroundColorId)); t.show(mVeilSurface); t.setLayer(mVeilSurface, VEIL_CONTAINER_LAYER); t.setLayer(mIconSurface, VEIL_ICON_LAYER); t.setLayer(mBackgroundSurface, VEIL_BACKGROUND_LAYER); t.setColor(mBackgroundSurface, Color.valueOf(mContext.getColor(getBackgroundColorId())).getComponents()); relayout(taskBounds, t); if (fadeIn) { cancelAnimation(); final SurfaceControl.Transaction veilAnimT = mSurfaceControlTransactionSupplier.get(); mVeilAnimator = new ValueAnimator(); mVeilAnimator.setFloatValues(0f, 1f); mVeilAnimator.setDuration(RESIZE_ALPHA_DURATION); mVeilAnimator.addUpdateListener(animation -> { t.setAlpha(mVeilSurface, mVeilAnimator.getAnimatedFraction()); t.apply(); veilAnimT.setAlpha(mBackgroundSurface, mVeilAnimator.getAnimatedFraction()); veilAnimT.apply(); }); mVeilAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { veilAnimT.show(mBackgroundSurface) .setAlpha(mBackgroundSurface, 0) .apply(); } @Override public void onAnimationEnd(Animator animation) { t.setAlpha(mVeilSurface, 1); t.apply(); veilAnimT.setAlpha(mBackgroundSurface, 1).apply(); } }); final SurfaceControl.Transaction iconAnimT = mSurfaceControlTransactionSupplier.get(); final ValueAnimator iconAnimator = new ValueAnimator(); iconAnimator.setFloatValues(0f, 1f); iconAnimator.setDuration(RESIZE_ALPHA_DURATION); iconAnimator.addUpdateListener(animation -> { mIconView.setAlpha(animation.getAnimatedFraction()); iconAnimT.setAlpha(mIconSurface, animation.getAnimatedFraction()); iconAnimT.apply(); }); iconAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { iconAnimT.show(mIconSurface) .setAlpha(mIconSurface, 0) .apply(); } @Override public void onAnimationEnd(Animator animation) { iconAnimT.setAlpha(mIconSurface, 1).apply(); } }); // Let the animators show it with the correct alpha value once the animation starts. t.hide(mIconSurface); t.hide(mBackgroundSurface); t.apply(); t.show(mVeilSurface) .addTransactionCommittedListener( mContext.getMainExecutor(), () -> { mVeilAnimator.start(); iconAnimator.start(); }) .setAlpha(mVeilSurface, 0); } else { // Show the veil immediately at full opacity. t.show(mVeilSurface).setAlpha(mVeilSurface, 1); // Show the veil immediately. t.show(mIconSurface); t.show(mBackgroundSurface); t.setAlpha(mIconSurface, 1); t.setAlpha(mBackgroundSurface, 1); t.apply(); } mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t); } /** Loading @@ -175,8 +235,9 @@ public class ResizeVeil { * @param newBounds bounds to update veil to. */ private void relayout(Rect newBounds, SurfaceControl.Transaction t) { mViewHost.relayout(newBounds.width(), newBounds.height()); t.setWindowCrop(mVeilSurface, newBounds.width(), newBounds.height()); final PointF iconPosition = calculateAppIconPosition(newBounds); t.setPosition(mIconSurface, iconPosition.x, iconPosition.y); t.setPosition(mParentSurface, newBounds.left, newBounds.top); t.setWindowCrop(mParentSurface, newBounds.width(), newBounds.height()); } Loading Loading @@ -204,7 +265,7 @@ public class ResizeVeil { mVeilAnimator.end(); } relayout(newBounds, t); mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t); t.apply(); } /** Loading @@ -217,14 +278,16 @@ public class ResizeVeil { mVeilAnimator.setDuration(RESIZE_ALPHA_DURATION); mVeilAnimator.addUpdateListener(animation -> { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); t.setAlpha(mVeilSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.setAlpha(mBackgroundSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.setAlpha(mIconSurface, 1 - mVeilAnimator.getAnimatedFraction()); t.apply(); }); mVeilAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); t.hide(mVeilSurface); t.hide(mBackgroundSurface); t.hide(mIconSurface); t.apply(); } }); Loading @@ -242,6 +305,11 @@ public class ResizeVeil { } } private PointF calculateAppIconPosition(Rect parentBounds) { return new PointF((float) parentBounds.width() / 2 - (float) mIconSize / 2, (float) parentBounds.height() / 2 - (float) mIconSize / 2); } private void cancelAnimation() { if (mVeilAnimator != null) { mVeilAnimator.removeAllUpdateListeners(); Loading @@ -260,11 +328,19 @@ public class ResizeVeil { mViewHost.release(); mViewHost = null; } if (mVeilSurface != null) { final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get(); if (mBackgroundSurface != null) { t.remove(mBackgroundSurface); mBackgroundSurface = null; } if (mIconSurface != null) { t.remove(mIconSurface); mIconSurface = null; } if (mVeilSurface != null) { t.remove(mVeilSurface); mVeilSurface = null; t.apply(); } t.apply(); } }