Android U Input系统 : 创建与启动

2,274 阅读5分钟

Input 系统分为底层和上层两部分,底层主要负责事件的分发,上层负责策略控制以及窗口处理事件。而整个 Input 系统的启动,是由上层的 InputManagerService 触发的。

system_server 进程中,与 InputManagerService 相关的主要操作,如下

// SystemServer.java

// 1. 创建
inputManager = new InputManagerService(context);

// 2. 启动
inputManager.start();

// 3. 就绪
inputManagerF.systemRunning();

创建

// InputManagerService.java

    public InputManagerService(Context context) {
        // 第二参数,使用 display thread looper
        this(new Injector(context, DisplayThread.get().getLooper()));
    }

    InputManagerService(Injector injector) {
        // The static association map is accessed by both java and native code, so it must be
        // initialized before initializing the native service.
        // The associations of input devices to displays by port. Maps from input device port (String)
        // to display id (int). Currently only accessed by InputReader.
        // 端口到id的绑定
        // input device port (String) -> to display id (int)
        // dumpsys input 没有看到这个数据
        mStaticAssociations = loadStaticInputPortAssociations();

        mContext = injector.getContext();
        // 使用的是 display thread looper
        mHandler = new InputManagerHandler(injector.getLooper());

        // 1. 初始化 native 层
        mNative = injector.getNativeService(this);

        // 监听 SettingsProvider 一些字段,例如,显示触摸坐标的 Settings.System.SHOW_TOUCHES
        mSettingsObserver = new InputSettingsObserver(mContext, mHandler, this, mNative);

        // A component of {@link InputManagerService} responsible for managing Physical Keyboard layouts.
        mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore,
                injector.getLooper());
        // A thread-safe component of {@link InputManagerService} responsible for managing the battery state of input devices.
        mBatteryController = new BatteryController(mContext, mNative, injector.getLooper());

        // A thread-safe component of {@link InputManagerService} responsible for managing the keyboard backlight for supported keyboards.
        mKeyboardBacklightController =
                KEYBOARD_BACKLIGHT_CONTROL_ENABLED ? new KeyboardBacklightController(mContext,
                        mNative, mDataStore, injector.getLooper())
                        : new KeyboardBacklightControllerInterface() {};
        
        // A component of {@link InputManagerService} responsible for managing key remappings.
        mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());

        // When true use the linux /dev/input/event subsystem to detect the switch changes
        // on the headphone/microphone jack. When false use the older uevent framework.
        // 默认为 false
        mUseDevInputEventForAudioJack =
                mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);

        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
                + mUseDevInputEventForAudioJack);

        // File used to enable the double touch gesture.
        // null
        String doubleTouchGestureEnablePath = mContext.getResources().getString(
                R.string.config_doubleTouchGestureEnableFile);
        // null
        mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
            new File(doubleTouchGestureEnablePath);

        mVelocityTrackerStrategy = DeviceConfig.getProperty(
                NAMESPACE_INPUT_NATIVE_BOOT, VELOCITYTRACKER_STRATEGY_PROPERTY);

        // 注册 local service
        injector.registerLocalService(new LocalService());
    }    

InputManagerService 在构造时,初始化了一些数据,然后最主要的就是对底层进行初始化

// com_android_server_input_InputManagerService.cpp

static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
                        jobject messageQueueObj) {

    // 获取底层关联的 message queue
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == nullptr) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    static std::once_flag nativeInitialize;
    NativeInputManager* im = nullptr;
    std::call_once(nativeInitialize, [&]() {
        // Create the NativeInputManager, which should not be destroyed or deallocated for the
        // lifetime of the process.
        // 创建 NativeInputManager
        im = new NativeInputManager(serviceObj, messageQueue->getLooper());
    });
    LOG_ALWAYS_FATAL_IF(im == nullptr, "NativeInputManager was already initialized.");

    // 返回 NativeInputManager 对象给上层
    return reinterpret_cast<jlong>(im);
}


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

    // 创建一个全局引用,指向上层的 InputManagerService
    mServiceObj = env->NewGlobalRef(serviceObj);

    // 创建并注册一个服务 InputManager
    // 注意两个参数,都是 NativeInputManager 对象
    InputManager* im = new InputManager(this, *this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
}

native 层初始化

  1. 创建 NativeInputManager,并返回给上层,并由 InputManagerService#mNative 保存 。
  2. NativeInputManager 创建一个全局引用 mServiceObj,指向上层的 InputManagerService 。
  3. 创建并注册了一个底层服务 InputManager。

来看下底层服务 InputManager 的创建

// InputManager.cpp

/**
 * The event flow is via the "InputListener" interface, as follows:
 * InputReader -> UnwantedInteractionBlocker -> InputProcessor -> InputDispatcher
 */
InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
                           InputDispatcherPolicyInterface& dispatcherPolicy) {
    // 创建 InputDispatcher
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    // 创建 InputProcessor
    mProcessor = std::make_unique<InputProcessor>(*mDispatcher);
    // 创建 UnwantedInteractionBlocker
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mProcessor);
    // 创建 InputReader
    mReader = createInputReader(readerPolicy, *mBlocker);
}

InputManager 创建了四个模块,并且从注释看,事件在这四个模块的流转顺序是 InputReader -> UnwantedInteractionBlocker -> InputProcessor -> InputDispatcher ,而各个模块之间是通过 InputListener 接口耦合的。

根据目前所创建的所有模块,可以大致总结出 Input 系统的结构,如下

111.png

启动

// InputManagerService.java

    public void start() {
        Slog.i(TAG, "Starting input manager");

        // 底层启动
        mNative.start();

        // watchdog 监听死锁
        Watchdog.getInstance().addMonitor(this);
    }

上层 InputManagerService 在启动的时候,几乎没有做任何实质性的事情,所有事情都是交给底层来启动

// com_android_server_input_InputManagerService.cpp

static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
    // 获取JNI层的NativeInputManager
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);

    // 通过NativeInputManager获取InputManager,然后启动它
    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

native 层启动的是系统服务 InputManager

// InputManager.cpp

status_t InputManager::start() {
    status_t result = mDispatcher->start();

    if (result) {
        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
        return result;
    }

    result = mReader->start();


    if (result) {
        ALOGE("Could not start InputReader due to error %d.", result);

        mDispatcher->stop();
        return result;
    }

    return OK;
}

InputManager 启动了两个模块 InputDispatcher 和 InputReader ,而这两个动画的启动,都是创建并启动了一个线程

status_t InputDispatcher::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
    return OK;
}

status_t InputReader::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
    return OK;
}

看下 InputThread 的构造过程

// InputThread.cpp

InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
      : mName(name), mThreadWake(wake) {
    // 创建线程
    mThread = sp<InputThreadImpl>::make(loop);
    // 启动线程
    mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}

// Implementation of Thread from libutils.
class InputThreadImpl : public Thread {
public:
    explicit InputThreadImpl(std::function<void()> loop)
          : Thread(/* canCallJava */ true), mThreadLoop(loop) {}

    ~InputThreadImpl() {}

private:
    std::function<void()> mThreadLoop;

    bool threadLoop() override {
        // mThreadLoop 来自于构造函数传入的参数 loop
        mThreadLoop();
        return true;
    }
};

InputThread 本身并不是一个线程,它会创建一个线程 InputThreadImpl ,并启动它。当线程启动后,会循环地执行 threadLoop() 函数,而每一次线程循环,会去执行 mThreadLoop 函数。 而 mThreadLoop 是创建 InputThread 传入的参数 loop。

因此,InputDispatcher 启动的时候,每一次线程循环,会执行 dispatchOnce(), 而 InputReader 会执行 loopOnce()。

就绪

// InputManagerService.java

    public void systemRunning() {
        if (DEBUG) {
            Slog.d(TAG, "System ready.");
        }

        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

        // 监听 SettingsProvider 字段,例如,是否显示触摸坐标
        mSettingsObserver.registerAndUpdate();

        synchronized (mLidSwitchLock) {
            mSystemReady = true;

            // Send the initial lid switch state to any callback registered before the system was
            // ready.
            int switchState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID);
            for (int i = 0; i < mLidSwitchCallbacks.size(); i++) {
                LidSwitchCallback callback = mLidSwitchCallbacks.get(i);
                callback.notifyLidSwitchChanged(0 /* whenNanos */, switchState == KEY_STATE_UP);
            }
        }

        // Set the HW mic toggle switch state
        final int micMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY,
                SW_MUTE_DEVICE);
        if (micMuteState == InputManager.SWITCH_STATE_ON) {
            setSensorPrivacy(Sensors.MICROPHONE, true);
        }
        // Set the HW camera toggle switch state
        final int cameraMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY,
                SW_CAMERA_LENS_COVER);
        if (cameraMuteState == InputManager.SWITCH_STATE_ON) {
            setSensorPrivacy(Sensors.CAMERA, true);
        }

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED);
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                reloadDeviceAliases();
            }
        }, filter, null, mHandler);

        // 通知底层加载一次设备别名
        mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES);

        if (mWiredAccessoryCallbacks != null) {
            mWiredAccessoryCallbacks.systemReady();
        }

        // 键盘相关
        mKeyboardLayoutManager.systemRunning();
        mBatteryController.systemRunning();
        mKeyboardBacklightController.systemRunning();
        mKeyRemapper.systemRunning();

        /** Set whether showing a pointer icon for styluses(触控笔) is enabled. */
        mNative.setStylusPointerIconEnabled(
                Objects.requireNonNull(mContext.getSystemService(InputManager.class))
                        .isStylusPointerIconEnabled());
    }

上层主要就是监听 SettingsProvider 相关字段改变,当然还有一些与底层相关的操作,例如,通知底层,重新加载设备别名、重新加载键盘布局文件,等等。与底层相关操作的代码流程,如果没用到,就暂时不去管,等到必要的时候,再回头分析也不迟。