Abstract
DRM is one factor affecting quality of online video streaming. In case that DRM system recognizes that a device is secured, high quality movie is streamed. In other case, low quality movie is provided or streaming is denied.
Ultimately, this quality depends on platformers operating DRM license server. Even if an application as DRM Info*1 indicates Widevine L1, it is not constantly guaranteed. As explained later, security level may be demoted someday by a platformer.
This post introduces Kotlin code for Android to probe such DRM security information for Android. Inserted codes are partly quoted from entire code. And entire code is attached at the end of this post.
And an outcome of this code is "DRM review", the Android application retrieving DRM and HDCP information. lease refer to the next post if you are interested.
impsbl.hatenablog.jp
DRM (Digital Rights Management) and Widevine for content protection
Security in DRM is for content protection. It prevents from piracy, and protect revenue of content providers. Specifically, it is a mechanism consist of content player including software and hardware with encryption for
- Cannot copy
- Cannot record
- Cannot capture
This is not only for smartphone, but also entire environment including it. Example, watching movie streamed to smartphone connecting with TV or projector. DRM works for this entire environment.
Even if smartphone is Widevine L1, security level of entire environment including other devices may be lower, example Widevine L2. Actually, some products indicate restriction from such circumstance.
Can't mirror Netflix and other similar streaming apps on iOS devices due to copyright limits
ETOE E2 FHD projector (A1191)etoeofficial.com
In DRM system, license server is a key. Quality or availability of streaming completely depends on its licensing.
And in case of Widevine, security level not constantly guaranteed. Higher level devices may be demoted later. Actually, this operation is in place now.
qiita.com
Probe DRM security level
Although method and constant value to get security level as Widevine L1 are provided, they are deprecated at API level 29~30 (Android 10~11).
How to determine if Android device is security Level 1 or Level 3 - Widevine Help
MediaDrm.SecurityLevel | Android Developers
Even though these method and constant still works to support older API level for covering wider versions of Android, someday security level may not be directly output. At that time, it may need to be educed with smaller granular outputs. Example,
HDCP | High bandwidth Digital Content Protection path to final output device |
Encryption scheme | DRM key management content encryption and decoding |
MediaDrm*2 class is utilized to probe them at following levels.
Protection system | Google Widevine Microsoft PlayReady Apple FairPlay etc |
Content type | MP4 WebM etc |
Encryption scheme | hardware-base software-base |
Although MediaDrm class can probe HDCP information, it is not covered in this post. It is discussed at the next post.
DRM review Ver 1.1 - DRM (Widevine)、HDCPなどの情報を表示するAndroidアプリ - Technically Impossible
Protection system level
Protection system means DRM protection system as Widevine, Microsoft PlayReady*3 and Apple FiarPlay*4. And their plug-in are installed to a smartphone and web browser. Their information is probed with corresponding UUID. Next code is its sample.
FYI, information as Widevine L1 is output at this level.
🔎Probe supported DRM system and its properties
val systemInfo = listOf( UUID.fromString(getString(R.string.uuid_widevine)), UUID.fromString(getString(R.string.uuid_playready)), UUID.fromString(getString(R.string.uuid_fairplay)) ) var myOutput = "" systemInfo.map { sys_key -> sys_key to MediaDrm.isCryptoSchemeSupported(sys_key) }.forEach { (sys_key, sys_val) -> myOutput += "----- status - protection system level\n" myOutput += "$sys_key \t $sys_val\n" if (sys_val){ myOutput += outputSystemLevelStatus(sys_key) myOutput += outputContentLevelStatus(sys_key) } } binding.txtHello.text = myOutput
private fun outputSystemLevelStatus(myUuid: UUID):String{ val mediaDrmInfo = listOf( MediaDrm.PROPERTY_DESCRIPTION, MediaDrm.PROPERTY_VERSION, MediaDrm.PROPERTY_VENDOR, MediaDrm.PROPERTY_ALGORITHMS, "securityLevel" ) val myMediaDrm = MediaDrm(myUuid) var myOutput = "" mediaDrmInfo.map { md_key -> md_key to myMediaDrm.getPropertyString(md_key) }.forEach { (md_key, md_val) -> myOutput += "$md_key \t $md_val\n" } return myOutput }
UUID of DRM protection system is listed at the site below.
dashif.org
If plugin corresonding provided UUID is installed, its properties are output. Images at the top of this post, its first half shows these information. Emulator on Android Studio has Google Widevine CDM Version 15, and security level of emulator is L3. Information at content type level introduced next paragraph supports this result.
Content type level
🔎Encryption and decoding in content type
private fun outputContentLevelStatus(myUuid: UUID):String{ val mimeInfo = listOf( getString(R.string.mime_mp4), getString(R.string.mime_webm) ) val securityLevelInfo = listOf( MediaDrm.SECURITY_LEVEL_UNKNOWN, MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO, MediaDrm.SECURITY_LEVEL_SW_SECURE_DECODE, MediaDrm.SECURITY_LEVEL_HW_SECURE_CRYPTO, MediaDrm.SECURITY_LEVEL_HW_SECURE_DECODE, MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL ) var myOutput = "----- status - content type level\n" mimeInfo.map { mime_key -> mime_key to MediaDrm.isCryptoSchemeSupported(myUuid, mime_key) }.forEach { (mime_key, mime_val) -> myOutput += "$mime_key \t $mime_val\n" if (mime_val){ securityLevelInfo.map { sl_key -> sl_key to MediaDrm.isCryptoSchemeSupported(myUuid, mime_key, sl_key) }.forEach { (sl_key, sl_val) -> myOutput += "$sl_key \t $sl_val\n" } } } return myOutput }
MIME type is listed at the following sites.
www.iana.org
developer.mozilla.org
developer.mozilla.org
If content type corresponding provided MIME type is supported, its security level is output. The image at the top of this post, its last half shows these information. Returned values as 0~5 corresponds following information.
0 | MediaDrm.SECURITY_LEVEL_UNKNOWN |
1 | MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO |
2 | MediaDrm.SECURITY_LEVEL_SW_SECURE_DECODE |
3 | MediaDrm.SECURITY_LEVEL_HW_SECURE_CRYPTO |
4 | MediaDrm.SECURITY_LEVEL_HW_SECURE_DECODE |
5 | MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL |
Emulator supports only encryption and decoding at software-based. This result leads to the result as Widevine L3.
Real devices shows different results. Both Microsoft Surface Duo and Nokia 8 Sirocco are defined as Widevine L1. Widevine CDM in Surface Duo is newer so that its OS is Android 12L. Although Nokia has common DRM with emulator, it is defined as Widevine L1.
"SECURITY_LEVEL_HW_SECURE_ALL" means all requierments are satisfied, which means regardless of encryption and decoding based on software or hardware, the output that this result is true leads to the result as Widevine L1.
Surface Duo | Nokia 8 Sirocco |
---|---|
Reference
Code