Merge "Remove screenshot window focus on touch outside." into sc-dev

This commit is contained in:
Matt Casey
2021-06-14 23:01:05 +00:00
committed by Android (Google) Code Review
2 changed files with 58 additions and 27 deletions

View File

@@ -61,7 +61,6 @@ import android.view.Display;
import android.view.DisplayAddress; import android.view.DisplayAddress;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ScrollCaptureResponse; import android.view.ScrollCaptureResponse;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.View; import android.view.View;
@@ -415,18 +414,12 @@ public class ScreenshotController {
public void onDismiss() { public void onDismiss() {
finishDismiss(); finishDismiss();
} }
});
// TODO(159460485): Remove this when focus is handled properly in the system @Override
mScreenshotView.setOnTouchListener((v, event) -> { public void onTouchOutside() {
if (event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) { // TODO(159460485): Remove this when focus is handled properly in the system
if (DEBUG_INPUT) {
Log.d(TAG, "onTouch: ACTION_OUTSIDE");
}
// Once the user touches outside, stop listening for input
setWindowFocusable(false); setWindowFocusable(false);
} }
return false;
}); });
mScreenshotView.setOnKeyListener((v, keyCode, event) -> { mScreenshotView.setOnKeyListener((v, keyCode, event) -> {

View File

@@ -50,11 +50,14 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.graphics.drawable.InsetDrawable; import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
import android.os.Looper;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.MathUtils; import android.util.MathUtils;
import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayCutout; import android.view.DisplayCutout;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -65,6 +68,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
@@ -79,6 +84,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract;
import java.util.ArrayList; import java.util.ArrayList;
@@ -94,6 +100,9 @@ public class ScreenshotView extends FrameLayout implements
void onUserInteraction(); void onUserInteraction();
void onDismiss(); void onDismiss();
/** DOWN motion event was observed outside of the touchable areas of this view. */
void onTouchOutside();
} }
private static final String TAG = logTag(ScreenshotView.class); private static final String TAG = logTag(ScreenshotView.class);
@@ -124,8 +133,6 @@ public class ScreenshotView extends FrameLayout implements
private final AccessibilityManager mAccessibilityManager; private final AccessibilityManager mAccessibilityManager;
private int mNavMode; private int mNavMode;
private int mLeftInset;
private int mRightInset;
private boolean mOrientationPortrait; private boolean mOrientationPortrait;
private boolean mDirectionLTR; private boolean mDirectionLTR;
@@ -152,6 +159,7 @@ public class ScreenshotView extends FrameLayout implements
private boolean mPendingSharedTransition; private boolean mPendingSharedTransition;
private GestureDetector mSwipeDetector; private GestureDetector mSwipeDetector;
private SwipeDismissHandler mSwipeDismissHandler; private SwipeDismissHandler mSwipeDismissHandler;
private InputMonitorCompat mInputMonitor;
private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>(); private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>();
private PendingInteraction mPendingInteraction; private PendingInteraction mPendingInteraction;
@@ -209,6 +217,17 @@ public class ScreenshotView extends FrameLayout implements
}); });
mSwipeDetector.setIsLongpressEnabled(false); mSwipeDetector.setIsLongpressEnabled(false);
mSwipeDismissHandler = new SwipeDismissHandler(); mSwipeDismissHandler = new SwipeDismissHandler();
addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
startInputListening();
}
@Override
public void onViewDetachedFromWindow(View v) {
stopInputListening();
}
});
} }
public void hideScrollChip() { public void hideScrollChip() {
@@ -238,6 +257,10 @@ public class ScreenshotView extends FrameLayout implements
@Override // ViewTreeObserver.OnComputeInternalInsetsListener @Override // ViewTreeObserver.OnComputeInternalInsetsListener
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
inoutInfo.touchableRegion.set(getTouchRegion());
}
private Region getTouchRegion() {
Region touchRegion = new Region(); Region touchRegion = new Region();
final Rect tmpRect = new Rect(); final Rect tmpRect = new Rect();
@@ -251,15 +274,41 @@ public class ScreenshotView extends FrameLayout implements
touchRegion.op(tmpRect, Region.Op.UNION); touchRegion.op(tmpRect, Region.Op.UNION);
if (QuickStepContract.isGesturalMode(mNavMode)) { if (QuickStepContract.isGesturalMode(mNavMode)) {
final WindowManager wm = mContext.getSystemService(WindowManager.class);
final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics();
final Insets gestureInsets = windowMetrics.getWindowInsets().getInsets(
WindowInsets.Type.systemGestures());
// Receive touches in gesture insets such that they don't cause TOUCH_OUTSIDE // Receive touches in gesture insets such that they don't cause TOUCH_OUTSIDE
Rect inset = new Rect(0, 0, mLeftInset, mDisplayMetrics.heightPixels); Rect inset = new Rect(0, 0, gestureInsets.left, mDisplayMetrics.heightPixels);
touchRegion.op(inset, Region.Op.UNION); touchRegion.op(inset, Region.Op.UNION);
inset.set(mDisplayMetrics.widthPixels - mRightInset, 0, mDisplayMetrics.widthPixels, inset.set(mDisplayMetrics.widthPixels - gestureInsets.right, 0,
mDisplayMetrics.heightPixels); mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
touchRegion.op(inset, Region.Op.UNION); touchRegion.op(inset, Region.Op.UNION);
} }
return touchRegion;
}
inoutInfo.touchableRegion.set(touchRegion); private void startInputListening() {
stopInputListening();
mInputMonitor = new InputMonitorCompat("Screenshot", Display.DEFAULT_DISPLAY);
mInputMonitor.getInputReceiver(Looper.getMainLooper(), Choreographer.getInstance(),
ev -> {
if (ev instanceof MotionEvent) {
MotionEvent event = (MotionEvent) ev;
if (event.getActionMasked() == MotionEvent.ACTION_DOWN
&& !getTouchRegion().contains(
(int) event.getRawX(), (int) event.getRawY())) {
mCallbacks.onTouchOutside();
}
}
});
}
private void stopInputListening() {
if (mInputMonitor != null) {
mInputMonitor.dispose();
mInputMonitor = null;
}
} }
@Override // ViewGroup @Override // ViewGroup
@@ -316,17 +365,6 @@ public class ScreenshotView extends FrameLayout implements
mDirectionLTR = mDirectionLTR =
getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
setOnApplyWindowInsetsListener((v, insets) -> {
if (QuickStepContract.isGesturalMode(mNavMode)) {
Insets gestureInsets = insets.getInsets(WindowInsets.Type.systemGestures());
mLeftInset = gestureInsets.left;
mRightInset = gestureInsets.right;
} else {
mLeftInset = mRightInset = 0;
}
return ScreenshotView.this.onApplyWindowInsets(insets);
});
// Get focus so that the key events go to the layout. // Get focus so that the key events go to the layout.
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
requestFocus(); requestFocus();