您的位置:首页 > 移动开发 > Android开发

Android Input流程分析(一):启动

2017-09-05 00:51 435 查看
  Java层的InputManagerService由System Server启动。

/frameworks/base/services/java/com/android/server/SystemServer.java

Slog.i(TAG, "Input Manager");
inputManager = new InputManagerService(context);


  重点关注nativeInit方法。

/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());

mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

LocalServices.addService(InputManagerInternal.class, new LocalService());
}


  nativeInit最终会调到JNI层的nativeInit函数。android_os_MessageQueue_getMessageQueue获得一个Native层的MessgaeQueue引用。之后new了一个NativeInputManager对象,返回NativeInputManager的指针保存在Java层的mPtr中。

/frameworks/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);
if (messageQueue == NULL) {
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的构造函数里new了一个EventHub和
4000
一个InputManager,EventHub用来收集底层传上来的Input事件,InputManager用来创建InputDispatcher和InputReader。

/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();

mContextObj = env->NewGlobalRef(contextObj);
mServiceObj = env->NewGlobalRef(serviceObj);

{
AutoMutex _l(mLock);
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
}
mInteractive = true;

sp<EventHub> eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
}


/frameworks/native/services/inputflinger/InputManager.cpp

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();
}


  initialize函数中创建了两个线程,但在哪里启动呢?

/frameworks/native/services/inputflinger/InputManager.cpp

void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}


  答案在SystemServer中的start函数中。

/frameworks/base/services/java/com/android/server/SystemServer.java

inputManager.start();


  InputManagerService的start函数会使用nativeStart调到JNI层,并使用保存了native层的NativeInputManager指针作为入参。

/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}


  从ptr中捞出native层的NativeInputManager指针。getInputManager返回的是InputManager对象,然后调用InputManager::start分别启动InputReaderThread和InputDispatcherThread两个线程。值得指出的是,调用Thread的run函数会进入ThreadLoop循环,这个ThreadLoop循环由子类实现,返回值是取决于内部pthread_create的返回值的,而不是内部循环的返回值,所以一经调用即有返回值,为0时表示成功。requestExit表示退出ThreadLoop循环。退出ThreadLoop循环的方法有两个:1.ThreadLoop内部返回false;2.调用requestExit方法。

/frameworks/native/services/inputflinger/InputManager.cpp

status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}

result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);

mDispatcherThread->requestExit();
return result;
}

return OK;
}


  EventHub,InputReader和InputDispatcher的关系是:EventHub负责从内核捞起Input事件,InputReader负责加工从EventHub送过来的Input事件,InputDispatcher负责分派InputReader送来的Input事件到合适的窗口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: