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

Commit 0d3e32d7 authored by Antonio Kantek's avatar Antonio Kantek
Browse files

(touch-mode-md 1/n) Initialize per display touch mode (base)

Use `config_perDisplayFocusEnabled` to determine
perDisplayTouchModeEnabled. If true, then touch mode will be set per
display (otherwill touch mode switch will be global).

This CL also introduces the displayId parameter when switching touch mode
(implementation to follow in the next incoming CLs).

Bug: 198499018
Test: atest FrameworksCoreTests WindowManagerServiceTests FrameworksServicesTests
Test: atest TouchModeTest
Change-Id: I1ed9bbd8e73a67d4771e2c5d8a9bccfba85240fd
parent d59f2a46
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ public class InputManagerService extends IInputManager.Stub
        }

        NativeInputManagerService getNativeService(InputManagerService service) {
            return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
            return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue());
        }

        void registerLocalService(InputManagerInternal localService) {
@@ -847,10 +847,13 @@ public class InputManagerService extends IInputManager.Stub
     * @param pid           the pid of the process that requested to switch touch mode state
     * @param uid           the uid of the process that requested to switch touch mode state
     * @param hasPermission if set to {@code true} then no further authorization will be performed
     * @param displayId     the target display (ignored if device is configured with per display
     *                      touch mode enabled)
     * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
     */
    public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission) {
        return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission);
    public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
            int displayId) {
        return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission, displayId);
    }

    @Override // Binder call
@@ -3031,6 +3034,13 @@ public class InputManagerService extends IInputManager.Stub
        return names.toArray(new String[0]);
    }

    // Native callback.
    @SuppressWarnings("unused")
    private boolean isPerDisplayTouchModeEnabled() {
        return mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_perDisplayFocusEnabled);
    }

    /**
     * Flatten a map into a string list, with value positioned directly next to the
     * key.
+17 −7
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.input;

import android.content.Context;
import android.hardware.display.DisplayViewport;
import android.hardware.input.InputSensorInfo;
import android.hardware.lights.Light;
@@ -64,7 +63,19 @@ public interface NativeInputManagerService {

    void setInputFilterEnabled(boolean enable);

    boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission);
    /**
     * Set the touch mode state for the display passed as argument.
     *
     * @param inTouchMode   true if the device is in touch mode
     * @param pid           the pid of the process that requested to switch touch mode state
     * @param uid           the uid of the process that requested to switch touch mode state
     * @param hasPermission if set to {@code true} then no further authorization will be performed
     * @param displayId     the target display (ignored if device is configured with per display
     *                      touch mode enabled)
     * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
     */
    boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission,
            int displayId);

    void setMaximumObscuringOpacityForTouch(float opacity);

@@ -194,12 +205,11 @@ public interface NativeInputManagerService {
        @SuppressWarnings({"unused", "FieldCanBeLocal"})
        private final long mPtr;

        NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
            mPtr = init(service, context, messageQueue);
        NativeImpl(InputManagerService service, MessageQueue messageQueue) {
            mPtr = init(service, messageQueue);
        }

        private native long init(InputManagerService service, Context context,
                MessageQueue messageQueue);
        private native long init(InputManagerService service, MessageQueue messageQueue);

        @Override
        public native void start();
@@ -240,7 +250,7 @@ public interface NativeInputManagerService {

        @Override
        public native boolean setInTouchMode(boolean inTouchMode, int pid, int uid,
                boolean hasPermission);
                boolean hasPermission, int displayId);

        @Override
        public native void setMaximumObscuringOpacityForTouch(float opacity);
+5 −2
Original line number Diff line number Diff line
@@ -1201,7 +1201,8 @@ public class WindowManagerService extends IWindowManager.Stub
                com.android.internal.R.bool.config_hasPermanentDpad);
        mInTouchMode = context.getResources().getBoolean(
                com.android.internal.R.bool.config_defaultInTouchMode);
        inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, true /* hasPermission */);
        inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, /* hasPermission= */ true,
                DEFAULT_DISPLAY);
        mDrawLockTimeoutMillis = context.getResources().getInteger(
                com.android.internal.R.integer.config_drawLockTimeoutMillis);
        mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
@@ -3824,7 +3825,9 @@ public class WindowManagerService extends IWindowManager.Stub
                                                      /* printlog= */ false);
            final long token = Binder.clearCallingIdentity();
            try {
                if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission)) {
                // TODO(b/198499018): Add displayId parameter indicating the target display.
                // For now, will just pass DEFAULT_DISPLAY for displayId.
                if (mInputManager.setInTouchMode(mode, pid, uid, hasPermission, DEFAULT_DISPLAY)) {
                    mInTouchMode = mode;
                }
            } finally {
+29 −19
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ static struct {
    jmethodID getContextForDisplay;
    jmethodID notifyDropWindow;
    jmethodID getParentSurfaceForPointers;
    jmethodID isPerDisplayTouchModeEnabled;
} gServiceClassInfo;

static struct {
@@ -265,7 +266,7 @@ protected:
    virtual ~NativeInputManager();

public:
    NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
    NativeInputManager(jobject serviceObj, const sp<Looper>& looper);

    inline sp<InputManagerInterface> getInputManager() const { return mInputManager; }

@@ -355,6 +356,10 @@ public:
    virtual PointerIconStyle getCustomPointerIconId();
    virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos);

    /* --- If touch mode is enabled per display or global --- */

    virtual bool isPerDisplayTouchModeEnabled();

private:
    sp<InputManagerInterface> mInputManager;

@@ -398,23 +403,17 @@ private:
    } mLocked GUARDED_BY(mLock);

    std::atomic<bool> mInteractive;

    void updateInactivityTimeoutLocked();
    void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
    void ensureSpriteControllerLocked();
    sp<SurfaceControl> getParentSurfaceForPointers(int displayId);
    static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);

    static inline JNIEnv* jniEnv() {
        return AndroidRuntime::getJNIEnv();
    }
    static inline JNIEnv* jniEnv() { return AndroidRuntime::getJNIEnv(); }
};



NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper)
      : mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();

    mServiceObj = env->NewGlobalRef(serviceObj);
@@ -429,7 +428,6 @@ NativeInputManager::NativeInputManager(jobject contextObj,
        mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
    }
    mInteractive = true;

    InputManager* im = new InputManager(this, this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
@@ -1488,6 +1486,16 @@ void NativeInputManager::setMotionClassifierEnabled(bool enabled) {
    mInputManager->getClassifier().setMotionClassifierEnabled(enabled);
}

bool NativeInputManager::isPerDisplayTouchModeEnabled() {
    JNIEnv* env = jniEnv();
    jboolean enabled =
            env->CallBooleanMethod(mServiceObj, gServiceClassInfo.isPerDisplayTouchModeEnabled);
    if (checkAndClearExceptionFromCallback(env, "isPerDisplayTouchModeEnabled")) {
        return false;
    }
    return static_cast<bool>(enabled);
}

// ----------------------------------------------------------------------------

static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
@@ -1495,16 +1503,15 @@ static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
            env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr));
}

static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
                        jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == nullptr) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    NativeInputManager* im = new NativeInputManager(serviceObj, messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}
@@ -1677,11 +1684,11 @@ static void nativeSetInputFilterEnabled(JNIEnv* env, jobject nativeImplObj, jboo
}

static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode,
                                     jint pid, jint uid, jboolean hasPermission) {
                                     jint pid, jint uid, jboolean hasPermission, jint displayId) {
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);

    return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid,
                                                                 hasPermission);
                                                                 hasPermission, displayId);
}

static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj,
@@ -2312,7 +2319,7 @@ static void nativeSetPointerDisplayId(JNIEnv* env, jobject nativeImplObj, jint d
static const JNINativeMethod gInputManagerMethods[] = {
        /* name, signature, funcPtr */
        {"init",
         "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
         "(Lcom/android/server/input/InputManagerService;Landroid/os/"
         "MessageQueue;)J",
         (void*)nativeInit},
        {"start", "()V", (void*)nativeStart},
@@ -2330,7 +2337,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
        {"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
        {"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers},
        {"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled},
        {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode},
        {"setInTouchMode", "(ZIIZI)Z", (void*)nativeSetInTouchMode},
        {"setMaximumObscuringOpacityForTouch", "(F)V",
         (void*)nativeSetMaximumObscuringOpacityForTouch},
        {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent},
@@ -2536,6 +2543,9 @@ int register_android_server_InputManager(JNIEnv* env) {
    GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
                  "getParentSurfaceForPointers", "(I)J");

    GET_METHOD_ID(gServiceClassInfo.isPerDisplayTouchModeEnabled, clazz,
                  "isPerDisplayTouchModeEnabled", "()Z");

    // InputDevice

    FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
+4 −2
Original line number Diff line number Diff line
@@ -301,7 +301,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        mWm.setInTouchMode(!currentTouchMode);

        verify(mWm.mInputManager).setInTouchMode(
                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true);
                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ true,
                DEFAULT_DISPLAY);
    }

    @Test
@@ -316,7 +317,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
        mWm.setInTouchMode(!currentTouchMode);

        verify(mWm.mInputManager).setInTouchMode(
                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false);
                !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false,
                DEFAULT_DISPLAY);
    }

    @Test