Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4470567b authored by Miranda Kephart's avatar Miranda Kephart Committed by Automerger Merge Worker
Browse files

Merge "Use ConstraintLayout for screenshot UI" into rvc-dev am: 91382f3d

Change-Id: I78bcd94799ce3e06a12f06297ef2b98ebf723cfb
parents 3d721f7d 91382f3d
Loading
Loading
Loading
Loading
+58 −30
Original line number Original line Diff line number Diff line
@@ -14,60 +14,89 @@
  ~ See the License for the specific language governing permissions and
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~ limitations under the License.
  -->
  -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/global_screenshot_frame"
    android:layout_width="match_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/global_screenshot_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@android:color/black"
        android:visibility="gone"/>
    <ImageView
    <ImageView
        android:id="@+id/global_screenshot_actions_background"
        android:id="@+id/global_screenshot_actions_background"
        android:layout_height="400dp"
        android:layout_height="@dimen/global_screenshot_bg_protection_height"
        android:layout_width="match_parent"
        android:layout_width="match_parent"
        android:layout_gravity="bottom|center"
        android:alpha="0.0"
        android:src="@drawable/screenshot_actions_background_protection"
        android:src="@drawable/screenshot_actions_background_protection"
        android:alpha="0"/>
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <ImageView
        android:id="@+id/global_screenshot_actions_container_background"
        android:visibility="gone"
        android:layout_height="0dp"
        android:layout_width="0dp"
        android:elevation="1dp"
        android:background="@drawable/action_chip_container_background"
        android:layout_marginStart="@dimen/screenshot_action_container_margin_horizontal"
        app:layout_constraintBottom_toBottomOf="@+id/global_screenshot_actions_container"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/global_screenshot_actions_container"
        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_actions_container"/>
    <HorizontalScrollView
    <HorizontalScrollView
        android:id="@+id/global_screenshot_actions_container"
        android:id="@+id/global_screenshot_actions_container"
        android:layout_width="wrap_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
        android:elevation="1dp"
        android:fillViewport="true"
        android:layout_marginHorizontal="@dimen/screenshot_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
        android:gravity="center"
        android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
        android:paddingLeft="@dimen/screenshot_action_container_padding_left"
        android:paddingRight="@dimen/screenshot_action_container_padding_right"
        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
        android:visibility="gone"
        android:elevation="1dp"
        android:scrollbars="none"
        android:scrollbars="none"
        android:background="@drawable/action_chip_container_background">
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintWidth_percent="1.0"
        app:layout_constraintWidth_max="wrap"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
        app:layout_constraintEnd_toEndOf="parent">
        <LinearLayout
        <LinearLayout
            android:id="@+id/global_screenshot_actions"
            android:id="@+id/global_screenshot_actions"
            android:layout_width="wrap_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
            android:layout_height="wrap_content"/>
    </HorizontalScrollView>
    </HorizontalScrollView>
    <ImageView
    <ImageView
        android:id="@+id/global_screenshot"
        android:id="@+id/global_screenshot_animated_view"
        android:layout_width="wrap_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:visibility="gone"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:background="@drawable/screenshot_rounded_corners"
        android:adjustViewBounds="true"/>
    <ImageView
        android:id="@+id/global_screenshot_preview"
        android:layout_width="@dimen/global_screenshot_x_scale"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_gravity="center"
        android:layout_marginStart="@dimen/screenshot_offset_x"
        android:layout_marginBottom="@dimen/screenshot_offset_y"
        android:scaleType="fitEnd"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:visibility="gone"
        android:visibility="gone"
        android:background="@drawable/screenshot_rounded_corners"
        android:background="@drawable/screenshot_rounded_corners"
        android:adjustViewBounds="true"
        android:adjustViewBounds="true"
        android:contentDescription="@string/screenshot_preview_description"/>
        android:contentDescription="@string/screenshot_preview_description"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>
    <FrameLayout
    <FrameLayout
        android:id="@+id/global_screenshot_dismiss_button"
        android:id="@+id/global_screenshot_dismiss_button"
        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
        android:elevation="7dp"
        android:elevation="7dp"
        android:visibility="gone"
        android:visibility="gone"
        android:contentDescription="@string/screenshot_dismiss_ui_description">
        android:contentDescription="@string/screenshot_dismiss_ui_description"
        app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview"
        app:layout_constraintEnd_toEndOf="@+id/global_screenshot_preview"
        app:layout_constraintTop_toTopOf="@+id/global_screenshot_preview"
        app:layout_constraintBottom_toTopOf="@+id/global_screenshot_preview">
        <ImageView
        <ImageView
            android:id="@+id/global_screenshot_dismiss_image"
            android:id="@+id/global_screenshot_dismiss_image"
            android:layout_width="match_parent"
            android:layout_width="match_parent"
@@ -79,14 +108,13 @@
        android:id="@+id/global_screenshot_flash"
        android:id="@+id/global_screenshot_flash"
        android:layout_width="match_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_height="match_parent"
        android:src="@android:color/white"
        android:visibility="gone"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:visibility="gone"/>
        android:src="@android:color/white"/>
    <com.android.systemui.screenshot.ScreenshotSelectorView
    <com.android.systemui.screenshot.ScreenshotSelectorView
        android:id="@+id/global_screenshot_selector"
        android:id="@+id/global_screenshot_selector"
        android:layout_width="match_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:visibility="gone"
        android:pointerIcon="crosshair"/>
        android:pointerIcon="crosshair"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
+2 −2
Original line number Original line Diff line number Diff line
@@ -19,11 +19,11 @@
    android:id="@+id/global_screenshot_action_chip"
    android:id="@+id/global_screenshot_action_chip"
    android:layout_width="wrap_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="@dimen/screenshot_action_chip_margin_right"
    android:layout_marginEnd="@dimen/screenshot_action_chip_margin_right"
    android:layout_gravity="center"
    android:layout_gravity="center"
    android:paddingVertical="@dimen/screenshot_action_chip_padding_vertical"
    android:paddingVertical="@dimen/screenshot_action_chip_padding_vertical"
    android:background="@drawable/action_chip_background"
    android:background="@drawable/action_chip_background"
    android:alpha="0"
    android:alpha="0.0"
    android:gravity="center">
    android:gravity="center">
    <ImageView
    <ImageView
        android:id="@+id/screenshot_action_chip_icon"
        android:id="@+id/screenshot_action_chip_icon"
+1 −0
Original line number Original line Diff line number Diff line
@@ -304,6 +304,7 @@
    <!-- The padding on the global screenshot background image -->
    <!-- The padding on the global screenshot background image -->
    <dimen name="global_screenshot_legacy_bg_padding">20dp</dimen>
    <dimen name="global_screenshot_legacy_bg_padding">20dp</dimen>
    <dimen name="global_screenshot_bg_padding">20dp</dimen>
    <dimen name="global_screenshot_bg_padding">20dp</dimen>
    <dimen name="global_screenshot_bg_protection_height">400dp</dimen>
    <dimen name="global_screenshot_x_scale">80dp</dimen>
    <dimen name="global_screenshot_x_scale">80dp</dimen>
    <dimen name="screenshot_preview_elevation">6dp</dimen>
    <dimen name="screenshot_preview_elevation">6dp</dimen>
    <dimen name="screenshot_offset_y">48dp</dimen>
    <dimen name="screenshot_offset_y">48dp</dimen>
+93 −60
Original line number Original line Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.screenshot;
package com.android.systemui.screenshot;


import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;


import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_SCROLLING_ENABLED;
@@ -72,7 +71,6 @@ import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.Toast;
@@ -187,10 +185,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset


    private final View mScreenshotLayout;
    private final View mScreenshotLayout;
    private final ScreenshotSelectorView mScreenshotSelectorView;
    private final ScreenshotSelectorView mScreenshotSelectorView;
    private final ImageView mBackgroundView;
    private final ImageView mScreenshotAnimatedView;
    private final ImageView mScreenshotView;
    private final ImageView mScreenshotPreview;
    private final ImageView mScreenshotFlash;
    private final ImageView mScreenshotFlash;
    private final HorizontalScrollView mActionsContainer;
    private final ImageView mActionsContainerBackground;
    private final FrameLayout mActionsContainer;
    private final LinearLayout mActionsView;
    private final LinearLayout mActionsView;
    private final ImageView mBackgroundProtection;
    private final ImageView mBackgroundProtection;
    private final FrameLayout mDismissButton;
    private final FrameLayout mDismissButton;
@@ -205,8 +204,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset


    private float mScreenshotOffsetXPx;
    private float mScreenshotOffsetXPx;
    private float mScreenshotOffsetYPx;
    private float mScreenshotOffsetYPx;
    private float mScreenshotHeightPx;
    private float mDismissButtonSize;
    private float mCornerSizeX;
    private float mCornerSizeX;
    private float mDismissDeltaY;
    private float mDismissDeltaY;


@@ -244,10 +241,19 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset


        // Inflate the screenshot layout
        // Inflate the screenshot layout
        mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
        mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
        mBackgroundView = mScreenshotLayout.findViewById(R.id.global_screenshot_background);
        mScreenshotAnimatedView =
        mScreenshotView = mScreenshotLayout.findViewById(R.id.global_screenshot);
                mScreenshotLayout.findViewById(R.id.global_screenshot_animated_view);
        mScreenshotView.setClipToOutline(true);
        mScreenshotAnimatedView.setClipToOutline(true);
        mScreenshotView.setOutlineProvider(new ViewOutlineProvider() {
        mScreenshotAnimatedView.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
                        ROUNDED_CORNER_RADIUS * view.getWidth());
            }
        });
        mScreenshotPreview = mScreenshotLayout.findViewById(R.id.global_screenshot_preview);
        mScreenshotPreview.setClipToOutline(true);
        mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            @Override
            public void getOutline(View view, Outline outline) {
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
@@ -255,6 +261,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            }
            }
        });
        });


        mActionsContainerBackground = mScreenshotLayout.findViewById(
                R.id.global_screenshot_actions_container_background);
        mActionsContainer = mScreenshotLayout.findViewById(
        mActionsContainer = mScreenshotLayout.findViewById(
                R.id.global_screenshot_actions_container);
                R.id.global_screenshot_actions_container);
        mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
        mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
@@ -273,9 +281,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        mScreenshotLayout.setFocusable(true);
        mScreenshotLayout.setFocusable(true);
        mScreenshotSelectorView.setFocusable(true);
        mScreenshotSelectorView.setFocusable(true);
        mScreenshotSelectorView.setFocusableInTouchMode(true);
        mScreenshotSelectorView.setFocusableInTouchMode(true);
        mScreenshotView.setPivotX(0);
        mScreenshotAnimatedView.setPivotX(0);
        mScreenshotView.setPivotY(0);
        mScreenshotAnimatedView.setPivotY(0);
        mActionsContainer.setPivotX(0);


        // Setup the window that we are going to use
        // Setup the window that we are going to use
        mWindowLayoutParams = new WindowManager.LayoutParams(
        mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -297,10 +304,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset


        mScreenshotOffsetXPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_x);
        mScreenshotOffsetXPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_x);
        mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
        mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
        mScreenshotHeightPx =
                resources.getDimensionPixelSize(R.dimen.screenshot_action_container_offset_y);
        mDismissButtonSize = resources.getDimensionPixelSize(
                R.dimen.screenshot_dismiss_button_tappable_size);
        mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale);
        mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale);
        mDismissDeltaY = resources.getDimensionPixelSize(R.dimen.screenshot_dismissal_height_delta);
        mDismissDeltaY = resources.getDimensionPixelSize(R.dimen.screenshot_dismissal_height_delta);


@@ -318,7 +321,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        Region touchRegion = new Region();
        Region touchRegion = new Region();


        Rect screenshotRect = new Rect();
        Rect screenshotRect = new Rect();
        mScreenshotView.getBoundsOnScreen(screenshotRect);
        mScreenshotPreview.getBoundsOnScreen(screenshotRect);
        touchRegion.op(screenshotRect, Region.Op.UNION);
        touchRegion.op(screenshotRect, Region.Op.UNION);
        Rect actionsRect = new Rect();
        Rect actionsRect = new Rect();
        mActionsContainer.getBoundsOnScreen(actionsRect);
        mActionsContainer.getBoundsOnScreen(actionsRect);
@@ -469,6 +472,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
     */
     */
    private void dismissScreenshot(String reason, boolean immediate) {
    private void dismissScreenshot(String reason, boolean immediate) {
        Log.v(TAG, "clearing screenshot: " + reason);
        Log.v(TAG, "clearing screenshot: " + reason);
        mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
        mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
        if (!immediate) {
        if (!immediate) {
            mDismissAnimation = createScreenshotDismissAnimation();
            mDismissAnimation = createScreenshotDismissAnimation();
            mDismissAnimation.addListener(new AnimatorListenerAdapter() {
            mDismissAnimation.addListener(new AnimatorListenerAdapter() {
@@ -488,23 +493,23 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        if (mScreenshotLayout.isAttachedToWindow()) {
        if (mScreenshotLayout.isAttachedToWindow()) {
            mWindowManager.removeView(mScreenshotLayout);
            mWindowManager.removeView(mScreenshotLayout);
        }
        }
        mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
        mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);


        // Clear any references to the bitmap
        // Clear any references to the bitmap
        mScreenshotView.setImageBitmap(null);
        mScreenshotPreview.setImageBitmap(null);
        mScreenshotAnimatedView.setImageBitmap(null);
        mActionsContainerBackground.setVisibility(View.GONE);
        mActionsContainer.setVisibility(View.GONE);
        mActionsContainer.setVisibility(View.GONE);
        mBackgroundView.setVisibility(View.GONE);
        mBackgroundProtection.setAlpha(0f);
        mBackgroundProtection.setAlpha(0f);
        mDismissButton.setVisibility(View.GONE);
        mDismissButton.setVisibility(View.GONE);
        mScreenshotView.setVisibility(View.GONE);
        mScreenshotPreview.setVisibility(View.GONE);
        mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
        mScreenshotPreview.setLayerType(View.LAYER_TYPE_NONE, null);
        mScreenshotView.setContentDescription(
        mScreenshotPreview.setContentDescription(
                mContext.getResources().getString(R.string.screenshot_preview_description));
                mContext.getResources().getString(R.string.screenshot_preview_description));
        mScreenshotLayout.setAlpha(1);
        mScreenshotLayout.setAlpha(1);
        mDismissButton.setTranslationY(0);
        mDismissButton.setTranslationY(0);
        mActionsContainer.setTranslationY(0);
        mActionsContainer.setTranslationY(0);
        mScreenshotView.setTranslationY(0);
        mActionsContainerBackground.setTranslationY(0);
        mScreenshotPreview.setTranslationY(0);
    }
    }


    /**
    /**
@@ -514,9 +519,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
     */
     */
    private void reloadAssets() {
    private void reloadAssets() {
        mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel));
        mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel));
        mActionsContainer.setBackground(
        mActionsContainerBackground.setBackground(
                mContext.getDrawable(R.drawable.action_chip_container_background));
                mContext.getDrawable(R.drawable.action_chip_container_background));

    }
    }


    /**
    /**
@@ -558,10 +562,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                    Toast.LENGTH_SHORT).show();
                    Toast.LENGTH_SHORT).show();
        }
        }



        // Add the view for the animation
        mScreenshotView.setImageBitmap(mScreenBitmap);

        mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);
        mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);


        saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
        saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
@@ -600,8 +600,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            // Play the shutter sound to notify that we've taken a screenshot
            // Play the shutter sound to notify that we've taken a screenshot
            mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
            mCameraSound.play(MediaActionSound.SHUTTER_CLICK);


            mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            mScreenshotView.buildLayer();
            mScreenshotPreview.buildLayer();
            mScreenshotAnimation.start();
            mScreenshotAnimation.start();
        });
        });
    }
    }
@@ -609,6 +609,14 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
    private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
    private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
        float cornerScale = mCornerSizeX / (float) width;
        float cornerScale = mCornerSizeX / (float) width;


        mScreenshotAnimatedView.setScaleX(1);
        mScreenshotAnimatedView.setScaleY(1);
        mScreenshotAnimatedView.setX(0);
        mScreenshotAnimatedView.setY(0);

        mScreenshotAnimatedView.setImageBitmap(mScreenBitmap);
        mScreenshotPreview.setImageBitmap(mScreenBitmap);

        AnimatorSet dropInAnimation = new AnimatorSet();
        AnimatorSet dropInAnimation = new AnimatorSet();
        ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
        ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
        flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
        flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
@@ -623,9 +631,16 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
                mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));


        final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
        final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
        final PointF finalPos = new PointF(mScreenshotOffsetXPx + width * cornerScale / 2f,
        float finalX;
                mDisplayMetrics.heightPixels - mScreenshotOffsetYPx
        if (mContext.getResources().getConfiguration().getLayoutDirection()
                        - height * cornerScale / 2f);
                == View.LAYOUT_DIRECTION_LTR) {
            finalX = mScreenshotOffsetXPx + width * cornerScale / 2f;
        } else {
            finalX = width - mScreenshotOffsetXPx - width * cornerScale / 2f;
        }
        float finalY =
                mDisplayMetrics.heightPixels - mScreenshotOffsetYPx - height * cornerScale / 2f;
        final PointF finalPos = new PointF(finalX, finalY);


        ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
        ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
        toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
        toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
@@ -639,30 +654,33 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            if (t < scalePct) {
            if (t < scalePct) {
                float scale = MathUtils.lerp(
                float scale = MathUtils.lerp(
                        1, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct));
                        1, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct));
                mScreenshotView.setScaleX(scale);
                mScreenshotAnimatedView.setScaleX(scale);
                mScreenshotView.setScaleY(scale);
                mScreenshotAnimatedView.setScaleY(scale);
            } else {
            } else {
                mScreenshotView.setScaleX(cornerScale);
                mScreenshotAnimatedView.setScaleX(cornerScale);
                mScreenshotView.setScaleY(cornerScale);
                mScreenshotAnimatedView.setScaleY(cornerScale);
            }
            }


            float currentScaleX = mScreenshotAnimatedView.getScaleX();
            float currentScaleY = mScreenshotAnimatedView.getScaleY();

            if (t < xPositionPct) {
            if (t < xPositionPct) {
                float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
                float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
                        mFastOutSlowIn.getInterpolation(t / xPositionPct));
                        mFastOutSlowIn.getInterpolation(t / xPositionPct));
                mScreenshotView.setX(xCenter - width * mScreenshotView.getScaleX() / 2f);
                mScreenshotAnimatedView.setX(xCenter - width * currentScaleX / 2f);
            } else {
            } else {
                mScreenshotView.setX(finalPos.x - width * mScreenshotView.getScaleX() / 2f);
                mScreenshotAnimatedView.setX(finalPos.x - width * currentScaleX / 2f);
            }
            }
            float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
            float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
                    mFastOutSlowIn.getInterpolation(t));
                    mFastOutSlowIn.getInterpolation(t));
            mScreenshotView.setY(yCenter - height * mScreenshotView.getScaleY() / 2f);
            mScreenshotAnimatedView.setY(yCenter - height * currentScaleY / 2f);
        });
        });


        toCorner.addListener(new AnimatorListenerAdapter() {
        toCorner.addListener(new AnimatorListenerAdapter() {
            @Override
            @Override
            public void onAnimationStart(Animator animation) {
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                super.onAnimationStart(animation);
                mScreenshotView.setVisibility(View.VISIBLE);
                mScreenshotAnimatedView.setVisibility(View.VISIBLE);
            }
            }
        });
        });


@@ -676,15 +694,16 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            @Override
            @Override
            public void onAnimationEnd(Animator animation) {
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                super.onAnimationEnd(animation);
                mScreenshotView.setScaleX(cornerScale);
                mScreenshotAnimatedView.setScaleX(1);
                mScreenshotView.setScaleY(cornerScale);
                mScreenshotAnimatedView.setScaleY(1);
                mScreenshotView.setX(finalPos.x - width * cornerScale / 2f);
                mScreenshotAnimatedView.setX(finalPos.x - width * cornerScale / 2f);
                mScreenshotView.setY(finalPos.y - height * cornerScale / 2f);
                mScreenshotAnimatedView.setY(finalPos.y - height * cornerScale / 2f);
                Rect bounds = new Rect();
                Rect bounds = new Rect();
                mScreenshotView.getBoundsOnScreen(bounds);
                mDismissButton.getBoundsOnScreen(bounds);
                mDismissButton.setX(bounds.right - mDismissButtonSize / 2f);
                mScreenshotAnimatedView.setVisibility(View.GONE);
                mDismissButton.setY(bounds.top - mDismissButtonSize / 2f);
                mScreenshotPreview.setVisibility(View.VISIBLE);
                mDismissButton.setVisibility(View.VISIBLE);
                mDismissButton.setVisibility(View.VISIBLE);
                mScreenshotLayout.forceLayout();
            }
            }
        });
        });


@@ -747,7 +766,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        mActionsView.addView(editChip);
        mActionsView.addView(editChip);
        chips.add(editChip);
        chips.add(editChip);


        mScreenshotView.setOnClickListener(v -> {
        mScreenshotPreview.setOnClickListener(v -> {
            try {
            try {
                imageData.editAction.actionIntent.send();
                imageData.editAction.actionIntent.send();
                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED);
@@ -757,7 +776,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                Log.e(TAG, "Intent cancelled", e);
                Log.e(TAG, "Intent cancelled", e);
            }
            }
        });
        });
        mScreenshotView.setContentDescription(imageData.editAction.title);
        mScreenshotPreview.setContentDescription(imageData.editAction.title);


        if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SCREENSHOT_SCROLLING_ENABLED, false)) {
        if (DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, SCREENSHOT_SCROLLING_ENABLED, false)) {
            ScreenshotActionChip scrollChip = (ScreenshotActionChip) inflater.inflate(
            ScreenshotActionChip scrollChip = (ScreenshotActionChip) inflater.inflate(
@@ -775,20 +794,33 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            chips.add(scrollChip);
            chips.add(scrollChip);
        }
        }


        // remove the margin from the last chip so that it's correctly aligned with the end
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)
                mActionsView.getChildAt(mActionsView.getChildCount() - 1).getLayoutParams();
        params.setMarginEnd(0);

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
        animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
        float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS
        float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS
                / SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS;
                / SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS;
        mActionsContainer.setVisibility(VISIBLE);
        mActionsContainer.setVisibility(View.VISIBLE);
        mActionsContainer.setAlpha(0);
        mActionsContainer.setAlpha(0f);
        mActionsContainerBackground.setAlpha(0f);
        mActionsContainerBackground.setVisibility(View.VISIBLE);

        mActionsContainer.setPivotX(0);
        mActionsContainerBackground.setPivotX(0);


        animator.addUpdateListener(animation -> {
        animator.addUpdateListener(animation -> {
            float t = animation.getAnimatedFraction();
            float t = animation.getAnimatedFraction();
            mBackgroundProtection.setAlpha(t);
            mBackgroundProtection.setAlpha(t);
            mActionsContainer.setAlpha(t < alphaFraction ? t / alphaFraction : 1);
            float containerAlpha = t < alphaFraction ? t / alphaFraction : 1;
            mActionsContainer.setAlpha(containerAlpha);
            mActionsContainerBackground.setAlpha(containerAlpha);
            float containerScale = SCREENSHOT_ACTIONS_START_SCALE_X
            float containerScale = SCREENSHOT_ACTIONS_START_SCALE_X
                    + (t * (1 - SCREENSHOT_ACTIONS_START_SCALE_X));
                    + (t * (1 - SCREENSHOT_ACTIONS_START_SCALE_X));
            mActionsContainer.setScaleX(containerScale);
            mActionsContainer.setScaleX(containerScale);
            mActionsContainerBackground.setScaleX(containerScale);
            for (ScreenshotActionChip chip : chips) {
            for (ScreenshotActionChip chip : chips) {
                chip.setAlpha(t);
                chip.setAlpha(t);
                chip.setScaleX(1 / containerScale); // invert to keep size of children constant
                chip.setScaleX(1 / containerScale); // invert to keep size of children constant
@@ -808,13 +840,14 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1);
        ValueAnimator yAnim = ValueAnimator.ofFloat(0, 1);
        yAnim.setInterpolator(mAccelerateInterpolator);
        yAnim.setInterpolator(mAccelerateInterpolator);
        yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS);
        yAnim.setDuration(SCREENSHOT_DISMISS_Y_DURATION_MS);
        float screenshotStartY = mScreenshotView.getTranslationY();
        float screenshotStartY = mScreenshotPreview.getTranslationY();
        float dismissStartY = mDismissButton.getTranslationY();
        float dismissStartY = mDismissButton.getTranslationY();
        yAnim.addUpdateListener(animation -> {
        yAnim.addUpdateListener(animation -> {
            float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction());
            float yDelta = MathUtils.lerp(0, mDismissDeltaY, animation.getAnimatedFraction());
            mScreenshotView.setTranslationY(screenshotStartY + yDelta);
            mScreenshotPreview.setTranslationY(screenshotStartY + yDelta);
            mDismissButton.setTranslationY(dismissStartY + yDelta);
            mDismissButton.setTranslationY(dismissStartY + yDelta);
            mActionsContainer.setTranslationY(yDelta);
            mActionsContainer.setTranslationY(yDelta);
            mActionsContainerBackground.setTranslationY(yDelta);
        });
        });


        AnimatorSet animSet = new AnimatorSet();
        AnimatorSet animSet = new AnimatorSet();