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

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