Android Telephony涉及的框架結構如圖1所示。
圖1 Android Telephony框架結構
通過圖1可以發現Android Telephony框架結構的一些規律,具體如下。
- Android Telephony的業務應用跨越了AP和BP。AP與BP相互通信,符合前面介紹的智能手機硬件基本結構。
- Android系統在AP上運行,而Telephony運行在Linux Kernel之上的User Space空間。
- Android Telephony也采用了分層結構的設計,共跨越了三層Java Applications、Java Frameworks和User Libraries層,與Android操作系統整體分層結構保持一致。
- Android Telephony從上到下共分三層:Telephony應用、Telephony框架、RIL(Radio Interface Layer,無線通信接口層,主要位於UserLibraries層中的HAL層,接下來詳細介紹HAL)。
- BP SoftWare在BP上運行,主要負責實際的無線通信能力處理。
1 系統運行庫層的HAL層
HAL(Hardware Abstraction Layer,硬件抽象層)在Linux和Windows操作系統平台下有不同的實現方式。
Windows下的HAL位於操作系統的最底層,它直接操作物理硬件設備,使用抽象接口來隔離不同硬件的具體實現,為上層的操作系統和設備驅動程序 提供一個統一接口,起到對硬件的抽象作用。這樣更換硬件時,編寫硬件的驅動只要實現符合HAL定義的標准接口即可,而上層應用並不會受到影響,不必關心具 體來實現的是什么硬件。
Linux 下的HAL與Windows下的HAL不太一樣,HAL並不是位於操作系統的最底層直接操作硬件,相反,它位於操作系統核心層和驅動程序之上,是一個運行在User Space用戶空間中的服務程序。
2 簡析HAL結構
通過前面的學習,我們知道Android是基於Linux Kernel的開源智能手機操作系統,所以在這里重點介紹Linux下的HAL,就不單獨介紹Windows下的HAL結構了。
要想知道HAL結構,先看看來自於HAL 0.4.0 Specification的框架圖吧,如圖1-4所示(引用自http://people.redhat.com/davidz/hal-spec/hal-spec.html)。
圖2 HAL 0.4.0 Specification框架結構
HAL是一個位於操作系統和驅動程序之上,運行在用戶空間中的服務程序。其目的是為上層應用提供一個統一的查詢硬件設備的接口。我們都知道,抽象就 是為了隔離變化,那么這里的HAL可以帶給我們什么?首先,有了HAL接口,可以提前開始應用的開發,而不必關心具體實現的是什么硬件;其次,硬件廠家如 果需要更改硬件設備,只要按照HAL接口規范和標准提供對應的硬件驅動,而不需要改變應用;最后,HAL簡化了應用程序查詢硬件的邏輯,把這一部分的復雜 性轉移給HAL統一處理,這樣當一些應用程序使用HAL時,可以把對不同硬件的實際操作的復雜性也交給不同硬件廠家提供的庫函數來處理。
總之,HAL所謂的抽象並不提供對硬件的實際操作,對硬件的操作仍然由具體的驅動程序來完成。
3 Android為什么引入HAL
HAL的一些優勢在前面章節已經提到,這里回顧一下。Android引入HAL不僅因為其自身的優勢,而且還有一個非常重要的原因,就是為了保障在 Android平台基於Linux開發的硬件驅動和應用程序不必遵循GPL(General Public License)許可而保持封閉,這保障了更多廠家的利益。我們都知道,Linux Kernel是開源的而且遵循GPL許可證,根據GPL許可證規定,對源碼的任何修改都必須向社會開源。
那么Android是如何做到的呢?Linux Kernel和Android的許可證不一樣,Linux Kernel是GPL許可證,Android是ASL(Apache Software License)許可證。ASL許可證規定,可以隨意使用源碼,不必開源,所以建立在Android之上的硬件驅動和應用程序都可以保持封閉。也就是說, 只要把關鍵的驅動處理相關的主要邏輯轉移到Android平台內,在LinuxKernel中僅保留基礎的通信功能,即使開源一部分代碼,對廠家來講也不 會有什么損失。
Google選擇了這樣做,並且特意修改Kernel,原本應該包括在Linux Kernel中的某些驅動關鍵處理邏輯,被轉移到了HAL層之中而達到了不必開源的目的。
4 Android中HAL的運行結構
Android源碼中實現了一部分HAL,包括Wi-Fi、GPS、RIL、Sensor等,這些代碼主要儲存於以下目錄:
- Android_src/hardware/libhardware_legacy:老式HAL結構,采用直接調用so動態鏈接庫方式;
- Android_src/hardware/libhardware:新式HAL結構,采用Stub代理方式調用;
- Android_src/hardware/ril:RIL(Radio Interface Layer,無線通信接口層),作為本書重點關注和學習的內容,后面將以獨立章節詳細講解。
在Android中,HAL的運行機制是什么樣的呢?它有兩種運行機制,老式HAL和新式HAL,如圖3所示。
圖3 Android中HAL兩種運行結構
從圖3中不難看出,左邊是老的HAL結構,應用或框架通過so動態鏈接庫調用而達到對硬件驅動的訪問。在so動態鏈接庫里,實現了對驅動的訪問邏輯處理。我們重點學習和理解HAL Stub方式, RIL也采用了此方式的設計思想。
HAL Stub 是一種Proxy代理概念,Stub雖然仍是以 *.so 的形式存在,但 HAL 已經將 *.so 的具體實現隱藏了起來。 Stub 向 HAL 提供operations方法,Runtime通過Stub提供的so獲取它的 operations方法,並告知Runtime的callback方法。這樣Runtime和Stub都有對方調用的方法,一個應用的請求通過 Runtime調用Stub的operations方法,而Stub響應operations方法並完成后,再調用Runtime的callback方法 進行返回。這里可能有一點繞,根據前面的描述再結合圖4所示會更容易理解。
圖4 HAL Stub結構
上層通過HAL提供的functions調用底層硬件,而底層硬件處理完成上層請求后或硬件狀態發生變化后,HAL層通過Runtime提供的callback接口回調上層應用。
HAL Stub 有一種包含關系,即 HAL 里包含了很多的 Stub。 Runtime 只要說明請求類型,就可以取得並操作Stub對應的operations。其實現主要在 hardware.c 和 hardware.h 文件中,實質也是通過dlopen方法加載 .so動態鏈接庫,從而呼叫 *.so 里的符號( symbol )實現。
------------------------------
本文節選自《深入理解Android : Telephony原理剖析與最佳實踐》,作者:楊青平。
豆瓣網址:http://book.douban.com/subject/20480692/
樣章試讀:http://download.csdn.net/detail/hzbooks/5068008
《深入理解Android : Telephony原理剖析與最佳實踐》從源代碼角度深入解析了 Android Telephony的架構設計與實現原理,深刻揭示了Android系統的通信機制。對於Android應用開發工程師和系統工程師而言,《深入理解 Android:Telephony原理剖析與最佳實踐》都是難得的研究和學習資料。全書共13章,分為五部分:第一部分(1~3章),首先介紹了智能手 機的系統結構、Android系統的架構、Telephony框架的結構,然后詳細介紹了Android源代碼編譯環境和閱讀環境的搭建方法,以及閱讀 《深入理解Android:Telephony原理剖析與最佳實踐》要做的技術准備;第二部分(4~6章),對Android的通話功能進行了深入的分 析,包括對通話流程的分析、對主動撥號和來電流程的分析、對通話應用機制的分析,以及對手機通信功能在框架層和應用層中的實現機制的分析;第三部分 (7~9章),對Android的通信功能進行了深入的分析,包括對網絡服務狀態的運行機制的分析、對Android手機上網的實現機制的分析,以及對短 息發送和接收流程的分析;第四部分(10~12章),對Android RIL的工作機制進行了深入的分析,包括對框架層中的RILJ運行機制的分析、對RILC系統結構及LibRIL運行機制的分析,以及對 Reference-RIL框架的原理的分析;第五部分(13章),分析了Telephony模塊所提供的系統服務,包括系統服務的注冊入口以及調用系統 服務接口的實例。