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

Commit 0b612bee authored by Miranda Kephart's avatar Miranda Kephart Committed by Automerger Merge Worker
Browse files

Merge "Fix screenshot UI for insets" into rvc-dev am: f39155c3

Change-Id: I3e6d64b374e8b5c9df7f2403d3a8eae909e1f425
parents 080d4ce3 f39155c3
Loading
Loading
Loading
Loading
+7 −61
Original line number Diff line number Diff line
@@ -14,9 +14,8 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<androidx.constraintlayout.widget.ConstraintLayout
<FrameLayout
    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_height="match_parent">
@@ -24,72 +23,18 @@
        android:id="@+id/global_screenshot_actions_background"
        android:layout_height="@dimen/screenshot_bg_protection_height"
        android:layout_width="match_parent"
        android:layout_gravity="bottom"
        android:alpha="0.0"
        android:src="@drawable/screenshot_actions_background_protection"
        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
        android:id="@+id/global_screenshot_actions_container"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
        android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
        android:elevation="1dp"
        android:scrollbars="none"
        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
            android:id="@+id/global_screenshot_actions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </HorizontalScrollView>
        android:src="@drawable/screenshot_actions_background_protection"/>
    <ImageView
        android:id="@+id/global_screenshot_animated_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone"
        android:elevation="@dimen/screenshot_preview_elevation"
        android:background="@drawable/screenshot_rounded_corners"
        android:adjustViewBounds="true"/>
    <include layout="@layout/global_screenshot_preview"/>
    <FrameLayout
        android:id="@+id/global_screenshot_dismiss_button"
        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
        android:elevation="7dp"
        android:visibility="gone"
        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
            android:id="@+id/global_screenshot_dismiss_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/screenshot_dismiss_button_margin"
            android:src="@drawable/screenshot_cancel"/>
    </FrameLayout>
    <ImageView
        android:id="@+id/global_screenshot_flash"
        android:layout_width="match_parent"
@@ -103,4 +48,5 @@
        android:layout_height="match_parent"
        android:visibility="gone"
        android:pointerIcon="crosshair"/>
</androidx.constraintlayout.widget.ConstraintLayout>
    <include layout="@layout/global_screenshot_static"/>
</FrameLayout>
+84 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2020 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.
  -->
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fitsSystemWindows="true"
    android:layout_width="match_parent"
    android:layout_height="match_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
        android:id="@+id/global_screenshot_actions_container"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/screenshot_action_container_margin_horizontal"
        android:layout_marginBottom="@dimen/screenshot_action_container_offset_y"
        android:paddingHorizontal="@dimen/screenshot_action_container_padding_right"
        android:paddingVertical="@dimen/screenshot_action_container_padding_vertical"
        android:elevation="1dp"
        android:scrollbars="none"
        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
            android:id="@+id/global_screenshot_actions"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </HorizontalScrollView>
    <ImageView
        android:id="@+id/global_screenshot_animated_view"
        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"/>
    <include layout="@layout/global_screenshot_preview"/>
    <FrameLayout
        android:id="@+id/global_screenshot_dismiss_button"
        android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
        android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
        android:elevation="7dp"
        android:visibility="gone"
        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
            android:id="@+id/global_screenshot_dismiss_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/screenshot_dismiss_button_margin"
            android:src="@drawable/screenshot_cancel"/>
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+2 −2
Original line number Diff line number Diff line
@@ -308,11 +308,11 @@
    <dimen name="global_screenshot_x_scale">80dp</dimen>
    <dimen name="screenshot_bg_protection_height">242dp</dimen>
    <dimen name="screenshot_preview_elevation">6dp</dimen>
    <dimen name="screenshot_offset_y">48dp</dimen>
    <dimen name="screenshot_offset_y">32dp</dimen>
    <dimen name="screenshot_offset_x">16dp</dimen>
    <dimen name="screenshot_dismiss_button_tappable_size">48dp</dimen>
    <dimen name="screenshot_dismiss_button_margin">8dp</dimen>
    <dimen name="screenshot_action_container_offset_y">32dp</dimen>
    <dimen name="screenshot_action_container_offset_y">16dp</dimen>
    <dimen name="screenshot_action_container_corner_radius">10dp</dimen>
    <dimen name="screenshot_action_container_padding_vertical">6dp</dimen>
    <dimen name="screenshot_action_container_margin_horizontal">8dp</dimen>
+36 −52
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ import android.util.Slog;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
@@ -212,8 +211,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
    private boolean mDirectionLTR = true;
    private boolean mOrientationPortrait = true;

    private float mScreenshotOffsetXPx;
    private float mScreenshotOffsetYPx;
    private float mCornerSizeX;
    private float mDismissDeltaY;

@@ -273,8 +270,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        mDisplayMetrics = new DisplayMetrics();
        mDisplay.getRealMetrics(mDisplayMetrics);

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

@@ -448,12 +443,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
     * Takes a screenshot of the current display and shows an animation.
     */
    private void takeScreenshot(Consumer<Uri> finisher, Rect crop) {
        // copy the input Rect, since SurfaceControl.screenshot can mutate it
        Rect screenRect = new Rect(crop);
        int rot = mDisplay.getRotation();
        int width = crop.width();
        int height = crop.height();

        Rect screenRect = new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);

        takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect);
    }

@@ -483,12 +477,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset

        onConfigChanged(mContext.getResources().getConfiguration());


        if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
            mDismissAnimation.cancel();
        }
        // Start the post-screenshot animation
        startAnimation(finisher, screenRect.width(), screenRect.height(), screenRect);
        startAnimation(finisher, mScreenBitmap.getWidth(), mScreenBitmap.getHeight(), screenRect);
    }

    void takeScreenshot(Consumer<Uri> finisher, Runnable onComplete) {
@@ -691,8 +684,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
    /**
     * Starts the animation after taking the screenshot
     */
    private void startAnimation(final Consumer<Uri> finisher, int w, int h,
            @Nullable Rect screenRect) {
    private void startAnimation(
            final Consumer<Uri> finisher, int bitmapWidth, int bitmapHeight, Rect screenRect) {
        // If power save is on, show a toast so there is some visual indication that a
        // screenshot has been taken.
        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -700,7 +693,21 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show();
        }

        mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);
        mScreenshotHandler.post(() -> {
            if (!mScreenshotLayout.isAttachedToWindow()) {
                mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
            }
            mScreenshotAnimatedView.setImageBitmap(mScreenBitmap);
            mScreenshotPreview.setImageBitmap(mScreenBitmap);

            // make static preview invisible (from gone) so we can query its location on screen
            mScreenshotPreview.setVisibility(View.INVISIBLE);

            mScreenshotHandler.post(() -> {
                mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);

                mScreenshotAnimation =
                        createScreenshotDropInAnimation(bitmapWidth, bitmapHeight, screenRect);

                saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
                            @Override
@@ -708,13 +715,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                                showUiOnActionsReady(imageData);
                            }
                        });
        mScreenshotHandler.post(() -> {
            if (!mScreenshotLayout.isAttachedToWindow()) {
                mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
            }
            mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);

            mScreenshotHandler.post(() -> {

                // Play the shutter sound to notify that we've taken a screenshot
                mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
@@ -726,18 +726,13 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        });
    }

    private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
        float screenWidth = mDisplayMetrics.widthPixels;
        float screenHeight = mDisplayMetrics.heightPixels;
    private AnimatorSet createScreenshotDropInAnimation(
            int bitmapWidth, int bitmapHeight, Rect bounds) {
        Rect previewBounds = new Rect();
        mScreenshotPreview.getBoundsOnScreen(previewBounds);

        int rotation = mContext.getDisplay().getRotation();
        float cornerScale;
        if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
            cornerScale = (mCornerSizeX /  screenHeight);
        } else {
            cornerScale = (mCornerSizeX / screenWidth);
        }
        float currentScale = width / screenWidth;
        float cornerScale = mCornerSizeX / (mOrientationPortrait ? bitmapWidth : bitmapHeight);
        float currentScale = bounds.height() / (float) bitmapHeight;

        mScreenshotAnimatedView.setScaleX(currentScale);
        mScreenshotAnimatedView.setScaleY(currentScale);
@@ -745,9 +740,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        mScreenshotAnimatedView.setPivotX(0);
        mScreenshotAnimatedView.setPivotY(0);

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

        AnimatorSet dropInAnimation = new AnimatorSet();
        ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
        flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
@@ -761,15 +753,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        flashOutAnimator.addUpdateListener(animation ->
                mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));

        // animate from the current location, to the static preview location
        final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
        float finalX;
        if (mDirectionLTR) {
            finalX = mScreenshotOffsetXPx + screenWidth * cornerScale / 2f;
        } else {
            finalX = screenWidth - mScreenshotOffsetXPx - screenWidth * cornerScale / 2f;
        }
        float finalY = screenHeight - mScreenshotOffsetYPx - screenHeight * cornerScale / 2f;
        final PointF finalPos = new PointF(finalX, finalY);
        final PointF finalPos = new PointF(previewBounds.centerX(), previewBounds.centerY());

        ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
        toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
@@ -795,13 +781,13 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            if (t < xPositionPct) {
                float xCenter = MathUtils.lerp(startPos.x, finalPos.x,
                        mFastOutSlowIn.getInterpolation(t / xPositionPct));
                mScreenshotAnimatedView.setX(xCenter - screenWidth * currentScaleX / 2f);
                mScreenshotAnimatedView.setX(xCenter - bitmapWidth * currentScaleX / 2f);
            } else {
                mScreenshotAnimatedView.setX(finalPos.x - screenWidth * currentScaleX / 2f);
                mScreenshotAnimatedView.setX(finalPos.x - bitmapWidth * currentScaleX / 2f);
            }
            float yCenter = MathUtils.lerp(startPos.y, finalPos.y,
                    mFastOutSlowIn.getInterpolation(t));
            mScreenshotAnimatedView.setY(yCenter - screenHeight * currentScaleY / 2f);
            float yCenter = MathUtils.lerp(
                    startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t));
            mScreenshotAnimatedView.setY(yCenter - bitmapHeight * currentScaleY / 2f);
        });

        toCorner.addListener(new AnimatorListenerAdapter() {
@@ -824,10 +810,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                super.onAnimationEnd(animation);
                mScreenshotAnimatedView.setScaleX(1);
                mScreenshotAnimatedView.setScaleY(1);
                mScreenshotAnimatedView.setX(finalPos.x - width * cornerScale / 2f);
                mScreenshotAnimatedView.setY(finalPos.y - height * cornerScale / 2f);
                Rect bounds = new Rect();
                mDismissButton.getBoundsOnScreen(bounds);
                mScreenshotAnimatedView.setX(finalPos.x - bounds.width() * cornerScale / 2f);
                mScreenshotAnimatedView.setY(finalPos.y - bounds.height() * cornerScale / 2f);
                mScreenshotAnimatedView.setVisibility(View.GONE);
                mScreenshotPreview.setVisibility(View.VISIBLE);
                mDismissButton.setVisibility(View.VISIBLE);