Input事件上报流程1

主要类功能介绍

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值