framework——IMS启动流程

1 前言

IMS 是 InputManagerService 的简称,主要负责输入事件管理。

1.1 基本概念

  • 输入设备:屏幕、电源/音量、键鼠、充电口、蓝牙、wifi 等
  • 设备节点:当输入设备可用时,Linux 内核会在 /dev/input 中创建对应的设备节点
  • 输入事件:触摸事件、按键事件、鼠标事件、插拔事件等
  • 输入子系统:负责采集 Linux 内核中输入事件原始信息,原始信息由 Kernel space 的驱动层一直传递到 User space 的设备节点

IMS 所做的工作就是监听 /dev/input 下的所有的设备节点,当设备节点有数据时,对数据进行加工处理并找到合适的 Window,将输入事件派发给它。

1.2 IMS 框架

framework——IMS启动流程_第1张图片

(1)EventHub

  • 监听、扫描、打开 /dev/input 目录下的输入设备
  • 根据配置文件和键值映射文件对设备进行配置和键值映射
  • 将所有设备添加到本地列表中
  • 抽取驱动程序上报的 inputEvent,主要包含设备可用性变化事件(设备事件)、设备节点中读取的原始输入事件。

(2)InputReader

  • 根据设备类型添加不同 InputMapper
  • 通过 EventHub.getEvents() 获取 EventHub 中未处理的事件

(3)InputDispatcher

  • 事件过滤,并发给上层。

2 Java 层 IMS 初始化流程

2.1 IMS 启动流程

(1)main

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

public static void main(String[] args) {
    new SystemServer().run();
}

(2)run

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

private void run() {
	try {
		...
		// 创建Looper
		Looper.prepareMainLooper();
		// 加载libandroid_servers.so
		System.loadLibrary("android_servers");
		// 创建系统的 Context:ContextImpl.createSystemContext(new ActivityThread())
		createSystemContext();
		// 创建 SystemServiceManager
		mSystemServiceManager = new SystemServiceManager(mSystemContext);
		LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
		...
	}
	...
	try {
		//启动引导服务,ActivityManagerService、ActivityTaskManagerService、PackageManagerService、PowerManagerService、DisplayManagerService 等
		startBootstrapServices(); 
		//启动核心服务,BatteryService、UsageStatusService 等
		startCoreServices(); 
		//启动其他服务,InputManagerService、WindowManagerService、CameraService、AlarmManagerService 等
		startOtherServices(); 
		...
	}
	...
	// 开启消息循环
	Looper.loop();
}

(3)startOtherServices

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

private void startOtherServices() {
	...
	WindowManagerService wm = null;
	...
	InputManagerService inputManager = null;
	...
	try {
        ...
        inputManager = new InputManagerService(context);
		...
        //PhoneWindowManager 是 WMP 的实现类
		wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
		ServiceManager.addService(Context.WINDOW_SERVICE, wm, false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
		ServiceManager.addService(Context.INPUT_SERVICE, inputManager, false, DUMP_FLAG_PRIORITY_CRITICAL);
		...
		mActivityManagerService.setWindowManager(wm);
		...
		wm.onInitReady(); //initPolicy
		...
        //wm 的 mInputManagerCallback 属性在定义时就被初始化
		inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
		inputManager.start();
		...
	}
}

通过 ServiceManager.addService() 将 Context.INPUT_SERVICE 与 IMS 绑定,因此在其他进程中可以通过如下方式获取 IMS。

IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); 
IInputManager im = IInputManager.Stub.asInterface(b);

2.2 IMS 初始化

(1)构造方法

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

public InputManagerService(Context context) {
	this.mContext = context;
	//在 android.display 线程中处理消息
	this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
	...
	//mPtr 为 JNI 层 NativeInputManager 对象的地址
	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());
}

nativeInit() 方法在 JNI 层创建了 NativeInputManager 对象,并返回其地址(后文会介绍);LocalService 是 IMS 的内部类,也是 InputManagerInternal 的实现类。 

(2)setWindowManagerCallbacks

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

public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
	mWindowManagerCallbacks = callbacks;
}

callbacks 来自 WMS.mInputManagerCallback,属于 InputManagerCallback 类(IMS.WindowManagerCallbacks 的实现类),WMS.mInputManagerCallback 在定义时就被初始化。

(3)start

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

public void start() {
	//启动 Native 层的 InputReaderThread 和 InputDispatcherThread 线程
	nativeStart(mPtr);
	//注册监听器
	registerPointerSpeedSettingObserver();
	registerShowTouchesSettingObserver();
	registerAccessibilityLargePointerSettingObserver();

	mContext.registerReceiver(new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			updatePointerSpeedFromSettings();
			updateShowTouchesFromSettings();
			updateAccessibilityLargePointerFromSettings();
		}
	}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);

	updatePointerSpeedFromSettings();
	updateShowTouchesFromSettings();
	updateAccessibilityLargePointerFromSettings();
}

nativeStart() 方法启动 Native 层 InputReaderThread 和 InputDispatcherThread 线程(后面会介绍)。

3 Native 层 IMS 初始化流程

本节主要介绍 IMS 构造方法中调用 nativeInit() 方法、start() 方法中调用 nativeStart() 方法的后续流程。

如图,展示了 IMS 初始化流程,浅蓝色、绿色、紫色分别表示 Java 层、JNI 层、Native 层。

framework——IMS启动流程_第2张图片

3.1 nativeInit 后续流程

(1)gInputManagerMethods

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

static const JNINativeMethod gInputManagerMethods[] = {
	//Java 层调用的 nativeInit 方法对应 JNI 层的 nativeInit 方法
    { "nativeInit",
            "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)J",
            (void*) nativeInit },
	//Java 层调用的 nativeStart 方法对应 JNI 层的 nativeStart 方法
    { "nativeStart", "(J)V",
            (void*) nativeStart },
	...
}

 gInputManagerMethods 数组列出了 Java 层调用 nativeInit()、nativeStart() 方法到 JNI 层具体调用方法的映射关系。

(2)nativeInit

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

//Java 层调用:mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
static jlong nativeInit(JNIEnv* env, jclass, jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
	//获取 JNI 层消息队列
    sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    ...
	//创建 NativeInputManager
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper());
    im->incStrong(0);
    //返回 NativeInputManager 对象指针给 Java 层(mPtr)
    return reinterpret_cast(im);
}

 NativeInputManager 是在该文件中定义的类。

(3)NativeInputManager

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

#include 

NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp& looper) : 
		mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();
    mServiceObj = env->NewGlobalRef(serviceObj);
    ...
    mInteractive = true;
	//创建 Native 层 InputManager,2 个 this 分别为:InputReaderPolicyInterface、InputDispatcherPolicyInterface
    mInputManager = new InputManager(this, this);
    defaultServiceManager()->addService(String16("inputflinger"), mInputManager, false);
}

 NativeInputManager 实现了 RefBase、InputReaderPolicyInterface、InputDispatcherPolicyInterface、PointerControllerPolicyInterface 4个接口。

 InputManager.h 中定义了抽象的 InputManager 类,InputManager.cpp 实现了 InputManager.h 中的抽象方法。

(4)InputManager

/frameworks/native/services/inputflinger/InputManager.h

class InputManager : public InputManagerInterface, public BnInputFlinger {
	...
public:
    InputManager(const sp& readerPolicy, const sp& dispatcherPolicy);
    virtual status_t start();
    ...
    virtual void setInputWindows(const std::vector& handles, const sp& setInputWindowsListener);
	virtual void transferTouchFocus(const sp& fromToken, const sp& toToken);
    ...
    virtual void registerInputChannel(const sp& channel);
private:
    sp mReader;
    sp mReaderThread;
	sp mClassifier;
    sp mDispatcher;
    sp mDispatcherThread;
	void initialize();
};

注意:InputManager 继承了 BnInputFlinger 接口(Binder 跨进程通讯的服务端)。

(5)InputManager

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

#include "InputManager.h"
#include "InputReaderFactory.h"

InputManager::InputManager(const sp& readerPolicy, const sp& dispatcherPolicy) {
	//创建 InputDispatcher
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mClassifier = new InputClassifier(mDispatcher);
	//创建 InputReader,createInputReader() 是 InputReaderFactory 类的方法
    mReader = createInputReader(readerPolicy, mClassifier);
    initialize();
}

(6)InputDispatcher

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

InputDispatcher::InputDispatcher(const sp& policy) :
    mPolicy(policy), ... {
	//创建消息循环
    mLooper = new Looper(false);
    mReporter = createInputReporter();
    ...
    policy->getDispatcherConfiguration(&mConfig);
}

(7)createInputReader

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

sp createInputReader(const sp& policy, const sp& listener) {
    return new InputReader(new EventHub(), policy, listener);
}

注意:此处创建了 EventHub,并注入到 InputReader 中。 

(8)InputReader

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

InputReader::InputReader(const sp& eventHub, const sp& policy, const sp& listener) :
        mContext(this), mEventHub(eventHub), mPolicy(policy), ... {
    mQueuedListener = new QueuedInputListener(listener);
    ...
}

(9)EventHub

/frameworks/native/services/inputflinger/EventHub.cpp

EventHub::EventHub(void) :
        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
        mOpeningDevices(nullptr), mClosingDevices(nullptr),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false), mNeedToScanDevices(true),
        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
    ...
    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
    ...
    mINotifyFd = inotify_init();
    mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
    ...
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
    ...
    int wakeFds[2];
    result = pipe(wakeFds);
    ...
    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];
    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
    ...
    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
    ...
    eventItem.data.fd = mWakeReadPipeFd;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
    ...
}

(10)initialize

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

void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}

 InputReaderThread 和 InputDispatcherThread 都继承了 Thread 类。

在 InputManager.h 文件中,已申明 InputReaderThread 和 InputDispatcherThread 的源码不再开源,如下。

/*
 * By design, the InputReaderThread class and InputDispatcherThread class do not share any
 */

3.2 nativeStart 后续流程

(1)nativeStart

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

static void nativeStart(JNIEnv* env, jclass, jlong ptr) {
    //通过对象地址获取 NativeInputManager 对象指针
    NativeInputManager* im = reinterpret_cast(ptr);
    //调用 Native 层 InputManager 的 start() 方法
    status_t result = im->getInputManager()->start();
    ...
}

inline sp getInputManager() const {
	return mInputManager; 
}

(2)start

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

status_t InputManager::start() {
	//开启 DispatcherThread 线程
    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    ...
	//开启 ReaderThread 线程
    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
	...
    return OK;
}

 

你可能感兴趣的:(framework,IMS启动流程,framework,Android)