大家最熟悉的Android系統(tǒng)應(yīng)該是手機(jī)和平板設(shè)備上的,大部分人可能沒(méi)想過(guò)Android系統(tǒng)和汽車有什么關(guān)系。但實(shí)際上,Android系統(tǒng)在四年前就在布局汽車這個(gè)平臺(tái)。我最近對(duì)相關(guān)內(nèi)容做了一些了解。下面將我所了解到的信息分享給大家。 ?
1、Android Auto
Android Auto是一個(gè)Android端的App,是專門為駕駛環(huán)境而設(shè)計(jì)的。 ? 運(yùn)行Android Auto需要Android 5.0或更高版本的系統(tǒng),并且還需要Google地圖和Google Play 音樂(lè)應(yīng)用。 ? Android Auto可以用來(lái)將Android設(shè)備上的部分功能映射到汽車屏幕上。 ? Android Auto在2014的Google I/O上首次亮相。相應(yīng)的App:Android Auto在2015年3月19日發(fā)布。 ? 當(dāng)Android Auto接到汽車屏幕上其界面看起來(lái)是下面這個(gè)樣子: ?
img ? 當(dāng)然,也可以不連接汽車,直接在手機(jī)上使用,其界面是下面這個(gè)樣子: ?
?
img
1.1 ?核心功能
在2014的Google I/O大會(huì)上,Google在介紹Android Auto時(shí),首先就是以安全性為引入點(diǎn)的:很多人在開(kāi)車會(huì)使用手機(jī),這就造成大量的交通事故。所以我們應(yīng)當(dāng)理解,汽車上的軟件功能并非越多越好。某些手機(jī)上很受歡迎的功能和軟件,它們未必適合車載系統(tǒng),例如:瀏覽器網(wǎng)頁(yè),閱讀,玩游戲,看視頻等等。
從上面的兩幅圖中可以看到,無(wú)論是汽車屏幕還是手機(jī)屏幕,界面底部包含了四個(gè)相同的按鈕(雖然位置不同)。 ? 以手機(jī)界面的按鈕順序,這四個(gè)按鈕的功能依次是:
回主界面
地圖功能
通話功能
音樂(lè)功能
1.1.1 Google Assistant
2007年,iPhone的發(fā)布宣示了觸摸交互方式的興起。在這之后,觸摸手勢(shì)徹底代替了物理鍵盤。 ? 當(dāng)時(shí)的運(yùn)營(yíng)商無(wú)法想象一個(gè)沒(méi)有物理鍵盤的手機(jī)會(huì)被大家喜歡。而在十年之后,曾經(jīng)能夠生產(chǎn)最好的物理鍵盤手機(jī)的制造商,例如黑莓和諾基亞都早已被市場(chǎng)淘汰。 因此我們可以想象,新一代的平臺(tái)和電子產(chǎn)品有可能會(huì)引入新的交互方式,或者是讓某個(gè)原先不太流行的交互方式成為主流。而對(duì)于汽車來(lái)說(shuō),語(yǔ)音無(wú)疑是比觸摸更好的交互方式。 ? 在駕駛環(huán)境中,語(yǔ)音交互存在如下優(yōu)勢(shì):
用戶不用改變自身的物理姿勢(shì),所以這種交互方式不影響對(duì)于駕駛的操控。
有些需要多次觸摸手勢(shì)的交互,可能一條語(yǔ)音就可以完成。
語(yǔ)音交互不存在入口的層次嵌套,數(shù)據(jù)更加扁平。
優(yōu)秀的語(yǔ)音系統(tǒng)可以利用對(duì)話的上下文完成任務(wù),避免用戶重復(fù)輸入。
除此之外,在駕駛環(huán)境中,對(duì)于語(yǔ)音功能的實(shí)現(xiàn)也更有利。因?yàn)?,駕駛艙的空間較小,便于語(yǔ)音數(shù)據(jù)的捕獲;駕駛艙座位的相對(duì)位置固定,系統(tǒng)更方便判斷發(fā)出語(yǔ)音的角色,例如區(qū)分發(fā)出語(yǔ)音指令的是駕駛員還是乘客而采取不同的處理。 ? 這就不奇怪Google將Google Assistant集成到Android Auto中了。 ? 當(dāng)語(yǔ)音系統(tǒng)能夠獲取到用戶的基本信息的情況下,很多操作會(huì)變得非常便利。例如,直接告訴系統(tǒng):”我要回家“。而不用先打開(kāi)地圖,然后搜索自己家的地址,然后再點(diǎn)擊導(dǎo)航按鈕:
img ? 當(dāng)系統(tǒng)有了更多的用戶的數(shù)據(jù)以及外部服務(wù)之后,可以做的事情將超遠(yuǎn)我們現(xiàn)在看到的。例如:在導(dǎo)航至某個(gè)餐館的途中直接幫忙預(yù)訂座位(今年的Google I/O上,Google已經(jīng)展示了通過(guò)AI完成的電話預(yù)訂:Google’s AI Assistant Can Now Make Real Phone Calls)。 ? 當(dāng)然,Google Assistant 不僅僅是為Android Auto設(shè)計(jì)的,它支持非常多的設(shè)備。不過(guò)這部分內(nèi)容已經(jīng)超過(guò)本文所要說(shuō)明的。 ?
img
1.2 兼容的車型和應(yīng)用
現(xiàn)代汽車是首個(gè)支持Android Auto的汽車制造商。2015的Hyundai Sonata是第一個(gè)支持Android Auto的汽車型號(hào)。 ? 到目前為止(2018年7月),支持Android Auto的汽車品牌已經(jīng)很多,包括:奧迪,別克,凱迪拉克,雪佛蘭,福特,本田,吉普,林肯,奔馳,馬自達(dá),大眾,Volvo等超過(guò)50家汽車制造商,超過(guò)500種汽車型號(hào)。 ? 詳細(xì)的品牌和型號(hào)請(qǐng)參見(jiàn)下面這個(gè)鏈接:Android Auto - The right information for the road ahead 。 ? 目前,支持Android Auto的應(yīng)用比較少。雖然2018年的Google I/O上宣稱這類應(yīng)用數(shù)量正在高速增長(zhǎng),但目前Google Play上支持Android Auto的應(yīng)用也只有數(shù)千款,這與Google Play上的三百多萬(wàn)應(yīng)用相比,就顯得很可憐了。 ? 可以通過(guò)這個(gè)鏈接瀏覽支持Android Auto的應(yīng)用:Apps for Android Auto。 ?
1.3 App
1.3.1 開(kāi)發(fā)
Android Auto目前僅支持兩類第三方的應(yīng)用:
音頻應(yīng)用:允許用戶瀏覽和播放汽車中的音樂(lè)和語(yǔ)音內(nèi)容。
消息應(yīng)用:通過(guò)text-to-speech朗讀消息并通過(guò)語(yǔ)音輸入回復(fù)消息。
為了聲明應(yīng)用支持Android Auto,需要在/res/xml/新建一個(gè)XML文件來(lái)進(jìn)行描述。 ? 例如,假設(shè)我們創(chuàng)建的文件是automotive_app_desc.xml,其內(nèi)容是
???
這里通過(guò)
media:該應(yīng)用使用Android框架API在車輛中播放音樂(lè)。
notification:該應(yīng)用在汽車的主屏幕中顯示消息通知,允許用戶選擇要朗讀的消息,并讓他們通過(guò)語(yǔ)音輸入進(jìn)行響應(yīng)。
定義完成該文件之后,需要在AndroidManifest.xml中指定:
????... ????
之后就是通過(guò)相應(yīng)的API完成功能開(kāi)發(fā)了,這部分內(nèi)容具體見(jiàn)Android Developer中的文檔,這里不再贅述:
Provide audio playback for Auto
Provide messaging for Auto
1.3.2 設(shè)計(jì)
Google專門為Android Auto上的UI設(shè)計(jì)做了一個(gè)指導(dǎo)網(wǎng)站,具體見(jiàn)這里:Auto UI guidelines。
img
基本的指導(dǎo)原則包括:
Android Auto上的互動(dòng)步調(diào)必須由駕駛員控制。
汽車界面上的觸摸目標(biāo)必須足夠大,以便可以輕松地瀏覽和點(diǎn)按。
適當(dāng)?shù)纳蕦?duì)比可幫助駕駛員快速解讀信息并做出決定。
應(yīng)用必須支持夜間模式,因?yàn)檫^(guò)高的亮度可能會(huì)干擾注意力。
Roboto字體在整個(gè)系統(tǒng)中用于保持一致性并幫助提高可讀性。
通過(guò)觸摸來(lái)進(jìn)行分頁(yè)應(yīng)該用來(lái)作為滑動(dòng)翻頁(yè)的補(bǔ)充。
謹(jǐn)慎和有選擇地使用圖像。
有節(jié)制的使用動(dòng)畫(huà)來(lái)描述兩個(gè)狀態(tài)之間的變化。
這些指導(dǎo)原則也值得其他車載的交互系統(tǒng)借鑒。
1.4 無(wú)線
目前的Android Auto需要通過(guò)USB線纜將手機(jī)連接到汽車上才能使用。
通過(guò)線纜連接這個(gè)動(dòng)作對(duì)用戶來(lái)說(shuō)無(wú)疑是一件很麻煩的事情。一來(lái)需要將手機(jī)從包中取出,二來(lái)再次拿手機(jī)時(shí)還受限于線的長(zhǎng)度。所以很顯然,無(wú)線的使用方式將是未來(lái)的設(shè)計(jì)趨勢(shì)。這一點(diǎn),從Apple的AirPods以及近期新上市的手機(jī)幾乎都會(huì)支持無(wú)線充電就可以看出。
在功耗和傳輸性能的限制下,有線設(shè)計(jì)只是暫時(shí)的妥協(xié)。不過(guò)一旦這些限制逐漸縮小,無(wú)線功能自然就會(huì)出現(xiàn)了。所以Google在今年提出了無(wú)線Android Auto。
可以看一下這個(gè)鏈接:Wireless Android Auto is available for Google phones。
Apple在iOS 9上就支持無(wú)線CarPlay了。不過(guò)目前只有BMW部分車型支持。
2 Android Automotive
Android Auto是以手機(jī)為中心的。這種模型既有好處,也有壞處。
好處是:數(shù)據(jù)和應(yīng)用始終是一致的,不存在需要數(shù)據(jù)同步的問(wèn)題,手機(jī)上裝的軟件和已有的數(shù)據(jù),接到汽車直接就有了。而壞處是,每次得拿出手機(jī),汽車只是手機(jī)一個(gè)外設(shè)。并且,這種模式不便于對(duì)于汽車本身的控制和相關(guān)數(shù)據(jù)的獲取。
如果是系統(tǒng)直接內(nèi)置于汽車,那就是完全不一樣的體驗(yàn)了。而Android Automotive則是面向這個(gè)方向設(shè)計(jì)的。
可以看一下下面的兩個(gè)鏈接:
Volvo’s native Google integration is the next level for Android Auto
For Google, it’s full speed ahead with Android Automotive, but not so much with Android Auto
不過(guò),據(jù)報(bào)道中的信息,這類產(chǎn)品兩年之內(nèi)恐怕都不會(huì)上市。
從這一點(diǎn)來(lái)講,AliOS是完全領(lǐng)先Android Automotive的。因?yàn)閮?nèi)置AliOS的榮威RX5早就已經(jīng)量產(chǎn)了。
一旦將系統(tǒng)內(nèi)置于汽車,可以完成的功能將大大增加。例如:直接在中控觸摸屏上調(diào)整空調(diào)和座椅。
同時(shí),系統(tǒng)也能獲取到更多關(guān)于汽車的信息,例如:油耗水平,剎車使用等等。這對(duì)于改進(jìn)駕駛體驗(yàn)是非常有意義的。
img
內(nèi)置于汽車內(nèi)部的系統(tǒng)甚至?xí)绊懫嚤旧淼脑O(shè)計(jì),兩者將非常好的融合在一起。
img
2.1 版本演進(jìn)
最近幾年的Android版本中,每個(gè)版本都為Android Auto增加了一些新特性。具體可以觀看今年的Google I/O中的相關(guān)演講:What’s new in automotive - Google I/O 2018。
下面是這個(gè)演講中對(duì)于版本演進(jìn)的特性小結(jié):
img
2.2 源碼與架構(gòu)
Android Automative的源碼包含在AOSP中。
關(guān)于AOSP以及如何獲取源碼可以參見(jiàn)其官方網(wǎng)站:
https://source.android.com,這里不再贅述。
如果你不想下載整個(gè)源碼,只想瀏覽Android Automative的相關(guān)源碼,可以直接點(diǎn)擊這個(gè)鏈接:/platform/packages/services/Car/。
這里是Android Automative的一些文檔。
Android Automative的整體架構(gòu)如下圖所示:
img
從這幅圖中我們可以看出,Android Automative是在原先Android的系統(tǒng)架構(gòu)上增加了一些與車相關(guān)的(圖中虛線框中綠色背景的)模塊。
包括:
Car App:包括OEM和第三方開(kāi)發(fā)的App
Car API:提供給汽車App特有的接口
Car Service:系統(tǒng)中與車相關(guān)的服務(wù)
Vehicle Network Service:汽車的網(wǎng)絡(luò)服務(wù)
Vehicle HAL:汽車的硬件抽象層描述
下面我們采取從上到下的順序?qū)χ饕K做一些介紹。
2.3 ?Car App
/car_product/build/car.mk 這個(gè)文件中列出了汽車系統(tǒng)中專有的模塊:
# Automotive specific packages PRODUCT_PACKAGES += vehicle_monitor_service CarService CarTrustAgentService CarDialerApp CarRadioApp OverviewApp CarLensPickerApp LocalMediaPlayer CarMediaApp CarMessengerApp CarHvacApp CarMapsPlaceholder CarLatinIME CarUsbHandler android.car libvehiclemonitor-native
這個(gè)列表中,首字母大寫(xiě)的模塊基本上都是汽車系統(tǒng)中專有的App。
這些App的源碼都位于/platform/packages/services/Car/目錄下。
當(dāng)然,OEM廠商可以添加更多的App。
你也可以在/platform/packages/services/Car/目錄下通過(guò)find . -name AndroidManifest.xml確認(rèn)哪些文件中包含了Car App。
2.4 Car API
源碼:/platform/packages/services/Car/car-lib
開(kāi)發(fā)汽車專有的App自然需要專有的API。這些API對(duì)于其他平臺(tái)(例如手機(jī)和平板)通常是沒(méi)有意義的。所以這些API沒(méi)有包含在Android Framework SDK中。
下面這張大圖列出了所有的Car API:
img
從這個(gè)圖中我們可以看到Car API主要包括:
android.car:包含了與車相關(guān)的基本API。例如:車輛后視鏡,門,座位,窗口等。
cabin:座艙相關(guān)API。
hvac:通風(fēng)空調(diào)相關(guān)API。(hvac是Heating, ventilation and air conditioning的縮寫(xiě))
property:屬性相關(guān)API。
radio:收音機(jī)相關(guān)API。
pm:應(yīng)用包相關(guān)API。
render:渲染相關(guān)API。
menu:車輛應(yīng)用菜單相關(guān)API。
annotation:包含了兩個(gè)注解。
app
cluster:儀表盤相關(guān)API。
content
diagnostic:包含與汽車診斷相關(guān)的API。
hardware:車輛硬件相關(guān)API。
input:輸入相關(guān)API。
media:多媒體相關(guān)API。
navigation:導(dǎo)航相關(guān)API。
settings:設(shè)置相關(guān)API。
vms:汽車監(jiān)測(cè)相關(guān)API,見(jiàn)下文。
2.5 Car Service
源碼:
Car service
Android Automative中的Car Service集中在一個(gè)App中??梢韵胂?,這個(gè)App需要非常高的權(quán)限,所以這是一個(gè)系統(tǒng)App。其Manifest開(kāi)頭如下:
????????xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" ????????package="com.android.car" ????????coreApp="true" ????????android:sharedUserId="android.uid.system">
android:sharedUserId屬性使得這個(gè)應(yīng)用具有系統(tǒng)權(quán)限。
Car Service并非一個(gè)服務(wù),而是一系列的服務(wù)。這些服務(wù)都在ICarImpl.java構(gòu)造函數(shù)中列了出來(lái)。
讀者可以瀏覽這些服務(wù)的源碼了解其實(shí)現(xiàn)。
public?ICarImpl(Context?serviceContext,?IVehicle?vehicle,?SystemInterface?systemInterface,
????????CanBusErrorNotifier?errorNotifier)?{ ????mContext?=?serviceContext; ????mHal?=?new?VehicleHal(vehicle); ????mSystemActivityMonitoringService?=?new?SystemActivityMonitoringService(serviceContext); ????mCarPowerManagementService?=?new?CarPowerManagementService( ????????????mHal.getPowerHal(),?systemInterface); ????mCarSensorService?=?new?CarSensorService(serviceContext,?mHal.getSensorHal()); ????mCarPackageManagerService?=?new?CarPackageManagerService(serviceContext,?mCarSensorService, ????????????mSystemActivityMonitoringService); ????mCarInputService?=?new?CarInputService(serviceContext,?mHal.getInputHal()); ????mCarProjectionService?=?new?CarProjectionService(serviceContext,?mCarInputService); ????mGarageModeService?=?new?GarageModeService(mContext,?mCarPowerManagementService); ????mCarInfoService?=?new?CarInfoService(serviceContext,?mHal.getInfoHal()); ????mAppFocusService?=?new?AppFocusService(serviceContext,?mSystemActivityMonitoringService); ????mCarAudioService?=?new?CarAudioService(serviceContext,?mHal.getAudioHal(), ????????????mCarInputService,?errorNotifier); ????mCarCabinService?=?new?CarCabinService(serviceContext,?mHal.getCabinHal()); ????mCarHvacService?=?new?CarHvacService(serviceContext,?mHal.getHvacHal()); ????mCarRadioService?=?new?CarRadioService(serviceContext,?mHal.getRadioHal()); ????mCarNightService?=?new?CarNightService(serviceContext,?mCarSensorService); ????mInstrumentClusterService?=?new?InstrumentClusterService(serviceContext, ????????????mAppFocusService,?mCarInputService); ????mSystemStateControllerService?=?new?SystemStateControllerService(serviceContext, ????????????mCarPowerManagementService,?mCarAudioService,?this); ????mCarVendorExtensionService?=?new?CarVendorExtensionService(serviceContext, ????????????mHal.getVendorExtensionHal()); ????mPerUserCarServiceHelper?=?new?PerUserCarServiceHelper(serviceContext); ????mCarBluetoothService?=?new?CarBluetoothService(serviceContext,?mCarCabinService, ????????????mCarSensorService,?mPerUserCarServiceHelper); ????if?(FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE)?{ ????????mVmsSubscriberService?=?new?VmsSubscriberService(serviceContext,?mHal.getVmsHal()); ????????mVmsPublisherService?=?new?VmsPublisherService(serviceContext,?mHal.getVmsHal()); ????} ????mCarDiagnosticService?=?new?CarDiagnosticService(serviceContext,?mHal.getDiagnosticHal()); ????...
2.6 Car Tool
還有幾個(gè)模塊沒(méi)有出現(xiàn)在上面的架構(gòu)圖中。但它們也包含在了Android Automative系統(tǒng)中,這里一并介紹一下。
2.6.1 VMS
源碼:
vehicle_monitor_service
libvehiclemonitor/
VMS全稱是Vehicle Monitor Service。正如其名稱所示,這個(gè)服務(wù)用來(lái)監(jiān)測(cè)其他進(jìn)程。
在運(yùn)行時(shí),這個(gè)服務(wù)是一個(gè)獨(dú)立的進(jìn)程,在init.car.rc中有關(guān)于它的配置:
如果你不熟悉rc文件請(qǐng)閱讀我之前寫(xiě)過(guò)的文章:Android系統(tǒng)啟動(dòng):init進(jìn)程與init語(yǔ)言
service?vms?/system/bin/vehicle_monitor_service
???class?core ???user?root ???group?root ???critical on?boot ????start?vms
這是一個(gè)Binder服務(wù),并提供了C++和Java的Binder接口用來(lái)供其他模塊使用。
2.6.2 EVS
源碼:
evs
Android 8.0包含一個(gè)汽車 HIDL 硬件抽象層(HAL),可用于在 Android 啟動(dòng)過(guò)程的初期提供圖像捕獲和顯示,并在系統(tǒng)啟動(dòng)后繼續(xù)運(yùn)行直到系統(tǒng)終止。HAL包含外部視景系統(tǒng) (Exterior View System,簡(jiǎn)稱EVS) 堆棧,通常用于在具有車載信息娛樂(lè)(IVI)系統(tǒng)(基于 Android)的車輛中支持后視攝像頭和環(huán)繞視圖顯示。EVS 還支持在用戶應(yīng)用中實(shí)現(xiàn)高級(jí)功能。
EVS 包括以下系統(tǒng)組件:
img
EVS應(yīng)用:該應(yīng)用負(fù)責(zé)從EVS管理器請(qǐng)求視頻幀,并將用于顯示的已完成的幀發(fā)送回EVS管理器。EVS和汽車服務(wù)可供使用后,它便立即由init啟動(dòng)。OEM可視需要修改或替換EVS應(yīng)用。 ?
EVS 管理器:EVS管理器可提供 EVS 應(yīng)用所需的編譯塊,以實(shí)現(xiàn)從簡(jiǎn)單的后視攝像頭顯示到6DOF多相機(jī)渲染的任何功能。它的接口通過(guò) HIDL呈現(xiàn),并被編譯為接受多個(gè)并發(fā)客戶端。其他應(yīng)用和服務(wù)(特別是汽車服務(wù))可以查詢 EVS 管理器狀態(tài),以了解EVS系統(tǒng)何時(shí)處于活動(dòng)狀態(tài)。 ?
EVS HIDL接口:在 EVS 系統(tǒng)中,相機(jī)和顯示元素均在 android.hardware.automotive.evs 程序包中進(jìn)行定義。用于實(shí)踐接口的示例實(shí)現(xiàn)(生成合成測(cè)試圖像并驗(yàn)證圖像進(jìn)行往返的過(guò)程)在?/hardware/interfaces/automotive/evs/1.0/default 中進(jìn)行提供。 ?
內(nèi)核驅(qū)動(dòng)程序:支持EVS堆棧的設(shè)備需要使用內(nèi)核驅(qū)動(dòng)程序。OEM無(wú)需創(chuàng)建新驅(qū)動(dòng)程序,他們可以選擇通過(guò)現(xiàn)有相機(jī)和/或顯示硬件驅(qū)動(dòng)程序來(lái)支持EVS所需的功能。重復(fù)使用驅(qū)動(dòng)程序可能會(huì)有好處,對(duì)于圖像呈現(xiàn)可能需要與其他活動(dòng)線程協(xié)調(diào)的顯示驅(qū)動(dòng)程序來(lái)說(shuō)尤其如此。
關(guān)于EVS的更多內(nèi)容請(qǐng)參見(jiàn)這里:AOSP camera-hal。
關(guān)于HIDL請(qǐng)參見(jiàn)這里:HIDL。
2.6.3 ODB2
源碼:
obd2-lib
ODB全稱是On-Board Diagnostics。這是一種裝置于車中用以監(jiān)控車輛運(yùn)行狀態(tài)和回報(bào)異常的系統(tǒng),可于車輛的子系統(tǒng)出現(xiàn)問(wèn)題時(shí),產(chǎn)生故障代碼和提醒訊號(hào)通知車主和車廠診斷維修。1980年車上診斷系統(tǒng)發(fā)明后,早期僅能以指示燈形式回報(bào)故障發(fā)生與否。隨著計(jì)算機(jī)技術(shù)的進(jìn)步,目前已經(jīng)能回報(bào)各式各樣的實(shí)時(shí)數(shù)據(jù)和標(biāo)準(zhǔn)化故障代碼(diagnostic trouble codes,DTC),使得汽車故障診斷維修方法發(fā)生翻天覆地的變化。
美國(guó)是最早規(guī)定車輛必須裝配車上診斷系統(tǒng)的國(guó)家,之后歐盟與日本也陸續(xù)采行。臺(tái)灣自2008年起實(shí)施。中國(guó)大陸部分地區(qū)則自2006年起陸續(xù)對(duì)新車推出了裝置車上診斷系統(tǒng)的要求。
OBD-II是基于OBD-I的基礎(chǔ)上,增加了資料容量并將其標(biāo)準(zhǔn)化。OBD-II明確定義了連接器型式、腳位、可用通訊協(xié)定以及訊息格式。OBD-II同時(shí)也提供額外可監(jiān)控汽車參數(shù)清單以及編碼方式說(shuō)明。
AOSP中的ODB2庫(kù)是以一個(gè)Java靜態(tài)庫(kù)的形式存在的。
它支持多種命令。這些命令按照類型實(shí)現(xiàn)在不同的文件中:
img
2.7 Vehicle Network Service
源碼:
vehicle_network_service
libvehiclenetwork
Vehicle Network Service的結(jié)構(gòu)和VMS的結(jié)構(gòu)是類似的,也是一個(gè)可執(zhí)行文件(vehicle_network_service)加一個(gè)庫(kù)(libvehiclenetwork)的形式。
libvehiclenetwork中既包含了C++的庫(kù),也包含了Java語(yǔ)言的庫(kù)。對(duì)于需要跨語(yǔ)言訪問(wèn)的數(shù)據(jù)結(jié)構(gòu),使用Protocol Buffers 格式描述:libvehiclenetwork/proto/。
Protocol Buffers是Google開(kāi)發(fā)的另外一個(gè)工具。它語(yǔ)言中立,平臺(tái)中立,具有可擴(kuò)展的機(jī)制,用于序列化結(jié)構(gòu)化數(shù)據(jù)。類似XML,但更小,更快,更簡(jiǎn)單。
vehicle Network Service的主要作用是通過(guò)它來(lái)設(shè)置HAL屬性(見(jiàn)下文HAL)。這些屬性在VehicleNetworkConsts.java中已經(jīng)全部列出:
public?static?final?int?VEHICLE_PROPERTY_INFO_VIN?=?0x00000100; public?static?final?int?VEHICLE_PROPERTY_INFO_MAKE?=?0x00000101; public?static?final?int?VEHICLE_PROPERTY_INFO_MODEL?=?0x00000102; public?static?final?int?VEHICLE_PROPERTY_INFO_MODEL_YEAR?=?0x00000103; public?static?final?int?VEHICLE_PROPERTY_INFO_FUEL_CAPACITY?=?0x00000104; public?static?final?int?VEHICLE_PROPERTY_PERF_ODOMETER?=?0x00000204; public?static?final?int?VEHICLE_PROPERTY_PERF_VEHICLE_SPEED?=?0x00000207; public?static?final?int?VEHICLE_PROPERTY_ENGINE_COOLANT_TEMP?=?0x00000301; public?static?final?int?VEHICLE_PROPERTY_ENGINE_OIL_TEMP?=?0x00000304; public?static?final?int?VEHICLE_PROPERTY_ENGINE_RPM?=?0x00000305; public?static?final?int?VEHICLE_PROPERTY_GEAR_SELECTION?=?0x00000400; public?static?final?int?VEHICLE_PROPERTY_CURRENT_GEAR?=?0x00000401; public?static?final?int?VEHICLE_PROPERTY_PARKING_BRAKE_ON?=?0x00000402; public?static?final?int?VEHICLE_PROPERTY_DRIVING_STATUS?=?0x00000404; public?static?final?int?VEHICLE_PROPERTY_FUEL_LEVEL_LOW?=?0x00000405; public?static?final?int?VEHICLE_PROPERTY_NIGHT_MODE?=?0x00000407; public?static?final?int?VEHICLE_PROPERTY_HVAC_FAN_SPEED?=?0x00000500; public?static?final?int?VEHICLE_PROPERTY_HVAC_FAN_DIRECTION?=?0x00000501; public?static?final?int?VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT?=?0x00000502; public?static?final?int?VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET?=?0x00000503; public?static?final?int?VEHICLE_PROPERTY_HVAC_DEFROSTER?=?0x00000504; public?static?final?int?VEHICLE_PROPERTY_HVAC_AC_ON?=?0x00000505; public?static?final?int?VEHICLE_PROPERTY_HVAC_MAX_AC_ON?=?0x00000506; public?static?final?int?VEHICLE_PROPERTY_HVAC_MAX_DEFROST_ON?=?0x00000507; public?static?final?int?VEHICLE_PROPERTY_HVAC_RECIRC_ON?=?0x00000508; public?static?final?int?VEHICLE_PROPERTY_HVAC_DUAL_ON?=?0x00000509; public?static?final?int?VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE?=?0x00000703; public?static?final?int?VEHICLE_PROPERTY_ENV_CABIN_TEMPERATURE?=?0x00000704; public?static?final?int?VEHICLE_PROPERTY_RADIO_PRESET?=?0x0000801; public?static?final?int?VEHICLE_PROPERTY_AUDIO_FOCUS?=?0x00000900; public?static?final?int?VEHICLE_PROPERTY_AUDIO_VOLUME?=?0x00000901; public?static?final?int?VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT?=?0x00000902; public?static?final?int?VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY?=?0x00000903; public?static?final?int?VEHICLE_PROPERTY_AUDIO_HW_VARIANT?=?0x00000904; public?static?final?int?VEHICLE_PROPERTY_AP_POWER_STATE?=?0x00000A00; public?static?final?int?VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS?=?0x00000A01; public?static?final?int?VEHICLE_PROPERTY_AP_POWER_BOOTUP_REASON?=?0x00000A02; public?static?final?int?VEHICLE_PROPERTY_HW_KEY_INPUT?=?0x00000A10; public?static?final?int?VEHICLE_PROPERTY_INSTRUMENT_CLUSTER_INFO?=?0x00000A20; public?static?final?int?VEHICLE_PROPERTY_CUSTOM_START?=?0x70000000; public?static?final?int?VEHICLE_PROPERTY_CUSTOM_END?=?0x73ffffff; public?static?final?int?VEHICLE_PROPERTY_INTERNAL_START?=?0x74000000; public?static?final?int?VEHICLE_PROPERTY_INTERNAL_END?=?0x74ffffff; public?static?final?int?VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE?=?0x74000000;
當(dāng)然,并非所有模塊都有權(quán)限設(shè)置這些HAL屬性。所以這里需要權(quán)限的控制。
對(duì)于這一點(diǎn),通過(guò)vns_policy.xml來(lái)控制。
這個(gè)文件中定義了每個(gè)屬性允許哪個(gè)角色訪問(wèn),以及訪問(wèn)權(quán)限是只讀(r)還是可讀可寫(xiě)(rw)。下面是vns_policy.xml中的一個(gè)代碼片段:
2.8 HAL
源碼:
hardware/libhardware/include/hardware/vehicle.h
hardware/libhardware/modules/vehicle/
車載HAL(Hareware Abstract Layer,硬件抽象層)接口會(huì)定義OEM可以實(shí)現(xiàn)的屬性,并會(huì)包含屬性元數(shù)據(jù)(例如,屬性是否為 int 以及允許使用哪些更改模式)。車載 HAL 接口是以對(duì)屬性(特定功能的抽象表示)的訪問(wèn)(讀取、寫(xiě)入、訂閱)為基礎(chǔ)。
2.8.1 HAL接口
車載HAL使用以下接口:
vehicle_prop_config_t const *(*list_properties)(..., int* num_properties)?列出車載 HAL 所支持的所有屬性的配置。車輛網(wǎng)絡(luò)服務(wù)只會(huì)使用受支持的屬性。
(*get)(..., vehicle_prop_value_t *data)?讀取屬性的當(dāng)前值。對(duì)于區(qū)域?qū)傩?,每個(gè)區(qū)域都可能具有不同的值。
(*set)(..., const vehicle_prop_value_t *data)?為屬性寫(xiě)入相應(yīng)值。寫(xiě)入的結(jié)果是按屬性進(jìn)行定義。
(*subscribe)(..., int32_t prop, float sample_rate, int32_t zones)?監(jiān)視屬性值的變化,回調(diào)見(jiàn)下文。
(*release_memory_from_get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data)?釋放從 get 調(diào)用分配的內(nèi)存。
車載HAL使用以下回調(diào)接口:
(*vehicle_event_callback_fn)(const vehicle_prop_value_t *event_data)?通知車輛屬性值的變化。
(*vehicle_error_callback_fn)(int32_t error_code, int32_t property, int32_t operation)?返回全局車載 HAL級(jí)錯(cuò)誤或每個(gè)屬性的錯(cuò)誤。全局錯(cuò)誤會(huì)導(dǎo)致HAL重新啟動(dòng),這可能導(dǎo)致包括應(yīng)用在內(nèi)的其他組件重新啟動(dòng)。
2.8.2 屬性與區(qū)域
每個(gè)屬性都由 int32 鍵唯一標(biāo)識(shí),且具有預(yù)定義的類型(value_type):INT32(和數(shù)組)、INT64、BOOLEAN、FLOAT(和數(shù)組)、字符串、字節(jié)。
區(qū)域類型除了值之外還有區(qū)域。車載HAL定義了下面幾種區(qū)域類型:
enum?vehicle_zone_type?{
????VEHICLE_ZONE_TYPE_NONE??????=?0x00, ????VEHICLE_ZONE_TYPE_ZONE??????=?0x01, ????VEHICLE_ZONE_TYPE_SEAT??????=?0x02, ????VEHICLE_ZONE_TYPE_DOOR??????=?0x04, ????VEHICLE_ZONE_TYPE_WINDOW????=?0x10, ????VEHICLE_ZONE_TYPE_MIRROR????=?0x20, };
2.8.3 處理區(qū)域?qū)傩耘e例
下面是獲取HVAC溫度的調(diào)用過(guò)程。
img
下面是設(shè)置HAVC溫度的調(diào)用過(guò)程。
img
圖中縮寫(xiě)說(shuō)明如下:
CS:CarService
VNS:VehicleNetworkService
VHAL:Vehicle HAL
3 結(jié)束語(yǔ)
最后,我們以Android系統(tǒng)在汽車行業(yè)上的發(fā)展小結(jié)一下車載系統(tǒng)的特點(diǎn):
保持駕駛安全永遠(yuǎn)是第一重要,任何新功能的增加都必須先考慮這個(gè)原則。
車載系統(tǒng)不是手機(jī)系統(tǒng)的簡(jiǎn)單移植,手機(jī)上的應(yīng)用大部分也不適合車載系統(tǒng)。
車機(jī)硬件差異太大,平臺(tái)需要處理好差異性。
交互方式需要用心對(duì)待,以便讓用戶更容易操作。
界面設(shè)計(jì)上也需要通過(guò)色彩或控件大小以突出重點(diǎn),讓用戶更容易辨識(shí)。
語(yǔ)音將是車載系統(tǒng)上很重要的交互方式。
導(dǎo)航,多媒體,消息將是車載系統(tǒng)上最主要的應(yīng)用類型。
無(wú)線通信是未來(lái),隨著硬件傳輸速度的提升,各種線纜將盡可能的減少。
車載系統(tǒng)將脫離手機(jī),內(nèi)置的原生系統(tǒng)能獲得更好的體驗(yàn)。
編輯:黃飛
?
評(píng)論
查看更多