您的位置:首页 > 娱乐 > 八卦 > 【安卓12源码】Input子系统(1) - input启动流程

【安卓12源码】Input子系统(1) - input启动流程

2024/12/23 3:06:32 来源:https://blog.csdn.net/qq_40587575/article/details/139130595  浏览:    关键词:【安卓12源码】Input子系统(1) - input启动流程

Android Input 体系中,大致有两种类型的事件:实体按键 key 事件,屏幕点击触摸事件。

如果根据事件类型的不同我们还能细分为基础实体按键的 key(power,volume up/down,recents,back,home),实体键盘按键,屏幕点击 (多点,单点),屏幕滑动等等的事件。

在 Android 整个 Input 体系中有三个格外重要的成员:Eventhub,InputReader,InputDispatcher。

它们分别担负着各自不同的职责,Eventhub 负责监听 / dev/input 产生 Input 事件,InputReader 负责从 Eventhub 读取事件,并将读取的事件发给 InputDispatcher,InputDispatcher 则根据实际的需要具体分发给当前手机获得焦点实际的 Window。

 inputmanagerservice启动原理

inpu子系统是运行在system 系统进程的

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

1325      private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
1326          t.traceBegin("startOtherServices");
。。。。。。
1471              t.traceBegin("StartInputManagerService");
// 1)创建 InputManagerService 对象
1472              inputManager = new InputManagerService(context);// 2)将其作为参数传入到wms 中
1488              wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
1489                      new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
// 增加这个input service,给客户端使用
1490              ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
1491                      DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
1492              ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
1493                      /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);// 3)启动 InputManagerService
1520              t.traceBegin("StartInputManager");
1521              inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
1522              inputManager.start();

1)创建 InputManagerService 对象

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

424      public InputManagerService(Context context) {
425          this.mContext = context;// 创建handler,在 DisplayThread 线程中处理
426          this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
427  
428          mStaticAssociations = loadStaticInputPortAssociations();
429          mUseDevInputEventForAudioJack =
430                  context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);// system 系统进程input,会打印下列的日志
431          Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
432                  + mUseDevInputEventForAudioJack);// 调用native 层的方法去初始化
433          mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
434  
435          String doubleTouchGestureEnablePath = context.getResources().getString(
436                  R.string.config_doubleTouchGestureEnableFile);
437          mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
438              new File(doubleTouchGestureEnablePath);
439  
440          LocalServices.addService(InputManagerInternal.class, new LocalService());
441      }

// 调用native 层的方法去初始化,looper 是 DisplayThread 线程

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

1488  static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
1489          jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
1490      sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
1491      if (messageQueue == nullptr) {
1492          jniThrowRuntimeException(env, "MessageQueue is not initialized.");
1493          return 0;
1494      }
1495  // 创建NativeInputManager 对象,looper 是DisplayThread 线程【再次说明】
1496      NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
1497              messageQueue->getLooper());
1498      im->incStrong(0);
1499      return reinterpret_cast<jlong>(im);
1500  }

创建NativeInputManager 对象

407  NativeInputManager::NativeInputManager(jobject contextObj,
408          jobject serviceObj, const sp<Looper>& looper) :// 缓存 mLooper
409          mLooper(looper), mInteractive(true) {
410      JNIEnv* env = jniEnv();
411  
412      mServiceObj = env->NewGlobalRef(serviceObj);
413  
414      {
415          AutoMutex _l(mLock);
416          mLocked.systemUiLightsOut = false;
417          mLocked.pointerSpeed = 0;
418          mLocked.pointerGesturesEnabled = true;
419          mLocked.showTouches = false;
420          mLocked.pointerCapture = false;
421          mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
422      }
423      mInteractive = true;
424  // 创建对象 InputManager,2个参数都是this
425      InputManager* im = new InputManager(this, this);
426      mInputManager = im;// 将其保存到 "inputflinger",给native 层调用
427      defaultServiceManager()->addService(String16("inputflinger"), im);
428  }

创建对象 InputManager,2个参数都是this
/frameworks/native/services/inputflinger/InputManager.cpp

53  InputManager::InputManager(
54          const sp<InputReaderPolicyInterface>& readerPolicy,
55          const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {// 1-1)创建 InputDispatcher对象
56      mDispatcher = createInputDispatcher(dispatcherPolicy);// 1-2)创建 InputClassifier 对象
57      mClassifier = new InputClassifier(mDispatcher);// 1-3)创建 InputReader 对象,传入了 InputClassifier对象
58      mReader = createInputReader(readerPolicy, mClassifier);
59  }
60  

// 1-1)创建 InputDispatcher对象
frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cpp

22  sp<InputDispatcherInterface> createInputDispatcher(
23          const sp<InputDispatcherPolicyInterface>& policy) {
24      return new android::inputdispatcher::InputDispatcher(policy);
25  }

 /frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

509  InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)//mPolicy 是 NativeInputManager,可以通过此从native层传消息给java 层,比如通知没有焦点窗口510        : mPolicy(policy),
511          mPendingEvent(nullptr),
512          mLastDropReason(DropReason::NOT_DROPPED),
513          mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
514          mAppSwitchSawKeyDown(false),
515          mAppSwitchDueTime(LONG_LONG_MAX),
516          mNextUnblockedEvent(nullptr),
517          mDispatchEnabled(false),
518          mDispatchFrozen(false),
519          mInputFilterEnabled(false),
520          // mInTouchMode will be initialized by the WindowManager to the default device config.
521          // To avoid leaking stack in case that call never comes, and for tests,
522          // initialize it here anyways.
523          mInTouchMode(true),
524          mMaximumObscuringOpacityForTouch(1.0f),
525          mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
526          mFocusedWindowRequestedPointerCapture(false),
527          mWindowTokenWithPointerCapture(nullptr),
528          mLatencyAggregator(),
529          mLatencyTracker(&mLatencyAggregator),
530          mCompatService(getCompatService()) {
531      mLooper = new Looper(false);
532      mReporter = createInputReporter();
533  
534      mKeyRepeatState.lastKeyEntry = nullptr;
535  
536      policy->getDispatcherConfiguration(&mConfig);
537  }

// 1-2)创建 InputClassifier 对象

/frameworks/native/services/inputflinger/InputClassifier.cpp

 构造函数中传入的参数 mListener 是inputdispatcher。而 InputClassifier也作为参数传入给 InputReader。相当于 InputClassifier 是 沟通 InputReader和 inputdispatcher 的桥梁

348  InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener)
349        : mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this)) {}
350  

// 1-3)创建 InputReader 对象,传入了 InputClassifier对象

/frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp

23  sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,
24                                             const sp<InputListenerInterface>& listener) {// 这里还创建了 EventHub,负责读取驱动的事件
25      return new InputReader(std::make_unique<EventHub>(), policy, listener);
26  }

InputReader 构造方法

/frameworks/native/services/inputflinger/reader/InputReader.cpp

43  InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
44                           const sp<InputReaderPolicyInterface>& policy,
45                           const sp<InputListenerInterface>& listener)
46        : mContext(this),
47          mEventHub(eventHub),
48          mPolicy(policy),
49          mGlobalMetaState(0),
50          mLedMetaState(AMETA_NUM_LOCK_ON),
51          mGeneration(1),
52          mNextInputDeviceId(END_RESERVED_ID),
53          mDisableVirtualKeysTimeout(LLONG_MIN),
54          mNextTimeout(LLONG_MAX),
55          mConfigurationChangesToRefresh(0) {// 创建 QueuedInputListener 对象,listener 是 InputClassifier.cpp
56      mQueuedListener = new QueuedInputListener(listener);
57  
58      { // acquire lock
59          std::scoped_lock _l(mLock);
60  
61          refreshConfigurationLocked(0);
62          updateGlobalMetaStateLocked();
63      } // release lock
64  }

/frameworks/native/services/inputflinger/InputListener.cpp

在调用 flush 后,可以将信息传递给 inputDispatcher 

315  QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
316          mInnerListener(innerListener) {
317  }367  void QueuedInputListener::flush() {
368      size_t count = mArgsQueue.size();
369      for (size_t i = 0; i < count; i++) {
370          NotifyArgs* args = mArgsQueue[i];
371          args->notify(mInnerListener);
372          delete args;
373      }
374      mArgsQueue.clear();
375  }

2)将其作为参数传入到wms 中

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

1204      private WindowManagerService(Context context, InputManagerService inputManager,
1205              boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
1206              ActivityTaskManagerService atm, DisplayWindowSettingsProvider
1207              displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
1208              Supplier<Surface> surfaceFactory,
1209              Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
1210          installLock(this, INDEX_WINDOW);
1211          mGlobalLock = atm.getGlobalLock();
1212          mAtmService = atm;
1213          mContext = context;
1214          mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
1215          mAllowBootMessages = showBootMsgs;
1216          mOnlyCore = onlyCore;
1217          mLimitedAlphaCompositing = context.getResources().getBoolean(
1218                  com.android.internal.R.bool.config_sf_limitedAlpha);
1219          mHasPermanentDpad = context.getResources().getBoolean(
1220                  com.android.internal.R.bool.config_hasPermanentDpad);
1221          mInTouchMode = context.getResources().getBoolean(
1222                  com.android.internal.R.bool.config_defaultInTouchMode);
1223          inputManager.setInTouchMode(mInTouchMode);
1224          mDrawLockTimeoutMillis = context.getResources().getInteger(
1225                  com.android.internal.R.integer.config_drawLockTimeoutMillis);
1226          mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
1227                  com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
1228          mMaxUiWidth = context.getResources().getInteger(
1229                  com.android.internal.R.integer.config_maxUiWidth);
1230          mDisableTransitionAnimation = context.getResources().getBoolean(
1231                  com.android.internal.R.bool.config_disableTransitionAnimation);
1232          mPerDisplayFocusEnabled = context.getResources().getBoolean(
1233                  com.android.internal.R.bool.config_perDisplayFocusEnabled);
1234          mAssistantOnTopOfDream = context.getResources().getBoolean(
1235                  com.android.internal.R.bool.config_assistantOnTopOfDream);
1236  
1237          mLetterboxConfiguration = new LetterboxConfiguration(context);
1238  // 缓存了 inputManager
1239          mInputManager = inputManager; // Must be before createDisplayContentLocked.

3)启动 InputManagerService

InputManager 类继承自 InputManagerInterface 接口,是系统处理输入事件的核心。 InputManager 包含两个线程:

  • InputReader  Thread(称为“ InputReader”)读取并预处理原始输入事件EventHub->getEvents,应用策略
  • InputDispatcher  Thread(称为“ InputDispatcher”)线程在队列上等待新事件,然 后异步将其分配给应用程序。

首先InputManagerService 设置callback: setWindowManagerCallbacks

该callback是:

4746      final InputManagerCallback mInputManagerCallback = new InputManagerCallback(this);

/frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java

    public InputManagerCallback(WindowManagerService service) {mService = service;}// 看起来是和回调通知消息给 wms相关public void notifyNoFocusedWindowAnr(@NonNull InputApplicationHandle applicationHandle) {mService.mAnrController.notifyAppUnresponsive(applicationHandle, "Application does not have a focused window");}

设置callback: setWindowManagerCallbacks

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

    public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {// 保证只有一个 callbackif (mWindowManagerCallbacks != null) {unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);}
// 缓存这个callbackmWindowManagerCallbacks = callbacks;registerLidSwitchCallbackInternal(mWindowManagerCallbacks);}

启动 InputManagerService

    public void start() {Slog.i(TAG, "Starting input manager");// native 去启动startnativeStart(mPtr);// Add ourself to the Watchdog monitors.Watchdog.getInstance().addMonitor(this);registerPointerSpeedSettingObserver();registerShowTouchesSettingObserver();.........

nativeStart

/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);// 获取到 InputManager 对象,调用其start 的方法status_t result = im->getInputManager()->start();if (result) {jniThrowRuntimeException(env, "Input manager could not be started.");}
}

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

status_t InputManager::start() {// 调用InputDispatcher 的start 方法status_t result = mDispatcher->start();if (result) {ALOGE("Could not start InputDispatcher thread due to error %d.", result);return result;}// 调用InputReader 的start 方法result = mReader->start();if (result) {ALOGE("Could not start InputReader due to error %d.", result);mDispatcher->stop();return result;}return OK;
}

// 调用InputDispatcher 的start 方法

/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

status_t InputDispatcher::start() {if (mThread) {return ALREADY_EXISTS;}// 再系统进程中创建线程,名字为 "InputDispatcher"
// 创建 InputThread 线程,传入lambda循环函数dispatchOncemThread = std::make_unique<InputThread>("InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });return OK;
}=============/frameworks/native/services/inputflinger/InputThread.cpp// 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;// 会调用 threadLoop,执行loop方法bool threadLoop() override {mThreadLoop();return true;}
};} // namespace// 创建 InputThread
InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake): mName(name), mThreadWake(wake) {// 创建InputThreadImpl对象,传入 loop函数mThread = new InputThreadImpl(loop);
// 开启线程循环。mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}

/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

执行loop 方法 

void InputDispatcher::dispatchOnce() {nsecs_t nextWakeupTime = LONG_LONG_MAX;{ // acquire lockstd::scoped_lock _l(mLock);mDispatcherIsAlive.notify_all();// Run a dispatch loop if there are no pending commands.// The dispatch loop might enqueue commands to run afterwards.if (!haveCommandsLocked()) {dispatchOnceInnerLocked(&nextWakeupTime);}// Run all pending commands if there are any.// If any commands were run then force the next poll to wake up immediately.if (runCommandsLockedInterruptible()) {nextWakeupTime = LONG_LONG_MIN;}// If we are still waiting for ack on some events,// we might have to wake up earlier to check if an app is anr'ing.const nsecs_t nextAnrCheck = processAnrsLocked();nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);// We are about to enter an infinitely long sleep, because we have no commands or// pending or queued eventsif (nextWakeupTime == LONG_LONG_MAX) {mDispatcherEnteredIdle.notify_all();}} // release lock// Wait for callback or timeout or wake.  (make sure we round up, not down)nsecs_t currentTime = now();int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);mLooper->pollOnce(timeoutMillis);
}

// 调用InputReader 的start 方法

/frameworks/native/services/inputflinger/reader/InputReader.cpp

status_t InputReader::start() {if (mThread) {return ALREADY_EXISTS;}// 同理,也是在系统进程中创建一个线程,名字为 InputReader
// 执行方法 loopOnce()mThread = std::make_unique<InputThread>("InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });return OK;
}============
void InputReader::loopOnce() {int32_t oldGeneration;int32_t timeoutMillis;bool inputDevicesChanged = false;std::vector<InputDeviceInfo> inputDevices;{ // acquire lockstd::scoped_lock _l(mLock);oldGeneration = mGeneration;timeoutMillis = -1;uint32_t changes = mConfigurationChangesToRefresh;if (changes) {mConfigurationChangesToRefresh = 0;timeoutMillis = 0;refreshConfigurationLocked(changes);} else if (mNextTimeout != LLONG_MAX) {nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);}} // release lock// 去从驱动中读取input 事件size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);{ // acquire lockstd::scoped_lock _l(mLock);mReaderIsAliveCondition.notify_all();if (count) {processEventsLocked(mEventBuffer, count);}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com