1、 ADB Server的啟動
前面我們講到adb模塊的源碼在system/core/adb下面,通過查看Android.mk文件我們了解到這個adb
模塊回編譯生成連個可執行文件adb、adbd,源碼通過ADB_HOST這個宏來控制編譯的是adb還是adbd。首先我們來看看這個運行於PC端的adb——ADB Server。
下面我們就來看看ADB Server的啟動adb.c(system/core/adb/):
接着來看看adb_commandline()(system/core/adb/commandline.c)的實現,它用來接收adb client輸入的adb命令。(在OVERVIEW.txt中有如下一段描述:是說adb server是通過adb client來啟動的。)
下面就以adb shell命令為例來看看adb client是如何來啟動adb server的。
此時由於ADB Server還沒有啟動,因此socket_loopback_client的返回值為-1,_adb_connect()的返回值就為-2。下面就能看到adb client是如何啟動ADB Server的了。
至此,我們需要再重新查看adb_commandline()方法了,此時我們執行的是adb fork-server server命令,因此is_server = 1, is_daemon = 1。
在adb_main中通過ADB_HOST這個宏來控制ADB Server和adbd daemon。在Android.mk文件中可以看出編譯adb server的時候ADB_HOST這個宏為1,而編譯adbd_daemon是ADB_HOST為0。
接下來我們來依次看看ADB Server啟動時都做了哪些事情?
a)、init_transport_registration():
上面講到transport_registration_func這個回調函數會在transport_registration_send這個Socket執行寫操作時,會被調用,那什么時候會執行寫操作呢?后面再來解答這個問題。
b)、下面再來看看usb_init(),初始化usb設備監聽。
此處我們就解答了上面的疑惑transport_register_func()什么時候會被調用。再來看看transport_register_func()又做了些什么呢?
3、local_init()
4、install_listener()
5、fdevent_loop();//通過IO多路選擇機制來選擇出要執行的fdevent,並執行它的毀掉函數。
上面我們詳細的講解了ADB Server的啟動過程,那么ADB Server啟動后又是如何與adb client以及adbd daemon進行通信的呢?下面我們在來看看。
下面我們繼續來以adb shell為例來分析:
此時fd = socket_loopback_client(__adb_server_port, SOCK_STREAM); 此時5037端口已經被監聽,返回值fd 即5037端口的Socket。
此時ADB Server端已經啟動,fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); ss_listener_event_func這個回調函數就會執行(后面再來看這個函數做了些什么)。
同時在interactive_shell()方法中,還創建了一個線程,用來讀取client端輸入的命令以及將該命令發送到ADB Server端進行處理。
通過上面這個thread就會將終端輸入的命令發送到adb server端了。上面還講到client端會發送一個tmp消息給ADB Server端,然后等待ADB Server端的響應OKAY/FAIL,那么ADB Server端又是如何響應的呢?下面我們在來進一步分析。
先來看看ss_listener_event_func
至此ADB Server端與adb client端的Socket建立完成了。上面在_adb_connect會向adb server端寫一個字符串,此時ADB Server端的local_socket_event_func方法將會被執行。
下面來看一下transport_sockets_events()
對於adb shell命令具體是如何操作的不是我們的重點,我們的重點是介紹adb的通信流程,因此在此就不再詳細分析。下面再來看看是如何將adb shell命令發送到adbd daemon的。
啟動adb server的時候創建了兩個線程,input_thread和output_thread,input_thread一直監聽5037端口,因此會接收到client端輸入的adb shell命令。然后通過 t->write_to_remote(p, t);發送到adbd daemon.
前面在初始化usb的時候(init_usb_transport())
t->read_from_remote = remote_read;
t->write_to_remote = remote_write;
再來看看ADB Server是如何通過remote_write將ADB Server端的命令發送到adbd daemon的。
至此,我們已經了解了adb shell命令是如何發送到adbd daemon那邊的了。下面再來看看adbd daemon是如何處理這些命令的。