Use PhoneWindow for screenshots
Bug: 174554386 Bug: 159419046 Fix: 174554386 Test: manual Change-Id: Ie2df84d8650adf6e3d5d4b37b645122983045e92
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user