Android输入系统(二)
2017-02-13 15:53
381 查看
Android输入系统(二)
Android输入系统二启动InputManagerService
InputManagerService构造函数
1nativeInit
11NativeInputManager
111EventHub
112InputManager
1121InputDispatcher
111211getDispatcherConfiguration
1122InputReader
1123initialize
2inputManagerstart
1nativeStart
11NativeInputManagerstart
前言:
今天大概来说说启动流程
由于我们前面文章提到过,SystemServer中启动了所有的Java服务,那么当然也包括输入系统的Java服务
启动InputManagerService
@(/frameworks/base/services/java/com/android/server/SystemServer.java)inputManager = new InputManagerService(context);//[1] wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); mSystemServiceManager.startService(VrManagerService.class); mActivityManagerService.setWindowManager(wm); inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); inputManager.start();//[2]
上面代码可以看出InputManagerService和WMS有着密不可分的关系,我们暂时不去深究内部关系,重点关心输入系统的结构上
1.InputManagerService构造函数
public InputManagerService(Context context) { this.mContext = context; this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());//对DisplayThread线程进行消息处理 mUseDevInputEventForAudioJack = context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());//[1.1]指向native input manager service object. LocalServices.addService(InputManagerInternal.class, new LocalService());//将服务添加到本地服务的全局注册表 }
小结:
- 使用DisplayThread线程进行消息处理
- 指向native层的InputManagerService
1.1nativeInit()
@(com_android_server_input_InputManagerService.cpp)static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);//得到DisplayThread的MessageQueue if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper());//[1.1.1]创建Native层的NativeInputManager对象 im->incStrong(0); return reinterpret_cast<jlong>(im); }
小结:
- 传递进来的是java层的InputManagerService对象引用和全局Context和DisplayThread的Loop
- 创建Ntive层的NativeInputManager对象
1.1.1NativeInputManager
@(com_android_server_input_InputManagerService.cpp)NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper), mInteractive(true) { JNIEnv* env = jniEnv(); mContextObj = env->NewGlobalRef(contextObj); mServiceObj = env->NewGlobalRef(serviceObj); { AutoMutex _l(mLock); mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE; mLocked.pointerSpeed = 0; mLocked.pointerGesturesEnabled = true; mLocked.showTouches = false; } mInteractive = true; sp<EventHub> eventHub = new EventHub();//创建EventHbu对象[1.1.1.1] mInputManager = new InputManager(eventHub, this, this);//[1.1.1.2]创建InputManager对象 }
小结:
- 将looper给成员变量mLooper,Context给mContextObj,java层的InputManagerService引用给mServiceObj
- 创建EventHub对象
- 创建InputManager对象,传入NativeInputManager和eventHub,其中NativeInputManager存有java层的InputManagerService对象引用和全局Context和DisplayThread的Loop
1.1.1.1EventHub
@(framework\native\services\inputflinger\EventHbu.cpp)
EventHub::EventHub(void) : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(), mOpeningDevices(0), mClosingDevices(0), mNeedToSendFinishedDeviceScan(false), mNeedToReopenDevices(false), mNeedToScanDevices(true), mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); mEpollFd = epoll_create(EPOLL_SIZE_HINT);//创建epoll ... mINotifyFd = inotify_init();//初始化inotify int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);//添加观测目录"/dev/input" struct epoll_event eventItem; memset(&eventItem, 0, sizeof(eventItem)); eventItem.events = EPOLLIN; eventItem.data.u32 = EPOLL_ID_INOTIFY; result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);//将mINotifyFd添加到epoll中 int wakeFds[2];//两个文件句柄,因为要跨进程所以必须将其中一个传递到另外一个非父子进程中 result = pipe(wakeFds);//通过管道实现 mWakeReadPipeFd = wakeFds[0]; mWakeWritePipeFd = wakeFds[1]; result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);//设置管道的读写是非阻塞 result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); ... eventItem.data.u32 = EPOLL_ID_WAKE; //将管道读添加到epoll中 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem); ... int major, minor; getLinuxRelease(&major, &minor); ... mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5); }
小结:
- 创建epoll用于监听文件的更新情况
- 创建inotify用于监听目录的更新情况
- 创建管道用于进程间通信
1.1.1.2InputManager
InputManager::InputManager( const sp<EventHubInterface>& eventHub, const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { mDispatcher = new InputDispatcher(dispatcherPolicy);//[1.1.1.2.1]创建InputDispatcher mReader = new InputReader(eventHub, readerPolicy, mDispatcher);//[1.1.1.2.2]创InputReader initialize();//[1.1.1.2.3] } --------------------------------------------------------------------------------------------- >这里注意传递new InputReader传递进来的参数是NativeInputManager.this,对照参数的接收 class NativeInputManager : public virtual RefBase, public virtual InputReaderPolicyInterface, public virtual InputDispatcherPolicyInterface, public virtual PointerControllerPolicyInterface {
小结:
- 创建InputDispatcher
- 创建InputReader并且创建InputReaderThread和InputDispatcherThread两个线程
1.1.1.2.1InputDispatcher
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) : mPolicy(policy), mPendingEvent(NULL), mLastDropReason(DROP_REASON_NOT_DROPPED), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), mNextUnblockedEvent(NULL), mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false), mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) { mLooper = new Looper(false);//创建Loop mKeyRepeatState.lastKeyEntry = NULL; policy->getDispatcherConfiguration(&mConfig);//[1.1.1.2.1.1]//policy是NativeInputManager.this }
#1.1.1.2.1.1getDispatcherConfiguration()
void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) { JNIEnv* env = jniEnv(); jint keyRepeatTimeout = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatTimeout); if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) { outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout); } jint keyRepeatDelay = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatDelay); if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) { outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay); } }
1.1.1.2.2InputReader
InputReader::InputReader(const sp<EventHubInterface>& eventHub, const sp<InputReaderPolicyInterface>& policy, const sp<InputListenerInterface>& listener) : mContext(this), mEventHub(eventHub), mPolicy(policy), mGlobalMetaState(0), mGeneration(1), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), mConfigurationChangesToRefresh(0) { mQueuedListener = new QueuedInputListener(listener); { // acquire lock AutoMutex _l(mLock); refreshConfigurationLocked(0); updateGlobalMetaStateLocked(); } // release lock }
1.1.1.2.3initialize()
创建两个线程
void InputManager::initialize() { mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher); }
2inputManager.start()
public void start() { nativeStart(mPtr);//[2.1] registerPointerSpeedSettingObserver(); registerShowTouchesSettingObserver(); registerAccessibilityLargePointerSettingObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); updatePointerSpeedFromSettings();//更新触摸点速度 updateShowTouchesFromSettings();//显示触摸点 updateAccessibilityLargePointerFromSettings();//更新是否允许触摸点 }
2.1nativeStart()
@(com_android_server_input_InputManagerService.cpp)//注意这里的ptr是mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); //记录的是NativeInputManager对象 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."); } }
2.1.1NativeInputManager.start()
@(InputManager.cpp)
status_t InputManager::start() { status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY); if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); if (result) { ALOGE("Could not start InputReader thread due to error %d.", result); mDispatcherThread->requestExit(); return result; } return OK; }
运行NativeInputManager中的两个线程
mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher);
总结:
java层:
- 在InputManagerService的构造中传入DisplayThread线程的Looper.使用DisplayThread的Message消息队列
- 加入本地服务中
- 将InputManagerServce传递到WMS中
- 将InputManagerService添加到ServiceManager中
- 启动inputManager服务
Native层:
- 创建Native层的NativeInputManager就是Java层的InputManagerService
- NativeInputManager对象持有Java层的Context,InputManagerService.this等等
- 创建EventHub,InputManager
- 使用epoll,inotify机制
- 开启两个线程,一个用于接收事件派发,一个用于获取事件处理
相关文章推荐
- Android输入法之输入系统
- Android核心分析(15)--------Android输入系统之输入路径详解
- Android 4.0 事件输入(Event Input)系统
- Android 输入系统解析 (2)
- Android 输入系统解析 (1)
- Android核心分析(14)------ Android GWES之输入系统
- Android 4.0 事件输入(Event Input)系统
- Android核心分析(15)--------Android输入系统之输入路径详解
- Android 4.0 事件输入(Event Input)系统
- Android用户输入系统结构和移植内容
- Android核心分析(14)------ Android GWES之输入系统
- Android 4.0 事件输入(Event Input)系统
- Android触摸屏输入系统
- Android核心分析(15)--------Android输入系统之输入路径详解k
- Android输入系统之输入路径详解
- Android用户输入系统和移植内容概要
- Android触摸屏输入系统
- Android核心分析(13)------ Android GWES之输入系统 .
- Android系统中的输入输出设备
- Android 4.0 事件输入(Event Input)系统