Andriod系统的Input设备分析二
来源:互联网 发布:zabbix二次开发 java 编辑:程序博客网 时间:2024/06/07 19:28
Andriod系统的Input设备分析二 (2012-09-12 20:15)一键转载
标签: input Andriod 分类:andorid
linux内核的iput子系统的驱动被封装成字符设备,目录位于/dev/inpuit,用户控件通过open()、read()读取来自底层驱动的输入事件。那么从最底层一步步来看看android的处理流程。在系统启动后,用户空间会通过读取/dev/inpput文件,而这个文件会通过openPlatformInput的scanDir调用openDevice。
点击(此处)折叠或打开
- bool EventHub::openPlatformInput(void)
- {
- /*
- * Open platform-specific input device(s).
- */
- int res;
- mFDCount = 1;
- mFDs = (pollfd*)calloc(1, sizeof(mFDs[0]));
- mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
- mFDs[0].events= POLLIN;
- mFDs[0].revents= 0;
- mDevices[0]= NULL;
- #ifdef HAVE_INOTIFY
- mFDs[0].fd= inotify_init();
- res = inotify_add_watch(mFDs[0].fd, device_path, IN_DELETE | IN_CREATE);
- if(res< 0) {
- LOGE("could not add watch for %s, %s\n", device_path, strerror(errno));
- }
- #else
- /*
- * The code in EventHub::getEvent assumes that mFDs[0]is an inotify fd.
- * We allocate space for it and set it to something invalid.
- */
- mFDs[0].fd= -1;
- #endif
- res = scanDir(device_path);
- if(res< 0) {
- LOGE("scan dir failed for %s\n", device_path);
- }
- return true;
- }
点击(此处)折叠或打开
- bool EventHub::getEvent(RawEvent* outEvent)
- {
- outEvent->deviceId= 0;
- outEvent->type= 0;
- outEvent->scanCode= 0;
- outEvent->keyCode= 0;
- outEvent->flags= 0;
- outEvent->value= 0;
- outEvent->when= 0;
- if (!mOpened){
- mError = openPlatformInput()? NO_ERROR : UNKNOWN_ERROR;
- mOpened = true;
- mNeedToSendFinishedDeviceScan = true;
- }
- for (;;){
- // Report any devices that had last been added/removed.
- if (mClosingDevices!= NULL) {
- device_t* device = mClosingDevices;
- LOGV("Reporting device closed: id=0x%x, name=%s\n",
- device->id, device->path.string());
- mClosingDevices = device->next;
- if (device->id== mFirstKeyboardId){
- outEvent->deviceId= 0;
- } else {
- outEvent->deviceId= device->id;
- }
- outEvent->type= DEVICE_REMOVED;
- outEvent->when= systemTime(SYSTEM_TIME_MONOTONIC);
- delete device;
- mNeedToSendFinishedDeviceScan =true;
- return true;
- }
- if (mOpeningDevices!= NULL) {
- device_t* device = mOpeningDevices;
- LOGV("Reporting device opened: id=0x%x, name=%s\n",
- device->id, device->path.string());
- mOpeningDevices = device->next;
- if (device->id== mFirstKeyboardId){
- outEvent->deviceId= 0;
- } else {
- outEvent->deviceId= device->id;
- }
- outEvent->type= DEVICE_ADDED;
- outEvent->when= systemTime(SYSTEM_TIME_MONOTONIC);
- mNeedToSendFinishedDeviceScan =true;
- return true;
- }
- if (mNeedToSendFinishedDeviceScan){
- mNeedToSendFinishedDeviceScan =false;
- outEvent->type= FINISHED_DEVICE_SCAN;
- outEvent->when= systemTime(SYSTEM_TIME_MONOTONIC);
- return true;
- }
- // Grab thenext input event.
- for (;;){
- // Consume buffered input events,if any.
- if (mInputBufferIndex < mInputBufferCount){
- const struct input_event& iev= mInputBufferData[mInputBufferIndex++];
- const device_t* device= mDevices[mInputDeviceIndex];
- LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
- (int) iev.time.tv_sec,(int) iev.time.tv_usec, iev.type, iev.code, iev.value);
- if (device->id== mFirstKeyboardId){
- outEvent->deviceId= 0;
- } else {
- outEvent->deviceId= device->id;
- }
- outEvent->type= iev.type;
- outEvent->scanCode= iev.code;
- if (iev.type == EV_KEY){
- status_t err = device->layoutMap->map(iev.code,
- & outEvent->keyCode,& outEvent->flags);
- LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
- iev.code, outEvent->keyCode, outEvent->flags,err);
- if (err != 0){
- outEvent->keyCode= AKEYCODE_UNKNOWN;
- outEvent->flags= 0;
- }
- } else {
- outEvent->keyCode= iev.code;
- }
- outEvent->value= iev.value;
- // Use an event timestampin the same timebase as
- // java.lang.System.nanoTime()and android.os.SystemClock.uptimeMillis()
- // as expected by the rest of the system.
- outEvent->when= systemTime(SYSTEM_TIME_MONOTONIC);
- return true;
- }
- mInputDeviceIndex += 1;
- if (mInputDeviceIndex >= mFDCount){
- break;
- }
- const struct pollfd& pfd= mFDs[mInputDeviceIndex];
- if (pfd.revents & POLLIN) {
- int32_t readSize = read(pfd.fd, mInputBufferData,
- sizeof(struct input_event)* INPUT_BUFFER_SIZE);
- if (readSize < 0){
- if (errno != EAGAIN&& errno != EINTR){
- LOGW("could not get event (errno=%d)", errno);
- }
- } else if ((readSize% sizeof(struct input_event))!= 0){
- LOGE("could not get event (wrong size: %d)", readSize);
- } else {
- mInputBufferCount = readSize/ sizeof(struct input_event);
- mInputBufferIndex = 0;
- }
- }
- }
- #if HAVE_INOTIFY
- // readNotify() will modify mFDsand mFDCount, so this must be done after
- // processing all other events.
- if(mFDs[0].revents& POLLIN) {
- readNotify(mFDs[0].fd);
- mFDs[0].revents= 0;
- continue; // report added or removed devices immediately
- }
- #endif
- mInputDeviceIndex = 0;
- release_wake_lock(WAKE_LOCK_ID);
- int pollResult = poll(mFDs, mFDCount,-1);
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
- if (pollResult<= 0){
- if (errno != EINTR){
- LOGW("poll failed (errno=%d)\n", errno);
- usleep(100000);
- }
- }
- }
- }
如果是第一次进入到这个函数时,并且成员变量mopened的值为false,于是就调用openplatforminput函数来打开系统输入设备,打开这个设备就是用poll对这个输入设备进行监控。如果不是第一次进入到这个函数,那么就会分析当前有没有input事件发生,进而等待下一次input事件的发生,这个函数主要是读取input驱动传过来的事件信息。往下走
点击(此处)折叠或打开
- void InputReader::loopOnce(){
- RawEvent rawEvent;
- mEventHub->getEvent(& rawEvent);
- #if DEBUG_RAW_EVENTS
- LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
- rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
- rawEvent.value);
- #endif
- process(& rawEvent);
- }
点击(此处)折叠或打开
- InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
- Thread(/*canCallJava*/true), mReader(reader){
- }
- InputReaderThread::~InputReaderThread(){
- }
- bool InputReaderThread::threadLoop(){
- mReader->loopOnce();
- return true;
- }
点击(此处)折叠或打开
- void InputManager::initialize(){
- mReaderThread = new InputReaderThread(mReader);
- mDispatcherThread = new InputDispatcherThread(mDispatcher);
- }
点击(此处)折叠或打开
- InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
- Thread(/*canCallJava*/true), mDispatcher(dispatcher){
- }
- InputDispatcherThread::~InputDispatcherThread(){
- }
- bool InputDispatcherThread::threadLoop(){
- mDispatcher->dispatchOnce();
- return true;
- }
点击(此处)折叠或打开
- void InputDispatcher::dispatchOnce(){
- nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
- nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
- nsecs_t nextWakeupTime = LONG_LONG_MAX;
- { // acquire lock
- AutoMutex _l(mLock);
- dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay,& nextWakeupTime);
- if (runCommandsLockedInterruptible()){
- nextWakeupTime = LONG_LONG_MIN;// force next poll to wake up immediately
- }
- } // release lock
- // Waitfor callback or timeoutor wake. (make sure we round up,not down)
- nsecs_t currentTime = now();
- int32_t timeoutMillis;
- if (nextWakeupTime> currentTime){
- uint64_t timeout = uint64_t(nextWakeupTime- currentTime);
- timeout = (timeout + 999999LL)/ 1000000LL;
- timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
- } else{
- timeoutMillis = 0;
- }
- mLooper->pollOnce(timeoutMillis);
- }
点击(此处)折叠或打开
- status_t InputManager::start(){
- char value[92];
- status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
- if (result){
- LOGE("Could not start InputDispatcher thread due to error %d.", result);
- return result;
- }
- result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
- if (result){
- LOGE("Could not start InputReader thread due to error %d.", result);
- mDispatcherThread->requestExit();
- return result;
- }
-
-
- property_get("ro.build.type", value,"usr");
- if(strcmp(value,"eng") == 0){
- LightWeight_KeyDispatchAnr::IS_ENG_BUILD= true;
- LOGD("current build is eng build\n");
- LightWeight_KeyDispatchAnr::createMonitorThread();
- }
-
- return OK;
- }
点击(此处)折叠或打开
- NativeInputManager::NativeInputManager(jobject callbacksObj):
- mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
- mMaxEventsPerSecond(-1),
- mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0){
- JNIEnv* env = jniEnv();
- mCallbacksObj = env->NewGlobalRef(callbacksObj);
- mDisplayOrientation = getHwRotation();
- sp<EventHub> eventHub= new EventHub();
- mInputManager = new InputManager(eventHub, this, this);
- }
点击(此处)折叠或打开
- static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
- jobject callbacks) {
- if (gNativeInputManager== NULL) {
- gNativeInputManager = new NativeInputManager(callbacks);
- } else{
- LOGE("Input manager already initialized.");
- jniThrowRuntimeException(env,"Input manager already initialized.");
- }
- }
点击(此处)折叠或打开
- static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
- jobject callbacks) {
- if (gNativeInputManager== NULL) {
- gNativeInputManager = new NativeInputManager(callbacks);
- } else{
- LOGE("Input manager already initialized.");
- jniThrowRuntimeException(env,"Input manager already initialized.");
- }
- }
点击(此处)折叠或打开
- static JNINativeMethod gInputManagerMethods[]= {
- /* name, signature, funcPtr*/
- { "nativeInit","(Lcom/android/server/InputManager$Callbacks;)V",
- (void*) android_server_InputManager_nativeInit},
点击(此处)折叠或打开
- public InputManager(Context context, WindowManagerService windowManagerService){
- this.mContext = context;
- this.mWindowManagerService = windowManagerService;
-
- this.mCallbacks = new Callbacks();
-
- init();
- }
-
- private void init(){
- Slog.i(TAG,"Initializing input manager");
- nativeInit(mCallbacks);
- }
点击(此处)折叠或打开
- private WindowManagerService(Context context, PowerManagerService pm,
- boolean haveInputMethods) {
- mLockScreenType = SystemProperties.getInt("curlockscreen",1);
- mContext = context;
- mHaveInputMethods = haveInputMethods;
- mLimitedAlphaCompositing = context.getResources().getBoolean(
- com.android.internal.R.bool.config_sf_limitedAlpha);
- mPowerManager = pm;
- mPowerManager.setPolicy(mPolicy);
- PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- "SCREEN_FROZEN");
- mScreenFrozenLock.setReferenceCounted(false);
- mActivityManager = ActivityManagerNative.getDefault();
- mBatteryStats = BatteryStatsService.getService();
- //Get persisted window scale setting
- mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
- Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
- mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
- Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
- // Track changesto DevicePolicyManager state so we can enable/disable keyguard.
- IntentFilter filter = new IntentFilter();
- filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- mContext.registerReceiver(mBroadcastReceiver,filter);
- mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
- "KEEP_SCREEN_ON_FLAG");
- mHoldingScreenWakeLock.setReferenceCounted(false);
- mInputManager = new InputManager(context, this);
- PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
- thr.start();
1.Eventhub:主要是管理所有系统中可以识别的输入设备的输入事件,当设备增加或者删去时,EventHub将产生相应的输入事件给系统。
2.InputReader:从EventHub中读取原始事件数据(RawEvent)
3.InputDispater:负责把事件分发给输入目标,在等列等待新的输入事件,并且异步的把这些事件分发给应用程序。
4.InputManager:事件处理的核心,不做具体的事。使用两个线程InputReader和InputDispater
- Andriod系统的Input设备分析二
- Andriod系统的Input设备分析二
- andriod input 系统架构
- Android系统层的input设备从上到下分析~
- Android系统层的input设备解析
- Android系统层的input设备解析
- Android系统层的input设备解析
- Android中Input型输入设备驱动原理分析(二)
- Android中Input型输入设备驱动原理分析<二>
- andriod系统的编译
- linux input设备驱动分析
- input子系统分析二
- 字符设备 和 input 设备--input设备的注册
- Andriod的activity生命周期分析
- linux input 子系统分析 二
- linux input 子系统分析 二
- linux input 子系统分析 二
- linux input 子系统分析 二
- 设计模式学习-工厂模式
- Spring的简单使用
- Elasticsearch源码分析之一——使用Guice进行依赖注入与模块化系统
- bootloader简介
- java中的反射
- Andriod系统的Input设备分析二
- java---反射
- 冒泡排序/选择排序
- VmWare 虚拟机增加硬盘容量的方法
- 圆圈中最后剩下的数字
- (第Ⅱ部分 创建型模式篇) 第2章 抽象工厂模式(Abstract Factory)
- python环境变量的配置
- (第Ⅱ部分 创建型模式篇) 第3章 建造者模式(Builder Pattern)
- 诫子书