input按鍵輸入源碼分析

我們基於android 5.1源碼對input按鍵輸入進行源碼分析。

1.0 InputManagerService.java

我們知道framework對input輸入的分發處理是在InputManagerService.java中進行的,爲了知道這個是怎麼啓動的,我們全局搜索“InputManagerService”,搜索結果如下所示(省略了無關部分),

39 435 frameworks/base/services/java/com/android/server/SystemServer.java <<>>
InputManagerService inputManager = null;
40 536 frameworks/base/services/java/com/android/server/SystemServer.java <<>>
inputManager = new InputManagerService(context);
41 1034 frameworks/base/services/java/com/android/server/SystemServer.java <<>>
mSystemServiceManager.startService(TvInputManagerService.class);
42 1168 frameworks/base/services/java/com/android/server/SystemServer.java <<>>
final InputManagerService inputManagerF = inputManager;

由上面的結果我們可以看到SystemServer.java這個文件應該很重要,所有的系統服務都是在這裏啓動的。我們看下SystemServer.java這個文件。

1.1 frameworks/base/services/java/com/android/server/SystemServer.java
我們先來大概看下SystemServer的執行流程。

  public static void main(String[] args) {
      /* @SPRD: Create hporfile directory for hporfile. @{ */
      String hprofile_path = android.os.Environment.getDataDirectory() + "/misc/hprofs/";
      File dir = new File(hprofile_path);
      if (!dir.exists()) {
          if (!dir.mkdirs()) {
              Log.w(TAG, "Path{" + hprofile_path + "} does not exist, and failed to create.");
          } else {
              Log.w(TAG, "Path{" + hprofile_path + "} does not exist, and success to create.");
              try {
                  libcore.io.Libcore.os.chmod(hprofile_path, 0777);
              } catch (Exception e) {
                  Log.w(TAG, "Failed to chmod(" + hprofile_path + "): " + e);
              }
          }
      }
      /* @} */
      new SystemServer().run();
 }

這個main()做的最重要的一件事情就是new SystemServer().run();

1.1.1 private void run()
經過上面的流程我們知道,run()中進行了重要的操作,我們來看下:
private void run() {
………………….
// Start services.
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
throw ex;
}

      // For debug builds, log event loop stalls to dropbox for analysis.
      if (StrictMode.conditionallyEnableDebugLogging()) {
          Slog.i(TAG, "Enabled StrictMode for system server main thread.");
      }

      // Loop forever.
      Looper.loop();
      throw new RuntimeException("Main thread loop unexpectedly exited");
  }

從上面我們看到,這個run()最重要的是三個start服務:
startBootstrapServices();
startCoreServices();
startOtherServices();
其實這三個都是啓動服務,只是根據服務的種類分別在不同的調用裏面去啓動,在這裏我們就不一一去進行分析了,我們只關注input這個相關的,通過大概瀏覽我們知道input的服務啓動是在
startOtherServices()
這個裏面,其他的我們在以後的章節裏再進行分析,我們來看startOtherServices()
private void startOtherServices() {
…………………
InputManagerService inputManager = null;
………………..
Slog.i(TAG, “Input Manager”);
inputManager = new InputManagerService(context);
Slog.i(TAG, “Window Manager”);
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

   mActivityManagerService.setWindowManager(wm);
   inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
   ***inputManager.start();***
 }

inputManager.start() 啓動了input服務了。

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

首先就new了一個InputManagerHandler線程來處理消息,然後調用nativeInit去完成初natvie層的初始化。
private final class InputManagerHandler extends Handler {
public InputManagerHandler(Looper looper) {
super(looper, null, true /async/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DELIVER_INPUT_DEVICES_CHANGED:
deliverInputDevicesChanged((InputDevice[])msg.obj);
break;
case MSG_SWITCH_KEYBOARD_LAYOUT:
handleSwitchKeyboardLayout(msg.arg1, msg.arg2);
break;
case MSG_RELOAD_KEYBOARD_LAYOUTS:
reloadKeyboardLayouts();
break;
case MSG_UPDATE_KEYBOARD_LAYOUTS:
updateKeyboardLayouts();
break;
case MSG_RELOAD_DEVICE_ALIASES:
reloadDeviceAliases();
break;
}
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章