車輛音訊外掛程式服務

Android 14 中的全新車輛原始設備製造商 (OEM) 外掛程式服務已啟用 要設定某些車輛元件尤其是音訊 外掛程式服務,讓原始設備製造商 (OEM) 可以靈活設定 如何在 AAOS 裝置上管理音訊:

  • 音訊焦點控制
  • 音訊音量和靜音控制
  • 「降低其他應用程式音量」控制

車用外掛程式服務架構

下圖提供汽車服務及其關係的總覽 原始設備製造商 (OEM) 汽車維修服務與應用程式程序和乘車服務程序類似 原始設備製造商 (OEM) 汽車維修程序會佔用其處理程序空間

圖片

車輛服務會找出 config_oemCarService。如果設定空白,表示 OEM 服務不存在 也不會啟動任何服務元件必須擴充 OemCarService。 車輛音訊服務必須覆寫用於取得車輛音訊原始設備製造商 (OEM) 的 API 服務:

public final class OemCarServiceImp extends OemCarService {
    @Override
    public OemCarAudioFocusService getOemAudioFocusService();

    @Override
    public OemCarAudioDuckingService getOemAudioDuckingService();

    @Override
    public OemCarAudioVolumeService getOemAudioVolumeService();
}

適用對象 example,請參閱 參考資源測試應用程式 packages/services/Car/tests/OemCarServiceTestApp

雖然車用服務啟動了這項服務,但並不會自動啟動。 沿用汽車音訊服務可用的權限。因此 原始設備製造商 (OEM) 服務所要求的權限,應附上適當的 以注意力機制為基礎舉例來說,請參閱 packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml

採用原始設備製造商 (OEM) 服務架構的汽車音響服務

在 AAOS 中,車輛音訊服務會管理以下動作:

  • 音訊路由
  • 音訊焦點
  • 降低其他應用程式音量
  • 音量和靜音

在 Android 14 之前,這種行為大多是靜態的 只能透過設定修改,但不適用於少數情況。 Android 14 導入了車用音訊機制 服務,藉此與原始設備製造商 (OEM) 定義元件通訊,而該元件管理:

  • 音訊焦點
  • 降低其他應用程式音量
  • 音量和靜音

下圖為汽車音訊服務的簡化架構。 汽車原始設備製造商 (OEM) 服務車輛音訊服務會定義可呼叫的不同掛鉤 車輛原始設備製造商 (OEM) 音訊服務來管理音訊行為。若是後者只發生 (如果已定義對應的原始設備製造商 (OEM) 汽車音響服務元件)。否則, 車輛音訊服務會使用預設行為。

圖片

確保車輛音訊服務和車輛原始設備製造商 (OEM) 音訊服務一直處於啟用狀態 同步時,車輛音訊服務也會在每次通話時,傳遞 音訊堆疊目前與車輛原始設備製造商 (OEM) 音訊服務的狀態。舉例來說 汽車音訊服務會攔截評估音訊焦點的要求, 與車輛原始設備製造商 (OEM) 音訊服務的堆疊目前狀態。目前狀態 包含目前的焦點持有者和目前的焦點遺失者。專注利物 仍屬於堆疊的一部分,但暫時遺失的焦點要求 重點。

車輛音訊服務必須管理車內所有音訊活動。如果車輛 而不會管理某些音訊行為 向車輛原始設備製造商 (OEM) 音訊服務公開的資訊不完整。舉例來說 原始設備製造商 (OEM) 透過註冊,以覆寫汽車服務中的音訊焦點處理方式 自己的音訊焦點政策,汽車音訊服務無法提供完整服務 將資料傳送給車輛原始設備製造商 (OEM) 音訊服務這可能會影響車輛 原始設備製造商 (OEM) 音訊服務可協助做出決策,因為可能缺少相關資訊 。

為了採取行動,汽車音訊服務會呼叫原始設備製造商 (OEM) 的汽車服務。這些通話 都會在各程序之間取得,並需要處理序間通訊 (IPC)。處理序間通訊 (IPC) 這會增加每次呼叫的延遲時間請務必盡量減少 原始設備製造商 (OEM) 服務。

由於向原始設備製造商 (OEM) 服務發出的車輛音訊服務呼叫遭到封鎖,因此原始設備製造商 (OEM) 服務 不得在直接評估 API 時呼叫車輛音訊服務。相反地 車輛音訊服務會提供必要資訊,這樣你就能在 只需要朝一個方向移動即可

原始設備製造商 (OEM) 汽車音訊服務定義

原始設備製造商 (OEM) 汽車語音焦點服務

車輛音訊服務註冊後,即可管理應用程式的音訊焦點要求 音訊政策焦點事件監聽器汽車音訊服務提供一種機制 根據靜態值 互動矩陣。 矩陣定義了三種不同的互動類型:

  • 同時互動。聚焦持有者可以保持專注 讓應用程式從可以最快做出回應的位置 回應使用者要求

  • 不重複互動:系統會從 目前的焦點擁有者

  • 拒絕互動。已根據以下原因拒絕傳入焦點要求: 目前的焦點持有者。

雖然這適用於某些汽車用途,但卻無法滿足所有汽車業需求 因原始設備製造商 (OEM) 規定而可能不同的互動需求。為此,我們 介紹 OemCarAudioFocusService

public interface OEmCarAudioFocusService {
    OemCarAuddioFocusResults evaluateAudioFocusRequest(
        OemCarAudioFocusEvaluationRequest request);
    
    void notifyAudioFocusChange(
        List<AudioFocusEntry> holder,
        List<AudioFocusEntry> losers, int zoneId);
}

系統隨時會從車輛音訊服務呼叫 API evaluateAudioFocusRequest 如果有要求需要評估音訊焦點 這個 API 會封鎖結果傳回結果要求中包含資訊 音訊堆疊的目前狀態:

這項資訊可用來評估newFocusRequestfocusHolders 中目前的焦點持有者,以及 focusLosers。API 應傳回結果:

class OemCarAudioFocusResult {
    int audioZoneId;
    int audioFocusEvaluationResults;
    AudioFocusEntry focusResult;
    List<AudioFocusEntry> newLosers;
    List<AudioFocusEntry> newlyBlocked;
}

當中包含實際評估結果 audioFocusEvaluationResults,指出目前的要求 或延遲,或失敗。目前焦點堆疊的任何變更 應在 newLosersnewlyBlocked 項目中設定 堆疊變更

其中 newLosers 包含先前具有焦點,但 就會永久或暫時失去焦點永久失焦 會從音訊焦點堆疊中進一步移除,暫時的焦點遺失 就會移至目前的焦點遺失堆疊,直到重新取回焦點或 放棄回覆原始的焦點要求者無論如何 這些要求就會收到對應的焦點遺失

newlyBlocked 清單包含先前位於焦點遺失工具中的項目 但現在遭到新項目封鎖。封鎖可以是永久性 暫時性,如果設為永久性封鎖,該項目將從堆疊中移除 焦點遺失則會傳送至焦點事件監聽器暫時失去焦點時 項目將保留在焦點損失堆疊中,但新的焦點障礙 加入封鎖程式清單後,系統不會像先前一樣傳送焦點遺失 第一次封鎖時傳送。當所有回應均已解除封鎖時,請求最後就會解除封鎖 現有的攔截器會移除,如果焦點是,則會從堆疊中移除 被拋棄。

第二個 API notifyAudioFocusChange 是一種在每個網路中呼叫的方式 要求或放棄音訊焦點此 API 主要用於通知原始設備製造商 (OEM) 服務 焦點變更可能會影響 OEM 汽車音響服務的行為。

重點評估指南

在 AAOS 中,音訊焦點的用途是管理音訊播放,以及 應用程式應依循為使用者提供最佳體驗。因此 原始設備製造商 (OEM) 外掛程式服務在管理 音訊焦點要求:

  • 未啟用任何高優先順序的音訊焦點 (例如通話、 緊急救援或安全) 應用程式,必須具備音訊焦點功能, 暫時性或永久有效。

  • 當媒體焦點處於啟用狀態時,應用程式會要求:

    • 通話使用焦點,應可同時接收焦點 或只有特定成員

    • 導航使用焦點,應可以接收焦點 一起處理

    • Google 助理使用焦點,應可接收焦點內容。 一起處理

  • 站在高優先順序的語音焦點時 (例如通話、緊急求救) 快訊或安全性警示) 應用程式已啟用、收到延遲音訊焦點 更新或延遲。

雖然上述建議並未涵蓋所有情況,但這麼做可確保 要求聚焦的應用程式在沒有處於使用狀態時應能夠取得焦點 。即使已啟用高優先順序音效,但會延遲焦點 使用者提出這些要求後,還是能收到 高優先順序的高音停止聲

原始設備製造商 (OEM) 車用音量服務

車輛音訊服務會透過監聽音量的方式,管理音量的重要事件 調整音訊系統,或直接監聽音量鍵事件 。在上述情況下,車輛的預設行為 音訊服務,是判斷要根據啟用狀態變更的音量群組 以及音訊情境優先順序清單

我們提供兩份優先清單。第一個清單考量了所有音訊 然後根據這個順序來標記其他背景資訊此清單依遞減順序呈現 優先順序由高至低舉例來說 同時啟用導航音訊和音樂音訊,以及 導覽音量在發生重要事件期間有所改變

  1. 導覽
  2. 致電
  3. 音樂
  4. 公告
  5. 語音指令
  6. 來電響鈴
  7. 系統音效
  8. 安全性
  9. 警報器
  10. 通知
  11. 車輛狀態
  12. 緊急

為降低音量鍵事件管理作業的複雜度,車輛音訊服務提供 音訊情境第二優先的清單:

  1. 致電
  2. 媒體
  3. 公告
  4. 語音指令

此外,這份清單也會按遞減順序顯示。這份昆蟲清單的目的 是允許透過重要事件變更更常見的聲響罕見 可以透過音訊設定管理 只有使用者介面。

您可以使用 audioVolumeAdjustmentContextsVersion 設定。您可將設定 設為 12 (預設為 2)。

為了更靈活地管理磁碟區: OemCarAudioVolumeService 已在 Android 14 中推出:

public interface OemCarAudioVolumeService {
    OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}

原始設備製造商 (OEM) 汽車音訊音量服務是一種單一方法,可採用 volumeAdjustmentOemCarAudioVolumeRequest

class OemCarAudioVolumeRequest {
    int audioZoneId;
    int callState;
    List<AudioAttributes> activePlaybackAttributes;
    List<AudioAttributes> duckedAttributes;
    List<CarVolumeGroupInfo> volumeGroupState;
}

要求的 activePlaybackAttributes 包含使用中的音訊屬性。 「duckedAttributes」目前都是已隱藏的音訊屬性。 volumeGroupState 具有磁碟區群組目前的狀態。要求 代表音訊堆疊的目前狀態,可用來判斷 應變更的音量群組結果應該會以 OemCarVolumeChangeInfo:

class OemCarVolumeChangeInfo {
    boolean change;
    CarVolumeGroupInfo volumeGroupChanged;
}

change 布林值表示是否有任何磁碟區發生變化,true 表示 變更有變更,應更新音量群組。 volumeGroupChanged 是實際應變更的磁碟區群組。這個 群組應根據原始 volumeAdjustment 參數進行變更 傳遞給 API例如,如果結果指出 音量群組應設為靜音,而布林值會是 true,而傳回的 分別在導覽時設定音量群組

原始設備製造商 (OEM) 汽車越野鴨服務

車輛音訊服務會監控音訊焦點變化, 傳送訊號給 AudioControl HAL,決定要將哪些音訊裝置帶入。 當焦點變更時,系統會評估所有使用中的焦點持有者,以決定 那麼應該去考慮這種靜態降低的 規則

  • 緊急警報的聲音 (通話音效除外)
  • 安全功能會替除了緊急音效以外的所有裝置
  • 導航會啟動除了安全和緊急音效之外的所有資訊
  • 撥打電話後,即可隱藏安全、緊急救援和導航音效以外的所有資訊
  • 語音你已中斷通話響鈴
  • 音樂和公告都應該好好休息

這些規則並未涵蓋所有情況,原始設備製造商 (OEM) 仍須負責判斷 為何要根據這些準則將聲音關閉。原始設備製造商 (OEM) 可以控制 根據可用的需求更主動地提供最佳化建議。 OemCarDuckingService 已在 Android 14 中推出:

class OemCarAudioDuckingService {
List<AudioAttributes>   evaluateAttributesToDuck(
        OemCarAudioVolumeRequest request);
}

當音訊焦點變更時,系統會從車輛音訊服務呼叫這個 API。重複使用 OemCarAudioVolumeRequest導入 原始設備製造商 (OEM) 汽車音量維修服務,且包含 做出決定請注意, 系統會比較 API 目前音訊屬性和目前的音訊狀態:

  • 音訊屬性目前已插入:

    • 清單上,繼續好好休息
    • 不在清單上,已關閉「降低其他應用程式」模式
  • 目前未隱藏的音訊屬性:

    • 已加入清單,已隱藏
    • 不在清單上,已關閉「降低其他應用程式」模式

接著,車輛音訊服務會決定可輸出音訊的裝置。 屬性的所有屬性,並新增至離線音訊輸出裝置清單 未切換的音訊裝置清單。這最終會傳送到 AudioControl HAL 執行 所需的硬體層級

下圖顯示降低其他應用程式音量的簡化序列圖表 控制焦點要求使用時機:

圖片

當應用程式提出要求時,這個序列就會開始 管理音訊焦點 公開音訊管理員 API要求會轉到車輛音訊裝置 以判斷結果。偵測到音訊焦點後,音訊就會「降低背景音量」 然後由呼叫 OemCarAudioDuckingService 的車輛音訊服務評估, 評估哪些音訊屬性應加載。傳回結果後 然後透過 evaluateAttributesToDuck API 計算出要去鴨的音訊裝置 且資訊最後會傳送到 AudioControl,以便執行「降低鴨」作業 音訊硬體

導入 OEM 汽車音訊服務參考資源

AAOS 提供原始設備製造商 (OEM) 汽車服務的參考實作 packages/services/Car/tests/OemCarServiceTestApp,可導入 OemCarServiceOemCarAudioFocusServiceOemCarAudioDuckingServiceOemCarAudioVolumeService。若是後者 每個服務都會使用 XML 檔案載入靜態行為。例如: OemCarAudioFocusServiceImp 會載入 oem_focus_config.xml, 包含一個互動矩陣。矩陣可用來評估焦點要求 呼叫 evaluateAudioFocusRequest 時。

參考測試應用程式偵錯

原始設備製造商 (OEM) 汽車服務測試應用程式屬於 Android 開放原始碼計畫原始碼的一部分。原始設備製造商 (OEM) 可以 自動調整資源配置如要偵錯,請使用 config_oemCarService 即可啟用測試應用程式。

<!-- This is the component name for the OEM customization service. OEM can choose to implement
this service to customize car service behavior for different policies. If OEMs choose to
implement it, they have to implement a service extending OemCarService exposed by car-lib,
and implement the required component services.
If the component name is invalid, CarService would not connect to any OEM service.
Component name can not be a third party package. It should be pre-installed -->
<string name="config_oemCarService" translatable="false">
com.android.car.oemcarservice.testapp/.OemCarServiceImpl
</string>

如要驗證原始設備製造商 (OEM) 汽車服務,請使用車輛服務 dump 指令的 原始設備製造商 (OEM) 服務:

adb shell dumpsys car_service --oem-service

結果可能與以下輸出內容相似:

***CarOemProxyService dump***
  mIsFeatureEnabled: true
  mIsOemServiceBound: true
  mIsOemServiceReady: true
  mIsOemServiceConnected: true
  mInitComplete: true
  OEM_CAR_SERVICE_CONNECTED_TIMEOUT_MS: 5000
  OEM_CAR_SERVICE_READY_TIMEOUT_MS: 5000
  mComponentName: com.android.car.oemcarservice.testapp/.OemCarServiceImpl

dump 資訊批次中的每個布林值會決定地圖項目的狀態 和服務舉例來說,轉儲資訊 mIsOemServiceReady 會指定 服務已可使用,其中 true 表示已就緒,false 表示作業尚未就緒。