Loading services/core/java/com/android/server/wm/ActivityRecordInputSink.java +5 −75 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) { Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } } } Loading
services/core/java/com/android/server/wm/ActivityRecordInputSink.java +5 −75 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) { Loading @@ -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) { Loading @@ -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; } Loading @@ -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); } } }