
本頁面概述 Android 數位著作權管理 (DRM) 架構,並介紹 DRM 外掛程式必須實作的介面。這個頁面不會說明 DRM 方案可能定義的穩健性規則或法規遵循規則。
架構
Android 平台提供可擴充的 DRM 架構,可讓應用程式根據與內容相關聯的授權限制,管理受權利保護的內容。DRM 架構支援許多 DRM 方案,裝置製造商會決定裝置支援哪些 DRM 方案。DRM 架構為應用程式開發人員提供統一介面,並隱藏 DRM 作業的複雜性。DRM 架構為受保護和未受保護的內容提供一致的運作模式。DRM 方案可透過授權中繼資料定義複雜的使用模型。DRM 架構會建立 DRM 內容與授權之間的關聯,並處理著作權管理事宜。這可讓媒體播放器從受 DRM 保護或未受保護的內容中抽象化。如要瞭解如何取得金鑰來解密受保護的媒體串流,請參閱 MediaDrm 類別。
圖 1 顯示 Android 11 之前的 DRM 硬體擷取層,圖 2 則顯示 Android 11 以上版本的層:
圖 1. Android 11 之前的 DRM 硬體抽象層。
圖 2. Android 11 以上版本支援 DRM 硬體抽象層。
豐富的數位內容對行動裝置使用者來說非常重要。為確保內容能廣為發布,Android 開發人員和數位內容發布商需要採用 Android 生態系統支援的 DRM 實作方式。為確保 Android 裝置可存取數位內容,並確保所有裝置至少有一個一致的 DRM 可用,Google 會在相容的 Android 裝置上提供免授權費的 DRM。DRM 外掛程式與 Android DRM 架構整合,可使用硬體支援的保護機制,確保優質內容和使用者憑證安全無虞。
DRM 外掛程式提供的內容保護機制,取決於基礎硬體平台的安全性和內容保護功能。裝置的硬體功能應包含硬體安全開機,以建立安全信任鏈,並保護加密金鑰。裝置的內容保護功能應包括保護裝置中解密的影格,以及透過信任的輸出保護機制保護內容。並非所有硬體平台都支援上述所有安全性和內容保護功能。安全性絕不會在堆疊中的單一位置實作,而是仰賴硬體、軟體和服務的整合。結合硬體安全功能、可信任的開機機制,以及用於處理安全功能的獨立安全作業系統,是提供安全裝置的關鍵。
建築
DRM 架構的設計與實作無關,並會將特定 DRM 方案實作的詳細資料,抽象化為方案專屬的 DRM 外掛程式。DRM 架構包含簡單的 API,可處理複雜的 DRM 作業、取得授權、佈建裝置、關聯 DRM 內容及其授權,最後解密 DRM 內容。
Android DRM 架構是在兩個架構層中實作:
- DRM 架構 API,透過 Android 應用程式架構向應用程式公開
- 原生程式碼 DRM 架構,可公開 DRM 外掛程式 (代理程式) 的介面,處理各種 DRM 方案的著作權管理和解密作業
圖 3 顯示 Android 11 之前的 DRM 架構,圖 4 則顯示 Android 11 以上版本的架構:
圖 3. Android 11 之前的 DRM 架構。
圖 4. Android 11 以上版本支援 DRM 架構。
詳情請參閱 MediaDrm 和 MediaCrypto。
DRM 外掛程式
系統啟動時,DRM 架構會掃描 HAL 執行個體和服務 (如 .rc
檔案所述),並探索外掛程式。媒體 DRM 伺服器 (mediadrmserver
) 會建立 CryptoHal
和 DrmHal
物件。CryptoHal
和 DrmHal
接著會呼叫外掛程式,並採用供應商專屬的實作方式。
外掛程式應實作繫結 HAL。繫結 HAL 使用 Android 介面定義語言 (AIDL),因此即使更換架構,也不必重建 HAL。
外掛程式由供應商或 SoC 製造商建構,並放在裝置的 /vendor
分區中。凡是搭載 Android 13 以上版本推出的裝置,都必須支援以 AIDL 語言編寫的繫結 HAL。
實作
如要透過外掛程式實作新的 DRM 架構 API,請按照下列步驟操作:
- 將外掛程式服務新增至裝置的建構檔案。
- 更新裝置資訊清單。
- 新增 SELinux 權限。
- 在
/vendor
下建立.rc
檔案。 - 實作外掛程式。
API 定義於 IDrmPlugin.aidl
、ICryptoPlugin.aidl
、IDrmFactory.aidl
和 ICryptoFactory.aidl
的每個版本中。
aidl/PLATFORM_ROOT/hardware/interfaces/drm/
將外掛程式服務新增至裝置建構檔案
舉例來說,如要新增 AIDL 介面支援,VENDOR DEVICE/device.mk
檔案必須包含 android.hardware.drm-service.*
套件:
PRODUCT_PACKAGES += \ android.hardware.drm-service.clearkey \ android.hardware.drm-service.widevine
更新裝置資訊清單
裝置的 vendor manifest.xml
檔案必須包含下列項目:
<hal format="aidl"> <name>android.hardware.drm</name> <version>STABLE AIDL VERSION</version> <fqname>ICryptoFactory/clearkey</fqname> <fqname>IDrmFactory/clearkey</fqname> <fqname>ICryptoFactory/widevine</fqname> <fqname>IDrmFactory/widevine</fqname> </hal>
穩定版 AIDL 版本是各個 AIDL API 版本的版本號碼 (例如 1、2)。或者,我們建議使用 vintf_fragments
。
新增 SELinux 權限
- 將權限新增至
VENDOR DEVICE/sepolicy/vendor/file.te
:
type mediadrm_vendor_data_file, file_type, data_file_type;
- 將權限新增至
VENDOR DEVICE/sepolicy/vendor/file_contexts
:
/vendor/bin/hw/android\.hardware\.drm-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
/data/vendor/mediadrm(/.*)? u:object_r:mediadrm_vendor_data_file:s0 - 將權限新增至
device/sepolicy/vendor/hal_drm_clearkey.te
:
vndbinder_use(hal_drm_clearkey) allow hal_drm_clearkey servicemanager:binder { call transfer }; allow hal_drm_clearkey hal_drm_service:service_manager add; allow hal_drm_clearkey { appdomain -isolated_app }:fd use; get_prop(ramdump, public_vendor_default_prop)
在 /vendor 下建立 RC 檔案
.rc
檔案會指定服務啟動時要採取的動作。
詳情請參閱「Android Init Language」。
實作外掛程式
- 在外掛程式服務的
service.cpp
中實作main()
進入點。 - 實作
ICryptoPlugin
、IDrmPlugin
、ICryptoFactory
和IDrmFactory
。 - 在外掛程式中實作新版 API。
DRM 外掛程式詳細資料
DRM 外掛程式供應商會實作 DrmFactory
、CryptoFactory
和 DRM 外掛程式。
DrmFactory 類別
DrmHal
類別會搜尋已註冊的 DRM 外掛程式服務,並透過 DrmFactory
類別建構支援特定加密配置的對應外掛程式。
IDrmFactory
是與供應商的 DRM HAL 互動的主要進入點,方法是透過 createPlugin
方法。使用這個方法建立 IDrmPlugin
例項。
::ndk::ScopedAStatus getSupportedCryptoSchemes( std::vector<::aidl::android::hardware::drm::Uuid>* _aidl_return);
getSupportedCryptoSchemes
會傳回 AIDL DRM HAL 執行個體支援的加密配置清單。這個序列會決定外掛程式工廠是否可以建構支援指定加密機制的 DRM 外掛程式,該機制由 UUID 指定:
::ndk::ScopedAStatus isCryptoSchemeSupported( const ::aidl::android::hardware::drm::Uuid& in_uuid, const std::string& in_mimeType, ::aidl::android::hardware::drm::SecurityLevel in_securityLevel, bool* _aidl_return);
這個序列會判斷外掛程式工廠是否可以建構支援 mimeType
指定媒體容器格式的 DRM 外掛程式:
::ndk::ScopedAStatus isContentTypeSupported(const std::string& in_mimeType, bool* _aidl_return);
這個序列會為 UUID 指定的加密機制建構 DRM 外掛程式:
::ndk::ScopedAStatus createPlugin( const ::aidl::android::hardware::drm::Uuid& in_uuid, const std::string& in_appPackageName, std::shared_ptr<::aidl::android::hardware::drm::IDrmPlugin>* _aidl_return);
CryptoFactory 類別
CryptoHal
類別會搜尋已註冊的 DRM 外掛程式服務,並透過 CryptoFactory
類別建構支援特定加密配置的對應外掛程式。
這個序列會決定加密編譯工廠是否可建構支援特定加密編譯機制 (由 UUID 指定) 的加密編譯外掛程式:
::ndk::ScopedAStatus isCryptoSchemeSupported( const ::aidl::android::hardware::drm::Uuid& in_uuid, bool* _aidl_return);
這個序列會決定外掛程式工廠是否可以建構支援特定加密編譯機制 (由 UUID 指定) 的加密編譯外掛程式:
::ndk::ScopedAStatus createPlugin( const ::aidl::android::hardware::drm::Uuid& in_uuid, const std::vector<uint8_t>& in_initData, std::shared_ptr<::aidl::android::hardware::drm::ICryptoPlugin>* _aidl_return);
DRM 外掛程式 API
這些 API 定義於hardware/interfaces/drm/aidl/aidl_api/android.hardware.drm/
VERSION/android/hardware/drm/IDrmPlugin.aidl
。建構後,您可以在 out/Soong
中找到對應的 IDrmPlugin.h
檔案。