Android 14 推出全新的遠端存取功能,合作夥伴可透過這項功能遠端喚醒車輛中的 Android,執行特定工作。舉例來說,執行車庫模式一整晚,以便套用軟體更新。端對端工作流程需要多個非 Android 元件。Android 不會定義或提供非 Android 元件的實作項目 (這項責任屬於您)。
詳情請參閱下列各節:
工作流程。範例架構中多個元件之間的工作流程,用於用戶端註冊和工作交付。
編寫遠端工作用戶端。使用遠端存取權,並瞭解如何編寫遠端工作用戶端。
供應商導入:範例架構中的供應商元件,可支援遠端存取。
恢復原廠設定並移轉擁有權。瞭解如何處理恢復原廠設定和車輛擁有權轉移。
測試遠端存取用戶端。瞭解如何測試遠端存取功能。
建築
以下內容假設使用下列範例架構,但這只是假設,可能無法反映實際架構。原始設備製造商應根據車輛和伺服器架構,調整實際的實作方式。
圖 1. 架構範例。
範例架構包含下列硬體元件:
硬體元件 | 說明 |
---|---|
應用程式處理器 | 執行 Android 的處理器。Android 可能會在這個處理器上透過虛擬記憶體 (VM) 執行 (而非透過實際硬體)。 |
車輛處理器 | 負責控制應用程式電源的處理器。 |
車載資訊娛樂控制單元 (TCU) | 車輛中的處理器隨時都能接收來自雲端的遠端訊息。TCU 預設為一律開啟或處於低功耗模式。使用遠端訊息喚醒 TCU。 |
喚醒伺服器 | 在雲端執行的遠端伺服器,負責與車輛中的 TCU 通訊,發出喚醒指令。 |
遠端工作伺服器 | 遠端工作伺服器會在雲端執行,與人員互動並管理遠端工作。 |
範例架構包含下列軟體元件,這些元件全都在 Android 上執行:
Android 軟體元件 | 說明 |
---|---|
車用服務 | AAOS 架構服務,提供遠端存取 API。 |
遠端工作用戶端 | 由供應商編寫的 Service 類別,可執行遠端工作。一個 Android 系統可以執行多個遠端工作用戶端。 |
遠端存取 HAL | 必須實作遠端存取功能。 AAOS 與非 Android 元件 (例如 TCU) 之間通訊的抽象層。 |
以下說明非 Android 軟體元件:
非 Android 軟體元件 | 說明 |
---|---|
喚醒用戶端 | 在 TCU 上執行的軟體,可與喚醒伺服器維持長期連線。此外,它也會與遠端存取 HAL 維持連線,將遠端工作傳送至車輛服務。 |
實作喚醒伺服器 | 與在 TCU 上執行的喚醒用戶端通訊的伺服器。可以向喚醒用戶端傳送喚醒要求。 |
實作遠端工作伺服器 | 管理遠端工作的伺服器。使用者會與這個伺服器互動,發布及監控遠端工作。 |
工作流程
本節列出範例工作流程中的步驟。
工作流程範例
詳細工作流程可能如下所示:
使用者將車輛停放在車庫。
合作夥伴會在車輛不太可能互動時,於夜間更新車輛。
合作夥伴雲端伺服器會將更新系統遠端工作傳送至車輛。具體來說,就是車載資訊娛樂控制單元 (TCU)。
車輛的 TCU 會喚醒 Android 電子控制單元 (ECU),而 OEM 服務會觸發車庫模式。
Android 會執行車庫模式,透過 Google Play 下載及安裝更新。
套用更新後,Android 會將工作標示為完成,並結束連線或達到指定逾時時間。
詳細工作流程
如要遠端存取,必須完成兩個重要步驟。第一步是註冊用戶端,也就是將特定使用者連結至在特定車輛上執行的特定遠端工作用戶端。另一項是傳送工作,也就是將特定使用者的遠端工作傳送至特定車輛上執行的特定遠端工作用戶端。
註冊用戶端
如要使用遠端存取功能,使用者必須至少開啟一次遠端工作用戶端應用程式,並完成用戶端註冊程序 (粗體文字表示 AAOS 實作的工作):
啟動時,車輛服務會從遠端存取 HAL 取得車輛資訊。
啟動時,車輛服務會根據意圖篩選器和權限啟動所有遠端工作用戶端。
遠端工作用戶端啟動時,會向車輛服務註冊。
車輛服務會將註冊資訊 (包括車輛 ID 和用戶端 ID) 通知遠端工作用戶端。用戶端 ID 是由車輛服務指派給這個用戶端的專屬 ID。保證在同一部車輛上,所有遠端工作用戶端都會有專屬 ID。
使用者透過遠端工作用戶端登入遠端工作伺服器,並為這部車輛啟用遠端存取功能。這個步驟通常需要透過遠端工作伺服器進行驗證。
遠端工作用戶端會將使用者資訊連同車輛 ID 和用戶端 ID 上傳至遠端工作伺服器,並要求將使用者連結至這個特定用戶端和車輛。
視需要,這個步驟可能需要使用者進行額外的雙重驗證。
遠端工作伺服器必須驗證要求中提供的車輛 ID 與傳送者的車輛 ID 相符,這可透過車輛認證完成。
除非恢復原廠設定,否則每位使用者在每輛車上都必須完成一次用戶端註冊程序。用戶端 ID 會儲存在車輛服務中,且同一位用戶端的 ID 不會變更。
圖 2. 註冊用戶端。
取消註冊用戶端
使用者可以透過車輛或遠端工作伺服器,取消車輛與帳戶的連結:
使用者可以在車輛上開啟遠端工作用戶端應用程式,發出取消連結要求,將車輛與先前連結的使用者帳戶取消連結。
在遠端工作伺服器上,使用者可以登入帳戶,並取消先前連結至這個帳戶的車輛。
如果使用者取消連結帳戶與車輛,遠端工作伺服器必須移除特定使用者的已儲存對應。
交付工作
儲存在雲端:
使用者透過遠端工作伺服器,將遠端工作傳送至特定車輛。
遠端工作伺服器會將使用者 ID 對應至車輛 ID 和用戶端 ID。並將工作資料、車輛 ID 和用戶端 ID 傳送至喚醒伺服器。
喚醒伺服器會根據車輛 ID 找出特定 TCU (假設 TCU 註冊程序已完成),然後將工作資料和 Client-ID 傳送至 TCU。
車輛 (粗體文字表示 AAOS 執行的工作):
TCU 會接收遠端伺服器傳送的遠端工作。
如果執行 AAOS 的應用程式處理器 (AP) 關閉,TCU 會使用車輛處理器 (VP) 喚醒 AP。
車輛服務會接收 TCU 的工作。
車輛服務會將工作分配給對應的遠端工作用戶端。
遠端工作用戶端會接收並執行工作。
(選用) 遠端工作用戶端會與工作伺服器聯絡,取得更多工作詳細資料並執行工作。
(選用) 遠端工作用戶端服務會向工作伺服器回報工作結果。
遠端工作用戶端會在工作完成時通知車輛服務。
如有需要,車輛服務會還原車輛的電源狀態。
圖 3. 交付工作。
編寫遠端工作用戶端
CarRemoteAccessManager
提供遠端存取功能的 API。詳情請參閱 CarRemoteAccessManager。遠端工作用戶端是 Android 服務,可執行遠端工作並使用 CarRemoteAccessManager
。這需要 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 函式,才能傳回空值。
@Override
public IBinder onBind(Intent intent) {
return null;
}
Car Service 會管理生命週期。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。 |
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
,代表目前的無聲模式。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,從遠端工作伺服器擷取詳細資訊。
隱私權和安全規定
工作 | Condition | 必要性 |
---|---|---|
TCU (喚醒用戶端) | MUST |
|
喚醒伺服器 | MUST |
|
遠端工作用戶端 | MUST |
|
遠端工作伺服器 | MUST |
|
恢復原廠設定並轉移擁有權
如果使用者將裝置恢復原廠設定,系統會清除儲存在車輛服務中的用戶端 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]