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

Commit 5c9d2e88 authored by Demon000's avatar Demon000 Committed by Demon Singur
Browse files

ScreenshotSelector: handle rotation issues

Disable rotation while the screenshot selector is visible,
because it cannot handle rotation internally,
and rotating while a certain selection is made might cause
the selection to go off-screen.

Also, adjust the crop coordinates so that they function properly.
The native screenshot taking functions expect the coordinates
to be in a physical left-to-right, top-to-bottom order, which
is not the case for 90 degree rotation, where the top is
actually the right physical edge, or for 270 degree rotation,
where the right is actually the top physical edge, or for
180 degrees, where both axes are flipped.

https://gitlab.com/LineageOS/issues/android/-/issues/1749

Change-Id: I18da90592cf7baa46547554df954bdb071961311
parent aa8afca1
Loading
Loading
Loading
Loading
+47 −7
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ 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;
@@ -814,6 +815,45 @@ class GlobalScreenshot {
        }
    }

    Rect getRotationAdjustedRect(Rect rect) {
        Display defaultDisplay = mWindowManager.getDefaultDisplay();
        Rect adjustedRect = new Rect(rect);

        mDisplay.getRealMetrics(mDisplayMetrics);
        int rotation = defaultDisplay.getRotation();
        switch (rotation) {
            case Surface.ROTATION_0:
                // properly rotated
                break;
            case Surface.ROTATION_90:
                adjustedRect.top = mDisplayMetrics.heightPixels - rect.bottom;
                adjustedRect.bottom = mDisplayMetrics.heightPixels - rect.top;
                break;
            case Surface.ROTATION_180:
                adjustedRect.left = mDisplayMetrics.widthPixels - rect.right;
                adjustedRect.top = mDisplayMetrics.heightPixels - rect.bottom;
                adjustedRect.right = mDisplayMetrics.widthPixels - rect.left;
                adjustedRect.bottom = mDisplayMetrics.heightPixels - rect.top;
                break;
            case Surface.ROTATION_270:
                adjustedRect.left = mDisplayMetrics.widthPixels - rect.right;
                adjustedRect.right = mDisplayMetrics.widthPixels - rect.left;
                break;
            default:
                throw new IllegalArgumentException("Unknown rotation: " + rotation);
        }

        return adjustedRect;
    }

    void setLockedScreenOrientation(boolean locked) {
        if (locked) {
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED;
        } else {
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        }
    }

    /**
     * Displays a screenshot selector
     */
@@ -825,6 +865,7 @@ class GlobalScreenshot {
        }

        setBlockedGesturalNavigation(true);
        setLockedScreenOrientation(true);
        mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
        mScreenshotSelectorView.setSelectionListener(
                new ScreenshotSelectorView.OnSelectionListener() {
@@ -849,7 +890,8 @@ class GlobalScreenshot {
        mCaptureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Rect rect = mScreenshotSelectorView.getSelectionRect();
                Rect rect = mScreenshotSelectorView.getSelectionRect();
                final Rect adjustedRect = getRotationAdjustedRect(rect);
                LayoutTransition layoutTransition = mScreenshotButtonsLayout.getLayoutTransition();
                layoutTransition.addTransitionListener(new TransitionListener() {
                    @Override
@@ -860,7 +902,7 @@ class GlobalScreenshot {
                    @Override
                    public void endTransition(LayoutTransition transition, ViewGroup container,
                            View view, int transitionType) {
                        takeScreenshot(finisher, statusBarVisible, navBarVisible, rect);
                        takeScreenshot(finisher, statusBarVisible, navBarVisible, adjustedRect);
                        transition.removeTransitionListener(this);
                    }
                });
@@ -874,6 +916,7 @@ class GlobalScreenshot {
    }

    void hideScreenshotSelector() {
        setLockedScreenOrientation(false);
        mWindowManager.removeView(mScreenshotLayout);
        mScreenshotSelectorView.stopSelection();
        mScreenshotSelectorView.setVisibility(View.GONE);
@@ -886,12 +929,9 @@ class GlobalScreenshot {
     */
    void stopScreenshot() {
        // If the selector layer still presents on screen, we remove it and resets its state.
        if (mScreenshotSelectorView.getSelectionRect() != null) {
            mWindowManager.removeView(mScreenshotLayout);
            mScreenshotSelectorView.stopSelection();
        if (mScreenshotLayout.getParent() != null) {
            hideScreenshotSelector();
        }

        setBlockedGesturalNavigation(false);
    }

    /**