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 层初始化
- 创建 NativeInputManager,并返回给上层,并由 InputManagerService#mNative 保存 。
- NativeInputManager 创建一个全局引用 mServiceObj,指向上层的 InputManagerService 。
- 创建并注册了一个底层服务 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 系统的结构,如下
启动
// 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 相关字段改变,当然还有一些与底层相关的操作,例如,通知底层,重新加载设备别名、重新加载键盘布局文件,等等。与底层相关操作的代码流程,如果没用到,就暂时不去管,等到必要的时候,再回头分析也不迟。