Android R input (一) 之 InputManagerService 的建立

文章托管在gitee上 Android Notes , 同步csdn

InputManagerService 介绍

InputManagerService是重要的系统服务,负责Android输入系统的管理,职责包括但不限于:

  • 输入设备的管理
  • 输入事件的加工m
  • 输入事件的派发与反馈
  • 输入事件的派发ANR的检测

常见的输入设备是触摸屏/按键,其他支持的设备还有键盘,鼠标等. 当有新输入设备可用时,Linux内核会在/dev/input/下创建对应的名称类似eventX(X>=0)的设备节点。当输入设备不可用时,对应的节点也会被移除。通过 getevent 命令可以获取设备信息

# getevent
add device 1: /dev/input/event6
  name:     "msm8xx2-snd-card-mtp Button Jack"
add device 2: /dev/input/event5
  name:     "msm8xx2-snd-card-mtp Headset Jack"
add device 3: /dev/input/event0
  name:     "qpnp_pon"
add device 4: /dev/input/event2
  name:     "ts"
add device 5: /dev/input/event1
  name:     "soc:matrix_keypad"
add device 6: /dev/input/event3
  name:     "hall_sensor"
add device 7: /dev/input/event4
  name:     "gpio_keys"

当用户操作输入设备时(如手指在屏幕上滑动或按power键),会触发相应的硬件中断,Linux内核将相关信息加工成原始的输入事件数据,然后写入其对应的设备节点中.在用户空间,EventHub通过read()系统调用函数将事件数据读出,然后进行相关加工处理。

引用输入理解Android 卷三的一句来描述整体过程:

Android输入系统的工作原理概括来说,就是监控/dev/input/下的所有设备节点,当某个节点有数据可读时,将数据读出并进行一系列的翻译加工,然后在所有的窗口中寻找合适的事件接收者,并派发给它。

InputManagerService 的创建

InputManagerService 如大多数系统服务一样,也是在SystemServer中创建. 具体工作可以总结如下:

  • 创建InputManagerService, 同时初始java和native
  • 注册InputManagerService到ServiceManager
  • 设置WindowManagerCallback,通知WMS一下感兴趣的事情
  • 调用InputManagerService的start方法,启动工作线程,注册一下监听等
  • 调用InputManagerService的systemRunning方法做一下初始工作
/// @frameworks/base/services/java/com/android/server/SystemServer.java
/**
 * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
 */
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
  ...
  t.traceBegin("StartInputManagerService");
  inputManager = new InputManagerService(context); // 创建InputManagerService
  t.traceEnd();

  t.traceBegin("StartWindowManagerService");
  // WMS needs sensor service ready
  ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
  mSensorServiceStart = null;
  wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
          new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
   // 注册WMS
  ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
          DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
  // 将 InputManagerService 注册到sm
  ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
          /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
  t.traceEnd();
  ...

  mActivityManagerService.setWindowManager(wm);
  wm.onInitReady();

  t.traceBegin("StartInputManager");
  // 设置 input callback, 通知wms一下input相关的事件,如anr
  inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
  inputManager.start(); // ims 启动
  t.traceEnd();

  ...

  // We now tell the activity manager it is okay to run third party
  // code.  It will call back into us once it has gotten to the state
  // where third party code can really run (but before it has actually
  // started launching the initial applications), for us to complete our
  // initialization.
  mActivityManagerService.systemReady(() -> {
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
    ...
    mSystemServiceManager.startBootPhase(t,SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    ...
    t.traceBegin("MakeInputManagerServiceReady");
    try {
        // TODO(BT) Pass parameter to input manager
        if (inputManagerF != null) {
            inputManagerF.systemRunning(); // 回调 systemRunning
        }
    } catch (Throwable e) {
        reportWtf("Notifying InputManagerService running", e);
    }
    ...
  }

}

接下来分析具体的流程

创建 InputManagerService

/// @frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public InputManagerService(Context context) {
    this.mContext = context;
    // 创建InputManagerHandler, 消息将在DisplayThread处理
    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);
    // 重点关注 , 初始化native , mPtr保存NativeInputManager地址     
    mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());

    String doubleTouchGestureEnablePath = context.getResources().getString(
            R.string.config_doubleTouchGestureEnableFile);
    mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
        new File(doubleTouchGestureEnablePath);
    // 注册 LocalService , 只能在SystemServer使用    
    LocalServices.addService(InputManagerInternal.class, new LocalService());
}

IMS JNI函数注册表

InputManagerService的native 实现在frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp , 下面的注册表描述了java native方法与相关jni函数的对应关系

static const JNINativeMethod gInputManagerMethods[] = {
        /* name, signature, funcPtr */
        {"nativeInit",
         "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
         "MessageQueue;)J",
         (void*)nativeInit},
        {"nativeStart", "(J)V", (void*)nativeStart},
        {"nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
         (void*)nativeSetDisplayViewports},
        {"nativeGetScanCodeState", "(JIII)I", (void*)nativeGetScanCodeState},
        {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState},
        {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState},
        {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys},
        {"nativeRegisterInputChannel", "(JLandroid/view/InputChannel;)V",
         (void*)nativeRegisterInputChannel},
        {"nativeRegisterInputMonitor", "(JLandroid/view/InputChannel;IZ)V",
         (void*)nativeRegisterInputMonitor},
        {"nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
         (void*)nativeUnregisterInputChannel},
        {"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers},
        {"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled},
        {"nativeSetInTouchMode", "(JZ)V", (void*)nativeSetInTouchMode},
        {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
         (void*)nativeInjectInputEvent},
        {"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
         (void*)nativeVerifyInputEvent},
        {"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock},
        {"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved},
        {"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
         (void*)nativeSetFocusedApplication},
        {"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay},
        {"nativeSetPointerCapture", "(JZ)V", (void*)nativeSetPointerCapture},
        {"nativeSetInputDispatchMode", "(JZZ)V", (void*)nativeSetInputDispatchMode},
        {"nativeSetSystemUiVisibility", "(JI)V", (void*)nativeSetSystemUiVisibility},
        {"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;)Z",
         (void*)nativeTransferTouchFocus},
        {"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed},
        {"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches},
        {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},
        {"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration},
        {"nativeVibrate", "(JI[JII)V", (void*)nativeVibrate},
        {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
        {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
        {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
        {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
        {"nativeMonitor", "(J)V", (void*)nativeMonitor},
        {"nativeIsInputDeviceEnabled", "(JI)Z", (void*)nativeIsInputDeviceEnabled},
        {"nativeEnableInputDevice", "(JI)V", (void*)nativeEnableInputDevice},
        {"nativeDisableInputDevice", "(JI)V", (void*)nativeDisableInputDevice},
        {"nativeSetPointerIconType", "(JI)V", (void*)nativeSetPointerIconType},
        {"nativeReloadPointerIcons", "(J)V", (void*)nativeReloadPointerIcons},
        {"nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V",
         (void*)nativeSetCustomPointerIcon},
        {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay},
        {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged},
        {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled},
};

nativeInit

java的nativeInit方法对应着同名的jni函数

/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    // 获取C++ 的MessageQueue
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == nullptr) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
    // 创建jni层的NativeInputManager, 用于InputManagerService与C++ InputManager 通信
    // serviceObj是InputManagerService, 因此NativeInputManager持有了IMS的引用
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

NativeInputManager 构造

/// @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();
    // 持有IMS的强引用
    mServiceObj = env->NewGlobalRef(serviceObj);

    {
        AutoMutex _l(mLock);
        mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
        mLocked.pointerSpeed = 0;
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
        mLocked.pointerCapture = false;
        mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
    }
    mInteractive = true;
    // 创建InputManager, 注意两个this,都是指代 NativeInputManager,它是相关策略的实现类
    mInputManager = new InputManager(this, this);
    // 注册InputManager到sm, 名称是inputflinger
    defaultServiceManager()->addService(String16("inputflinger"),
            mInputManager, false);
}

从NativeInputManager的继承体系来看,它是InputReaderPolicyInterface,InputDispatcherPolicyInterface等策略的实现类

/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
class NativeInputManager : public virtual RefBase,
    public virtual InputReaderPolicyInterface,
    public virtual InputDispatcherPolicyInterface,
    public virtual PointerControllerPolicyInterface {...

创建InputManager

从继承结构上看,InputManager是binder service的Bn端,对外提供服务, 通过名称inputflinger获取

/// @frameworks/native/services/inputflinger/InputManager.h
class InputManager : public InputManagerInterface, public BnInputFlinger {
  private:
    sp<InputReaderInterface> mReader;
    sp<InputClassifierInterface> mClassifier;
    sp<InputDispatcherInterface> mDispatcher;

InputManager构造函数 , 此处的readerPolicy和dispatcherPolicy实际上都是NativeInputManager

/// @frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = createInputDispatcher(dispatcherPolicy); // 使用工厂创建InputDispatcher
    mClassifier = new InputClassifier(mDispatcher); // 创建InputClassifier,持有mDispatcher
    mReader = createInputReader(readerPolicy, mClassifier); // 使用工厂创建InputReader,注意mClassifier参数
}

以上工厂方法对应的头文件如下, 实现在对应的cpp文件

#include "InputDispatcherFactory.h"
#include "InputReaderFactory.h"

createInputDispatcher

/// @frameworks/native/services/inputflinger/dispatcher/InputDispatcherFactory.cpp
sp<InputDispatcherInterface> createInputDispatcher(
        const sp<InputDispatcherPolicyInterface>& policy) {
    return new android::inputdispatcher::InputDispatcher(policy);
}
创建 InputDispatcher
/// @frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
      : mPolicy(policy),
        mPendingEvent(nullptr),
        mLastDropReason(DropReason::NOT_DROPPED),
        mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
        mAppSwitchSawKeyDown(false),
        mAppSwitchDueTime(LONG_LONG_MAX),
        mNextUnblockedEvent(nullptr),
        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(true), // 默认touch mode
        mFocusedDisplayId(ADISPLAY_ID_DEFAULT) {
    mLooper = new Looper(false); // 创建 Looper
    mReporter = createInputReporter();

    mKeyRepeatState.lastKeyEntry = nullptr;

    policy->getDispatcherConfiguration(&mConfig);
}

创建 InputClassifier

由上可知,mListener的值实际上是mDispatcher. InputClassifier代表输入事件的一个处理阶段,对于motion events会交由MotionClassifier处理,其他事件则是直通的,也就是直接交于mListener进行处理.

/// @frameworks/native/services/inputflinger/InputClassifier.cpp
/*
* Implementation of the InputClassifierInterface.
* Represents a separate stage of input processing. All of the input events go through this stage.
* Acts as a passthrough for all input events except for motion events.
* The events of motion type are sent to MotionClassifier.
*/
InputClassifier::InputClassifier(const sp<InputListenerInterface>& listener)
      : mListener(listener), mHalDeathRecipient(new HalDeathRecipient(*this)) {}

createInputReader

此处的listener就是上面创建的InputClassifier, 而它持有InputDispatcher的引用, 因此InputReader间接持有InputDispatcher的引用, 另外注意此处创建了EventHub, 用于加工处理原始事件

/// @frameworks/native/services/inputflinger/reader/InputReaderFactory.cpp
sp<InputReaderInterface> createInputReader(const sp<InputReaderPolicyInterface>& policy,
                                           const sp<InputListenerInterface>& listener) {
    return new InputReader(std::make_unique<EventHub>(), policy, listener);
}

创建 InputReader
/// @frameworks/native/services/inputflinger/reader/InputReader.cpp
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         const sp<InputListenerInterface>& listener)
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mGlobalMetaState(0),
        mGeneration(1),
        mNextInputDeviceId(END_RESERVED_ID),
        mDisableVirtualKeysTimeout(LLONG_MIN),
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    //queues up and defers dispatch of decoded events until flushed.
    mQueuedListener = new QueuedInputListener(listener); // 间接持有InputDispatcher的引用

    { // acquire lock
        AutoMutex _l(mLock);

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

它用于向Dispatcher发送事件,实现事件排队并推迟派发事件直到调用flush

/// @frameworks/native/services/inputflinger/include/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);
    virtual void notifyKey(const NotifyKeyArgs* args);  // key 事件
    virtual void notifyMotion(const NotifyMotionArgs* args); // motion 事件
    virtual void notifySwitch(const NotifySwitchArgs* args);
    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);

    void flush();

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

} // namespace android

InputManagerService#start

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

    // Add ourself to the Watchdog monitors.
    Watchdog.getInstance().addMonitor(this);  // 添加到watchdog监听

    // 注册一些监听
    registerPointerSpeedSettingObserver();
    registerShowTouchesSettingObserver();
    registerAccessibilityLargePointerSettingObserver();
    registerLongPressTimeoutObserver();

    mContext.registerReceiver(new BroadcastReceiver() {  // 注册 ACTION_USER_SWITCHED
        @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");
}

nativeStart

nativeStart 对应同名的jni函数

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
  // 取出在nativeInit创建的NativeInputManager
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

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

InputManager#start()

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

    result = mReader->start();  // 启动 reader 线程
    if (result) {
        ALOGE("Could not start InputReader due to error %d.", result);

        mDispatcher->stop();
        return result;
    }

    return OK;
}

InputDispatcher::start
status_t InputDispatcher::start() {
    if (mThread) { // 已经创建
        return ALREADY_EXISTS;
    }
    // 创建InputDispatcher线程, 线程执行会调用dispatchOnce
    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake();/* wake函数*/ });
    return OK;
}

dispatcher 线程会不断调用dispatchOnce去分发事件

InputReader::start
status_t InputReader::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    // 创建InputReader线程,  线程执行会调用loopOnce
    mThread = std::make_unique<InputThread>(
            "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake();/* wake函数*/ });
    return OK;
}

reader线程会不断调用loopOnce去获取底层的事件, 然后将事件传递给dispatcher线程

InputThread

这个是一个线程封装类, 用于持续处理事件, 直到退出

/* A thread that loops continuously until destructed to process input events.
 *
 * Creating the InputThread starts it immediately. The thread begins looping the loop
 * function until the InputThread is destroyed. The wake function is used to wake anything
 * that sleeps in the loop when it is time for the thread to be destroyed.
 */
class InputThread {
public:
    explicit InputThread(std::string name, std::function<void()> loop, // 线程循环函数
                         std::function<void()> wake = nullptr /* 要销毁时调用,唤醒Loop中的sleep*/);
    virtual ~InputThread();
    bool isCallingThread();

private:
    std::string mName;
    std::function<void()> mThreadWake;
    sp<Thread> mThread;
};

} // namespace android

InputThread构造
InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
      : mName(name), mThreadWake(wake) {
    mThread = new InputThreadImpl(loop);  // 真正创建一个线程
    // 启动线程,执行threadLoop
    mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}

通过InputThread构造的构造方法可知,在其中创建了真正的Thread实现类InputThreadImpl,并执行其run方法启动了线程. 因此reader和dispatcher中创建InputThread,实际上已经启动了内部创建的线程.

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; // loop 函数

    bool threadLoop() override {
        mThreadLoop(); // threadLoop 函数中执行 mThreadLoop函数
        return true;  // 返回true表示线程不退出,继续循环
    }
};

IMS#systemRunning

这个方法用于通知System ready, 然后做一些注册和其他工作

public void systemRunning() {
        if (DEBUG) {
            Slog.d(TAG, "System ready.");
        }
        mNotificationManager = (NotificationManager)mContext.getSystemService(
                Context.NOTIFICATION_SERVICE);
        mSystemReady = true; // ready 标志

        // 监听ACTION_PACKAGE_ADDED, 用于更新keyboard布局
        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        filter.addDataScheme("package");
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateKeyboardLayouts();
            }
        }, filter, null, mHandler);

        // 监听ACTION_ALIAS_CHANGED
        filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED);
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                reloadDeviceAliases();
            }
        }, filter, null, mHandler);

        // 更新相关信息
        mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES);
        mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS);

        if (mWiredAccessoryCallbacks != null) {
            mWiredAccessoryCallbacks.systemReady();
        }
    }

更新设备信息

更新操作, 都是调用的native方法.

private void reloadKeyboardLayouts() {
    if (DEBUG) {
        Slog.d(TAG, "Reloading keyboard layouts.");
    }
    nativeReloadKeyboardLayouts(mPtr);
}

private void reloadDeviceAliases() {
    if (DEBUG) {
        Slog.d(TAG, "Reloading device names.");
    }
    nativeReloadDeviceAliases(mPtr);
}

对应的jni函数如下 , 都是调用的InputReader

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

    im->getInputManager()->getReader()->requestRefreshConfiguration(
            InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
}

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

    im->getInputManager()->getReader()->requestRefreshConfiguration(
            InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
}

InputReader::requestRefreshConfiguration

InputReader 会更新mConfigurationChangesToRefresh, 然后唤醒线程

void InputReader::requestRefreshConfiguration(uint32_t changes) {
    AutoMutex _l(mLock);

    if (changes) {
        bool needWake = !mConfigurationChangesToRefresh;
        mConfigurationChangesToRefresh |= changes;

        if (needWake) {
            mEventHub->wake();
        }
    }
}

reader线程被唤醒后会执行loopOnce方法

void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        AutoMutex _l(mLock);
        ...

        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes); // 更新配置
        } else if (mNextTimeout != LLONG_MAX) {...
    } // release lock
    ...

refreshConfigurationLocked

具体更新

void InputReader::refreshConfigurationLocked(uint32_t changes) {
    mPolicy->getReaderConfiguration(&mConfig);
    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);

    if (changes) {
        ALOGI("Reconfiguring input devices, changes=%s",
              InputReaderConfiguration::changesToString(changes).c_str());
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        if (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO) {
            updatePointerDisplayLocked();
        }

        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
            mEventHub->requestReopenDevices();
        } else {
            for (auto& devicePair : mDevices) {
                std::shared_ptr<InputDevice>& device = devicePair.second;
                device->configure(now, &mConfig, changes);
            }
        }
    }
}

总结

本篇主要介绍了InputManagerService的启动流程,它的实现包含java和native两个部分. native的部分才是真正的实现,而java层的通常是相关功能的封装. 在native层创建了两个线程, reader线程不断的从EventHub从获取事件,然后将事件交给dispatcher线程进行分发. dispatcher会找到合适的window, 然后将事件派发给它.对应的window处理完相关事件后,向ims发送处理完毕的反馈,然后ims做一些收尾工作,此次事件派发循环才算完整结束.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值