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 的連線 ,將遠端工作交給 Car Service 處理。 |
喚醒伺服器實作 | 與在 TCU 上執行的喚醒用戶端通訊的伺服器。罐類收納 將喚醒要求傳送至喚醒用戶端。 |
遠端工作伺服器實作 | 管理遠端工作的伺服器。使用者與此伺服器互動, 以及監控遠端工作 |
工作流程
本節列出範例工作流程中的步驟。
範例工作流程
詳細的工作流程可以類似下列內容:
使用者停在車庫中的車輛。
合作夥伴希望在車輛互動期間整晚更新車輛資料 可能性不高。
合作夥伴雲端伺服器將更新系統遠端工作傳送至車輛。 具體來說,就是電動控制單位 (TCU)。
車輛的 TCU 會喚醒 Android 電子控制裝置 (ECU) 和 原始設備製造商 (OEM) 服務會觸發車庫模式。
Android 會執行車庫模式,透過 Google Play 下載及安裝更新。
套用更新後,Android 會將工作標示為完成, 造成連線中斷或達到指定的逾時時間。
詳細工作流程
遠端存取需要兩個重要步驟。第一個是 註冊用戶端,以便將特定使用者連結至特定遙控器 在特定車輛上執行的工作用戶端另一項工作則是任務 為特定使用者傳送遠端工作給特定的遠端工作 在特定車輛上運作的用戶端
註冊用戶端
如要使用遠端存取功能,使用者必須開啟遠端工作用戶端 至少一次,並完成客戶註冊流程 (粗體文字) 表示 AAOS 實作的工作:
車輛服務在開機時,即可從遠端存取車輛資訊 HAL。
啟動時,Car Service 會根據 意圖篩選器和權限
當遠端工作用戶端啟動時,遠端工作用戶端會自行向 汽車服務。
車輛服務向遠端工作用戶端通知註冊事宜 資訊,包括車輛 ID 和用戶端 ID。用戶端 ID 不得重複 並由 Car Service 指派給這個用戶端容器一定不會重複 讓所有遠端工作用戶端共用同一輛車的所有遠端工作用戶端。
使用者透過遠端工作用戶端登入遠端工作伺服器,並且 啟用這輛車的遠端存取功能。這通常 包括透過遠端工作伺服器進行驗證。
遠端工作用戶端上傳使用者資訊和車輛 ID 和用戶端 ID 連結到遠端工作伺服器,並要求將使用者連結至 這個特定用戶端和這部特定車輛
或者,這個步驟可能會需要額外的雙重驗證 而非使用者的問題
遠端工作伺服器必須驗證 要求與傳送者的車輛 ID 相符,請前往 車輛認證
除非恢復原廠設定,否則必須完成用戶端註冊程序 每輛車每位使用者只能查看一次用戶端 ID 儲存在本機的 Car Service 中 並為同一個用戶端保持不變
圖 2. 註冊用戶端。
取消註冊用戶端
使用者可以將車輛與帳戶取消連結,也可將車輛和帳戶取消連結 遠端工作伺服器:
使用者可以在車輛上開啟遠端工作用戶端應用程式並發生問題 取消連結這輛車與先前連結使用者的連結要求 帳戶。
在遠端工作伺服器上,使用者可以登入自己的帳戶並取消連結 這個帳戶先前連結過的車輛。
如果使用者將車輛與帳戶取消連結,遠端工作伺服器必須 移除儲存的特定使用者對應關係。
交付工作
雲端:
使用者使用遠端工作伺服器,將遠端工作傳送至特定的 。
遠端工作伺服器將使用者 ID 對應到車輛 ID 和用戶端 ID。這項服務 將工作資料、車輛 ID 和用戶端 ID 傳送至喚醒伺服器。
喚醒伺服器會尋找車輛 ID 的特定 TCU (假設 TCU 註冊已完成),並將工作資料和用戶端 ID 傳送給 TCU。
在車上 (粗體文字表示 AAOS 執行的工作):
TCU 會從遠端伺服器接收遠端工作。
如果執行 AAOS 的應用程式處理器 (AP) 關閉,TCU 就會使用 用於喚醒 AP。
租車服務會從 TCU 接收工作。
Car Service 將工作分配給對應的遠端工作用戶端。
遠端工作用戶端接收並執行工作。
(選用) 遠端工作用戶端聯絡工作伺服器取得更多工作詳細資料 並執行工作
(選用) 遠端工作用戶端服務會將工作結果回報給工作伺服器。
遠端工作用戶端會在工作完成時通知車用服務。
如果需要,車輛服務會還原車輛的電源狀態。
圖 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;
}
汽車服務會管理其生命週期。車輛服務在下列期間繫結至這項服務 直到遠端工作到達時再啟動。車輛服務在下列情況下解除繫結至這項服務: 工作都已完成詳情請參閱: 管理服務的生命週期。
遠端工作用戶端是以系統使用者的身分執行,因此沒有存取權 任何使用者特定資料
以下範例說明如何處理已註冊的回呼:
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() |
取得可透過喚醒 用戶端。 |
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 可與執行於 AP 的喚醒用戶端通訊 透過遠端存取 HAL。
圖 4. TCU (喚醒用戶端)。
雲端元件
喚醒伺服器
喚醒伺服器會與 TCU 上的喚醒用戶端進行通訊,以執行下列操作:
- 與車輛的 TCU 保持長久連線。
- 根據車輛 ID 尋找特定的 TCU。
- 回報車輛狀態。例如線上/離線或最近一次 傳送到遠端工作伺服器的時間。
在實際實作中,喚醒伺服器可以與遠端連線合併 工作伺服器
遠端工作伺服器
遠端工作伺服器會管理這些遠端工作。
使用者與伺服器互動,啟動新的遠端工作及監控 遠端工作。
使用遠端喚醒伺服器,喚醒應用程式處理器 我們非常注重車輛
與在車上執行的遠端工作用戶端互動。
儲存客戶註冊資訊。這會將特定使用者建立關聯 附加至特定車輛上的特定遠端工作用戶端。
通常是透過遠端工作伺服器傳送至喚醒狀態的工作資料 傳送至車輛的 TCU,最終傳送到遠端工作用戶端 以及工作 ID遠端工作用戶端使用工作 ID 擷取 接收遠端工作伺服器提供的資訊
隱私權和安全性規定
工作 | Condition | 必要性 |
---|---|---|
TCU (喚醒用戶端) | 必須 |
|
喚醒伺服器 | 必須 |
|
遠端任務用戶端 | 必須 |
|
遠端工作伺服器 | 必須 |
|
恢復原廠設定並轉移擁有權
如果使用者將裝置恢復原廠設定,儲存在 Car Service 中的用戶端 ID 就會是 已抹除資料。不過,伺服器 (遠端工作伺服器和遠端喚醒伺服器) 在不知情的狀況下,伺服器會保留過期的用戶端 ID 到 。因此,如果使用者對車輛啟動新的遠端工作, 所用的用戶端 ID 已過期。車輛已喚醒,但遠端工作 無法執行,因為遠端工作用戶端擁有其他用戶端 ID, 就不符合條件
以下說明一種可能的恢復原廠設定實作方式。
使用者恢復原廠設定時,供應商會提示使用者登入 遠端工作伺服器,如果使用者有 先前連結了這輛車裝置不保證可以連上網路 存取。因此,發出取消連結要求 恢復原廠設定後,就可能無法解決問題。
車輛所有權轉移時,部分操作 確保前任擁有者無法再從遠端發送遠端工作給 。舉例來說,系統可能會要求新擁有者:
將手機恢復原廠設定。確保系統重新產生用戶端 ID。更新後 這個步驟,前擁有者還是可以喚醒車輛,但 不必費心執行遠端任務
開啟遠端工作用戶端應用程式,然後按照 取消註冊用戶端程序以取消連結車輛 從前擁有者的帳戶登入。新擁有者可以追蹤註冊 用戶端程序,包括將車輛連結至帳戶,並取代 先前連結的帳戶
新擁有者可透過「註冊用戶端」程序, 將車輛連結至帳戶,並替換先前連結的帳戶。
測試遠端工作用戶端
我們提供遠端存取 HAL
default
敬上
目錄,測試遠端工作用戶端。您可以使用下列 debug
命令,在 HAL 中插入假遠端工作,該 HAL 會轉送至您的
遠端工作用戶端 (如果您提供正確的用戶端 ID)。可協助您取得用戶端
將註冊資訊記錄在遠端工作用戶端中
。
adb root && adb shell dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --inject-task [clientID] [taskData]