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

Commit 2d0de8e7 authored by Linus Tufvesson's avatar Linus Tufvesson Committed by Automerger Merge Worker
Browse files

Merge "Move touch blocking into InputDispatcher" into tm-dev am: a9abd2bf

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17071217

Change-Id: I64b2e4ce250e3500b263371092b51ee784b9ba92
parents 593ddf9c a9abd2bf
Loading
Loading
Loading
Loading
+5 −75
Original line number Diff line number Diff line
@@ -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);
        }
    }
}