Android2.1 輸入設備檢測BUG修正

重新運行了2.2版本後,發現我這個研究就是笑話,同樣的源碼在2.2下非常正常,在2.1下卻有這個問題,唯一的想法是使用的LINUX內核引發的問題。

原文:

這些天,在盒子上跑Android2.1的時候,經常發生遙控器不可用的問題。剛開始以爲是不小心什麼地方修改了2.1的源碼導致的,只好修改回去重新編譯,運行時現象依然存在。無奈只好想到在源碼中追加打印,看什麼地方鍵值傳遞出問題了。

從網上的資料結合源碼發現,在窗口服務啓動的時候,會開啓一個KeyQ的線程去獲取鍵值加入隊列。下圖是網上的一個Android輸入系統的架構圖

Android輸入系統

從圖上可用看出實際上輸入設備的管理在EventHub中,打開EventHub的DEBUG開關,運行程序發現雖然虛擬輸入驅動已經加載,但是EventHub卻並沒有打開設備。多次運行,有時候系統能打開虛擬輸入設備,有時候卻不能打開設備。抽拔USB鼠標,如果USB鼠標已經插上,則可用打開虛擬設備。拔掉鼠標,有提示設備拔掉,再插上鼠標卻沒有提示打開設備。於是猜測Android只能在第一次系統初始化的時候會找得到輸入設備,初始化完畢後,再加入的設備都找不到。果斷把輸入設備驅動加載放到系統初始化流程靠前的位置,運行多次,遙控器都能正常使用。

下面從EventHub的源碼中分析造成BUG的原因。只看了openPlatformInput和getEvent很快就得出了結論。KeyQ線程調用getEvent函數獲取鍵值,該函數會去檢測平臺輸入有沒有初始化,沒有則調用openPlatformInput完成初始化。初始化完畢後,採用POLL函數循環監控設備Fd和一個特殊的Fd.這個特殊的Fd就是在openPlatformInput生成的,它就是造成BUG的根源。

 

Inotify 是一個 Linux 內核特性,它監控文件系統,並且及時向專門的應用程序發出相關的事件警告,比如刪除、讀、寫和卸載操作等。您還可以跟蹤活動的源頭和目標等細節。具體的使用細節都可以在網上查閱到。該源碼的意思是使用mFDs[0].fd監控/dev/input目錄下的文件變化,IN_DELETE | IN_CREATE指監控文件的刪除和創建。結合getEvent,當/dev/input目錄下文件有刪除和創建時,從mFDs[0].fd讀取事件打開或者刪除一個設備。這不是很正確麼,有什麼問題呢,問題就出在IN_CREATE上,這個監控的是文件的創建,但是通過我的測試發現,插USB鼠標生成的/dev/input/event0和/dev/input/mouse0並不屬於文件創建,此時Inotify根本就沒有發送文件創建事件,期待獲取該事件打開設備的動作當然也不能觸發了。修正辦法如下:

 

使用IN_MOVE_TO屬性,同時在read_notify中修改下事件響應。OK,現在任何時候加載虛擬設備驅動和插拔USB鼠標都沒有問題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章