Android系统源码分析Input - 启动流程

Input是Android 平台中负责处理用户输入事件核心组件,他的主要作用有:从各种硬件设备(触摸屏、物理键盘、鼠标等)接收原始输入事件、将输入事件传递给正确的应用程序和视图、识别多点触控手势。Input是Android实现流畅人机交互的基础设施,直接影响用户体验的质量。因此我们有必要进行深入理解。

  1. 在SystemServer启动过程中会启动很多系统服务,其中就包括InputManagerServic。可以看到在创建WindowManagerService的时候把inputManager传了进去,并且在InputManagerService中设置了WindowManagerCallbacks,这样他们就可以互相通信了。
ini 复制代码
// frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    WindowManagerService wm = null;
    InputManagerService inputManager = null;
    ...
    
    inputManager = new InputManagerService(context);
    ...
    
    wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
        new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
                | DUMP_FLAG_PROTO);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
    ...
    
    inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());    
}
  1. 在InputManagerService的构造过程中,创建了NativeInputManagerService.NativeImpl。NativeImpl的构造器调用了init(),这是个jni接口。
scss 复制代码
// frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

static class Injector {
    Injector(Context context, Looper looper, UEventManager uEventManager) {
        mContext = context;
        mLooper = looper;
        mUEventManager = uEventManager;
    }
    ...
    
    NativeInputManagerService getNativeService(InputManagerService service) {
        return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue());
    }
}

public InputManagerService(Context context) {
    this(new Injector(context, DisplayThread.get().getLooper(), new UEventManager() {}));
}

InputManagerService(Injector injector) {
    ...
    mNative = injector.getNativeService(this);
    ...
}
java 复制代码
// frameworks/base/services/core/java/com/android/server/input/NativeInputManagerService.java

class NativeImpl implements NativeInputManagerService {
@SuppressWarnings({"unused", "FieldCanBeLocal"})
    private final long mPtr;

    NativeImpl(InputManagerService service, MessageQueue messageQueue) {
        mPtr = init(service, messageQueue);
    }
    
    private native long init(InputManagerService service, MessageQueue messageQueue);
}    
  1. init方法中创建了NativeInputManager,这里和java层使用了同一个looper。
ini 复制代码
// frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
                        jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == nullptr) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    static std::once_flag nativeInitialize;
    NativeInputManager* im = nullptr;
    std::call_once(nativeInitialize, [&]() {
        // Create the NativeInputManager, which should not be destroyed or deallocated for the
        // lifetime of the process.
        im = new NativeInputManager(serviceObj, messageQueue->getLooper());
    });
    LOG_ALWAYS_FATAL_IF(im == nullptr, "NativeInputManager was already initialized.");
    return reinterpret_cast<jlong>(im);
}
  1. NativeInputManager构造器中创建了InputManager,并注册了inputflinger服务
scss 复制代码
// frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp


NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper)
      : mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();

    mServiceObj = env->NewGlobalRef(serviceObj);

    InputManager* im = new InputManager(this, *this, *this, *this);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
}
  1. 创建InputManager时传入的四个参数用于回调java层。这里创建了InputDispacher和InputReader。SystemServer调用InputManagerService的start(),最终会调用到InputManager的start()。这里又分别调用了InputDispacher和InputReader的start()
ini 复制代码
// frameworks/native/services/inputflinger/InputManager.cpp

InputManager::InputManager(const sp<InputReaderPolicyInterface>& readerPolicy,
                           InputDispatcherPolicyInterface& dispatcherPolicy,
                           PointerChoreographerPolicyInterface& choreographerPolicy,
                           InputFilterPolicyInterface& inputFilterPolicy) {

    // 创建Dispacher
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    // 将InputDispacher封装为TracedInputListener,并添加到mTracingStages中
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("InputDispatcher", *mDispatcher));

    if (ENABLE_INPUT_FILTER_RUST) {
        mInputFilter = std::make_unique<InputFilter>(*mTracingStages.back(), *mInputFlingerRust,
                                                     inputFilterPolicy);
        mTracingStages.emplace_back(
                std::make_unique<TracedInputListener>("InputFilter", *mInputFilter));
    }

    if (ENABLE_INPUT_DEVICE_USAGE_METRICS) {
        mCollector = std::make_unique<InputDeviceMetricsCollector>(*mTracingStages.back());
        mTracingStages.emplace_back(
                std::make_unique<TracedInputListener>("MetricsCollector", *mCollector));
    }

    mProcessor = std::make_unique<InputProcessor>(*mTracingStages.back());
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("InputProcessor", *mProcessor));

    mChoreographer =
            std::make_unique<PointerChoreographer>(*mTracingStages.back(), choreographerPolicy);
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("PointerChoreographer", *mChoreographer));

    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mTracingStages.back());
    mTracingStages.emplace_back(
            std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker));

    mReader = createInputReader(readerPolicy, *mTracingStages.back());
    }back(
            std::make_unique<TracedInputListener>("UnwantedInteractionBlocker", *mBlocker));
    // 创建InputReader时将mTracingStages传给InputReader
    mReader = createInputReader(readerPolicy, *mTracingStages.back());
}

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;
}
  1. 在创建InputReader时,创建了EventHub。
ruby 复制代码
// frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp

std::unique_ptr<InputDispatcherInterface> createInputDispatcher(
        InputDispatcherPolicyInterface& policy) {
    return std::make_unique<android::inputdispatcher::InputDispatcher>(policy);
}
  1. InputDispatcher和InputReader分别在start()中创建了自己的线程
ruby 复制代码
// frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
                                 std::unique_ptr<trace::InputTracingBackendInterface> traceBackend) {
    mLooper = sp<Looper>::make(false);
    ...
}

status_t InputDispatcher::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }

    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
    return OK;
}
kotlin 复制代码
// frameworks/native/services/inputflinger/reader/InputReader.cpp

status_t InputReader::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }

    mThread = std::make_unique<InputThread>(
            "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
    return OK;
}
相关推荐
coder_pig2 小时前
🤡 公司Android老项目升级踩坑小记
android·flutter·gradle
死就死在补习班3 小时前
Android系统源码分析Input - InputReader读取事件
android
死就死在补习班3 小时前
Android系统源码分析Input - InputChannel通信
android
死就死在补习班3 小时前
Android系统源码分析Input - 设备添加流程
android
tom4i3 小时前
Launcher3 to Launchpad 01 布局修改
android
雨白4 小时前
OkHttpClient 核心配置详解
android·okhttp
淡淡的香烟4 小时前
Android auncher3实现简单的负一屏功能
android
RabbitYao4 小时前
Android 项目 通过 AndroidStringsTool 更新多语言词条
android·python
RabbitYao4 小时前
使用 Gemini 及 Python 更新 Android 多语言 Excel 文件
android·python