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;
}
相关推荐
2501_915909061 小时前
苹果上架App软件全流程指南:iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传与审核技巧详解
android·ios·小程序·https·uni-app·iphone·webview
2501_915921431 小时前
iOS 文件管理与能耗调试结合实战 如何查看缓存文件、优化电池消耗、分析App使用记录(uni-app开发与性能优化必备指南)
android·ios·缓存·小程序·uni-app·iphone·webview
2501_915918412 小时前
App 苹果 上架全流程解析 iOS 应用发布步骤、App Store 上架流程
android·ios·小程序·https·uni-app·iphone·webview
2501_916007472 小时前
苹果上架全流程详解,iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传与审核要点完整指南
android·ios·小程序·https·uni-app·iphone·webview
PuddingSama3 小时前
Android 高级绘制技巧: BlendMode
android·前端·面试
2501_915921433 小时前
iOS App 性能监控与优化实战 如何监控CPU、GPU、内存、帧率、耗电情况并提升用户体验(uni-app iOS开发调试必备指南)
android·ios·小程序·uni-app·iphone·webview·ux
Digitally4 小时前
如何将视频从安卓手机传输到电脑?
android·智能手机·电脑
CV资深专家4 小时前
Android 相机框架的跨进程通信架构
android
前行的小黑炭4 小时前
Android :如何提升代码的扩展性,方便复制到其他项目不会粘合太多逻辑,增强你的实战经验。
android·java·kotlin
2501_915921434 小时前
前端开发工具有哪些?常用前端开发工具、前端调试工具、前端构建工具与效率提升工具对比与最佳实践
android·前端·ios·小程序·uni-app·iphone·webview