Định tuyến âm thanh

Trong Android 10, car_audio_configuration.xml sẽ thay thế car_volumes_groups.xmlIAudioControl.getBusForContext. Trong tệp cấu hình mới, một danh sách các vùng được xác định. Mỗi vùng có một hoặc nhiều các nhóm âm lượng với thiết bị được liên kết của chúng và mỗi thiết bị có bối cảnh cần được định tuyến trong vùng đó. Bắt buộc phải thể hiện tất cả ngữ cảnh trong từng vùng.

Định cấu hình định tuyến âm thanh

Các tệp chính sách âm thanh (thường nằm trong phân vùng nhà cung cấp) đại diện cho cấu hình phần cứng âm thanh của bo mạch. Tất cả thiết bị được tham chiếu trong car_audio_configuration.xml phải được xác định trong audio_policy_configuration.xml

Bật tính năng định tuyến AAOS

Để sử dụng định tuyến dựa trên AAOS, bạn phải đặt audioUseDynamicRouting gắn cờ thành true:

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

Khi false, tính năng định tuyến và phần lớn CarAudioService sẽ bị tắt và hệ điều hành sẽ quay lại hành vi mặc định của AudioService.

Vùng chính

Theo mặc định, tất cả âm thanh sẽ được chuyển đến vùng chính. Chỉ có thể là một vùng chính được biểu thị trong cấu hình theo thuộc tính isPrimary="true".

Cấu hình mẫu

Ví dụ: một chiếc xe có thể có hai khu vực — một khu vực chính và một chỗ ngồi sau hệ thống giải trí. Với cách đó, car_audio_configuration.xml có thể sẽ được xác định như sau:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

Ở đây, vùng chính đã phân tách ngữ cảnh cho các thiết bị khác nhau. Điều này cho phép HAL để áp dụng các hiệu ứng hậu xử lý khác nhau và trộn trên mỗi đầu ra của thiết bị bằng phần cứng của xe. Các thiết bị này đã được sắp xếp thành 4 nhóm âm lượng: nội dung nghe nhìn, tính năng chỉ đường, cuộc gọi và chuông báo. Nếu hệ thống được định cấu hình để useFixedVolume, thì hệ thống sẽ chuyển các mức âm lượng cho từng nhóm vào HAL để áp dụng cho đầu ra của các thiết bị này.

Đối với vùng phụ, đầu ra dự kiến là thông qua một thiết bị đầu ra duy nhất. Trong ví dụ này, tất cả các trường hợp sử dụng đều được định tuyến đến một thiết bị và nhóm âm lượng để làm cho mọi thứ đơn giản.

Cấu hình âm thanh của người trong khu vực

Trong Android 11, car_audio_configuration.xml được mở rộng thêm thành đưa vào hai trường mới là audioZoneIdoccupantZoneId. Thứ nhất, audioZoneId có thể được dùng để kiểm soát tốt hơn việc quản lý vùng. Mặt khác, occupantZoneId có thể được sử dụng để định cấu hình dựa trên mã nhận dạng người dùng định tuyến.

Để sử dụng các trường mới này, V2 của car_audio_configuration.xml là là bắt buộc. Xem lại cấu hình âm thanh ở trên nhưng sử dụng trường mới cho Ánh xạ mã vùng âm thanh và mã khu vực có người ở, cấu hình mới không có âm lượng Bạn có thể thiết lập định nghĩa nhóm thành:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

Cấu hình ở trên xác định việc ánh xạ vùng chính đến khu vực có người lưu trú 0, và audioZoneId 1 đến occupantZoneId 1. Nhìn chung, bất kỳ mối liên kết nào bạn có thể định cấu hình giữa vùng có người và vùng âm thanh, nhưng phải ánh xạ 1-1. Dưới đây là các quy tắc xác định hai trường mới:

  • audioZoneId của vùng chính luôn bằng 0
  • Không thể lặp lại số audioZoneIdoccupantZoneId
  • audioZoneIdoccupantZoneId chỉ có thể có một mối liên kết 1-1

Định tuyến thông qua UID của ứng dụng

Một loạt API ẩn đã được đưa vào CarAudioManager trong 10 API để cho phép các ứng dụng để truy vấn và thiết lập vùng âm thanh cũng như tập trung.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);

Các API ở trên cho phép ứng dụng bên thứ nhất quản lý cơ sở dữ liệu định tuyến âm thanh trên UID của ứng dụng. Do đó, cả mã vùng âm thanh và UID của ứng dụng đều là cũng cần thiết. Khi có thông tin đó, bạn có thể thiết lập định tuyến âm thanh bằng cách sử dụng API CarAudioManager#setZoneIdForUid.

Thay đổi vùng cho một ứng dụng

Theo mặc định, tất cả âm thanh đều được định tuyến đến vùng chính. Để cập nhật một ứng dụng thành được định tuyến đến một vùng khác, hãy sử dụng CarAudioManager#setZoneIdForUid:

// Find zone to play
int zoneId = ...

// Find application's uid
Int uid = mContext.getPackageManager()
        .getApplicationInfo(mContext.getPackageName(), 0)
        .uid;

if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) {
    Log.d(TAG, "Zone successfully updated");
} else {
    Log.d(TAG, "Failed to change zone");
}

B Lưu ý: Các luồng và tiêu điểm không thể tự động chuyển đổi vùng. Do đó, phải dừng phát và yêu cầu lại tiêu điểm để thay đổi vùng.

Định tuyến bằng Mã nhận dạng người dùng

Mặc dù việc định tuyến dựa trên UID của ứng dụng cho phép kiểm soát tốt định tuyến âm thanh, dịch vụ này cũng yêu cầu định tuyến âm thanh cho từng ứng dụng trước vào ứng dụng thực sự yêu cầu quyền phát âm thanh và phát âm thanh. Để giảm thiểu điều này và tạo điều kiện cho các ứng dụng của bên thứ ba phát âm thanh mà không cần sửa đổi, CarAudioService dùng thông tin ánh xạ vùng âm thanh và khu vực của hành khách để xác định việc định tuyến dựa trên mã nhận dạng người dùng. Bằng cách này, khi người dùng đăng nhập vào khu vực có người, âm thanh của xe dịch vụ sẽ được thông báo. Với tín hiệu này, tính năng quản lý và định tuyến quyền phát âm thanh sẽ tự động được định cấu hình cho tất cả các vùng âm thanh.

Ứng dụng vẫn có thể định tuyến dựa trên UID nhưng phải được thực hiện độc lập với định tuyến user id. Điều này có nghĩa là nếu dữ liệu lập bản đồ vùng âm thanh của người ở nhà đã xác định, thì định tuyến dựa trên UID sẽ bị tắt và cố gắng gọi CarAudioManager#setZoneidForUid sẽ gửi một lỗi.

Mặc dù tính năng định tuyến âm thanh và quản lý tiêu điểm đã được đơn giản hoá với vùng có người quản lý, thì người dùng vẫn phải được chỉ định cho khu vực có người. Có thể thực hiện việc này bằng cách bằng cách sử dụng CarOccupantZoneManager#assignProfileUserToOccupantZone. Chiến dịch này API yêu cầu quyền để quản lý người dùng. Kỳ vọng hiện tại là để OEM quản lý chỉ định vùng cho người dùng thông qua một số loại giao diện người dùng hệ thống. Sau khi hoàn tất, ứng dụng chạy, định tuyến âm thanh, quản lý tiêu điểm đều sẽ được định cấu hình tự động cho người dùng.

Định tuyến bằng setPreferenceDevice

Cùng với những thay đổi nêu trên, Android 11 cũng có một API mới để truy vấn thiết bị đầu ra liên kết với từng vùng, CarAudioManager#getOutputDeviceForUsage(int vùngId, sử dụng int).

Bạn có thể dùng API này để truy vấn một thiết bị đầu ra cho một vùng cụ thể và một thuộc tính âm thanh mức sử dụng. Bằng cách này, ứng dụng của bên thứ nhất có thể định tuyến âm thanh đến những vùng khác nhau bằng cách bằng cách sử dụng API setPreferredDevice của người chơi. Chiến lược phát hành đĩa đơn Cần có API getOutputDeviceForUsage PERMISSION_CAR_CONTROL_AUDIO_SETTINGS và là một API hệ thống. Dưới đây là ví dụ về cách tìm thiết bị truyền thông cho một vùng cụ thể và định tuyến đến thiết bị đó thông qua API setPreferredDevice.

audioZoneId = ... ;
mediaDeviceInfo = mCarAudioManager
            .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA);
…
mPlayer.setPreferredDevice(mediaDeviceInfo);