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

Commit 79bce632 authored by Mark Renouf's avatar Mark Renouf Committed by Android (Google) Code Review
Browse files

Merge "Use PhoneWindow for screenshots"

parents 59fa0874 09f4e926
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -40,18 +40,4 @@
        android:visibility="gone"
        android:pointerIcon="crosshair"/>
    <include layout="@layout/global_screenshot_static"/>
    <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_description">
        <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>
</com.android.systemui.screenshot.ScreenshotView>
+18 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
<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
@@ -62,4 +61,22 @@
        </LinearLayout>
    </HorizontalScrollView>
    <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"
        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"
        android:contentDescription="@string/screenshot_dismiss_description">
        <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>
+38 −17
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.screenshot;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;

import static java.util.Objects.requireNonNull;

@@ -52,7 +54,8 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -60,6 +63,7 @@ import android.widget.Toast;

import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.systemui.R;
import com.android.systemui.util.DeviceConfigProxy;

@@ -147,6 +151,8 @@ public class ScreenshotController {
    private final MediaActionSound mCameraSound;
    private final ScrollCaptureClient mScrollCaptureClient;
    private final DeviceConfigProxy mConfigProxy;
    private final PhoneWindow mWindow;
    private final View mDecorView;

    private final Binder mWindowToken;
    private ScreenshotView mScreenshotView;
@@ -189,13 +195,12 @@ public class ScreenshotController {

        final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class));
        mDisplay = dm.getDisplay(DEFAULT_DISPLAY);
        mContext = context.createDisplayContext(mDisplay);
        mContext = context.createWindowContext(TYPE_SCREENSHOT, null);
        mWindowManager = mContext.getSystemService(WindowManager.class);

        mAccessibilityManager = AccessibilityManager.getInstance(mContext);
        mConfigProxy = configProxy;

        reloadAssets();
        Configuration config = mContext.getResources().getConfiguration();
        mInDarkMode = config.isNightModeActive();
        mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
@@ -204,9 +209,8 @@ public class ScreenshotController {
        mScrollCaptureClient.setHostWindowToken(mWindowToken);

        // Setup the window that we are going to use
        mWindowLayoutParams = new WindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
                WindowManager.LayoutParams.TYPE_SCREENSHOT,
        mWindowLayoutParams = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, 0, 0,
                TYPE_SCREENSHOT,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -217,11 +221,19 @@ public class ScreenshotController {
        mWindowLayoutParams.setTitle("ScreenshotAnimation");
        mWindowLayoutParams.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        mWindowLayoutParams.setFitInsetsTypes(0 /* types */);
        mWindowLayoutParams.token = mWindowToken;
        // This is needed to let touches pass through outside the touchable areas
        mWindowLayoutParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;

        mWindow = new PhoneWindow(mContext);
        mWindow.setWindowManager(mWindowManager, null, null);
        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
        mWindow.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
        mWindow.setBackgroundDrawableResource(android.R.color.transparent);
        mDecorView = mWindow.getDecorView();

        reloadAssets();

        mDisplayMetrics = new DisplayMetrics();
        mDisplay.getRealMetrics(mDisplayMetrics);

@@ -355,11 +367,21 @@ public class ScreenshotController {
     * button and the actions container background, since the buttons are re-inflated on demand.
     */
    private void reloadAssets() {
        boolean wasAttached = mScreenshotView != null && mScreenshotView.isAttachedToWindow();
        boolean wasAttached = mDecorView.isAttachedToWindow();
        if (wasAttached) {
            mWindowManager.removeView(mScreenshotView);
            mWindowManager.removeView(mDecorView);
        }

        // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait
        mWindowLayoutParams.setFitInsetsTypes(
                mOrientationPortrait ? 0 : WindowInsets.Type.displayCutout());

        // ignore system bar insets for the purpose of window layout
        mDecorView.setOnApplyWindowInsetsListener((v, insets) -> v.onApplyWindowInsets(
                new WindowInsets.Builder(insets)
                        .setInsets(WindowInsets.Type.all(), Insets.NONE)
                        .build()));

        // Inflate the screenshot layout
        mScreenshotView = (ScreenshotView)
                LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null);
@@ -382,9 +404,8 @@ public class ScreenshotController {
            return false;
        });

        if (wasAttached) {
            mWindowManager.addView(mScreenshotView, mWindowLayoutParams);
        }
        // view is added to window manager in startAnimation
        mWindow.setContentView(mScreenshotView, mWindowLayoutParams);
    }

    /**
@@ -510,10 +531,10 @@ public class ScreenshotController {
        mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
        mScreenshotHandler.post(() -> {
            if (!mScreenshotView.isAttachedToWindow()) {
                mWindowManager.addView(mScreenshotView, mWindowLayoutParams);
                mWindowManager.addView(mWindow.getDecorView(), mWindowLayoutParams);
            }

            mScreenshotView.prepareForAnimation(mScreenBitmap, screenRect, screenInsets);
            mScreenshotView.prepareForAnimation(mScreenBitmap, screenInsets);

            mScreenshotHandler.post(() -> {
                mScreenshotView.getViewTreeObserver().addOnComputeInternalInsetsListener(
@@ -541,7 +562,7 @@ public class ScreenshotController {

    private void resetScreenshotView() {
        if (mScreenshotView.isAttachedToWindow()) {
            mWindowManager.removeView(mScreenshotView);
            mWindowManager.removeView(mDecorView);
        }
        mScreenshotView.reset();
        mOnCompleteRunnable.run();
@@ -636,8 +657,8 @@ public class ScreenshotController {
        } else {
            mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        }
        if (mScreenshotView.isAttachedToWindow()) {
            mWindowManager.updateViewLayout(mScreenshotView, mWindowLayoutParams);
        if (mDecorView.isAttachedToWindow()) {
            mWindowManager.updateViewLayout(mDecorView, mWindowLayoutParams);
        }
    }

+6 −4
Original line number Diff line number Diff line
@@ -240,8 +240,7 @@ public class ScreenshotView extends FrameLayout implements

        setOnApplyWindowInsetsListener((v, insets) -> {
            if (QuickStepContract.isGesturalMode(mNavMode)) {
                Insets gestureInsets = insets.getInsets(
                        WindowInsets.Type.systemGestures());
                Insets gestureInsets = insets.getInsets(WindowInsets.Type.systemGestures());
                mLeftInset = gestureInsets.left;
                mRightInset = gestureInsets.right;
            } else {
@@ -272,7 +271,7 @@ public class ScreenshotView extends FrameLayout implements
        mScreenshotSelectorView.requestFocus();
    }

    void prepareForAnimation(Bitmap bitmap, Rect screenRect, Insets screenInsets) {
    void prepareForAnimation(Bitmap bitmap, Insets screenInsets) {
        mScreenshotPreview.setImageDrawable(createScreenDrawable(mResources, bitmap, screenInsets));
        // make static preview invisible (from gone) so we can query its location on screen
        mScreenshotPreview.setVisibility(View.INVISIBLE);
@@ -284,6 +283,8 @@ public class ScreenshotView extends FrameLayout implements

        Rect previewBounds = new Rect();
        mScreenshotPreview.getBoundsOnScreen(previewBounds);
        int[] previewLocation = new int[2];
        mScreenshotPreview.getLocationInWindow(previewLocation);

        float cornerScale =
                mCornerSizeX / (mOrientationPortrait ? bounds.width() : bounds.height());
@@ -310,7 +311,8 @@ public class ScreenshotView extends FrameLayout implements

        // animate from the current location, to the static preview location
        final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
        final PointF finalPos = new PointF(previewBounds.centerX(), previewBounds.centerY());
        final PointF finalPos = new PointF(previewLocation[0] + previewBounds.width() / 2f,
                previewLocation[1] + previewBounds.height() / 2f);

        ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
        toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);