Custom Extensions to MediaDrm
Properties and vendor extensions used by Widevine.
Why extensions exist
The MediaDrm API is intentionally generic — it can speak to Widevine, PlayReady, ClearKey, or anything else with a registered UUID. To expose Widevine-specific knobs without polluting the generic API, Widevine uses two MediaDrm escape hatches:
- Property strings / byte arrays via
getPropertyString/getPropertyByteArray(and their setters). - Vendor-defined events via
EVENT_VENDOR_DEFINED.
Useful property strings
String version = drm.getPropertyString("version");
String vendor = drm.getPropertyString("vendor");
String description= drm.getPropertyString("description");
String secLevel = drm.getPropertyString("securityLevel"); // "L1" | "L3"
String algorithms = drm.getPropertyString("algorithms");
byte[] devId = drm.getPropertyByteArray("deviceUniqueId");
These are pure introspection — useful for:
- Diagnostics dashboards ("we have N L1 devices, M L3 devices").
- Conditional UX (don't offer 4K download to L3).
- Bug reports (always log
version,securityLevel,vendor).
Setting properties
A few properties are settable. The ones that matter most:
// Per-origin provisioning (Provisioning 3.0)
drm.setPropertyString("origin", "https://premium.example.com");
// Some Widevine-specific service flags (vendor docs cover the exact set)
drm.setPropertyString("privacyMode", "enable");
Setting origin before opening any session enables per-origin device certificates. This is how Provisioning 3.0 isolates apps / origins from each other on the same device.
The origin property is the Android-side knob for per-origin provisioning. Set it before openSession; otherwise the CDM uses the default device-wide certificate.
Vendor events
EVENT_VENDOR_DEFINED lets the CDM emit Widevine-specific events not covered by the generic enum. Real-world examples include "rights have been revoked" and "secure stop required" notifications. Most apps ignore them; integrators with specific compliance requirements may need to handle them.
Compatibility caveats
Property strings vary across:
- OEMCrypto versions.
- Android versions (some properties were added in API 28+).
- Vendor implementations.
Always wrap calls in try/catch:
try {
securityLevel = drm.getPropertyString("securityLevel");
} catch (Exception e) {
securityLevel = "unknown";
}
Properties to log on every session
If you want one diagnostic line per playback that solves 80% of support tickets:
WV vendor=Google version=15.0.0 securityLevel=L1 oemcrypto=18.0
That single line captures most of what reviewers ask when a viewer reports a problem.