Android输入系统(一)——初始化阶段(基于Android 13)

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等参数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值