1 输入事件的处理流程
输入系统大致可分为三部分,输入系统部分、WMS部分和View处理部分。用户输入需要通过输入子系统将原始信息转化为事件交由InputManagerService进行处理加工并找到合适的Window,将事件分发到对应的Window。
2 InputManagerService的创建
2.1 SystemServer创建IMS
SystemServer初始化从main方法开始
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
main方法中只是调用了SystemServer的run方法。
frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
...
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t); //启动引导服务
startCoreServices(t); //启动核心服务
startOtherServices(t); //启动其他服务
startApexServices(t); //启动apex相关的服务
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
...
在run方法中启动了各种系统服务,其中IMS是在其他服务中启动的。
frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
InputManagerService inputManager = null;
...
t.traceBegin("StartInputManagerService"); //1
inputManager = new InputManagerService(context);
t.traceEnd();
...
t.traceBegin("StartWindowManagerService"); //2
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();
...
t.traceBegin("StartInputManager"); //3
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();
t.traceEnd();
...
这里截取了其中IMS被WMS创建和启动的部分。IMS使用的是InputManagerService类的构造器去创建的,后面调用IMS的start方法去启动。WMS则是通过WMS的main方法去创建的,其中第二个参数就是上面创建的IMS的对象,这样IMS就和WMS相关联了,接着将WMS和IMS添加到ServiceManager进行管理。
2.2 InputManagerService的构造函数
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
/** Point of injection for test dependencies. */
@VisibleForTesting
static class Injector {
private final Context mContext;
private final Looper mLooper;
Injector(Context context, Looper looper) {//1
mContext = context;
mLooper = looper;
}
Context getContext() {
return mContext;
}
Looper getLooper() {
return mLooper;
}
NativeInputManagerService getNativeService(InputManagerService service) {
return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
}
void registerLocalService(InputManagerInternal localService) {
LocalServices.addService(InputManagerInternal.class, localService);
}
}
public InputManagerService(Context context) {
this(new Injector(context, DisplayThread.get().getLooper())); //2
}
@VisibleForTesting
InputManagerService(Injector injector) {
// The static association map is accessed by both java and native code, so it must be
// initialized before initializing the native service.
mStaticAssociations = loadStaticInputPortAssociations();
mContext = injector.getContext();
mHandler = new InputManagerHandler(injector.getLooper()); //3
mNative = injector.getNativeService(this); //4
mUseDevInputEventForAudioJack =
mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
String doubleTouchGestureEnablePath = mContext.getResources().getString(
R.string.config_doubleTouchGestureEnableFile);
mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
new File(doubleTouchGestureEnablePath);
injector.registerLocalService(new LocalService());
}
注释2处是InputManagerService的构造函数,调用的是InputManagerService(Injector injector)这个重载的构造函数,传入的参数是一个新建的Injector对象,调用注释1处的Injector静态内部类的构造函数,传入的是android.display线程的Looper,在注释3处获取该Looper来创建InputManagerHandler对象。这样InputManagerHandler就运行在android.display线程,该线程是系统共享的单例前台线程,这个线程内部执行了WMS的创建。
注释4处调用了Injector类中的getNativeService方法,返回的是NativeInputManagerService.NativeImpl的一个实例对象。
frameworks/base/services/core/java/com/android/server/input/NativeInputManagerService.java
class NativeImpl implements NativeInputManagerService {
/** Pointer to native input manager service object, used by native code. */
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final long mPtr;
NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
mPtr = init(service, context, messageQueue);
}
private native long init(InputManagerService service, Context context,
MessageQueue messageQueue); //1
...
}
初始化调用的是native层的init方法。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());//1
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
在注释1处创建了InputManager,构造函数如下:
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
JNIEnv* env = jniEnv();
mServiceObj = env->NewGlobalRef(serviceObj);
{
AutoMutex _l(mLock);
mLocked.systemUiLightsOut = false;
mLocked.pointerSpeed = 0;
mLocked.pointerAcceleration = android::os::IInputConstants::DEFAULT_POINTER_ACCELERATION;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
}
mInteractive = true;
InputManager* im = new InputManager(this, this);//1
mInputManager = im;
defaultServiceManager()->addService(String16("inputflinger"), im);
}
注释1处创建了InputManager对象,并将其添加到servicemanager进行管理。
frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = createInputDispatcher(dispatcherPolicy); //1
mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
mReader = createInputReader(readerPolicy, *mBlocker); //2
}
InputManager的构造函数中创建了InputDispatcher(注释1处)和InputReader(注释2处)。InputReader会不断读取EventHub中的原始信息进行加工并交给InputDispatcher,InputDispatcher中保存了Window的信息,可以将事件信息派发到合适的窗口。InputReader和InputDispatcher都是耗时的操作,在单独的线程中执行。
2.3 InputDispatcher和InputReader初始化
- InputDispatcher的初始化
frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cpp
std::unique_ptr<InputDispatcherInterface> createInputDispatcher(
const sp<InputDispatcherPolicyInterface>& policy) {
return std::make_unique<android::inputdispatcher::InputDispatcher>(policy);
}
使用std:make_unique调用InputDispatcher的构造函数,其构造函数如下:
frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
std::chrono::nanoseconds staleEventTimeout)
: mPolicy(policy),
mPendingEvent(nullptr),
mLastDropReason(DropReason::NOT_DROPPED),
mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
mAppSwitchSawKeyDown(false),
mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(nullptr),
mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
mDispatchEnabled(false),
mDispatchFrozen(false),
mInputFilterEnabled(false),
// mInTouchMode will be initialized by the WindowManager to the default device config.
// To avoid leaking stack in case that call never comes, and for tests,
// initialize it here anyways.
mInTouchMode(kDefaultInTouchMode),
mMaximumObscuringOpacityForTouch(1.0f),
mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
mWindowTokenWithPointerCapture(nullptr),
mStaleEventTimeout(staleEventTimeout),
mLatencyAggregator(),
mLatencyTracker(&mLatencyAggregator) {
mLooper = new Looper(false);
mReporter = createInputReporter();
mWindowInfoListener = new DispatcherWindowListener(*this);
SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
mKeyRepeatState.lastKeyEntry = nullptr;
policy->getDispatcherConfiguration(&mConfig);
}
InputDispatcher的构造函数中创建了Looper和InputReporter,也创建了对于Window的监听器。
- InputReader初始化
frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp
std::unique_ptr<InputReaderInterface> createInputReader(
const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) {
return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener);
}
使用std:make_unique调用InputDispatcher的构造函数,其构造函数如下:
frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
const sp<InputReaderPolicyInterface>& policy,
InputListenerInterface& listener)
: mContext(this),
mEventHub(eventHub),
mPolicy(policy),
mQueuedListener(listener),
mGlobalMetaState(AMETA_NONE),
mLedMetaState(AMETA_NONE),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
refreshConfigurationLocked(0);
updateGlobalMetaStateLocked();
}
初始化了EventHub等参数。