主要类功能介绍
WindowManagerService-管理窗口,手机input事件和分发input事件;
InputManager:接收分发事件,创建底层对象,启动线程,跟java层对接。
EventHub:打开所有的输入设备,输入事件映射
InputReader:InputReader手机到input事件并进行判断处理。
InputDispatcher:事件过滤,将事件发送给上层。
其他模块:上层事件分发,输入法等。
2 create主线
create主线主要是创建 Input 系统相关对象,从 Java 层一直到 Native 层。
frameworks/base/services/java/com/android/server/System
Server.java中创建InputManagerService。
t.traceBegin("StartInputManagerService");
inputManager = new InputManagerService(context);
t.traceEnd();
并且将inputManager当做参数传递给WindowManagerService
t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();
t.traceBegin("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
t.traceEnd();
t.traceBegin("WindowManagerServiceOnInitReady");
wm.onInitReady();
t.traceEnd();
InputManagerService的初始化代码如下
public InputManagerService(Context context) {
this.mContext = context;
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);
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
String doubleTouchGestureEnablePath = context.getResources().getString(
R.string.config_doubleTouchGestureEnableFile);
mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
new File(doubleTouchGestureEnablePath);
LocalServices.addService(InputManagerInternal.class, new LocalService());
}
private static native long nativeInit(InputManagerService service,Context context, MessageQueue messageQueue);
nativeInit方法位于frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp中
{"nativeInit", "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
"MessageQueue;)J",
(void*)nativeInit},
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
//拿到一个消息队列
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
//初始化工作
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
mServiceObj = env->NewGlobalRef(serviceObj);
{
AutoMutex _l(mLock);
mLocked.systemUiLightsOut = false;
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
}
mInteractive = true;
InputManager* im = new InputManager(this, this);
mInputManager = im;
defaultServiceManager()->addService(String16("inputflinger"), im);
}
创建了frameworks/native/services/inputflinger/InputManager.cpp 对象,我们查看InputManager的初始化会发现它持有mDispatcher 、mReader ,并且我们继续查看对应createInputDispatcher与createInputReader的创建方法,可以看到createInputReader返回的InputReader对象持有EventHub对象。
这样InputManager也可以通过mReader 获取到eventhub。
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = createInputDispatcher(dispatcherPolicy);
mClassifier = new InputClassifier(mDispatcher);
// 创建InputReader事件读取对象,间接持有InputDispatcher的引用,以便事件读取完成后通知其进行事件分发
mReader = createInputReader(readerPolicy, mClassifier);
}
frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cpp
sp<InputDispatcherInterface> createInputDispatcher(
23 const sp<InputDispatcherPolicyInterface>& policy) {
24 return new android::inputdispatcher::InputDispatcher(policy);
25 }
frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp
sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,
24 const sp<InputListenerInterface>& listener) {
// InputReader持有InputDispatcher的引用listener
25 return new InputReader(std::make_unique<EventHub>(), policy, listener);
26 }
27
3.start主线
start主线会启动两条线程 InputReader(读取事件)、InputDispatcher(分发事件),并且这两条线程会一直循环执行,不会终止。
InputManagerService.java的start()方法会调用 nativeStart(mPtr);
同上在com_android_server_input_InputManagerService.cpp 的nativeStart会通过NativeInputManager获取InputManager对象并调用他的start方法。
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1504 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1505
1506 status_t result = im->getInputManager()->start();
1507 if (result) {
1508 jniThrowRuntimeException(env, "Input manager could not be started.");
1509 }
1510 }
InputManager的start方法分别调用 mReader->start();和mReader->start();的start方法。
status_t InputManager::start() {
70 status_t result = mDispatcher->start();
71 if (result) {
72 ALOGE("Could not start InputDispatcher thread due to error %d.", result);
73 return result;
74 }
75
76 result = mReader->start();
77 if (result) {
78 ALOGE("Could not start InputReader due to error %d.", result);
79
80 mDispatcher->stop();
81 return result;
82 }
83
84 return OK;
85 }
查看InputDispatcher.cpp 它创建了InputThread对象并且名字为InputDispatcher。
status_t InputDispatcher::start() {
567 if (mThread) {
568 return ALREADY_EXISTS;
569 }
570 mThread = std::make_unique<InputThread>(
571 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
572 return OK;
573 }
查看InputReader.cpp它创建了InputThread对象并且名字为InputReader,并且mEventHub->wake()当做参数传入
status_t InputReader::start() {
69 if (mThread) {
70 return ALREADY_EXISTS;
71 }
72 mThread = std::make_unique<InputThread>(
73 "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
74 return OK;
75 }
我们去查看InputThread中的代码,通过查看代码我们可以看到InputThread的构造方法会创建InputThreadImpl对象,并启动thread,并且InputThreadImpl 继承自 libutils 中的 Thread,其会一直运行threadLoop 函数。
此函数会调用 mThreadLoop(),它由InputThread创建时参数传入。
通过上述描述InputDispatcher.cpp中会一直运行dispatchOnce()方法。
InputReader.cpp会一直运行 loopOnce()方法。
#include "InputThread.h"
18
19 namespace android {
20
21 namespace {
22
23 // Implementation of Thread from libutils.
24 class InputThreadImpl : public Thread {
25 public:
26 explicit InputThreadImpl(std::function<void()> loop)
27 : Thread(/* canCallJava */ true), mThreadLoop(loop) {}
28
29 ~InputThreadImpl() {}
30
31 private:
32 std::function<void()> mThreadLoop;
33
34 bool threadLoop() override {
35 mThreadLoop();
36 return true;
37 }
38 };
39
40 } // namespace
41
42 InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
43 : mName(name), mThreadWake(wake) {
44 mThread = new InputThreadImpl(loop);
45 mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
46 }
47
48 InputThread::~InputThread() {
49 mThread->requestExit();
50 if (mThreadWake) {
51 mThreadWake();
52 }
53 mThread->requestExitAndWait();
54 }
55
56 bool InputThread::isCallingThread() {
57 return gettid() == mThread->getTid();
58 }
59
60 } // namespace android