Android13 InputManagerService启动流程分析

InputManagerService由SystemServer启动,整体流程如下:

 代码如下:

//frameworks/base/core/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {
    private void startOtherServices() {  
           ........
           //调用构造函数
           inputManager = new InputManagerService(context);
           ......
           //将InputManagerService添加到servicemanager中
           ServiceManager.addService(Context.INPUT_SERVICE, inputManager,  
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);  
           ......
           //将InputMonitor注册到IMS中,用于对事件筛选和派发的处理
           inputManager.setWindowManagerCallbacks(wm.getInputMonitor());  
           ......
          //调用到Native层,启动InputReader和InputDispatcher的线程循环
          inputManager.start();  
          ......
    }
 }  

上面方法主要处理如下:

1、通过new的方式创建InputManagerService对象。

2、调用inputManager的setWindowManagerCallbacks方法,将InputMonitor注册到IMS中,用于对事件筛选和派发的处理。

3、调用inputManager的start方法,启动InputReader和InputDispatcher的线程循环。

下面分别进行分析:

new InputManagerService

通过new的方式创建InputManagerService对象,InputManagerService构造方法如下:

//frameworks/base/service/core/java/android/server/input/InputManagerService.java
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
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());
        mNative = injector.getNativeService(this);


        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());
    }
}

调用Injector的getNativeService方法:

//frameworks/base/service/core/java/android/server/input/InputManagerService.java
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
    static class Injector {
        NativeInputManagerService getNativeService(InputManagerService service) {
            return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
        }
    }
}

通过new的方式创建NativeInputManagerService.NativeImpl对象,NativeImpl的构造方法如下:

public interface NativeInputManagerService {
    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);
    }

调用init方法,该方法是native方法,在中com_android_server_inputManagerService.cpp实现:

//frameworks/base/services/core/jni/com_android_server_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());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

通过new的方式创建NativeInputManager对象,NativeInputManager的构造方法如下:

//frameworks/base/services/core/jni/com_android_server_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);
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);
}

new InputManager

通过new的方式创建InputManager对象:

//frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
    mReader = createInputReader(readerPolicy, *mBlocker);
}

上面方法的主要处理如下:

1、调用createInputDispatcher方法,创建InputDispatcher对象。

2、调用createInputReader方法,创建InputReader对象。

下面分别进行分析:

createInputDispatcher

调用createInputDispatcher方法,创建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);
}
InputDispatcher::InputDispatcher

创建InputDispatcher对象,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);
}

createInputReader

调用createInputReader方法,创建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);
}
InputReader::InputReader

创建InputReader对象,InputReader的构造方法如下:

//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::EventHub

创建EventHub对象,EventHub的构造方法如下:

//frameworks/native/services/inputflinger/reader/EventHub.cpp
EventHub::EventHub(void)
      : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
        mNextDeviceId(1),
        mControllerNumbers(),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false),
        mNeedToScanDevices(true),
        mPendingEventCount(0),
        mPendingEventIndex(0),
        mPendingINotify(false) {
    ensureProcessCanBlockSuspend();


    // 1.创建一个新的epoll实例
    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));


    // 2.创建一个新的inotify实例,Inotify API用于检测文件系统变化的机制。Inotify可用于检测单个文件,也可以检测整个目录。
    // 当目录下的设备节点发生增删事件时,可已通过 read(fd) 获取事件的详细信息
    mINotifyFd = inotify_init1(IN_CLOEXEC);


    std::error_code errorCode;
    bool isDeviceInotifyAdded = false;
    // 3.添加 /dev/input 或者 /dev 目录的Inotify
    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
        addDeviceInputInotify();
    } else {
        addDeviceInotify();
        isDeviceInotifyAdded = true;
        if (errorCode) {
            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
                  errorCode.message().c_str());
        }
    }


    if (isV4lScanningEnabled() && !isDeviceInotifyAdded) {
        addDeviceInotify();
    } else {
        ALOGI("Video device scanning disabled");
    }


    struct epoll_event eventItem = {};
    eventItem.events = EPOLLIN | EPOLLWAKEUP;
    eventItem.data.fd = mINotifyFd;
    // 4. 把 inotify 添加到 epoll 监听队列中,当 inotify 事件到来时,epoll_wait() 会立即返回,EventHub 可以从 fd 中读取设备节点的增删信息并进行处理
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance.  errno=%d", errno);


    // 5. 创建管道,fds[0] 表示管道的读端,fds[1] 表示管道的写端
    int wakeFds[2];
    result = pipe2(wakeFds, O_CLOEXEC);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);


    mWakeReadPipeFd = wakeFds[0];
    mWakeWritePipeFd = wakeFds[1];


    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); // 设置唤醒读端为非阻塞式
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
                        errno);


    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); // 设置唤醒写端为非阻塞式
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
                        errno);


    //6. 把唤醒读端的 fd 添加到 epoll 监听队列中,目的是在必要时唤醒 reader 线程
    eventItem.data.fd = mWakeReadPipeFd;
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
                        errno);
}

inputManager setWindowManagerCallbacks

调用InputManagerService的setWindowManagerCallbacks方法,将InputMonitor注册到IMS中,用于对事件筛选和派发的处理:

//frameworks/base/service/core/java/android/server/input/InputManagerService.java
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
    public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
        if (mWindowManagerCallbacks != null) {
            unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);
        }
        mWindowManagerCallbacks = callbacks;
        registerLidSwitchCallbackInternal(mWindowManagerCallbacks);
    }
}

调用InputManagerService的registerLidSwitchCallbackInternal方法:

//frameworks/base/service/core/java/android/server/input/InputManagerService.java
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
    void registerLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {
        synchronized (mLidSwitchLock) {
            mLidSwitchCallbacks.add(callback);


            // Skip triggering the initial callback if the system is not yet ready as the switch
            // state will be reported as KEY_STATE_UNKNOWN. The callback will be triggered in
            // systemRunning().
            if (mSystemReady) {
                boolean lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID)
                        == KEY_STATE_UP;
                callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);
            }
        }
    }
}

InputManagerService start

调用InputManagerService 的start方法:

//frameworks/base/service/core/java/android/server/input/InputManagerService.java
public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
    private final NativeInputManagerService mNative;
    public void start() {
        Slog.i(TAG, "Starting input manager");
        mNative.start();


        // Add ourselves to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);


        registerPointerSpeedSettingObserver();
        registerShowTouchesSettingObserver();
        registerAccessibilityLargePointerSettingObserver();
        registerLongPressTimeoutObserver();
        registerMaximumObscuringOpacityForTouchSettingObserver();
        registerBlockUntrustedTouchesModeSettingObserver();


        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updatePointerSpeedFromSettings();
                updateShowTouchesFromSettings();
                updateAccessibilityLargePointerFromSettings();
                updateDeepPressStatusFromSettings("user switched");
            }
        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);


        updatePointerSpeedFromSettings();
        updateShowTouchesFromSettings();
        updateAccessibilityLargePointerFromSettings();
        updateDeepPressStatusFromSettings("just booted");
        updateMaximumObscuringOpacityForTouchFromSettings();
        updateBlockUntrustedTouchesModeFromSettings();
    }
}

调用mNative(NativeInputManagerService)的start方法,NativeInputManagerService是一个接口,start是一个Native方法,在com_android_server_input_inputManagerService.cpp中实现:

//frameworks/base/services/core/jni/com_android_server_input_inputManagerService.cpp
static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);


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

InputManager start

调用getInputManager获取InputManagerInterface对象,然后调用InputManagerInterface的start方法,InputManagerInterface是一个接口,由InputManager实现:

//frameworks/native/services/inputflinger/InputManager.cpp
std::unique_ptr<InputDispatcherInterface> mDispatcher;
std::unique_ptr<InputReaderInterface> mReader;
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、调用mDispatcher(InputDispatcherInterface)的start方法。

2、调用mReader(InputReaderInterface)的start方法。

下面分别进行分析:

InputDispatcher start

调用mDispatcher(InputDispatcherInterface)的start方法,InputDispatcherInterface是一个接口,由InputDispatcher实现,InputDispatcher的start方法会创建一个线程,然后开启线程Loop,循环处理输入事件:

//frameworks/native/services/inputflinger/dispatcher/InputDispatcher.java
status_t InputDispatcher::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
    return OK;
}
InputDispatcher dispatchOnce

InputDispatcher在start() 方法中会启动一个线程,在被唤醒后会调用到dispatchOnce 方法,在该方法中,通过调用dispatchOnceInnerLocked来分发事件:

Android13 InputDispatcher dispatchOnce流程分析-CSDN博客

InputReader start

调用mReader(InputReaderInterface)的start方法,InputReaderInterface是一个接口,由InputReader实现,

Android13 InputReader start流程分析-CSDN博客

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值