input按键输入源码分析

来源:互联网 发布:如何看软件版本 编辑:程序博客网 时间:2024/05/01 12:22

我们基于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;
}
}
}

0 0