学习 Android O HIDL
HIDL 簡介
HIDL 即HAL interface definition language,在 Android Project Treble 中被起草,在 Android O 中被全面使用。
HIDL用于進程間通信(IPC)。對于c++和Java程序員來說,HIDL的語法看起來會很熟悉,即使它有一系列不同的關鍵字。HIDL還使用java風格的注解。
Project Treble
Project treble是Android O中引入的特性.?
主要的目標是Android模塊化,根據谷歌、SoC供應商和OEM的需求分離所有權和分配不同的模塊。?
Vendor 模塊被分離到一個獨立的可單獨更新的image,從而改進了軟件升級發布的過程?
Treble由以下幾部分組成:
-
Kernel modularization
-
HAL re-architecture (binderization)
-
Separation of the vendor and OEM modules from the system image
關于HIDL的設計
HIDL的設計目的是為了能夠在不重新編譯HALs的情況下能夠替換framework。HALs將由供應商或SOC制造商構建,并放在設備的vendor下的分區中,而framework框架在它自己的分區中發揮作用,能夠被OTA替換而不重新編譯HALs。
HIDL的設計平衡了以下問題:?
共用性?
在進程間創建可靠的共用接口,而這些進程可能有不同的架構、工具鏈和構建配置。HIDL接口是版本化的,在發布后不能更改。?
效率?
HIDL會將復制的次數最小化。HIDL定義的數據以C++標準layout data structures的形式傳遞給c++代碼,這種數據結構可以不打包的情況下使用。HIDL還提供共享內存接口,由于RPCs天生有點慢,HIDL無需使用RPC調用,而支持兩種傳輸數據的方法:shared memory?(共享內存)和?Fast Message Queue?(FMQ).
直觀?
對于RPC,HIDL只使用參數(參見AIDL),避免了內存所有權的棘手問題;不能有效通過方法返回的值通過回調函數返回。既不將數據傳遞到HIDL,也不從HIDL接收數據,改變數據的所有權。數據只需要在被調用函數的持續時間內存在,并且可以在被調用函數返回后立即銷毀。
使用 passthrough 模式
為了更新運行在Android系統早期版本的設備到Android O操作系統,你可以將傳統的(和 legacy遺留的)HALs封裝在新的HIDL接口中,這一接口以binderized 和same-process (passthrough)的模式服務于HAL。這種封裝對HAL和Android框架都是透明的。
Passthrough模式僅適用于c++的客戶端和實現。運行Android早期版本的設備沒有Java編寫的HALs,因此Java HALs必然使用binderized 的模式。
Passthrough header files
當一個.hal文件被編譯后, hidl-gen除了用于binder通信的頭文件外,還生成一個額外的 passthrough 頭文件 BsFoo.h ;這個頭文件定義了dlopened的函數. 由于passthrough HALs 運行在調用它們的相同的進程中,大多數情況下 passthrough 方法被直接通過函數調用 (相同線程)。oneway 方法在他們自己的線程中運行,因為它們并不打算等待HAL來處理它們(這意味著任何在passthrough模式中使用oneway方法的HAL必須是線程安全的)。
給定一個IFoo.hal文件,BsFoo.h封裝了hidl生成的方法以提供額外的特性(比如在另一個線程中運行oneway事務)。這個文件類似于BpFoo。但是,不是通過binder進行IPC調用,而是直接調用所需的函數。未來HALs可能提供多種實現,例如FooFast HAL和FooAccurate HAL。在這種情況下,將創建每個額外實現的文件(例如:PTFooFast.cpp和PTFooAccurate.cpp)。
Binderizing passthrough HALs
支持passthrough 模式的HAL實現可以binderized 。對于一個HAL 接口a.b.c.d@M.N::IFoo,需要創建兩個包:
- a.b.c.d@M.N::IFoo-impl.?包含HAL的實現,并暴露函數IFoo * HIDL_FETCH_IFoo(const char * name)。在legacy hal設備上,這個包是dlopened 的,實現是使用HIDL_FETCH_IFoo實例化的。 您可以使用hidl - gen和- lc + + - impl和- landroidbp - impl生成基本代碼。
- a.b.c.d@M.N::IFoo-service.?打開passthrough HAL并將其注冊為一個binder化服務,使相同的HAL實現被用作passthrough 和binderized。
給定類型IFoo,您可以調用sp < IFoo > IFoo::getService(string name, bool getStub)來獲取IFoo的實例。
如果getStub值是true,getService嘗試只以passthrough模式打開HAL。如果getStub為false,則getService嘗試查找到一個binderized 服務;如果失敗,則嘗試找到passthrough服務。getStub參數除了defaultPassthroughServiceImplementation不應使用。(使用Android O的設備是完全binderized 的設備,因此不允許以passthrough模式打開一個服務。)
HIDL 語法
HIDL語言類似于C(但不使用C預處理器)
- /*?/ 表示文檔注釋.
- /* */ 表示文檔多行注釋.
- // 表示在一行結束后注釋
- [empty] 表明當前項的值為空
- ? 放置在項前,表明該項為可選項.
- … 表明該序列包含0個或多個如前述使用分隔符隔開的項
- , 逗號用于分隔序列中的元素
- ; 分號用于標記每個元素的結束位置.
- @entry 當前HAL模塊被使用時應當被最先調用的接口
- @exit 當前HAL模塊被調用時應當被最后調用的接口
- @callflow(next={“name_a”, “name_b”, “name_c”}) 當前接口被調用后可能被調用的接口列表。其中name_a接口被調用的概率最大,name_c接口被調用的概率最小。如果只存在1個可能被調用的接口,那么花括號{ }可以省略不寫。如果給定的接口名無效,則會導致VTS編譯失敗。
- @callflow(next={“*”}) 當前接口被調用后可能會調用任意接口
Example:
ROOT =PACKAGE IMPORTS PREAMBLE { ITEM ITEM ... } // not for types.halPREAMBLE = interface identifier EXTENDS| PACKAGE IMPORTS ITEM ITEM... // only for types.hal; no method definitionsITEM =ANNOTATIONS? oneway? identifier(FIELD, FIELD ...) GENERATES?;| struct identifier { SFIELD; SFIELD; ...}; // Note - no forward declarations| union identifier { UFIELD; UFIELD; ...};| enum identifier: TYPE { ENUM_ENTRY, ENUM_ENTRY ... }; // TYPE = enum or scalar| typedef TYPE identifier;VERSION = integer.integer;PACKAGE = package android.hardware.identifier[.identifier[...]]@VERSION;PREAMBLE = interface identifier EXTENDSEXTENDS = <empty> | extends import_name // must be interface, not packageGENERATES = generates (FIELD, FIELD ...)// allows the Binder interface to be used as a type // (similar to typedef'ing the final identifier) IMPORTS =[empty]| IMPORTS import import_name;TYPE =uint8_t | int8_t | uint16_t | int16_t | uint32_t | int32_t | uint64_t | int64_t |float | double | bool | string | identifier // must have been previously typedef'd// or defined with struct, union, enum, or import | memory | pointer | vec<TYPE> | bitfield<TYPE> // TYPE is user-defined enum | fmq_sync<TYPE> | fmq_unsync<TYPE> | TYPE[SIZE]FIELD =TYPE identifierUFIELD =TYPE identifier| struct identifier { FIELD; FIELD; ...} identifier;| union identifier { FIELD; FIELD; ...} identifier;SFIELD =TYPE identifier| struct identifier { FIELD; FIELD; ...};| union identifier { FIELD; FIELD; ...};| struct identifier { FIELD; FIELD; ...} identifier;| union identifier { FIELD; FIELD; ...} identifier;SIZE = // Must be greater than zeroconstexprANNOTATIONS =[empty]| ANNOTATIONS ANNOTATIONANNOTATION =| @identifier| @identifier(VALUE)| @identifier(ANNO_ENTRY, ANNO_ENTRY ...)ANNO_ENTRY =identifier=VALUEVALUE ="any text including \" and other escapes"| constexpr| {VALUE, VALUE ...} // only in annotationsENUM_ENTRY =identifier| identifier = constexpr- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
原文地址: http://blog.csdn.net/ch853199769/article/details/77840099
總結
以上是生活随笔為你收集整理的学习 Android O HIDL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解Linux内存管理--目录导航
- 下一篇: android sina oauth2.