Android InputFlinger简单分析(主要分析Touch)
首先,它有个服务,InputManagerService.
InputManagerService启动
startOtherServices@SystemServer
...
inputManager = new InputManagerService(context);
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
...
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
...
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
...
看看构造函数:
public InputManagerService(Context context) {
...
mPtr = nativeInit(this, mContext,mHandler.getLooper().getQueue());
...
}
这个mPrt之后作为了其他native函数的第一个参数。先看看nativeInit
(位置base/services/core/jni/com_android_server_input_InputManagerService.cpp)
static jlong nativeInit(JNIEnv* env, jclass clazz,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
...
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
简单来理解就是获取java层的消息队列,然后构造了一个NativeInputManager对象,然后返回java层,赋值给mPtr。
前文,startOtherServices@SystemServer中还调用了
inputManager.start();
start()@InputManagerService
...
nativeStart(mPtr);
...
nativeStart:
static void nativeStart(JNIEnv* env, jclass clazz, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
...
}
即用nativeInit中new的NativeInputManager对象调用start函数。
那NativeInputManager是什么呢?
inline sp<InputManager> getInputManager() const { return mInputManager; }
直接去看InputManager调用start函数就好了。
接下来,我们的工作目录就集中到
frameworks/native/services/inputflinger
从InputManager::start开始
...
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
...
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
...
mDispatcherThread和mReaderThread的run函数,都会去调用threadLoop函数(就当是常识了)。
bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();
return true;
}
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}
从名字上来看,一个专门去读取input,一个专门去分发input.可是为什么只运行一次(loopOnce)呢?
我们这次主要关注的是touch事件,即MotionEvent.
InputDispatcher.h
struct MotionEntry : EventEntry {
Motion是Event的一种!
virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
virtual void notifyKey(const NotifyKeyArgs* args);
virtual void notifyMotion(const NotifyMotionArgs* args);
virtual void notifySwitch(const NotifySwitchArgs* args);
virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
这几个函数功能应该类似,只不过Event种类不同。
在InputDispatcher.cpp中竟然找不到调用。嗯!yes!搜索结果如下:
InputReader.cpp:2551: getListener()->notifyMotion(&args);
...
getListener@InputReader:
class InputReader : public InputReaderInterface {
...
virtual InputListenerInterface* getListener();
InputDispatcher.h:
class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface
...
class InputDispatcher : public InputDispatcherInterface
回头过去看一下InputManager的构造函数,就都明白了
InputManager::InputManager
InputManager::InputManager(
const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
//注意第三个参数
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
initialize();
}
InputReader的构造函数:
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
//这个
const sp<InputListenerInterface>& listener) :
mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mGeneration(1),
mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);
而
InputListenerInterface* InputReader::ContextImpl::getListener() {
return mReader->mQueuedListener.get();
}
总的来说就是,notifyMotion函数的调用来自InputReader.读到input之后notify!
InputReader分析
InputReader::loopOnce
//引出一个EventHub,getEvents也非常类似平时在adb shell中使用的命令
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
...
processEventsLocked(mEventBuffer, count);
...
InputReader::processEventsLocked
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
...
//type不是
//DEVICE_ADDED,DEVICE_REMOVED,FINISHED_DEVICE_SCAN这三个
if(type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
...
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
}
}
}
我们来看看一个开机加载T