Animate cuttout protection
Bug: 145095085
Change-Id: Ida54d4369a2cb8c300cbeb90f0d7f3e4b562be42
Merged-In: Ida54d4369a2cb8c300cbeb90f0d7f3e4b562be42
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 3a8524a..022a254 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -26,8 +26,10 @@
import static com.android.systemui.tuner.TunablePadding.FLAG_START;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.annotation.Dimension;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -869,6 +871,8 @@
public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
RegionInterceptableView {
+ private static final float HIDDEN_CAMERA_PROTECTION_SCALE = 0.5f;
+
private final DisplayInfo mInfo = new DisplayInfo();
private final Paint mPaint = new Paint();
private final List<Rect> mBounds = new ArrayList();
@@ -888,6 +892,8 @@
private int mColor = Color.BLACK;
private boolean mStart;
private int mRotation;
+ private float mCameraProtectionProgress = HIDDEN_CAMERA_PROTECTION_SCALE;
+ private ValueAnimator mCameraProtectionAnimator;
public DisplayCutoutView(Context context, boolean start,
Runnable visibilityChangedListener, ScreenDecorations decorations) {
@@ -928,17 +934,18 @@
getLocationOnScreen(mLocation);
canvas.translate(-mLocation[0], -mLocation[1]);
- if (mShowProtection && !mProtectionRect.isEmpty()) {
- mPaint.setColor(mColor);
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setAntiAlias(true);
- canvas.drawPath(mProtectionPath, mPaint);
- } else if (!mBoundingPath.isEmpty()) {
+ if (!mBoundingPath.isEmpty()) {
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
canvas.drawPath(mBoundingPath, mPaint);
}
+ if (mCameraProtectionProgress > HIDDEN_CAMERA_PROTECTION_SCALE
+ && !mProtectionRect.isEmpty()) {
+ canvas.scale(mCameraProtectionProgress, mCameraProtectionProgress,
+ mProtectionRect.centerX(), mProtectionRect.centerY());
+ canvas.drawPath(mProtectionPath, mPaint);
+ }
}
@Override
@@ -973,8 +980,31 @@
mShowProtection = shouldShow;
updateBoundingPath();
- requestLayout();
- invalidate();
+ // Delay the relayout until the end of the animation when hiding the cutout,
+ // otherwise we'd clip it.
+ if (mShowProtection) {
+ requestLayout();
+ }
+ if (mCameraProtectionAnimator != null) {
+ mCameraProtectionAnimator.cancel();
+ }
+ mCameraProtectionAnimator = ValueAnimator.ofFloat(mCameraProtectionProgress,
+ mShowProtection ? 1.0f : HIDDEN_CAMERA_PROTECTION_SCALE).setDuration(750);
+ mCameraProtectionAnimator.setInterpolator(Interpolators.DECELERATE_QUINT);
+ mCameraProtectionAnimator.addUpdateListener(animation -> {
+ mCameraProtectionProgress = (float) animation.getAnimatedValue();
+ invalidate();
+ });
+ mCameraProtectionAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCameraProtectionAnimator = null;
+ if (!mShowProtection) {
+ requestLayout();
+ }
+ }
+ });
+ mCameraProtectionAnimator.start();
}
private boolean isStart() {