Determine the DRM security level with the Encrypted Media Extensions

In the previous blog post I explained why the security level of a DRM system has a crucial influence on the type of content any device is allowed to play. In order to check the underlying security level in a browser based environment, the Encrypted Media Extensions (EME) provides the required function. However, it can be a little bit tricky to find the right settings. When I first tried to determine if a Chrome browser on Android supports L1 security I had to check multiple combinations of codecs, robustnessLevel and settings like persistentState and distinctiveIdentifier. Providing only a single unsupported attribute to the EME requestMediaKeySystemAccess() call will result in a rejected promise. For instance, setting 

distinctiveIdentifier: 'required'

will most likely fail on desktop browsers, regardless if the rest of the configuration is supported. 

In order to programmatically search for the maximum available security level a small test page can save a lot of time. Such a test page is accessible here. The app iterates through all possible settings and outputs the results for both content types (audio and video) in a compact form. Moreover, the outcome of each individual check is listed in a detailed table. It is important to note, that the app only checks if the promise returned by the requestMediaKeySystemAccess() function is resolved or rejected. It does not compare the actual configuration returned as part of the promise. For instance a configuration like

const config = [
  {
    "initDataTypes": [
      "cenc"
    ],
    "persistentState": "optional",
    "distinctiveIdentifier": "optional",
    "sessionTypes": [
      "temporary"
    ],
    "audioCapabilities": [
      {
        "robustness": "SW_SECURE_CRYPTO",
        "contentType": "audio/mp4;codecs=\"mp4a.40.2\""
      }
    ],
    "videoCapabilities": [
      {
        "robustness": "SW_SECURE_CRYPTO",
        "contentType": "video/mp4;codecs=\"avc1.42E01E\""
      }
    ]
  }
]

might be resolved to

const config = [
  {
    "initDataTypes": [
      "cenc"
    ],
    "persistentState": "required",
    "distinctiveIdentifier": "not-allowed",
    "sessionTypes": [
      "temporary"
    ],
    "audioCapabilities": [
      {
        "robustness": "SW_SECURE_CRYPTO",
        "contentType": "audio/mp4;codecs=\"mp4a.40.2\""
      }
    ],
    "videoCapabilities": [
      {
        "robustness": "SW_SECURE_CRYPTO",
        "contentType": "video/mp4;codecs=\"avc1.42E01E\""
      }
    ]
  }
]

in which the persistentState and the distinctiveIdentifier are different from the provided input data. 

Using this testpage we found out that Android devices will resolve a video robustnessLevel equivalent to a hardware DRM only when no audio configuration is provided.