1【Android 12】Input相关服务的创建和启动

发布于:2022-12-25 ⋅ 阅读:(540) ⋅ 点赞:(0)

在这里插入图片描述

Input相关服务启动的起点在SystemServer.startOtherServices:

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
     */
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("startOtherServices");

        final Context context = mSystemContext;
        ......
        InputManagerService inputManager = null;
        ......

        try {
            ......

            t.traceBegin("StartInputManagerService");
            inputManager = new InputManagerService(context);
            t.traceEnd();

            ......

            t.traceBegin("StartInputManager");
            inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
            inputManager.start();
            t.traceEnd();
            
            ....
        }    
    }

1)、创建了一个InputManagerService对象inputManager。

2)、调用了InputManagerService.start方法。

先分析InputManagerService的创建流程,然后再分析start流程。

在这里插入图片描述

1 创建

在这里插入图片描述

1.1 InputManagerService.init

    public InputManagerService(Context context) {
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());

        mStaticAssociations = loadStaticInputPortAssociations();
        mUseDevInputEventForAudioJack =
                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
                + mUseDevInputEventForAudioJack);
        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());
    }

初始化了一些成员变量,唯一需要注意的是mPtr保存了一个指向Native层的input相关服务对象的指针:

    // Pointer to native input manager service object.
    private final long mPtr;

我们重点关注nativeInit的部分。

1.2 com_android_server_input_InputManagerService.nativeInit

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());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

这里调用了JNI层InputManagerService的nativeInit函数。

这一步创建了一个NativeInputManager实例。

1.3 NativeInputManager.init

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.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
        mLocked.pointerCapture = false;
        mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
    }
    mInteractive = true;

    InputManager* im = new InputManager(this, this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
}

这里创建了一个Native层的InputManager对象,它对应的就是之前在Java层创建的InputManagerService。

1.4 InputManager.init

InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = new InputClassifier(mDispatcher);
    mReader = createInputReader(readerPolicy, mClassifier);
}

1.4.1 创建InputDispatcher对象

sp<InputDispatcherInterface> createInputDispatcher(
        const sp<InputDispatcherPolicyInterface>& policy) {
    return new android::inputdispatcher::InputDispatcher(policy);
}

创建了一个InputDispatcher对象。

1.4.2 创建InputClassifier对象

基于上一步创建的InputDispatcher对象,创建了一个InputClassifier对象:

InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener)
      : mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this)) {}

将其内部的mListener指向了上一步创建的InputDispatcher实例,mListener是:

    // The next stage to pass input events to
    sp<InputListenerInterface> mListener;

如注释所说,InputClassifier会将输入事件传给mListener,后续我们会看到事件是怎么从InputClassifier传到InputDispatcher的。

1.4.3 创建InputReader对象

基于上一步创建的InputClassifier对象,创建一个InputReader对象:

sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,
                                           const sp<InputListenerInterface>& listener) {
    return new InputReader(std::make_unique<EventHub>(), policy, listener);
}

这里创建了一个EventHub对象,然后基于这个EventHub和之前传入的InputClassifier来创建InputReader。

InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         const sp<InputListenerInterface>& listener)
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mGlobalMetaState(0),
        mLedMetaState(AMETA_NUM_LOCK_ON),
        mGeneration(1),
        mNextInputDeviceId(END_RESERVED_ID),
        mDisableVirtualKeysTimeout(LLONG_MIN),
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    mQueuedListener = new QueuedInputListener(listener);

    { // acquire lock
        std::scoped_lock _l(mLock);

        refreshConfigurationLocked(0);
        updateGlobalMetaStateLocked();
    } // release lock
}

看到这里基于传入的InputClassifier生成了一个QueuedInputListener对象,QueuedInputListener定义在InputListener.h中:

/*
 * An implementation of the listener interface that queues up and defers dispatch
 * of decoded events until flushed.
 */
class QueuedInputListener : public InputListenerInterface {
protected:
    virtual ~QueuedInputListener();

public:
    explicit QueuedInputListener(const sp<InputListenerInterface>& innerListener);

    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
    virtual void notifyKey(const NotifyKeyArgs* args) override;
    virtual void notifyMotion(const NotifyMotionArgs* args) override;
    ......

    void flush();

private:
    sp<InputListenerInterface> mInnerListener;
    std::vector<NotifyArgs*> mArgsQueue;
};

QueuedInputListener用来在刷新前将解码后的事件进行排队和延迟分发。

这里的mArgsQueue存储的是NotifyArgs类型的对象,NotifyArgs是描述输入事件的超类,其子类有键盘事件NotifyKeyArgs和触摸事件NotifyMotionArgs等,那么mArgsQueue就是用来存储这些排队等待分发的事件的。

这里的mInnerListener赋值在QueuedInputListener的构造方法中:

QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
        mInnerListener(innerListener) {
}

那么这里的mInnerListener指向的是一个InputClassifier,QueuedInputListener调用flush函数后,mArgsQueue就会发送到mInnerListener也就是InputClassifier处。

扯远了,后面再分析具体事件是怎么从InputReader到InputClassifier再到InputDispatcher的。

1.5 小结

1)、创建了Java上层的InputManagerService,JNI层的NativeInputManager以及Native层的InputManager。

2)、Native层的InputManager在创建的时候,创建了InputReader和InputDispatcher,并且创建了一个InputClassifier对象。

3)、InputReader内部有一个成员变量mQeueuInputListener,mQeueuInputListener维护了一个当前正在排队等待分发的输入事件队列mArgsQueue,并且有一个mInnerListener成员指向InputClassifier,QueuedInputListener调用flush函数后,mArgsQueue就会发送到mInnerListener也就是InputClassifier处。

4)、InputClassifier有一个成员变量mListener,指向InputDispatcher,InputClassifer收到的事件会发送给mListener,最终,InputReader获取到的事件会通过InputClassifier发送给InputDispatcher。

2 启动

在这里插入图片描述

2.1 InputManagerService.start

    public void start() {
        Slog.i(TAG, "Starting input manager");
        nativeStart(mPtr);
        ......
    }

上面分析了InputManagerService初始化过程,现在来看InputManagerService的启动流程,这里也是调用了JNI层InputManagerService.nativeStart。

2.2 com_android_server_input_InputManagerService.nativeStart

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

这里传入的指针是之前1.2节中com_android_server_input_InputManagerService.nativeInit处得到的NativeInputManager的指针,那么这里就可以获取之前已经创建过的NativeInputManager,最后调用了Native层的InputManager.start。

2.3 InputManager.start

status_t InputManager::start() {
    status_t result = mDispatcher->start();
    if (result) {
        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
        return result;
    }

    result = mReader->start();
    if (result) {
        ALOGE("Could not start InputReader due to error %d.", result);

        mDispatcher->stop();
        return result;
    }

    return OK;
}

InputManager.start调用了InputReader.start和InputDispatcher.start,分别分析一下具体内容。

2.3.1 InputReader.start

status_t InputReader::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
    return OK;
}

这里看到,InputReader.start函数会创建一个唯一的名为“InputReader”的InputThread对象,并且赋值给InputThread类型的mThread成员变量。

InputThread的构造方法定义是:

InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
      : mName(name), mThreadWake(wake) {
    mThread = new InputThreadImpl(loop);
    mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}

可以看到,首先InputThread内部也会先创建一个InputThreadImpl类型的对象赋值给mThread成员变量,接着调用mThread.run。

InputThreadImpl继承自Thread,那么调用mThread.run会调用到InputThreadImpl的threadLoop函数,再看下InputThreadImpl的定义:

// Implementation of Thread from libutils.
class InputThreadImpl : public Thread {
public:
    explicit InputThreadImpl(std::function<void()> loop)
          : Thread(/* canCallJava */ true), mThreadLoop(loop) {}

    ~InputThreadImpl() {}

private:
    std::function<void()> mThreadLoop;

    bool threadLoop() override {
        mThreadLoop();
        return true;
    }
};

只要threadLoop函数返回true,以下语句就会一直循环调用:

mThreadLoop();

这里传入的循环函数是InputReader的loopOnce。

那么这里也就是说,调用InputReader的start函数后,会创建一个名为“InputReader”的InputThread对象,并且其内部线程mThread会一直循环调用InputReader.loopOnce函数。

2.3.2 InputDispatcher.start

status_t InputDispatcher::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
    return OK;
}

InputDispatcher.start也是同理,会创建一个名为“InputDispatcher”的InputThread对象,其内部线程mThread会一直循环调用InputDispatcher.dispatchOnce函数。

2.4 小结

1)、InputReader内部维护一个唯一的,名为“InputReader”的InputThread对象,该InputThread对象内部有一个线程会一直循环调用InputReader的loopOnce函数,这个线程可以认为是InputReader的读取线程。

2)、InputDispatcher内部维护一个唯一的,名为“InputDispatcher”的InputThread对象,该InputThread对象内部有一个线程会一直循环调用InputDispatcher的dispatchOnce函数,这个线程可以认为是InputDispatcher的分发线程。

本文含有隐藏内容,请 开通VIP 后查看