Android O之后Treble VNDK, HIDL

Treble框架

Android 8.0 重新設(shè)計(jì)了 Android 操作系統(tǒng)框架(在一個(gè)名為“Treble”的項(xiàng)目中)春寿,以便讓制造商能夠以更低的成本更輕松膀篮、更快速地將設(shè)備更新到新版 Android 系統(tǒng)忍些。在這種新架構(gòu)中撬统,HAL 接口定義語(yǔ)言(HIDL缝呕,發(fā)音為“hide-l”)指定了 HAL 和其用戶之間的接口垒玲,讓用戶無(wú)需重新構(gòu)建 HAL陆馁,就能替換 Android 框架。在 Android 10 中合愈,HIDL 功能已整合到 AIDL 中叮贩。此后,HIDL 就被廢棄了佛析,并且僅供尚未轉(zhuǎn)換為 AIDL 的子系統(tǒng)使用益老。

利用新的供應(yīng)商接口,Treble 將供應(yīng)商實(shí)現(xiàn)(由芯片制造商編寫的設(shè)備專屬底層軟件)與 Android 操作系統(tǒng)框架分離開(kāi)來(lái)寸莫。供應(yīng)商或 SOC 制造商構(gòu)建一次 HAL捺萌,并將其放置在設(shè)備的 /vendor 分區(qū)中;框架可以在自己的分區(qū)中通過(guò)無(wú)線下載 (OTA) 更新進(jìn)行替換膘茎,而無(wú)需重新編譯 HAL桃纯。

舊版 Android 架構(gòu)與當(dāng)前基于 HIDL 的架構(gòu)之間的區(qū)別在于對(duì)供應(yīng)商接口的使用:

  • Android 7.x 及更低版本中沒(méi)有正式的供應(yīng)商接口,因此設(shè)備制造商必須更新大量 Android 代碼才能將設(shè)備更新到新版 Android 系統(tǒng)


  • Android 8.0 及更高版本提供了一個(gè)穩(wěn)定的新供應(yīng)商接口披坏,因此設(shè)備制造商可以訪問(wèn) Android 代碼中特定于硬件的部分态坦,這樣一來(lái),設(shè)備制造商只需更新 Android 操作系統(tǒng)框架棒拂,即可跳過(guò)芯片制造商直接提供新的 Android 版本:

    所有搭載 Android 8.0 及更高版本的新設(shè)備都可以利用這種新架構(gòu)伞梯。為了確保供應(yīng)商實(shí)現(xiàn)的向前兼容性,供應(yīng)商接口會(huì)由供應(yīng)商測(cè)試套 (VTS) 進(jìn)行驗(yàn)證帚屉,該套件類似于兼容性測(cè)試套件 (CTS)谜诫。您可以使用 VTS 在舊版 Android 架構(gòu)和當(dāng)前 Android 架構(gòu)中自動(dòng)執(zhí)行 HAL 和操作系統(tǒng)內(nèi)核測(cè)試。

Android官網(wǎng)資料

Android 開(kāi)發(fā)者網(wǎng)站攻旦,面向應(yīng)用開(kāi)發(fā)者喻旷,
https://developer.android.google.cn/

Android 開(kāi)源操作系統(tǒng)網(wǎng)站,面向系統(tǒng)開(kāi)發(fā)者牢屋,系統(tǒng)架構(gòu)且预,安全牺陶,Treble方案,VNDK這里都有詳細(xì)的說(shuō)明辣之,官網(wǎng)資料都是晦澀難懂掰伸,多看幾遍就好。
https://source.android.google.cn/devices/architecture

Treble之后系統(tǒng)變化

按 Treble 架構(gòu)要求怀估,System 分區(qū)拆分成 System 和 Vendor 分區(qū)狮鸭。System 鏡像包含Android 原生倉(cāng)及 Vendor/ODM 開(kāi)發(fā)的 app 和 framework/JNI。Vendor 主要提供芯片/硬件相關(guān)接口實(shí)現(xiàn)多搀。Android 版本中與 Treble 相關(guān)的新特性:

  • HIDL binderized歧蕉,framework 與 HAL 實(shí)現(xiàn)運(yùn)行在不同進(jìn)程,通過(guò) hwbinder 通信
  • System康铭、Vendor 獨(dú)立分區(qū)
  • Vendor 包含獨(dú)立 SELinux 策略惯退、Property 屬性
  • Kernel 要求 linux4.4 以上版本,推薦 4.9
  • 新增 VTS 測(cè)試从藤,保證兼容性
  • 新增 PureAndroidTest催跪,由 Google 提供鏡像,覆蓋廠商 system 分區(qū)后執(zhí)行 VTS 測(cè)試夷野;
IPC 域 說(shuō)明
/dev/binder 框架/應(yīng)用進(jìn)程之間的 IPC懊蒸,使用 AIDL 接口
/dev/hwbinder 框架/供應(yīng)商進(jìn)程之間的 IPC,使用 HIDL 接口
供應(yīng)商進(jìn)程之間的 IPC悯搔,使用 HIDL 接口
/dev/vndbinder 供應(yīng)商/供應(yīng)商進(jìn)程之間的 IPC骑丸,使用 AIDL 接口

binder,hwbinder妒貌,vndbinder之間的關(guān)系
Android O 獨(dú)立 System通危、Vendor 分區(qū)后,增加了相應(yīng) Selinux 規(guī)則灌曙,System 進(jìn)程不能按原有方式綁定 Vendor 服務(wù)菊碟。因?yàn)樵?Android O 中,/dev/binder 設(shè)備節(jié)點(diǎn)成為了框架進(jìn)程的專屬節(jié)點(diǎn)平匈,這意味著 Vendor 進(jìn)程將無(wú)法再訪問(wèn)該節(jié)點(diǎn)框沟,而要使用 kernel 新增的 hwbinder和 vndbinder藏古。

Android O IPC 規(guī)范.png

About VNDK

Treble工程的目標(biāo)是system/vendor進(jìn)程解耦增炭,讓Android系統(tǒng)更新不依賴芯片方案商適配,要實(shí)現(xiàn)這一框架拧晕,需要先解耦system/vendor依賴(VNDK)隙姿,并提供穩(wěn)定的API/ABI, 再打通system/vendor直接溝通(HIDL)厂捞,這玩意输玷,要學(xué)習(xí)參考官網(wǎng)資料吧.
https://source.android.google.cn/devices/architecture/vndk

HIDL簡(jiǎn)介

Android O 引入 HIDL 語(yǔ)言队丝,用于描述 O 中新增的跨進(jìn)程 HAL 接口。原生架構(gòu)下欲鹏,F(xiàn)ramework 作為 Client 端机久,Vendor 作為 Service 端。Framework 框架由谷歌提供赔嚎,原生 HIDL要求保持穩(wěn)定膘盖,適配工作主要在 Vendor Service。
Client 端:包含 Android 原生或海思擴(kuò)展服務(wù)尤误。
Server 端:Android 原生或芯片廠擴(kuò)展 HAL 服務(wù)侠畔。
HIDL 文件(.hal)一般使用 Android.bp 編譯。Android.bp 通過(guò) hidl-gen 工具將 HIDL 文
件轉(zhuǎn)換成
.h/*.cpp损晤,再編譯生成 android.hardware.xxxx@1.0.sovendor.xxx.hardware.xxxx@1.0软棺。

HIDL 流程示意圖

HIDL示例Demo

  1. 創(chuàng)建HIDL接口
hardware/interfaces/demo/1.0/IDemo.hal 
package android.hardware.demo@1.0;

interface IDemo {
    doDemo(float bar) generates(int32_t status);
};
  1. 生成接口的執(zhí)行代碼
    這個(gè)命令會(huì)在hardware/interfaces/demo/1.0/default 下生成Demo.cpp 和 Demo.h兩個(gè)文件
hidl-gen -o hardware/interfaces/demo/1.0/default -Lc++-impl -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.demo@1.0
  1. 生成makefile
    根目錄執(zhí)行腳本,自動(dòng)生成*.hal 對(duì)應(yīng)的 Android.bp 和 Android.mk 文件
./hardware/interfaces/update-makefiles.sh 
  1. 添加接口聲明
    擴(kuò)展接口需要在 vendor/manifest.xml 中聲明, 或device/hisilicon/Hi37XXVXXX/manifest.xml
  <hal format="hidl">
      <name>android.hardware.demo</name>
      <transport>hwbinder</transport>
      <version>1.0</version>
      <interface>
          <name>IDemo</name>
          <instance>default</instance>
      </interface>
  </hal>
  1. 增加 hash 值
    HIDL 接口層是 Treble 架構(gòu)的基礎(chǔ)尤勋,原則上發(fā)布后不能變動(dòng)喘落,新接口應(yīng)升級(jí)版本號(hào)。系統(tǒng)編譯時(shí)會(huì)檢查已發(fā)布接口 hash 值最冰,防止篡改揖盘。已有接口對(duì)應(yīng) hash 值詳見(jiàn)hardware/interfaces/current.txt。新增擴(kuò)展接口锌奴,可在 Android 根目錄執(zhí)行命令生成 hash 值:
hidl-gen -L hash -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.demo@1.0 >> hardware/interfaces/current.txt
  1. 服務(wù)端實(shí)現(xiàn)
    代碼目錄結(jié)構(gòu)如下兽狭,default目錄下面Android.mk, service.cpp, android.hardware.demo@1.0-service.rc需要自
    己創(chuàng)建,目錄結(jié)構(gòu)如下鹿蜀,
hardware/interfaces/demo/1.0
├── Android.bp
├── Android.mk
├── default
│   ├── android.hardware.demo@1.0-service.rc
│   ├── Android.mk
│   ├── Demo.cpp
│   ├── Demo.h
│   └── service.cpp
└── IDemo.hal

Demo.cpp就添加一個(gè)打印

#include "Demo.h"
#include <log/log_main.h>
#define LOG_TAG "Demo"

namespace android {
namespace hardware {
namespace demo {
namespace V1_0 {
namespace implementation {

// Methods from ::android::hardware::demo::V1_0::IDemo follow.
Return<int32_t> Demo::doDemo(float bar) {
    // Demo就簡(jiǎn)單做個(gè)打印箕慧,
    ALOGD(" Hello Hidl Demo Bar is %f \n", bar);
    return int32_t {0};
}

// Methods from ::android::hidl::base::V1_0::IBase follow.

IDemo* HIDL_FETCH_IDemo(const char* /* name */) {
    return new Demo();
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace demo
}  // namespace hardware
}  // namespace android

service.cpp將IDemo注冊(cè)到hwservicemanager:

#define LOG_TAG "android.hardware.demo@1.0-service"
#include "Demo.h"
#include <hidl/LegacySupport.h>
#include <android/log.h>

using android::hardware::demo::V1_0::IDemo;
using android::hardware::defaultPassthroughServiceImplementation;

int main() {
    return defaultPassthroughServiceImplementation<IDemo>();
}

android.hardware.demo@1.0-service.rc啟動(dòng)腳本

service demo_hal_service /vendor/bin/hw/android.hardware.demo@1.0-service
    class hal
    user  root
    group  root 

Android.mk參考其他hidl模塊寫

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.demo@1.0-impl
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES :=  \
        Demo.cpp
LOCAL_C_INCLUDES := \
LOCAL_SHARED_LIBRARIES := \
    libutils \
    libcutils \
    liblog \
    libbinder \
    libhardware \
    libhidlbase \
    libhidltransport \
    libhidlmemory \
    android.hardware.demo@1.0 \

include $(BUILD_SHARED_LIBRARY)
############################################

include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.demo@1.0-service
LOCAL_INIT_RC := android.hardware.demo@1.0-service.rc
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true

LOCAL_SRC_FILES := service.cpp

LOCAL_SHARED_LIBRARIES := \
    android.hardware.demo@1.0 \
    libbase \
    libcutils \
    libhidlbase \
    libhidltransport \
    liblog \
    libutils

include $(BUILD_EXECUTABLE)
  1. 實(shí)現(xiàn)客戶端
//Android.bp
frameworks/native/cmds/demo$ cat *
cc_binary {
    name: "demo_client",
    srcs: ["demo_client.cpp"],
    shared_libs: [
        "libhidlbase",
        "libhidltransport",
        "libutils",
        "liblog",
        "android.hardware.demo@1.0",
    ],
}
//demo_client.cpp
#include <android/hardware/demo/1.0/IDemo.h>
#include <hidl/Status.h>
#include <hidl/LegacySupport.h>
#include <hidl/HidlSupport.h>

#include <utils/misc.h>
#include <utils/Log.h>
#define LOG_TAG "demo_client"
using android::hardware::demo::V1_0::IDemo;
using android::sp;

int main(int argc, char* argv[])
{
    android::sp<IDemo> service = IDemo::getService();
    if(service == nullptr){
        ALOGD("Failed to get service\n");
        return -1;
    }
    float bar = 1.0;
    service->doDemo(bar);
    return 0;
}
  1. 添加SELinux策略
    我這邊把自定義SELinux策略放到了獨(dú)立目錄,
//device/honeybee/system/sepolicy/vendor/hal_demo.te
type hal_demo, domain;
type hal_demo_exec, exec_type, file_type, vendor_file_type;
hwbinder_use(hal_demo);
init_daemon_domain(hal_demo)
add_hwservice(hal_demo, hal_demo_hwservice)

//device/honeybee/system/sepolicy/vendor/file_contexts
# Vendor files
/(vendor|system/vendor)/bin/DoraemonService                                             u:object_r:DoraemonService_exec:s0
/(vendor|system/vendor)/bin/hw/android\.hardware\.demo@1\.0-service     u:object_r:hal_demo_exec:s0

//device/honeybee/system/sepolicy/vendor/hwservice.te
type hal_demo_hwservice, hwservice_manager_type;

//device/honeybee/system/sepolicy/vendor/hwservice_contexts
android.hardware.demo::IDemo  u:object_r:hal_demo_hwservice:s0
  1. 添加編譯聲明
    如果不添加茴恰,系統(tǒng)編譯的時(shí)候不會(huì)編譯你的模塊颠焦,
PRODUCT_PACKAGES += \
       android.hardware.demo@1.0 \
       android.hardware.demo@1.0-impl \
       android.hardware.demo@1.0-service
  1. 生成二進(jìn)制
    新增 Demo HIDL示例生成的二進(jìn)制文件如下所示:
system/lib64/android.hardware.demo@1.0.so
system/lib/android.hardware.demo@1.0.so
vendor/etc/init/android.hardware.demo@1.0-service.rc
vendor/bin/hw/android.hardware.demo@1.0-service
vendor/lib64/hw/android.hardware.demo@1.0-impl.so
vendor/lib/hw/android.hardware.demo@1.0-impl.so
  1. Demo測(cè)試
    把demo_client 編譯好push到/system/bin,
Hi3751V811:/system/bin # demo_client                                           
Hi3751V811:/system/bin # logcat | grep Demo
01-01 16:00:11.529  1809  1809 D Demo    :  Hello Hidl Demo Bar is 1.000000 

----Demo完畢。

HIDL平時(shí)需要參考系統(tǒng)模塊寫就好往枣,如果要學(xué)習(xí)參考官網(wǎng)就好伐庭,或者下面博客
http://www.reibang.com/p/ca6823b897b5

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市分冈,隨后出現(xiàn)的幾起案子圾另,更是在濱河造成了極大的恐慌,老刑警劉巖雕沉,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件集乔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡坡椒,警方通過(guò)查閱死者的電腦和手機(jī)扰路,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門尤溜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人汗唱,你說(shuō)我怎么就攤上這事宫莱。” “怎么了哩罪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵梢睛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我识椰,道長(zhǎng)绝葡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任腹鹉,我火速辦了婚禮藏畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘功咒。我一直安慰自己愉阎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布力奋。 她就那樣靜靜地躺著榜旦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪景殷。 梳的紋絲不亂的頭發(fā)上溅呢,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音猿挚,去河邊找鬼咐旧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绩蜻,可吹牛的內(nèi)容都是我干的铣墨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼办绝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伊约!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起孕蝉,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤屡律,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后昔驱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體疹尾,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡上忍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年骤肛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纳本。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腋颠,死狀恐怖繁成,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淑玫,我是刑警寧澤巾腕,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站絮蒿,受9級(jí)特大地震影響尊搬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜土涝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一佛寿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧但壮,春花似錦冀泻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至溯祸,卻和暖如春肢专,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背焦辅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工鸟召, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氨鹏。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓欧募,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親仆抵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跟继,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355