quyền phát âm thanh

Trước khi bắt đầu một luồng logic, ứng dụng phải yêu cầu quyền phát âm thanh bằng cách sử dụng các thuộc tính âm thanh giống như được dùng cho luồng logic của ứng dụng. Mặc dù bạn nên gửi yêu cầu tiêu điểm như vậy, nhưng hệ thống không thực thi yêu cầu này. Một số ứng dụng có thể bỏ qua việc gửi yêu cầu một cách rõ ràng để thực hiện các hành vi cụ thể (ví dụ: để chủ ý phát âm thanh trong cuộc gọi điện thoại).

Vì lý do này, bạn nên coi tiêu điểm là một cách để gián tiếp kiểm soát và giải quyết xung đột phát, chứ không phải là cơ chế điều khiển âm thanh chính; xe không được phụ thuộc vào hệ thống tiêu điểm để vận hành hệ thống con âm thanh.

Lượt tương tác với tiêu điểm

Để hỗ trợ nhu cầu của AAOS, các yêu cầu về quyền phát âm thanh được xử lý dựa trên các lượt tương tác được xác định trước giữa CarAudioContext của yêu cầu và lượt tương tác của chủ thể có quyền phát hiện hiện tại. Có 3 loại tương tác: độc quyền, từ chối và đồng thời.

Hoạt động tương tác độc quyền

Trong các lượt tương tác độc quyền, mỗi lần chỉ có một ứng dụng được phép giữ tiêu điểm. Do đó, yêu cầu tiêu điểm sắp tới sẽ được cấp tiêu điểm trong khi chủ thể tiêu điểm hiện tại mất tiêu điểm. Ví dụ: khi người dùng khởi động một ứng dụng nhạc mới trong khi nhạc đang phát trong một ứng dụng hiện có. Vì cả hai đều đang phát nội dung đa phương tiện, nên mỗi lần chỉ có một trong hai ứng dụng được giữ tiêu điểm. Do đó, yêu cầu tiêu điểm của ứng dụng mới bắt đầu sẽ trả về bằng AUDIOFOCUS_REQUEST_GRANTED và ứng dụng hiện đang phát nhạc sẽ nhận được sự kiện thay đổi tiêu điểm với trạng thái mất tương ứng với loại yêu cầu đã được thực hiện. Đây là mô hình tương tác thường thấy nhất với Android.

Từ chối tương tác

Với các lượt tương tác từ chối, yêu cầu đến luôn bị từ chối. Cố gắng phát nhạc trong khi đang có cuộc gọi là một ví dụ về tương tác bị từ chối. Trong trường hợp này, nếu trình quay số hiện đang giữ quyền phát âm thanh cho một cuộc gọi và một ứng dụng thứ hai yêu cầu quyền phát âm thanh để phát nhạc, thì ứng dụng nhạc sẽ nhận được AUDIOFOCUS_REQUEST_FAILED để phản hồi yêu cầu của ứng dụng đó. Vì yêu cầu tiêu điểm bị từ chối, nên không có loại tiêu điểm nào bị mất được gửi đến chủ sở hữu tiêu điểm hiện tại.

Tương tác đồng thời

Điểm độc đáo nhất của AAOS là các lượt tương tác đồng thời. Điều này cho phép các ứng dụng yêu cầu quyền phát âm thanh trong ô tô giữ quyền phát đồng thời với các ứng dụng khác. Để một lượt tương tác đồng thời diễn ra, bạn phải đáp ứng các điều kiện sau. Các:

Nếu đáp ứng các tiêu chí này, thì yêu cầu tiêu điểm sẽ trả về bằng AUDIOFOCUS_REQUEST_GRANTED trong khi chủ sở hữu tiêu điểm hiện tại không có thay đổi nào về tiêu điểm. Tuy nhiên, nếu chủ thể tiêu điểm hiện tại chọn nhận sự kiện nhấn để ẩn hoặc tạm dừng khi bị nhấn để ẩn, thì chủ thể tiêu điểm hiện tại sẽ mất tiêu điểm giống như khi có một lượt tương tác độc quyền.

Xử lý các luồng đồng thời

Mặc dù hoạt động tương tác đồng thời có nhiều ứng dụng hữu ích, nhưng nhà sản xuất thiết bị gốc (OEM) phải chú ý đến việc kết hợp và giảm âm ở cấp phần cứng trên các thiết bị đầu ra. Do đó, bạn nên chỉ định CarAudioContext đến cùng một thiết bị đầu ra với CarAudioContext mà chúng không thể phát đồng thời. Bằng cách có các thiết bị đầu ra riêng biệt cho các luồng đồng thời, điều này cho phép HAL loại bỏ một trong các luồng trước khi kết hợp các luồng đó với nhau hoặc định tuyến các luồng thực tế đến các loa khác nhau trong xe. Nếu các luồng logic được kết hợp trong Android, thì mức tăng của các luồng này sẽ không bị thay đổi và được phân phối trong cùng một luồng thực.

Ví dụ: khi chỉ đường và nội dung nghe nhìn được phân phối đồng thời, mức tăng cho luồng nội dung nghe nhìn có thể tạm thời giảm (được giảm) để có thể nghe rõ hơn hướng dẫn chỉ đường. Ngoài ra, luồng chỉ đường có thể được định tuyến đến loa bên người lái trong khi nội dung nghe nhìn tiếp tục phát trong phần còn lại của cabin.

Ma trận tương tác

Bảng dưới đây cho thấy ma trận tương tác do CarAudioService xác định. Các hàng đại diện cho CarAudioContext của chủ sở hữu tiêu điểm hiện tại và các cột đại diện cho yêu cầu sắp tới.

Hãy xem xét một ví dụ, trong đó ứng dụng đa phương tiện âm nhạc hiện đang giữ tiêu điểm và ứng dụng điều hướng yêu cầu tiêu điểm, ma trận cho thấy hai lượt tương tác có thể phát đồng thời, giả sử các tiêu chí khác cho Tương tác đồng thời được đáp ứng.

Do các lượt tương tác đồng thời, có thể có nhiều trình giữ tiêu điểm. Trong trường hợp này, yêu cầu tiêu điểm sắp tới sẽ được so sánh với từng chủ sở hữu tiêu điểm hiện tại trước khi quyết định loại tương tác sẽ áp dụng. Trong trường hợp này, hoạt động tương tác bảo thủ nhất sẽ thắng (từ chối, sau đó là độc quyền và cuối cùng là đồng thời).

Trong bảng sau, các hoạt động tương tác với tiêu điểm giữa CarAudioContext cho một yêu cầu tiêu điểm sắp tới (cột) và ngữ cảnh của các chủ sở hữu tiêu điểm hiện có (hàng) được cung cấp. Mỗi ô đại diện cho loại tương tác dự kiến cho hai ngữ cảnh.

Tương tác với quyền phát âm thanh

Hình 1. Tương tác với quyền phát âm thanh

Trong Android 11, chúng tôi đã ra mắt một chế độ cài đặt mới cho phép người dùng thay đổi hành vi tương tác giữa tính năng chỉ đường và cuộc gọi điện thoại. Khi được đặt, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL sẽ thay đổi hoạt động tương tác giữa các yêu cầu tiêu điểm NAVIGATION sắp tới và các chủ sở hữu tiêu điểm CALL hiện tại từ tương tranh thành từ chối. Vì vậy, nếu không muốn hướng dẫn chỉ đường làm gián đoạn cuộc gọi, người dùng có thể bật chế độ cài đặt này. Giá trị này được duy trì cho người dùng và có thể được đặt một cách linh động để các yêu cầu tiêu điểm tiếp theo tuân theo giá trị cài đặt mới.

Quyền phát âm thanh có thể trì hoãn

Trong Android 11, AAOS đã thêm tính năng hỗ trợ yêu cầu tiêu điểm âm thanh có thể trì hoãn. Điều này cho phép các yêu cầu tiêu điểm không tạm thời bị trì hoãn khi tương tác với các chủ sở hữu tiêu điểm hiện tại thường dẫn đến việc bị từ chối. Khi một thay đổi về tiêu điểm dẫn đến trạng thái mà yêu cầu bị trì hoãn có thể lấy tiêu điểm, yêu cầu sẽ được cấp.

Quy tắc đối với yêu cầu quyền phát âm thanh bị trì hoãn

  • Chỉ yêu cầu không tạm thời – như đã đề cập trước đó, bạn chỉ có thể thực hiện yêu cầu bị trì hoãn cho các nguồn không tạm thời. Điều này là để tránh phát âm thanh tạm thời sau khi âm thanh đó không còn liên quan nữa.
  • Chỉ có thể trì hoãn một yêu cầu tại một thời điểm – Nếu một yêu cầu có thể trì hoãn được thực hiện trong khi đã có một yêu cầu bị trì hoãn, thì yêu cầu bị trì hoãn ban đầu sẽ nhận được một sự kiện thay đổi AUDIOFOCUS_LOSS và yêu cầu mới sẽ nhận được phản hồi đồng bộ của AUDIOFOCUS_REQUEST_DELAYED.
  • Yêu cầu có thể trì hoãn phải có OnAudioFocusChangeListener. Sau khi một yêu cầu bị trì hoãn, trình nghe sẽ được dùng để thông báo cho người yêu cầu khi yêu cầu đó cuối cùng được cấp (AUDIOFOCUS_GAIN) hoặc nếu yêu cầu đó bị từ chối sau này (AUDIOFOCUS_LOSS).

Yêu cầu tiêu điểm có thể trì hoãn

Để tạo một yêu cầu có thể bị trì hoãn, hãy sử dụng AudioFocusRequest.Builder#setAcceptsDelayedFocusGain:

mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();

mDelayedFocusRequest = new AudioFocusRequest
     .Builder(AudioManager.AUDIOFOCUS_GAIN)
     .setAudioAttributes(mMusicAudioAttrib)
     .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
     .setForceDucking(false)
     .setWillPauseWhenDucked(false)
     .setAcceptsDelayedFocusGain(true)
     .build();

Sau đó, khi thực hiện yêu cầu, hãy xử lý phản hồi AUDIOFOCUS_REQUEST_DELAYED:

int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// start audio playback
return;
}
if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
     // audio playback delayed to audio focus listener
     return;
}

Khi yêu cầu bị trì hoãn, trình nghe tiêu điểm sẽ chịu trách nhiệm xử lý các thay đổi về tiêu điểm:

private final class MediaWithDelayedFocusListener implements
OnAudioFocusChangeListener {
       @Override
       public void onAudioFocusChange(int focusChange) {
           synchronized (mLock) {
               switch (focusChange) {
                   case AudioManager.AUDIOFOCUS_GAIN:
                        // Start focus playback
                   case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // Pause media transiently
                   case AudioManager.AUDIOFOCUS_LOSS:
                        // Stop media

Quản lý tiêu điểm nhiều vùng

Đối với những xe có nhiều vùng âm thanh, tiêu điểm âm thanh được quản lý độc lập cho từng vùng. Do đó, yêu cầu đối với một vùng không tính đến nội dung đang giữ tiêu điểm trong các vùng khác, cũng không khiến trình giữ tiêu điểm trong các vùng khác mất tiêu điểm. Nhờ đó, bạn có thể quản lý tiêu điểm của khoang chính riêng biệt với hệ thống giải trí cho hàng ghế sau, nhờ đó tránh làm gián đoạn quá trình phát âm thanh ở một khu vực do các thay đổi về tiêu điểm ở khu vực khác.

Đối với tất cả các ứng dụng, CarAudioService sẽ tự động xử lý việc quản lý tiêu điểm. Vùng âm thanh của yêu cầu lấy tiêu điểm được xác định dựa trên UserId hoặc UID liên kết. Để biết thông tin chi tiết, hãy xem phần Điều hướng âm thanh.

Yêu cầu âm thanh từ nhiều vùng đồng thời

Nếu muốn phát âm thanh đồng thời ở nhiều vùng, ứng dụng phải yêu cầu quyền phát trung tâm cho từng vùng bằng cách đưa AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID vào gói:

// Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

// Create focus request using built attributesWithZone

Tham số gói này cho phép người yêu cầu ghi đè các mối liên kết vùng âm thanh tự động để sử dụng mã vùng được chỉ định. Do đó, ứng dụng có thể đưa ra các yêu cầu riêng biệt cho các vùng âm thanh khác nhau.

Quyền phát âm thanh HAL

Kể từ Android 11, HAL hiện được bật để thay mặt cho các luồng bên ngoài yêu cầu tiêu điểm. Mặc dù không bắt buộc, nhưng bạn nên sử dụng các API này để cho phép âm thanh bên ngoài tham gia tốt hơn vào hệ sinh thái Android và mang lại trải nghiệm người dùng mượt mà hơn.

Xin lưu ý rằng HAL vẫn chịu trách nhiệm thực hiện lệnh gọi cuối cùng về âm thanh nào sẽ được ưu tiên. Ở mức độ này, âm thanh khẩn cấp và âm thanh quan trọng về an toàn phải được phát bất kể HAL có được cấp quyền phát âm thanh hay không và phải tiếp tục phát khi thích hợp ngay cả khi HAL mất quyền phát âm thanh. Điều này cũng đúng với mọi âm thanh theo yêu cầu của quy định.

Tương tự như vậy, HAL vẫn phải chủ động tắt tiếng các luồng Android khi thích hợp khi phát âm thanh khẩn cấp hoặc âm thanh quan trọng về an toàn để đảm bảo người dùng nghe được rõ ràng.

AudioControl@2.0

Phiên bản 2.0 của AudioControl HAL giới thiệu một số API mới:

API Mục đích
IAudioControl#registerFocusListener Đăng ký một thực thể của IFocusListener với AudioControl HAL. Trình nghe này cho phép HAL yêu cầu và từ bỏ quyền phát âm thanh. HAl dự kiến sẽ cung cấp một thực thể ICloseHandle để Android sử dụng nhằm huỷ đăng ký trình nghe.
IAudioControl#onAudioFocusChange Thông báo cho HAL về các thay đổi về trạng thái để tập trung vào các yêu cầu do HAL đưa ra thông qua IFocusListener. Trong đó có cả phản hồi cho các yêu cầu tiêu điểm ban đầu.
IFocusListener#requestAudioFocus Thay mặt HAL yêu cầu tiêu điểm cho một mục đích sử dụng, mã nhận dạng vùng và loại lợi tức tiêu điểm được chỉ định.
IFocusListener#abandonAudioFocus Bỏ qua các yêu cầu tiêu điểm HAL hiện có cho mục đích sử dụng và mã vùng đã chỉ định.

HAL có thể có nhiều yêu cầu lấy tiêu điểm cùng một lúc, nhưng chỉ được giới hạn ở một yêu cầu cho mỗi lần sử dụng và ghép nối mã vùng. Xin lưu ý rằng Android giả định HAL ngay lập tức bắt đầu phát âm thanh cho một lần sử dụng sau khi yêu cầu được thực hiện và tiếp tục làm như vậy cho đến khi từ bỏ tiêu điểm.

Ngoài registerFocusListener, tất cả các yêu cầu này đều là oneway để đảm bảo rằng Android không trì hoãn HAL trong khi xử lý yêu cầu lấy tiêu điểm. HAL không được chờ lấy tiêu điểm trước khi phát âm thanh quan trọng về an toàn. HAL không bắt buộc phải theo dõi và phản hồi các thay đổi về tiêu điểm âm thanh thông qua IAudioControl#onAudioFocusChange, mặc dù bạn nên làm như vậy khi thích hợp.