Android R input 之 InputManagerService 的建立
Posted pecuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android R input 之 InputManagerService 的建立相关的知识,希望对你有一定的参考价值。
文章托管在gitee上 Android Notes , 同步csdn
InputManagerService 介绍
InputManagerService是重要的系统服务,负责android输入系统的管理,职责包括但不限于:
- 输入设备的管理
- 输入事件的加工m
- 输入事件的派发与反馈
- 输入事件的派发ANR的检测
常见的输入设备是触摸屏/按键,其他支持的设备还有键盘,鼠标等. 当有新输入设备可用时,Linux内核会在/dev/input/下创建对应的名称类似eventX(X>=0)的设备节点。当输入设备不可用时,对应的节点也会被移除。通过 getevent 命令可以获取设备信息
# getevent
add device 1: /dev/input/event6
name: "msm8xx2-snd-card-mtp Button Jack"
add device 2: /dev/input/event5
name: "msm8xx2-snd-card-mtp Headset Jack"
add device 3: /dev/input/event0
name: "qpnp_pon"
add device 4: /dev/input/event2
name: "ts"
add device 5: /dev/input/event1
name: "soc:matrix_keypad"
add device 6: /dev/input/event3
name: "hall_sensor"
add device 7: /dev/input/event4
name: "gpio_keys"
当用户操作输入设备时(如手指在屏幕上滑动或按power键),会触发相应的硬件中断,Linux内核将相关信息加工成原始的输入事件数据,然后写入其对应的设备节点中.在用户空间,EventHub通过read()系统调用函数将事件数据读出,然后进行相关加工处理。
引用输入理解Android 卷三的一句来描述整体过程:
Android输入系统的工作原理概括来说,就是监控/dev/input/下的所有设备节点,当某个节点有数据可读时,将数据读出并进行一系列的翻译加工,然后在所有的窗口中寻找合适的事件接收者,并派发给它。
InputManagerService 的创建
InputManagerService 如大多数系统服务一样,也是在SystemServer中创建. 具体工作可以总结如下:
- 创建InputManagerService, 同时初始java和native
- 注册InputManagerService到ServiceManager
- 设置WindowManagerCallback,通知WMS一下感兴趣的事情
- 调用InputManagerService的start方法,启动工作线程,注册一下监听等
- 调用InputManagerService的systemRunning方法做一下初始工作
/// @frameworks/base/services/java/com/android/server/SystemServer.java
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t)
...
t.traceBegin("StartInputManagerService");
inputManager = new InputManagerService(context); // 创建InputManagerService
t.traceEnd();
t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
// 注册WMS
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
// 将 InputManagerService 注册到sm
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();
...
mActivityManagerService.setWindowManager(wm);
wm.onInitReady();
t.traceBegin("StartInputManager");
// 设置 input callback, 通知wms一下input相关的事件,如anr
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start(); // ims 启动
t.traceEnd();
...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() ->
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
mSystemServiceManager.startBootPhase(t,SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
...
t.traceBegin("MakeInputManagerServiceReady");
try
// TODO(BT) Pass parameter to input manager
if (inputManagerF != null)
inputManagerF.systemRunning(); // 回调 systemRunning
catch (Throwable e)
reportWtf("Notifying InputManagerService running", e);
...
接下来分析具体的流程
创建 InputManagerService
/// @frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public InputManagerService(Context context)
this.mContext = context;
// 创建InputManagerHandler, 消息将在DisplayThread处理
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
mStaticAssociations = loadStaticInputPortAssociations();
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
// 重点关注 , 初始化native , mPtr保存NativeInputManager地址
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
String doubleTouchGestureEnablePath = context.getResources().getString(
R.string.config_doubleTouchGestureEnableFile);
mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
new File(doubleTouchGestureEnablePath);
// 注册 LocalService , 只能在SystemServer使用
LocalServices.addService(InputManagerInternal.class, new LocalService());
IMS JNI函数注册表
InputManagerService的native 实现在frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp , 下面的注册表描述了java native方法与相关jni函数的对应关系
static const JNINativeMethod gInputManagerMethods[] =
/* name, signature, funcPtr */
"nativeInit",
"(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
"MessageQueue;)J",
(void*)nativeInit,
"nativeStart", "(J)V", (void*)nativeStart,
"nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
(void*)nativeSetDisplayViewports,
"nativeGetScanCodeState", "(JIII)I", (void*)nativeGetScanCodeState,
"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState,
"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState,
"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys,
"nativeRegisterInputChannel", "(JLandroid/view/InputChannel;)V",
(void*)nativeRegisterInputChannel,
"nativeRegisterInputMonitor", "(JLandroid/view/InputChannel;IZ)V",
(void*)nativeRegisterInputMonitor,
"nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
(void*)nativeUnregisterInputChannel,
"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers,
"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled,
"nativeSetInTouchMode", "(JZ)V", (void*)nativeSetInTouchMode,
"nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
(void*)nativeInjectInputEvent,
"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
(void*)nativeVerifyInputEvent,
"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock,
"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved,
"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
(void*)nativeSetFocusedApplication,
"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay,
"nativeSetPointerCapture", "(JZ)V", (void*)nativeSetPointerCapture,
"nativeSetInputDispatchMode", "(JZZ)V", (void*)nativeSetInputDispatchMode,
"nativeSetSystemUiVisibility", "(JI)V", (void*)nativeSetSystemUiVisibility,
"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;)Z",
(void*)nativeTransferTouchFocus,
"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed,
"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches,
"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive,
"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration,
"nativeVibrate", "(JI[JII)V", (void*)nativeVibrate,
"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate,
"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts,
"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases,
"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump,
"nativeMonitor", "(J)V", (void*)nativeMonitor,
"nativeIsInputDeviceEnabled", "(JI)Z", (void*)nativeIsInputDeviceEnabled,
"nativeEnableInputDevice", "(JI)V", (void*)nativeEnableInputDevice,
"nativeDisableInputDevice", "(JI)V", (void*)nativeDisableInputDevice,
"nativeSetPointerIconType", "(JI)V", (void*)nativeSetPointerIconType,
"nativeReloadPointerIcons", "(J)V", (void*)nativeReloadPointerIcons,
"nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V",
(void*)nativeSetCustomPointerIcon,
"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay,
"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged,
"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled,
;
nativeInit
java的nativeInit方法对应着同名的jni函数
/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj)
// 获取C++ 的MessageQueue
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == nullptr)
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
// 创建jni层的NativeInputManager, 用于InputManagerService与C++ InputManager 通信
// serviceObj是InputManagerService, 因此NativeInputManager持有了IMS的引用
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
NativeInputManager 构造
/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true)
JNIEnv* env = jniEnv();
// 持有IMS的强引用
mServiceObj = env->NewGlobalRef(serviceObj);
AutoMutex _l(mLock);
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
mLocked.pointerCapture = false;
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
mInteractive = true;
// 创建InputManager, 注意两个this,都是指代 NativeInputManager,它是相关策略的实现类
mInputManager = new InputManager(this, this);
// 注册InputManager到sm, 名称是inputflinger
defaultServiceManager()->addService(String16("inputflinger"),
mInputManager, false);
从NativeInputManager的继承体系来看,它是InputReaderPolicyInterface,InputDispatcherPolicyInterface等策略的实现类
/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
class NativeInputManager : public virtual RefBase,
public virtual InputReaderPolicyInterface,
public virtual InputDispatcherPolicyInterface,
public virtual PointerControllerPolicyInterface ...
创建InputManager
从继承结构上看,InputManager是binder service的Bn端,对外提供服务, 通过名称inputflinger获取
/// @frameworks/native/services/inputflinger/InputManager.h
class InputManager : public InputManagerInterface, public BnInputFlinger
private:
sp<InputReaderInterface> mReader;
sp<InputClassifierInterface> mClassifier;
sp<InputDispatcherInterface> mDispatcher;
InputManager构造函数 , 此处的readerPolicy和dispatcherPolicy实际上都是NativeInputManager
/// @frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy)
mDispatcher = createInputDispatcher(dispatcherPolicy); // 使用工厂创建InputDispatcher
mClassifier = new InputClassifier(mDispatcher); // 创建InputClassifier,持有mDispatcher
mReader = createInputReader(readerPolicy, mClassifier); // 使用工厂创建InputReader,注意mClassifier参数
以上工厂方法对应的头文件如下, 实现在对应的cpp文件
#include "InputDispatcherFactory.h"
#include "InputReaderFactory.h"
createInputDispatcher
/// @frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cpp
sp<InputDispatcherInterface> createInputDispatcher(
const sp<InputDispatcherPolicyInterface>& policy)
return new android::inputdispatcher::InputDispatcher(policy);
创建 InputDispatcher
/// @frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
: mPolicy(policy),
mPendingEvent(nullptr),
mLastDropReason(DropReason::NOT_DROPPED),
mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
mAppSwitchSawKeyDown(false),
mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(nullptr),
mDispatchEnabled(false),
mDispatchFrozen(false),
mInputFilterEnabled(false),
// mInTouchMode will be initialized by the WindowManager to the default device config.
// To avoid leaking stack in case that call never comes, and for tests,
// initialize it here anyways.
mInTouchMode(true), // 默认touch mode
mFocusedDisplayId(ADISPLAY_ID_DEFAULT)
mLooper = new Looper(false); // 创建 Looper
mReporter = createInputReporter();
mKeyRepeatState.lastKeyEntry = nullptr;
policy->getDispatcherConfiguration(&mConfig);
创建 InputClassifier
由上可知,mListener的值实际上是mDispatcher. InputClassifier代表输入事件的一个处理阶段,对于motion events会交由MotionClassifier处理,其他事件则是直通的,也就是直接交于mListener进行处理.
/// @frameworks/native/services/inputflinger/InputClassifier.cpp
/*
* Implementation of the InputClassifierInterface.
* Represents a separate stage of input processing. All of the input events go through this stage.
* Acts as a passthrough for all input events except for motion events.
* The events of motion type are sent to MotionClassifier.
*/
InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener)
: mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this))
createInputReader
此处的listener就是上面创建的InputClassifier, 而它持有InputDispatcher的引用, 因此InputReader间接持有InputDispatcher的引用, 另外注意此处创建了EventHub, 用于加工处理原始事件
/// @frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp
sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener)
return new InputReader(std::make_unique<EventHub>(), policy, listener);
创建 InputReader
/// @frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener)
: mContext(this),
mEventHub(eventHub),
mPolicy(policy),
mGlobalMetaState(0),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0)
//queues up and defers dispatch of decoded events until flushed.
mQueuedListener = new QueuedInputListener(listener); // 间接持有InputDispatcher的引用
// acquire lock
AutoMutex _l(mLock);
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
// release lock
QueuedInputListener
它用于向Dispatcher发送事件,实现事件排队并推迟派发事件直到调用flush
/// @frameworks/native/services/inputflinger/include/InputListener.h
/*
* An implementation of the listener interface that queues up and defers dispatch
* of decoded events until flushed.
*/
class QueuedInputListener : public InputListenerInterface
protected:
virtual ~QueuedInputListener();
public:
explicit QueuedInputListener(const sp<InputListenerInterface>& innerListener);
virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
virtual void notifyKey(const NotifyKeyArgs* args); // key 事件
virtual void notifyMotion(const NotifyMotionArgs* args); // motion 事件
virtual void notifySwitch(const NotifySwitchArgs* args);
virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
void flush();
private:
sp<InputListenerInterface> mInnerListener;
std::vector<NotifyArgs*> mArgsQueue;
;
// namespace android
InputManagerService#start
public void start()
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr); // 调用 nativeStart
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this); // 添加到watchdog监听
// 注册一些监听
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
registerAccessibilityLargePointerSettingObserver();
registerLongPressTimeoutObserver();
mContext.registerReceiver(new BroadcastReceiver() // 注册 ACTION_USER_SWITCHED
@Override
public void onReceive(Context context, Intent intent)
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
updateDeepPressStatusFromSettings("user switched");
, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
// 更新配置
updatePointerSpeedFromSettings();
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
updateDeepPressStatusFromSettings("just booted");
nativeStart
nativeStart 对应同名的jni函数
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr)
// 取出在nativeInit创建的NativeInputManager
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
if (result)
jniThrowRuntimeException(env, "Input manager could not be started.");
InputManager#start()
status_t InputManager::start()
status_t result = mDispatcher->start(); // 启动 dispatcher 线程
if (result)
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
result = mReader->start(); // 启动 reader 线程
if (result)
ALOGE("Could not start InputReader due to error %d.", result);
mDispatcher->stop();
return result;
return OK;
InputDispatcher::start
status_t InputDispatcher::start()
if (mThread) // 已经创建
return ALREADY_EXISTS;
// 创建InputDispatcher线程, 线程执行会调用dispatchOnce
mThread = std::make_unique<InputThread>(
"InputDispatcher", [this]() dispatchOnce(); , [this]() mLooper->wake();/* wake函数*/ );
return OK;
dispatcher 线程会不断调用dispatchOnce去分发事件
InputReader::start
status_t InputReader::start()
if (mThread)
return ALREADY_EXISTS;
// 创建InputReader线程, 线程执行会调用loopOnce
mThread = std::make_unique<InputThread>(
"InputReader", [this]() loopOnce(); , [this]() mEventHub->wake();/* wake函数*/ );
return OK;
reader线程会不断调用loopOnce去获取底层的事件, 然后将事件传递给dispatcher线程
InputThread
这个是一个线程封装类, 用于持续处理事件, 直到退出
/* A thread that loops continuously until destructed to process input events.
*
* Creating the InputThread starts it immediately. The thread begins looping the loop
* function until the InputThread is destroyed. The wake function is used to wake anything
* that sleeps in the loop when it is time for the thread to be destroyed.
*/
class InputThread
public:
explicit InputThread(std::string name, std::function<void()> loop, // 线程循环函数
std::function<void()> wake = nullptr /* 要销毁时调用,唤醒Loop中的sleep*/);
virtual ~InputThread();
bool isCallingThread();
private:
std::string mName;
std::function<void()> mThreadWake;
sp<Thread> mThread;
;
// namespace android
InputThread构造
InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
: mName(name), mThreadWake(wake)
mThread = new InputThreadImpl(loop); // 真正创建一个线程
// 启动线程,执行threadLoop
mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
通过InputThread构造的构造方法可知,在其中创建了真正的Thread实现类InputThreadImpl,并执行其run方法启动了线程. 因此reader和dispatcher中创建InputThread,实际上已经启动了内部创建的线程.
InputThreadImpl
线程的真正实现类
// 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; // loop 函数
bool threadLoop() override
mThreadLoop(); // threadLoop 函数中执行 mThreadLoop函数
return true; // 返回true表示线程不退出,继续循环
;
IMS#systemRunning
这个方法用于通知System ready, 然后做一些注册和其他工作
public void systemRunning()
if (DEBUG)
Slog.d(TAG, "System ready.");
mNotificationManager = (NotificationManager)mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
mSystemReady = true; // ready 标志
// 监听ACTION_PACKAGE_ADDED, 用于更新keyboard布局
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
updateKeyboardLayouts();
, filter, null, mHandler);
// 监听ACTION_ALIAS_CHANGED
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);
mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS);
if (mWiredAccessoryCallbacks != null)
mWiredAccessoryCallbacks.systemReady();
更新设备信息
更新操作, 都是调用的native方法.
private void reloadKeyboardLayouts()
if (DEBUG)
Slog.d(TAG, "Reloading keyboard layouts.");
nativeReloadKeyboardLayouts(mPtr);
private void reloadDeviceAliases()
if (DEBUG)
Slog.d(TAG, "Reloading device names.");
nativeReloadDeviceAliases(mPtr);
对应的jni函数如下 , 都是调用的InputReader
static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
jclass /* clazz */, jlong ptr)
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
static void nativeReloadDeviceAliases(JNIEnv* /* env */,
jclass /* clazz */, jlong ptr)
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
InputReader::requestRefreshConfiguration
InputReader 会更新mConfigurationChangesToRefresh, 然后唤醒线程
void InputReader::requestRefreshConfiguration(uint32_t changes)
AutoMutex _l(mLock);
if (changes)
bool needWake = !mConfigurationChangesToRefresh;
mConfigurationChangesToRefresh |= changes;
if (needWake)
mEventHub->wake();
reader线程被唤醒后会执行loopOnce方法
void InputReader::loopOnce()
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
// acquire lock
AutoMutex _l(mLock);
...
uint32_t changes = mConfigurationChangesToRefresh;
if (changes)
mConfigurationChangesToRefresh = 0;
timeoutMillis = 0;
refreshConfigurationLocked(changes); // 更新配置
else if (mNextTimeout != LLONG_MAX) ...
// release lock
...
refreshConfigurationLocked
具体更新
void InputReader::refreshConfigurationLocked(uint32_t changes)
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
if (changes)
ALOGI("Reconfiguring input devices, changes=%s",
InputReaderConfiguration::changesToString(changes).c_str());
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)
updatePointerDisplayLocked();
if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN)
mEventHub->requestReopenDevices();
else
for (auto& devicePair : mDevices)
std::shared_ptr<InputDevice>& device = devicePair.second;
device->configure(now, &mConfig, changes);
总结
本篇主要介绍了InputManagerService的启动流程,它的实现包含java和native两个部分. native的部分才是真正的实现,而java层的通常是相关功能的封装. 在native层创建了两个线程, reader线程不断的从EventHub从获取事件,然后将事件交给dispatcher线程进行分发. dispatcher会找到合适的window, 然后将事件派发给它.对应的window处理完相关事件后,向ims发送处理完毕的反馈,然后ims做一些收尾工作,此次事件派发循环才算完整结束.
以上是关于Android R input 之 InputManagerService 的建立的主要内容,如果未能解决你的问题,请参考以下文章
Android R input 之 InputChannel之发送事件处理反馈
Android R input 之 InputDispatcher 工作流程
Android R input 之 InputDispatcher 工作流程
Android R input 之 InputManagerService 的建立