這個工具的主要目的就是記錄屏幕上的各種操作,然後多次回放,用於穩定性測試和一些需要多次重複才能復現的bug的重現。
代碼在以下位置:
http://download.csdn.net/detail/dfysy/8479123
之前,別人轉發我一個記錄/回放 event的程序,在KK以前都是可以用的,但是由於Android L enable了PIE(positionindependent execution), 在L上沒法用了。又沒有源碼,只能自己再寫一個。
程序的原理:
就是讀取/dev/input下面的所有event輸入,把他們都記錄下來,然後在回放的時候在一個一個的寫回去。記錄的信息除了input_event的內容外,還需要記錄該event是從哪一個input節點讀入的,因爲回放的時候需要知道這個event應該寫入哪一個節點。
由於input_event裏面記錄的event發生時間和實際讀取的時間會有差異,會導致回放的時候計算兩個event之間的時間差出現錯誤(負值)。最好的設計應該是對所有讀出的event再根據發生時間進行排序。但是爲了簡化設計,此處直接記錄讀取event的牆鍾時間,這樣雖然不同input節點間的時間關係可能有偏差。但是同一個input節點直接的順序還是正確的。
程序的主要風格是C和C++的混合體,之所以使用C++,主要是因爲使用了template處理map和vector,這樣就不用使用C語言費力巴哈的去實現相關的插入查找的算法,目的是快速,不是較勁。
主要的數據結構和功能:
map<string,int> fileName2fd; /*input filenameàinput fd*/
map<string,int> fileName2fdr; /*記錄文件中的filenameà記錄文件中的fd*/
map<int,string> fd2fileName;/*input fdàinputfilename*/
map<int,string> fdr2fileName;/*記錄文件中的fdà記錄文件中的filename*/
map<int,int> fdr2fd;/*記錄文件中的fdàinputfd*/
vector<event_info>eventListFile;/*記錄文件中的所有list,這樣就不用每次都讀文件了*/
vector<event_info>eventListScan; /*記錄所有從input 文件節點讀取到的event*/
程序主要分爲以下幾個部分
1) 遍歷dev/input目錄,打開所有節點,(此部分使用了android的getevent部分代碼)。建立fd和文件名之間的相互map
scanAndOpenInputs(INPUT_DIR);
2) 分析命令輸入,如果是recording的話,進入receiveEvents(),讀取input文件節點的event,並進行保存。此處使用了select來監控各個input。
ret= select(max_fd, &fds, NULL, NULL, &timeout);
3) 分析命令輸入,如果是playback的話,則從文件中讀出各個event,並計算各個event之間的時間差,然後根據fd和filename對應將其寫入對應的文件節點。
Android.mk 裏面需要加以下的選項,以便可以使用stl的庫,這裏採用的靜態編譯,以免下載到某些設備找不到庫
LOCAL_C_INCLUDES += bionic bionic/libstdc++/include external/stlport/stlport
LOCAL_STATIC_LIBRARIES := libc libstlport_static
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
TODO:1)增加輸出到指定文件的功能,這樣就可以爲不同的測試內容記錄不同的文件
2)增加playback指定文件的功能,這樣就可以用shell來組織各個功能的測試了。