Move touch blocking into InputDispatcher
Remove the InputHandle from ActivityRecordInputSink and instead set NO_INPUT_CHANNEL and let InputDispatcher drop the touches. When touches are blocked InputDispatcher logs something like: 03-04 11:36:46.974 16299 16431 W InputDispatcher: Not sending touch gesture to f619bcf ActivityRecordInputSink .FocusTouchActivity because it is not responsive 03-04 11:36:47.155 16299 16431 W InputDispatcher: Not sending touch gesture to f619bcf ActivityRecordInputSink .FocusTouchActivity because it is not responsive Bug: 194480991 Bug: 222292477 Test: Manually tested that blocking still works Test: atest android.server.wm.WindowUntrustedTouchTest Test: atest InputSurfacesTest Change-Id: If7d9503cb573fbd56f6f9e9eb2dee6298ac1f948
This commit is contained in:
@@ -18,20 +18,11 @@ package com.android.server.wm;
|
||||
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.os.IBinder;
|
||||
import android.os.InputConfig;
|
||||
import android.os.InputConstants;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.util.Slog;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InputEvent;
|
||||
import android.view.InputEventReceiver;
|
||||
import android.view.InputWindowHandle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Creates a InputWindowHandle that catches all touches that would otherwise pass through an
|
||||
@@ -45,20 +36,12 @@ class ActivityRecordInputSink {
|
||||
@ChangeId
|
||||
static final long ENABLE_TOUCH_OPAQUE_ACTIVITIES = 194480991L;
|
||||
|
||||
private static final String TAG = "ActivityRecordInputSink";
|
||||
private static final int NUMBER_OF_TOUCHES_TO_DISABLE = 3;
|
||||
private static final long TOAST_COOL_DOWN_MILLIS = 3000L;
|
||||
|
||||
private final ActivityRecord mActivityRecord;
|
||||
private final boolean mIsCompatEnabled;
|
||||
private final String mName;
|
||||
|
||||
// Hold on to InputEventReceiver to prevent it from getting GCd.
|
||||
private InputEventReceiver mInputEventReceiver;
|
||||
private InputWindowHandleWrapper mInputWindowHandleWrapper;
|
||||
private SurfaceControl mSurfaceControl;
|
||||
private int mRapidTouchCount = 0;
|
||||
private IBinder mToken;
|
||||
private boolean mDisabled = false;
|
||||
|
||||
ActivityRecordInputSink(ActivityRecord activityRecord) {
|
||||
@@ -66,7 +49,7 @@ class ActivityRecordInputSink {
|
||||
mIsCompatEnabled = CompatChanges.isChangeEnabled(ENABLE_TOUCH_OPAQUE_ACTIVITIES,
|
||||
mActivityRecord.getUid());
|
||||
mName = Integer.toHexString(System.identityHashCode(this)) + " ActivityRecordInputSink "
|
||||
+ mActivityRecord.mActivityComponent.getShortClassName();
|
||||
+ mActivityRecord.mActivityComponent.flattenToShortString();
|
||||
}
|
||||
|
||||
public void applyChangesToSurfaceIfChanged(SurfaceControl.Transaction transaction) {
|
||||
@@ -93,16 +76,13 @@ class ActivityRecordInputSink {
|
||||
private InputWindowHandleWrapper getInputWindowHandleWrapper() {
|
||||
if (mInputWindowHandleWrapper == null) {
|
||||
mInputWindowHandleWrapper = new InputWindowHandleWrapper(createInputWindowHandle());
|
||||
InputChannel inputChannel =
|
||||
mActivityRecord.mWmService.mInputManager.createInputChannel(mName);
|
||||
mToken = inputChannel.getToken();
|
||||
mInputEventReceiver = createInputEventReceiver(inputChannel);
|
||||
}
|
||||
if (mDisabled || !mIsCompatEnabled || mActivityRecord.isInTransition()) {
|
||||
// TODO(b/208662670): Investigate if we can have feature active during animations.
|
||||
mInputWindowHandleWrapper.setToken(null);
|
||||
mInputWindowHandleWrapper.setInputConfigMasked(InputConfig.NOT_TOUCHABLE,
|
||||
InputConfig.NOT_TOUCHABLE);
|
||||
} else {
|
||||
mInputWindowHandleWrapper.setToken(mToken);
|
||||
mInputWindowHandleWrapper.setInputConfigMasked(0, InputConfig.NOT_TOUCHABLE);
|
||||
}
|
||||
return mInputWindowHandleWrapper;
|
||||
}
|
||||
@@ -115,58 +95,8 @@ class ActivityRecordInputSink {
|
||||
inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
||||
inputWindowHandle.ownerUid = Process.myUid();
|
||||
inputWindowHandle.ownerPid = Process.myPid();
|
||||
inputWindowHandle.dispatchingTimeoutMillis =
|
||||
InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||
inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
|
||||
inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.NO_INPUT_CHANNEL;
|
||||
return inputWindowHandle;
|
||||
}
|
||||
|
||||
private InputEventReceiver createInputEventReceiver(InputChannel inputChannel) {
|
||||
return new SinkInputEventReceiver(inputChannel,
|
||||
mActivityRecord.mAtmService.mUiHandler.getLooper());
|
||||
}
|
||||
|
||||
private void showAsToastAndLog(String message) {
|
||||
Toast.makeText(mActivityRecord.mAtmService.mUiContext, message,
|
||||
Toast.LENGTH_LONG).show();
|
||||
Slog.wtf(TAG, message + " " + mActivityRecord.mActivityComponent);
|
||||
}
|
||||
|
||||
private class SinkInputEventReceiver extends InputEventReceiver {
|
||||
private long mLastToast = 0;
|
||||
|
||||
SinkInputEventReceiver(InputChannel inputChannel, Looper looper) {
|
||||
super(inputChannel, looper);
|
||||
}
|
||||
|
||||
public void onInputEvent(InputEvent event) {
|
||||
if (!(event instanceof MotionEvent)) {
|
||||
Slog.wtf(TAG,
|
||||
"Received InputEvent that was not a MotionEvent");
|
||||
finishInputEvent(event, true);
|
||||
return;
|
||||
}
|
||||
MotionEvent motionEvent = (MotionEvent) event;
|
||||
if (motionEvent.getAction() != MotionEvent.ACTION_DOWN) {
|
||||
finishInputEvent(event, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getEventTime() - mLastToast > TOAST_COOL_DOWN_MILLIS) {
|
||||
String message = "go/activity-touch-opaque - "
|
||||
+ mActivityRecord.mActivityComponent.getPackageName()
|
||||
+ " blocked the touch!";
|
||||
showAsToastAndLog(message);
|
||||
mLastToast = event.getEventTime();
|
||||
mRapidTouchCount = 1;
|
||||
} else if (++mRapidTouchCount >= NUMBER_OF_TOUCHES_TO_DISABLE && !mDisabled) {
|
||||
// Disable touch blocking until Activity Record is recreated.
|
||||
String message = "Disabled go/activity-touch-opaque - "
|
||||
+ mActivityRecord.mActivityComponent.getPackageName();
|
||||
showAsToastAndLog(message);
|
||||
mDisabled = true;
|
||||
}
|
||||
finishInputEvent(event, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user