.

宣告

  • 其實對於Android系統Binder通訊的機制早就有分析的想法,記得去年6、7月份Mr.Deng離職期間約定一起對其進行研究的,但因為我個人問題沒能實施這個計劃,留下些許遺憾...
  • 最近,剛好在做公司某專案中一個難題就是關於Binder的,於是想借此機會對其進行儘量深入的分析,以算是彌補過去的遺憾吧。而且,一年後我對於Android系統的理解,比去年確實加深了很多;
  • 文中參考了很多前輩們寫的書籍及部落格內容,可能涉及的比較多先不具體列出來了,等有時間再新增進來;
  • 本文使用的程式碼是LineageOS的cm-14.1,對應Android 7.1.2,可以參考我的另一篇部落格:[如何下載Nexus5的LineageOS14.1(cm-14.1)系統原始碼並編譯、刷機](https://my.oschina.net/XiaoMaPedro/blog/3028748 "如何下載Nexus5的LineageOS14.1(cm-14.1)系統原始碼並編譯、刷機");

0 寫在前面的

    其實,Android系統的基礎是Linux,它本可以使用Linux體系下的IPC機制,為什麼還要再實現一個Binder機制呢?答案肯定是Linux現有的IPC機制沒有一個能夠滿足Android系統的需求的,相對於其他IPC機制Binder:

  • Binder更加靈活並節省記憶體;
  • Binder還解決和避免了傳統的程序間通訊可能會增加程序開銷的問題,也避免了程序過載和安全漏洞等方面的風險;

    這個表達有點蒼白,不過沒關係,後面會越來越體會到Binder機制的intelligence,Binder主要實現下面的功能:

  1. 用驅動程式來推動程序間通訊;
  2. 通過共享記憶體來提高效能;
  3. 為程序請求分配每個程序的執行緒池;
  4. 針對系統中的物件引入了引用計數和跨程序的物件引用對映;
  5. 程序間同步呼叫;

    這幾條聽起來有點太學術了。要明白的是Binder這個機制根本上還是為執行在ART基礎上的系統服務提供支撐的。因為APP不同程序間需要通訊、而且它們需要使用框架層的各種服務框架的Java介面(框架層的系統服務框架大多數執行在同一個程序system_server的上下文環境中,並且可以在servicemanager輔助下被查詢到)。

    system_server是以--start-system-server引數從Zygote中fork()出來的,而servicemanager則是Android系統的core類守護程序之一。它們兩個共同提供了對整個Android框架服務架構的支援和上下文環境。

servicemanager

    可以先看一下我的Nexus 5 cm-14.1系統中的servicemanager.rc檔案,它所在的原始碼目錄為:~/LineageOS/frameworks/native/cmds/servicemanager/servicemanager.rc

service servicemanager /system/bin/servicemanager
    class core
    user system
    group system readproc
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart audioserver
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart inputflinger
    onrestart restart drm
    onrestart restart cameraserver
    writepid /dev/cpuset/system-background/tasks

    從這個rc檔案中就可以看出來,首先它處於core類服務中,很多關鍵服務都依賴於它的存在,比如healthd、zygote、audioserver、media、surfaceflinger、inputflinger、drm、cameraserver這些service在servicemanager重啟時全部都要跟著進行重啟,就可以看出servicemanager有多重要。而且,servicemanager服務用關鍵字critical修飾,意思是如果這個服務反覆重啟5次系統就會自動進入recovery模式。

    servicemanager是作為其他作業系統服務的定位器(locator)或稱索引目錄(directory)而存在的。任何一個應用或系統元件想要使用其他服務時,都必須先到servicemanager查詢,獲得一個控制代碼(handle),然後才能繼續執行操作。服務也沒法直接告訴客戶端自己在什麼位置,它也必須先到servicemanager註冊,然後才能被需要使用它的客戶端找到。所以如果servicemanager重啟了的話,所有依賴於它的服務都必須重啟,所有的服務都必須要重新再註冊一遍。如果servicemanager掛了的話,程序間通訊也將被中斷。

    使用者模式的服務是通過一個字元裝置節點/dev/binder(這個裝置節點可以被所有的程序讀取和訪問)來訪問binder進行程序間通訊的。同一時刻,只有一個使用者態程序可以使用Binder中的context manager,context manager是系統中所有其他程序(無論它是客戶端程序還是服務端程序)的匯接點。服務必須把自己的服務名以及介面註冊在context manager中,客戶端必須通過在context manager中進行檢索,才能找到它們要使用的服務。

    servicemanager也只是一個很小的elf檔案,所完成的操作也很簡單:它首先呼叫binder_open獲取/dev/binder的檔案描述符,然後再呼叫binder_become_context_manager註冊ServiceManager服務,該服務的handle索引值為0。再接下來,servicemanager就會進入一個名為binder_loop的無限迴圈中。在這個無限迴圈裡,servicemanager會讓自己進入阻塞狀態,直到/dev/binder中產生一個transaction(即某個客戶端發來了請求),隨後程序就會被喚醒,並呼叫它的svcmgr_handler回撥函式處理這個transaction。

    servicemanager必須是全域性可訪問的。這樣,各種服務才能上它這兒來註冊,客戶端也才能來查詢服務。在使用C/C++程式碼時,服務和客戶端同樣可以呼叫defaultServiceManager()獲得一個訪問servicemanager的控制代碼(從技術上說,這只是它的介面,是個sp< IServiceManager >型別的物件),這個定義在IServiceManager.h中的介面,匯出了幾個transaction請求碼。下表列出了這些請求碼及實現這些請求碼的可供C/C++程式碼呼叫的API。值得注意的是,在這張表中並沒有用來刪除服務的API,這是因為在對應的程序死掉之後,服務會被自動刪除。因為Binder能夠檢測到這種情況,並在檢查到這種情況時,向servicemanager傳送一個BR_DEAD_BINDERC程序死亡通知)。

        

    addService被認為是個非常敏感的功能,只有UID為0或1000(AID_SYSTEM)的服務才能自由地註冊服務,其他的系統服務則會受到限制。受限制的服務在Android 5之後被寫在了SELinux的/service_contexts檔案中,這使得系統能以極為靈活的方式對服務進行控制,system_server.c這個原始碼檔案己經被簡化成對check_mac_perms()函式的一次呼叫,這個函式然後又會去呼叫selinux_check_access()函式。用這一方式,可以對所有服務的註冊和查詢強制進行安全檢查,同時,這也使得裝置的製造商可以在不需要重新編譯任何原始碼的前提下新增它們自己的服務。

    開啟原始碼目錄:~/LineageOS/system/sepolicy/service_contexts

accessibility                             u:object_r:accessibility_service:s0
account                                   u:object_r:account_service:s0
activity                                  u:object_r:activity_service:s0
alarm                                     u:object_r:alarm_service:s0
android.os.UpdateEngineService            u:object_r:update_engine_service:s0
android.security.keystore                 u:object_r:keystore_service:s0
android.service.gatekeeper.IGateKeeperService    u:object_r:gatekeeper_service:s0
appops                                    u:object_r:appops_service:s0
appwidget                                 u:object_r:appwidget_service:s0
assetatlas                                u:object_r:assetatlas_service:s0
audio                                     u:object_r:audio_service:s0
backup                                    u:object_r:backup_service:s0
batteryproperties                         u:object_r:batteryproperties_service:s0
batterystats                              u:object_r:batterystats_service:s0
battery                                   u:object_r:battery_service:s0
bluetooth_manager                         u:object_r:bluetooth_manager_service:s0
bluetooth                                 u:object_r:bluetooth_service:s0
carrier_config                            u:object_r:radio_service:s0
clipboard                                 u:object_r:clipboard_service:s0
com.android.net.IProxyService             u:object_r:IProxyService_service:s0
commontime_management                     u:object_r:commontime_management_service:s0
common_time.clock                         u:object_r:mediaserver_service:s0
common_time.config                        u:object_r:mediaserver_service:s0
connectivity                              u:object_r:connectivity_service:s0
connmetrics                               u:object_r:connmetrics_service:s0
consumer_ir                               u:object_r:consumer_ir_service:s0
content                                   u:object_r:content_service:s0
contexthub_service                        u:object_r:contexthub_service:s0
country_detector                          u:object_r:country_detector_service:s0
cpuinfo                                   u:object_r:cpuinfo_service:s0
dbinfo                                    u:object_r:dbinfo_service:s0
device_policy                             u:object_r:device_policy_service:s0
deviceidle                                u:object_r:deviceidle_service:s0
devicestoragemonitor                      u:object_r:devicestoragemonitor_service:s0
diskstats                                 u:object_r:diskstats_service:s0
display.qservice                          u:object_r:surfaceflinger_service:s0
display                                   u:object_r:display_service:s0
netd_listener                             u:object_r:netd_listener_service:s0
DockObserver                              u:object_r:DockObserver_service:s0
dreams                                    u:object_r:dreams_service:s0
drm.drmManager                            u:object_r:drmserver_service:s0
dropbox                                   u:object_r:dropbox_service:s0
ethernet                                  u:object_r:ethernet_service:s0
fingerprint                               u:object_r:fingerprint_service:s0
android.hardware.fingerprint.IFingerprintDaemon u:object_r:fingerprintd_service:s0
gfxinfo                                   u:object_r:gfxinfo_service:s0
graphicsstats                             u:object_r:graphicsstats_service:s0
gpu                                       u:object_r:gpu_service:s0
hardware                                  u:object_r:hardware_service:s0
hardware_properties                       u:object_r:hardware_properties_service:s0
hdmi_control                              u:object_r:hdmi_control_service:s0
inputflinger                              u:object_r:inputflinger_service:s0
input_method                              u:object_r:input_method_service:s0
input                                     u:object_r:input_service:s0
iphonesubinfo_msim                        u:object_r:radio_service:s0
iphonesubinfo2                            u:object_r:radio_service:s0
iphonesubinfo                             u:object_r:radio_service:s0
ims                                       u:object_r:radio_service:s0
imms                                      u:object_r:imms_service:s0
isms_msim                                 u:object_r:radio_service:s0
isms2                                     u:object_r:radio_service:s0
isms                                      u:object_r:radio_service:s0
isub                                      u:object_r:radio_service:s0
jobscheduler                              u:object_r:jobscheduler_service:s0
launcherapps                              u:object_r:launcherapps_service:s0
location                                  u:object_r:location_service:s0
lock_settings                             u:object_r:lock_settings_service:s0
media.audio_flinger                       u:object_r:audioserver_service:s0
media.audio_policy                        u:object_r:audioserver_service:s0
media.camera                              u:object_r:cameraserver_service:s0
media.camera.proxy                        u:object_r:cameraproxy_service:s0
media.log                                 u:object_r:audioserver_service:s0
media.player                              u:object_r:mediaserver_service:s0
media.extractor                           u:object_r:mediaextractor_service:s0
media.codec                               u:object_r:mediacodec_service:s0
media.resource_manager                    u:object_r:mediaserver_service:s0
media.radio                               u:object_r:audioserver_service:s0
media.sound_trigger_hw                    u:object_r:audioserver_service:s0
media.drm                                 u:object_r:mediadrmserver_service:s0
media_projection                          u:object_r:media_projection_service:s0
media_resource_monitor                    u:object_r:media_session_service:s0
media_router                              u:object_r:media_router_service:s0
media_session                             u:object_r:media_session_service:s0
meminfo                                   u:object_r:meminfo_service:s0
midi                                      u:object_r:midi_service:s0
mount                                     u:object_r:mount_service:s0
netd                                      u:object_r:netd_service:s0
netpolicy                                 u:object_r:netpolicy_service:s0
netstats                                  u:object_r:netstats_service:s0
network_management                        u:object_r:network_management_service:s0
network_score                             u:object_r:network_score_service:s0
network_time_update_service               u:object_r:network_time_update_service:s0
nfc                                       u:object_r:nfc_service:s0
notification                              u:object_r:notification_service:s0
otadexopt                                 u:object_r:otadexopt_service:s0
package                                   u:object_r:package_service:s0
permission                                u:object_r:permission_service:s0
persistent_data_block                     u:object_r:persistent_data_block_service:s0
phone_msim                                u:object_r:radio_service:s0
phone1                                    u:object_r:radio_service:s0
phone2                                    u:object_r:radio_service:s0
phone                                     u:object_r:radio_service:s0
pinner                                    u:object_r:pinner_service:s0
power                                     u:object_r:power_service:s0
print                                     u:object_r:print_service:s0
processinfo                               u:object_r:processinfo_service:s0
procstats                                 u:object_r:procstats_service:s0
radio.phonesubinfo                        u:object_r:radio_service:s0
radio.phone                               u:object_r:radio_service:s0
radio.sms                                 u:object_r:radio_service:s0
recovery                                  u:object_r:recovery_service:s0
restrictions                              u:object_r:restrictions_service:s0
rttmanager                                u:object_r:rttmanager_service:s0
samplingprofiler                          u:object_r:samplingprofiler_service:s0
scheduling_policy                         u:object_r:scheduling_policy_service:s0
search                                    u:object_r:search_service:s0
sensorservice                             u:object_r:sensorservice_service:s0
serial                                    u:object_r:serial_service:s0
servicediscovery                          u:object_r:servicediscovery_service:s0
shortcut                                  u:object_r:shortcut_service:s0
simphonebook_msim                         u:object_r:radio_service:s0
simphonebook2                             u:object_r:radio_service:s0
simphonebook                              u:object_r:radio_service:s0
sip                                       u:object_r:radio_service:s0
soundtrigger                              u:object_r:voiceinteraction_service:s0
statusbar                                 u:object_r:statusbar_service:s0
SurfaceFlinger                            u:object_r:surfaceflinger_service:s0
task                                      u:object_r:task_service:s0
telecom                                   u:object_r:telecom_service:s0
telephony.registry                        u:object_r:registry_service:s0
textservices                              u:object_r:textservices_service:s0
trust                                     u:object_r:trust_service:s0
tv_input                                  u:object_r:tv_input_service:s0
uimode                                    u:object_r:uimode_service:s0
updatelock                                u:object_r:updatelock_service:s0
usagestats                                u:object_r:usagestats_service:s0
usb                                       u:object_r:usb_service:s0
user                                      u:object_r:user_service:s0
vibrator                                  u:object_r:vibrator_service:s0
voiceinteraction                          u:object_r:voiceinteraction_service:s0
vrmanager                                 u:object_r:vr_manager_service:s0
wallpaper                                 u:object_r:wallpaper_service:s0
webviewupdate                             u:object_r:webviewupdate_service:s0
wifip2p                                   u:object_r:wifip2p_service:s0
wifiscanner                               u:object_r:wifiscanner_service:s0
wifi                                      u:object_r:wifi_service:s0
window                                    u:object_r:window_service:s0
*                                         u:object_r:default_android_service:s0

    程式設計時使用的API己經打包在框架類android.os.ServiceManagerNative 中了,這個類又由android.os.ServiceManager 做了進一步的封裝。Android也不鼓勵App直接使用這個類,而是希望開發者呼叫Context.getSystemService()方法來查詢系統服務,並通過intent 使用第三方服務。不過無論是使用哪種方式,與服務進行通訊(不論它是個系統服務還是第三方服務)都是通過binder訊息來完成的。

          相關文章