Android 14引入了新的遠端存取功能,使合作夥伴能夠遠端喚醒車輛中的Android以執行特定任務。例如,夜間執行車庫模式以應用軟體更新。端到端工作流程需要多個非 Android 元件。 Android 不定義或提供非 Android 元件的實作(此責任屬於您)。
要了解更多信息,請參閱以下部分:
工作流程。範例架構中多個元件之間的工作流程,用於客戶端註冊和任務交付。
編寫一個遠端任務客戶端。使用遠端存取並學習如何編寫遠端任務用戶端。
供應商實施。範例架構中的供應商組件支援遠端存取。
恢復出廠設定和所有權轉移。了解如何處理恢復原廠設定和車輛所有權轉讓。
測試遠端存取客戶端。了解如何測試遠端存取功能。
建築學
以下內容假設使用以下範例架構,這是假設的,可能不反映實際架構。 OEM 應該根據其車輛和伺服器架構調整實際實作。
圖 1.範例架構。
範例架構由下列硬體組件組成:
硬體組件 | 描述 |
---|---|
應用處理器 | 運行 Android 的處理器。 Android 可能會在此處理器上的虛擬記憶體 (VM)(而不是實際硬體)上運作。 |
車用處理器 | 處理器負責控制應用處理器的電源。 |
遠端資訊處理控制單元 (TCU) | 車輛中的處理器始終能夠從雲端接收遠端訊息。假定 TCU 始終處於開啟或低功耗模式。使用遠端訊息喚醒 TCU。 |
喚醒伺服器 | 運行在雲端的遠端伺服器,負責與車輛中的TCU通訊以發出喚醒命令。 |
遠端任務伺服器 | 遠端任務伺服器運行在雲端,與人互動並管理遠端任務。 |
範例架構由以下軟體元件組成,所有這些元件都在 Android 上運行:
Android 上的軟體元件 | 描述 |
---|---|
汽車服務 | 提供遠端存取API的AAOS框架服務。 |
遠端任務客戶端 | 供應商編寫的執行遠端任務的Service 類別。一個Android系統可以運行多個遠端任務客戶端。 |
遠端存取HAL | 必須實現遠端存取。 用於 AAOS 和非 Android 元件(例如 TCU)之間通訊的抽象層。 |
非 Android 軟體元件說明如下:
非 Android 軟體元件 | 描述 |
---|---|
喚醒客戶端 | 在 TCU 上運行的軟體,與喚醒伺服器保持長期連線。它還與遠端存取 HAL 保持連接,以向汽車服務交付遠端任務。 |
喚醒伺服器實現 | 與 TCU 上執行的喚醒客戶端通訊的伺服器。可以向喚醒客戶端發送喚醒請求。 |
遠端任務伺服器實現 | 管理遠端任務的伺服器。使用者與該伺服器互動以發出和監控遠端任務。 |
工作流程
本部分列出了範例工作流程中的步驟。
工作流程範例
詳細的工作流程可能類似以下內容:
用戶將車輛停放在車庫中。
當車輛互動不太可能時,合作夥伴尋求連夜更新車輛。
合作夥伴雲端伺服器向車輛發送更新系統遠端任務。具體來說,就是遠端資訊處理控制單元(TCU)。
車輛的 TCU 喚醒 Android 電子控制單元 (ECU),OEM 服務觸發車庫模式。
Android 運行 Garage 模式,透過 Google Play 下載和安裝更新。
套用更新後,Android 會將任務標記為已完成,並終止連線或達到指定的逾時時間。
詳細工作流程
遠端存取需要兩個重要步驟。第一個是註冊客戶端,即將特定使用者連結到特定車輛上運行的特定遠端任務用戶端。另一種是下發任務,即將特定使用者的遠端任務下發到特定車輛上執行的特定遠端任務用戶端。
註冊一個客戶
若要使用遠端存取功能,使用者必須至少開啟一次遠端任務用戶端應用程式並完成用戶端註冊過程(粗體文字表示由 AAOS 實現的任務):
啟動時,汽車服務從遠端存取 HAL 獲取車輛資訊。
啟動時,汽車服務會根據意圖過濾器和權限啟動所有遠端任務用戶端。
遠端任務用戶端啟動後,遠端任務用戶端將自身註冊到汽車服務。
汽車服務通知遠端任務客戶端有關註冊信息,包括車輛 ID 和客戶端 ID。客戶端 ID 是唯一的,由汽車服務分配給該客戶端。它保證在同一輛車上的所有遠端任務用戶端中是唯一的。
使用者透過遠端任務用戶端登入遠端任務伺服器,開啟該車輛的遠端存取功能。此步驟通常涉及透過遠端任務伺服器進行身份驗證。
遠端任務用戶端將使用者的資訊以及車輛ID和客戶端ID上傳到遠端任務伺服器,並要求其將使用者與該特定客戶端和該特定車輛連結。
或者,此步驟可能涉及來自使用者的額外兩因素身份驗證。
遠端任務伺服器必須驗證請求中提供的車輛 ID 是否與發送者的車輛 ID 匹配,這可以透過車輛證明來完成。
除非恢復出廠設置,否則每個使用者每輛車都需要執行一次客戶端註冊程序。客戶端 ID 本機儲存在汽車服務中,並且對於相同客戶端保持不變。
圖 2.註冊客戶端。
註銷客戶
使用者可以從車輛或遠端任務伺服器取消車輛與其帳戶的連結:
在車輛上,用戶可以打開遠端任務用戶端應用程式並發出取消連結請求,以取消該車輛與其先前連結的用戶帳戶的連結。
在遠端任務伺服器上,使用者可以登入自己的帳戶並取消先前連結的車輛與該帳戶的連結。
如果使用者取消車輛與其帳戶的鏈接,則遠端任務伺服器必須刪除為特定使用者儲存的對應。
交付任務
在雲端:
使用者使用遠端任務伺服器向特定車輛發送遠端任務。
遠端任務伺服器將使用者ID對應到車輛ID和客戶端ID。它將任務資料、車輛 ID 和客戶端 ID 傳送到喚醒伺服器。
喚醒伺服器找到車輛ID的特定TCU(假設TCU註冊已經完成)並將任務資料和客戶端ID傳送到TCU。
在車輛上(粗體文字表示 AAOS 執行的任務):
TCU從遠端伺服器接收遠端任務。
如果執行 AAOS 的應用處理器 (AP) 關閉,TCU 使用車輛處理器 (VP) 喚醒 AP。
汽車服務接收來自 TCU 的任務。
汽車服務將任務分發到對應的遠端任務用戶端。
遠端任務客戶端接收並執行任務。
(可選)遠端任務用戶端聯絡任務伺服器以取得更多任務詳細資訊並執行任務。
(可選)遠端任務用戶端服務將任務結果報告給任務伺服器。
遠端任務客戶端在任務完成時通知汽車服務。
如果需要,汽車服務會恢復車輛的電源狀態。
圖 3.交付任務。
編寫遠端任務客戶端
CarRemoteAccessManager
提供遠端存取功能的 API。要了解更多信息,請參閱CarRemoteAccessManager 。遠端任務用戶端是執行遠端任務並使用CarRemoteAccessManager
的 Android 服務。這需要PERMISSION_USE_REMOTE_ACCESS
和PERMISSION_CONTROL_REMOTE_ACCESS
並且必須為RemoteTaskClientService
聲明一個意圖過濾器,例如:
<service android:name=".remoteaccess.RemoteTaskClientService"
android:directBootAware="true"
android:exported="true">
<intent-filter>
<action android:name="android.car.remoteaccess.RemoteTaskClientService" />
</intent-filter>
</service>
遠端任務用戶端應在建立期間將自身註冊到汽車服務:
public final class RemoteTaskClientService extends Service {
@Override
public void onCreate() {
// mCar = Car.createCar()...
mRemoteAccessManager = (CarRemoteAccessManager)
mcar.getCarManager(Car.CAR_REMOTE_ACCESS_SERVICE);
if (mRemoteAccessManager == null) {
// Remote access feature is not supported.
return;
}
mRemoteAccessManager.setRemoteTaskClient(executor, mRemoteTaskClient);
}
}
它必須重寫 onBind 函數才能傳回 null。
@Override
public IBinder onBind(Intent intent) {
return null;
}
汽車服務管理其生命週期。 Car Service 在啟動期間和遠端任務到達時綁定到此服務。任務完成後,汽車服務會解除與此服務的綁定。要了解更多信息,請參閱管理服務的生命週期。
遠端任務用戶端以系統使用者身分執行,因此它無權存取任何特定於使用者的資料。
以下範例顯示如何處理註冊的回呼:
private final class RemoteTaskClient
implements CarRemoteAccessManager.RemoteTaskClientCallback {
@Override
public void onRegistrationUpdated(
RemoteTaskClientRegistrationInfo info) {
// Register to remote task server using info.
}
@Override
public void onRemoteTaskRequested(String taskId,
byte[] data, int remainingTimeSec) {
// Parses the data and execute the task.
// Report task result to remote task server.
mRemoteAccessManager.reportRemoteTaskDone(taskId);
}
@Override
public void onShutdownStarting(CompleteableRemoteTaskFuture future) {
// Stop the executing task.
// Clear the pending task queue.
future.complete();
}
}
供應商實施
遠端存取功能是可選的,預設為停用。若要啟用功能,請新增如下所示的 RRO:
// res/xml/overlays.xml
<?xml version="1.0" encoding="utf-8"?>
<overlay>
<item target="array/config_allowed_optional_car_features" value="@array/config_allowed_optional_car_features" />
</overlay>
// res/values/config.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array translatable="false" name="config_allowed_optional_car_features">
<item>car_remote_access_service</item>
</string-array>
</resources>
// Android.bp
runtime_resource_overlay {
name: "RemoteAccessOverlay",
resource_dirs: ["res"],
manifest: "AndroidManifest.xml",
sdk_version: "current",
product_specific: true
}
或在 userdebug/eng 建置上使用以下 adb 指令:
adb shell cmd car_service enable-feature car_remote_access_service
Android 上的要求
遠端存取HAL
遠端存取硬體抽象層 (HAL) 是供應商實現的抽象層,用於 AAOS 和另一個 ECU(例如 TCU)之間的通訊。它是支援遠端存取功能所必需的。如果沒有實現遠端存取功能則不需要實作。
此介面在IRemoteAccess.aidl中定義,並包含以下方法:
班級 | 描述 |
---|---|
String getVehicleId() | 取得喚醒伺服器可以識別的唯一車輛ID。 |
String getWakeupServiceName() | 取得遠端喚醒伺服器的名稱。 |
String getProcessorId() | 取得唯一的處理器ID,可以透過喚醒客戶端來識別該ID。 |
void setRemoteTaskCallback(IRemoteTaskCallback callback) 設定請求遠端任務時呼叫的回調。 | |
void clearRemoteTaskCallback() | 清除先前設定的遠端任務回調。 |
void notifyApStateChange(in ApState state) 檢測應用處理器是否準備好接收遠端任務。 |
回呼介面在IRemoteTaskCallback.aid
處定義。
班級 | 描述 |
---|---|
oneway void onRemoteTaskRequested(String clientId, in byte[] data) 請求遠端任務時呼叫的回調。 |
請參閱使用外部 TCU 的參考實作。此實作使用長期讀取流來接收遠端任務並支援以下debug
命令:
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default
車輛HAL
為了支援遠端存取功能,VHAL 必須支援以下屬性:
班級 | 描述 |
---|---|
SHUTDOWN_REQUEST | 請求關閉主機。 |
VEHICLE_IN_USE |
|
要了解更多信息,請參閱支援的系統屬性。
靜音模式
遠端存取功能必須支援靜音模式,以便車輛在無人在場時能夠以靜音模式啟動以執行遠端任務。在靜音模式下,AAOS 裝置啟動時顯示和音訊關閉。
靜默模式是透過兩個 Linux 核心sysfs
檔案控制的。
班級 | 描述 |
---|---|
/sys/kernel/silent_boot/pm_silentmode_kernel_state 代表目前靜音模式。 | |
/sys/kernel/silent_boot/pm_silentmode_hw_state 代表設定新靜音模式的硬體訊號。 |
車輛處理器向 Android SoC 發送硬體訊號以開啟/關閉靜音模式。訊號(0 或 1)寫入/sys/kernel/silent_boot/pm_silentmode_hw_state
。然後,AAOS 框架會相應地更新/sys/kernel/silent_boot/pm_silentmode_kernel_state
,它代表目前的 Silent 模式。 AAOS 模組檢查/sys/kernel/silent_boot/pm_silentmode_kernel_state
以了解系統是否處於靜默模式。
當接收到遠端任務並且 AAOS 啟動時,車輛處理器會設定靜音模式並啟動 AAOS,以便系統在顯示/音訊關閉的情況下啟動。
車載非 Android 組件
車用處理器
車輛處理器是車輛中的處理器,可以控制運行Android的應用程式處理器的電源。在範例架構中,TCU 透過向車輛處理器發送訊號來喚醒應用處理器。
車載非 Android 組件
車輛TCU始終可以接收遠端訊息。
喚醒客戶端在 TCU 上運行,以確保與遠端喚醒伺服器的長期連線。
AP 上執行的 AAOS 可以透過遠端存取 HAL 與 TCU 上執行的喚醒用戶端進行通訊。
圖 4.TCU (喚醒客戶端)。
雲端上元件
喚醒伺服器
喚醒伺服器與 TCU 上的喚醒客戶端通訊以:
- 與車輛的 TCU 保持長期連線。
- 根據車輛 ID 尋找特定的 TCU。
- 報告車輛的狀態。例如,線上或離線,或遠端任務伺服器的上次線上時間。
在實際實作中,喚醒伺服器可以與遠端任務伺服器合併。
遠端任務伺服器
遠端任務伺服器管理這些遠端任務。
使用者與伺服器互動以啟動新的遠端任務並監視遠端任務。
使用遠端喚醒伺服器喚醒車輛中的應用程式處理器。
與車輛上運行的遠端任務用戶端互動。
儲存客戶端註冊資訊。這將特定使用者與特定車輛上的特定遠端任務用戶端相關聯。
通常,透過遠端任務伺服器傳送到喚醒伺服器、車輛的 TCU、並最終傳送到遠端任務用戶端的任務資料只是一個任務 ID。遠端任務用戶端使用任務ID從遠端任務伺服器取得詳細資訊。
隱私和安全要求
任務 | 狀態 | 要求 |
---|---|---|
TCU(喚醒客戶端) | 必須 |
|
喚醒伺服器 | 必須 |
|
遠端任務客戶端 | 必須 |
|
遠端任務伺服器 | 必須 |
|
恢復出廠設定和所有權轉移
如果使用者執行恢復出廠設置,則儲存在汽車服務中的用戶端 ID 將被擦除。但是,不會通知伺服器(遠端任務伺服器和遠端喚醒伺服器)。伺服器保留從現已過期的客戶端 ID 到車輛的對應。因此,如果使用者為車輛啟動新的遠端任務,它將使用過期的客戶端 ID。車輛被喚醒,但遠端任務無法執行,因為遠端任務用戶端具有不匹配的不同客戶端 ID。
下面描述了恢復出廠設定的一種可能的實現方式。
當使用者恢復出廠設定時,供應商會提示使用者登入遠端任務伺服器,並在使用者先前連結車輛的情況下取消車輛與其帳戶的連結。不保證設備在恢復出廠設定期間能夠存取網路。因此,在恢復出廠設定時從設備發出取消連結請求可能不可行。
每當車輛所有權發生轉移時,都應執行一些操作以確保先前的車主無法再向車輛發出遠端任務。例如,新所有者可能會被要求:
執行恢復出廠設定。這可確保重新產生客戶端 ID。完成此步驟後,原車主仍可喚醒車輛,但無法再執行遠端任務。
打開遠端任務用戶端應用程序,然後按照取消註冊客戶端流程來取消車輛與前車主帳戶的連結。新車主可以按照註冊客戶流程將車輛連結到他們的帳戶並替換先前連結的帳戶。
新車主可以使用註冊客戶流程將車輛連結到他們的帳戶並替換先前連結的帳戶。
測試遠端任務客戶端
我們提供參考遠端存取HAL default
目錄來測試遠端任務用戶端。您可以使用下列debug
指令將假遠端任務注入 HAL,如果您提供正確的用戶端 ID,則該任務將轉送至您的遠端任務用戶端。您可以透過在遠端任務用戶端實作中記錄註冊資訊來取得客戶端 ID。
adb root && adb shell dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --inject-task [clientID] [taskData]