Android Input — 长按分发repeat时间间隔

长按分发超时参数keyRepeatTimeout

  • 0. 概述
  • 1. 流程原理及源码

0. 概述

  Android系统中长按键部分:Linux驱动只是在起初按下时上报个down事件,在抬起后再报个up事件;其中,不会在有按键上报。对长按键的处理是在Android上层的InputDispatcher中,具体实现还未研究;如下是repeat的时间间隔设定地方。有空在对具体机制做分析。

1. 流程原理及源码

  Android 中 repeat 的时间间隔是由长按分发超时参数 keyRepeatTimeout 和 KeyRepeatDelay 控制的,下面结合源码来看具体实现及修改位置。

注:代码基于Android P(9.0)版本

frameworks\native\services\inputflinger\InputDispatcher.cpp

InputDispatcher构造方法,getDispatcherConfiguration

// --- InputDispatcher ---

InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
    mPolicy(policy),
    mPendingEvent(NULL), mLastDropReason(DROP_REASON_NOT_DROPPED),
    mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
    mNextUnblockedEvent(NULL),
    mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
    mLooper = new Looper(false);

    mKeyRepeatState.lastKeyEntry = NULL;

    policy->getDispatcherConfiguration(&mConfig);
}

frameworks\base\services\core\jni\com_android_server_input_InputManagerService.cpp

policy是NativeInputManager,在com_android_server_input_InputManagerService.cpp里面。mServiceObj是Java层的InputManagerService,getKeyRepeatTimeout和getKeyRepeatDelay已经自注释了。

void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
    ATRACE_CALL();
    JNIEnv* env = jniEnv();

    jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
            gServiceClassInfo.getKeyRepeatTimeout);
    if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
        outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
    }

    jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
            gServiceClassInfo.getKeyRepeatDelay);
    if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
        outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
    }
}

frameworks\base\services\core\java\com\android\server\input\InputManagerService.java

InputManagerService中,通过ViewConfiguration去取值

    // Native callback.
    private int getKeyRepeatTimeout() {
        return ViewConfiguration.getKeyRepeatTimeout();
    }

    // Native callback.
    private int getKeyRepeatDelay() {
        return ViewConfiguration.getKeyRepeatDelay();
    }

frameworks\base\core\java\android\view\ViewConfiguration.java

KeyRepeatTimeout是在Settings数据库里面存储的值,默认的DEFAULT_LONG_PRESS_TIMEOUT是500ms。

    /**
     * @return the time before the first key repeat in milliseconds.
     */
    public static int getKeyRepeatTimeout() {
        return getLongPressTimeout();
    }

    /**
     * @return the time between successive key repeats in milliseconds.
     */
    public static int getKeyRepeatDelay() {
        return KEY_REPEAT_DELAY;
    }
    /**
     * Defines the default duration in milliseconds before a press turns into
     * a long press
     */
    private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500;

    /**
     * Defines the time between successive key repeats in milliseconds.
     */
    private static final int KEY_REPEAT_DELAY = 50;
    /**
     * @return the duration in milliseconds before a press turns into
     * a long press
     */
    public static int getLongPressTimeout() {
        return AppGlobals.getIntCoreSetting(Settings.Secure.LONG_PRESS_TIMEOUT,
                DEFAULT_LONG_PRESS_TIMEOUT);
    }

Settings数据库可以参考Android system — settings数据库

  1. 在Settings数据库SettingsProvider初始化的时候DatabaseUtils的loadSecureSettings会从defaults.xml中读取默认值进行赋值。
  2. defaults.xml,改的越小就越快
  3. 原生的数据库字段可能维护有问题,目前使用的DEFAULT_LONG_PRESS_TIMEOUT和KEY_REPEAT_DELAY,修改这两个默认值可直接生效
            loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
                    R.integer.def_long_press_timeout_millis);
    <!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS -->
    <integer name="def_long_press_timeout_millis">200</integer>
<setting id="8" name="long_press_timeout" value="400" package="android" defaultValue="400" defaultSysSet="true" />

你可能感兴趣的:(#,Android,Input,android,java,input)