Tăng cường bảo mật âm thanh nền

Kể từ Android 17, khung âm thanh sẽ thực thi các hạn chế đối với hoạt động tương tác âm thanh trong nền, bao gồm cả hoạt động phát âm thanh, yêu cầu quyền phát âm thanh và API thay đổi âm lượng để đảm bảo rằng người dùng chủ động bắt đầu các thay đổi này.

Tất cả các ứng dụng chạy trên Android 17 có các hoạt động tương tác âm thanh trong nền này đều phải có một hoạt động hiển thị hoặc phải đang chạy một dịch vụ trên nền trước không thuộc loại SHORT_SERVICE. Điều này áp dụng cho dù ứng dụng có nhắm đến API cấp 37 hay không.

Nếu một ứng dụng nhắm đến Android 17 (cấp độ API 37), thì sẽ có thêm một hạn chế. Nếu đang chạy trong nền, ứng dụng phải đang chạy một dịch vụ trên nền trước có các chức năng khi đang sử dụng (WIU). (Một dịch vụ trên nền trước được cấp các chức năng WIU nếu dịch vụ đó được bắt đầu để phản hồi một thao tác do người dùng khởi tạo hoặc trong khi ứng dụng hiển thị với người dùng.) Tuy nhiên, yêu cầu về các chức năng WIU sẽ được miễn nếu ứng dụng đã được cấp quyền báo thức chính xác và đang thực hiện các thay đổi đối với luồng âm thanh có thuộc tính USAGE_ALARM.

Nếu ứng dụng cố gắng gọi API âm thanh trong khi ứng dụng không ở trong một vòng đời hợp lệ, thì API phát âm thanh và API thay đổi âm lượng sẽ không thành công một cách âm thầm mà không đưa ra một ngoại lệ hoặc cung cấp thông báo lỗi. API quyền phát âm thanh không thành công với mã kết quả AUDIOFOCUS_REQUEST_FAILED.

Lý do chúng tôi thực hiện thay đổi

Mục đích của việc đưa ra các hạn chế này là để giảm các trải nghiệm lỗi âm thanh trong nền không chủ ý. Một số ví dụ bao gồm:

  • Các ứng dụng phát âm thanh mà không có dịch vụ trên nền trước có thể bị đóng băng. Khi ứng dụng được mở băng, ứng dụng sẽ tiếp tục phát âm thanh một cách bất ngờ, có thể là vài giờ sau đó.
  • Các ứng dụng phát âm thanh mà không có dịch vụ trên nền trước phải đối mặt với nhiều hạn chế khi chạy, dẫn đến hiệu suất âm thanh bị giật.
  • Hoạt động phát bị tách khỏi vòng đời của activity, điều này có thể dẫn đến rò rỉ phiên phát hoặc rò rỉ sự kiện quyền phát âm thanh tiếp tục mà người dùng không có cách nào để dừng phát.

Chúng tôi khuyến khích nhà phát triển kiểm thử ứng dụng của họ và cung cấp ý kiến phản hồi về thay đổi hành vi nếu có trường hợp sử dụng âm thanh có chủ ý bị ảnh hưởng tiêu cực. Vui lòng báo cáo mọi vấn đề bằng công cụ theo dõi vấn đề về khả năng tương thích của ứng dụng Android 17 này.

Xác định các trường hợp sử dụng âm thanh trong nền bị ảnh hưởng

Kiểm tra việc triển khai phát âm thanh và xác định xem ứng dụng của bạn có ý định cung cấp chức năng tương tác âm thanh trong nền ngay cả trong các trường hợp có điều kiện hay không.

Nếu ứng dụng của bạn chỉ có ý định phát âm thanh hoặc sử dụng API âm thanh trong khi đang hiển thị một hoạt động mà người dùng có thể nhìn thấy, bao gồm cả việc sử dụng chế độ Hình trong hình (PiP), thì ứng dụng đó sẽ không bị ảnh hưởng bởi bất kỳ thay đổi nào trong số này.

Nếu ứng dụng của bạn cung cấp chức năng VOIP, bao gồm cả các ứng dụng gọi video, thì ứng dụng đó phải đáp ứng các yêu cầu đang được giới thiệu để phát (thường là thông qua việc sử dụng các API viễn thông được đề xuất) để ghi âm thành công, và do đó, ứng dụng đó khó có thể bị ảnh hưởng.

Nếu ứng dụng của bạn có ý định tiếp tục phát âm thanh trong khi màn hình tắt hoặc trong khi hoạt động của bạn không hiển thị, thường thấy nhất trong các ứng dụng phát nhạc trực tuyến hoặc ứng dụng podcast, thì ứng dụng của bạn được coi là cung cấp chức năng âm thanh trong nền và phải đáp ứng các yêu cầu mới.

Các trường hợp âm thanh trong nền có khả năng bị ảnh hưởng

Nếu ứng dụng của bạn không tuân theo mô hình tiếp tục tương tác âm thanh được khởi tạo trong khi ứng dụng đang mở hoặc để phản hồi một trình kích hoạt rõ ràng của người dùng, thì có khả năng chức năng của ứng dụng sẽ bị chặn một cách âm thầm.

Ví dụ: nếu ứng dụng của bạn bắt đầu một dịch vụ trên nền trước để phản hồi BOOT_COMPLETE và cố gắng tương tác với âm thanh, thì ứng dụng đó sẽ bị chặn.

Các phương pháp hay nhất về âm thanh trong nền để giảm thiểu tác động

  • Sử dụng thành phần MediaSessionService của thư viện Jetpack media3 để quản lý hoạt động phát âm thanh trong nền.

    Nếu bạn làm như vậy, thì ứng dụng của bạn khó có thể bị ảnh hưởng bởi việc tăng cường bảo mật trong nền do thư viện hỗ trợ quản lý vòng đời phát.

  • Nếu không tận dụng thư viện media3, bạn sẽ cần bắt đầu một FGS mediaPlayback theo cách thủ công. Luôn bắt đầu một dịch vụ trên nền trước trong khi ứng dụng đang ở nền trước nếu có thể xảy ra âm thanh trong nền.

    Ví dụ: nếu ứng dụng của bạn là một ứng dụng phát video trực tuyến thường chỉ ở nền trước nhưng có một tính năng hỗ trợ người dùng để tiếp tục phát trong khi màn hình tắt, thì khi trình kích hoạt phát do người dùng khởi tạo xảy ra, ứng dụng của bạn vẫn phải bắt đầu một dịch vụ trên nền trước.

    Việc này đảm bảo rằng dịch vụ trên nền trước được bắt đầu với các chức năng WIU.

  • Duy trì trạng thái hoạt động của FGS mediaPlayback trong thời gian lỗi tạm thời dưới 10 phút.

    Nếu ứng dụng của bạn gặp lỗi tạm thời, chẳng hạn như sự cố với việc lưu vào bộ đệm do hoạt động mạng hoặc có sự gián đoạn tạm thời dự kiến như AUDIOFOCUS_LOSS_TRANSIENT, thì ý định phát sẽ tiếp tục. Do đó, FGS của bạn sẽ vẫn hoạt động.

  • Dừng dịch vụ trên nền trước khi kết thúc quá trình phát và chỉ khởi động lại quá trình phát nếu người dùng tiếp tục phát một cách rõ ràng.

    Trong trường hợp có tín hiệu vĩnh viễn để kết thúc quá trình phát (ví dụ: nội dung đã hoàn tất mà không tự động phát, AUDIOFOCUS_LOSS, sự kiện tạm dừng từ UMO hoặc sự kiện phím đa phương tiện) hoặc lỗi không thể khôi phục, ứng dụng của bạn phải ngừng tương tác âm thanh, dừng dịch vụ trên nền trước và kết thúc phiên đa phương tiện. Việc thực hiện tất cả những điều này tương ứng với quan niệm của người dùng về việc "hoàn tất" hoạt động tương tác âm thanh trong nền mong muốn. Sau khi thực hiện việc này, ứng dụng của bạn không còn có các chức năng tương tác âm thanh trong nền nữa.

    Sau đó, nếu người dùng tiếp tục phát một cách rõ ràng, chẳng hạn như thông qua giao diện người dùng của ứng dụng hoặc thông qua nút phát Đối tượng đa phương tiện phổ quát, thì ý định bắt đầu phát âm thanh sẽ quay lại, dẫn đến một FGS mới được bắt đầu.

  • Kiểm thử hành vi phát âm thanh bằng các lệnh adb shell.

Kiểm thử các thay đổi

Bạn có thể kiểm thử việc tuân thủ của ứng dụng trên các ứng dụng chạy Android 17 trở lên (bắt đầu từ Beta 3) bằng cách chạy lệnh ADB sau:

adb shell cmd audio set-enable-hardening <enable|disable|throw>

Lệnh này có các lựa chọn sau:

  • enable: Bật tất cả các hạn chế tăng cường bảo mật âm thanh cho tất cả các ứng dụng. Yêu cầu về các dịch vụ trên nền trước WIU được áp dụng cho dù ứng dụng có nhắm đến Android 17 (cấp độ API 37) hay không. Ngoài ra, yêu cầu này được thực thi ngay cả khi ứng dụng đang thực hiện các thay đổi đối với luồng báo thức và có quyền báo thức chính xác.

  • disable: Tắt tất cả các hạn chế tăng cường bảo mật âm thanh.

  • throw: Bật tất cả các hạn chế tăng cường bảo mật âm thanh cho tất cả các ứng dụng, giống như enable. Ngoài ra, cờ này bật các lỗi lớn, đưa ra IllegalStateException cho các hoạt động tương tác về âm lượng và tiêu điểm. Đối với hoạt động phát âm thanh, phương thức ghi liên tục trả về mã lỗi. Đối với các chế độ phát không có hoạt động ghi rõ ràng, ứng dụng sẽ gặp sự cố.

Sử dụng adb dumpsys audio hoặc logcat để xác định xem ứng dụng có gặp lỗi âm thầm do việc thực thi tăng cường bảo mật âm thanh hay không. Nếu có, sẽ có một mục được gắn tiền tố AudioHardening với tên gói của bạn. Nếu thông báo chứa level: full, thì ứng dụng của bạn đang chạy một dịch vụ trên nền trước, nhưng dịch vụ đó không có chức năng khi đang sử dụng. Nếu thông báo chứa level: partial, thì ứng dụng của bạn hoàn toàn không chạy dịch vụ trên nền trước.

Tìm hiểu về FGS có chức năng khi đang sử dụng

Nói chung, các dịch vụ trên nền trước (FGS) phải được khởi chạy trong khi một ứng dụng đang ở nền trước để mở rộng các thao tác do người dùng khởi tạo. Trong một số trường hợp cụ thể, các ứng dụng được phép khởi chạy một dịch vụ trên nền trước trong khi ứng dụng đang ở nền. Tuy nhiên, các dịch vụ trên nền trước này thường không được cấp các chức năng Khi đang sử dụng (WIU).

WIU hoạt động như một cổng bảo mật – ngăn FGS bắt đầu từ nền tham gia vào một số hành vi nhạy cảm khi người dùng có thể không biết về hoạt động của ứng dụng. Tính năng này ngăn ứng dụng truy cập vào dữ liệu nhạy cảm như vị trí, camera hoặc micrô và bắt đầu từ Android 17, tính năng này cũng chặn các API âm thanh thường yêu cầu ngữ cảnh giao diện người dùng hiển thị.

Sau đây là tài liệu tham khảo hữu ích:

Đọc thêm trong Các hạn chế khi khởi động dịch vụ trên nền trước từ nền.

Danh sách đầy đủ các API âm thanh bị ảnh hưởng

Hàm âm thanh

Kết quả

API bị ảnh hưởng

Phát âm thanh

Hoạt động phát bị tắt tiếng

Không có ngoại lệ, không có thông báo lỗi do bất kỳ API nào cung cấp

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES dành cho Android

Mọi thư viện đa phương tiện phía máy khách quản lý hoạt động phát như media3, Exoplayer và Oboe cũng có thể bị ảnh hưởng.

Yêu cầu quyền phát âm thanh

Trả về AUDIOFOCUS_REQUEST_FAILED

Không ảnh hưởng đến hoạt động phát âm thanh của các ứng dụng khác, không có quyền phát âm thanh

AudioManager.requestAudioFocus()

API chế độ âm lượng và chuông

Không ảnh hưởng đến chế độ chuông hoặc âm lượng (lệnh gọi phương thức bị bỏ qua một cách âm thầm)

Không có ngoại lệ, không có thông báo lỗi do bất kỳ API nào cung cấp

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()