275 lines
13 KiB
HTML
275 lines
13 KiB
HTML
<html devsite>
|
|
<head>
|
|
<title>DRM</title>
|
|
<meta name="project_path" value="/_project.yaml" />
|
|
<meta name="book_path" value="/_book.yaml" />
|
|
</head>
|
|
<body>
|
|
<!--
|
|
Copyright 2017 The Android Open Source Project
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
|
|
|
|
<img style="float: right; margin: 0px 15px 15px 15px;" src="images/ape_fwk_hal_drm.png" alt="Android DRM HAL icon"/>
|
|
|
|
<p>This document provides an overview of the Android DRM framework, and
|
|
introduces the interfaces a DRM plug-in must implement. This document does not
|
|
describe robustness rules or compliance rules that may be defined by a DRM
|
|
scheme.</p>
|
|
|
|
<h2 id="introduction">Introduction</h2>
|
|
|
|
<p>The Android platform provides an extensible DRM framework that lets
|
|
applications manage rights-protected content according to the license
|
|
constraints associated with the content. The DRM framework supports many DRM
|
|
schemes; which DRM schemes a device supports is up to the device manufacturer.
|
|
The DRM framework introduced in Android 3.0 provides a unified interface for
|
|
application developers and hides the complexity of DRM operations. The DRM
|
|
framework provides a consistent operation mode for protected and non-protected
|
|
content. DRM schemes can define very complex usage models by license metadata.
|
|
The DRM framework provides the association between DRM content and license, and
|
|
handles the rights management. This enables the media player to be abstracted
|
|
from DRM-protected or non-protected content. See <a
|
|
href="https://developer.android.com/reference/android/media/MediaDrm.html">MediaDrm</a>
|
|
for the class to obtain keys for decrypting protected media streams.</p>
|
|
|
|
<img src="/devices/images/ape_fwk_drm.png" alt="Android DRM HAL" />
|
|
|
|
<p class="img-caption"><strong>Figure 1.</strong> DRM Hardware Abstraction
|
|
Layer</p>
|
|
|
|
<p>
|
|
Availability of rich digital content is important to users on mobile devices. To
|
|
make their content widely available, Android developers and digital content
|
|
publishers need a consistent DRM implementation supported across the Android
|
|
ecosystem. To make that digital content available on Android devices and to ensure at least one consistent DRM available across all
|
|
devices, Google provides DRM without license fees on compatible Android devices.
|
|
On Android 3.0 and higher platforms, the DRM plug-in is integrated with the
|
|
Android DRM framework and can use hardware-backed protection to secure premium
|
|
content and user credentials.
|
|
</p>
|
|
|
|
<p>
|
|
The content protection provided by the DRM plug-in depends on the security and
|
|
content protection capabilities of the underlying hardware platform. The
|
|
hardware capabilities of the device include hardware secure boot to establish a
|
|
chain of trust of security and protection of cryptographic keys. Content
|
|
protection capabilities of the device include protection of decrypted frames in
|
|
the device and content protection via a trusted output protection mechanism. Not
|
|
all hardware platforms support all of the above security and content protection
|
|
features. Security is never implemented in a single place in the
|
|
stack, but instead relies on the integration of hardware, software, and
|
|
services. The combination of hardware security functions, a trusted boot
|
|
mechanism, and an isolated secure OS for handling security functions is critical
|
|
to providing a secure device.</p>
|
|
|
|
|
|
<h2 id="architecture">Architecture</h2>
|
|
<p>The DRM framework is designed to be implementation agnostic and
|
|
abstracts the details of the specific DRM scheme implementation in a
|
|
scheme-specific DRM plug-in. The DRM framework includes simple APIs to handle
|
|
complex DRM operations, register users and devices to online DRM services,
|
|
extract constraint information from the license, associate DRM content and its
|
|
license, and finally decrypt DRM content.</p>
|
|
|
|
<p>The Android DRM framework is implemented in two architectural layers:</p>
|
|
<ul>
|
|
<li>A DRM framework API, which is exposed to applications through the Android
|
|
application framework and runs through the Dalvik VM for standard
|
|
applications.</li>
|
|
<li>A native code DRM manager, which implements the DRM framework and exposes an
|
|
interface for DRM plug-ins (agents) to handle rights management and decryption
|
|
for various DRM schemes.</li>
|
|
</ul>
|
|
|
|
<img src="images/ape_fwk_drm_2.png" alt="Android DRM Framework" />
|
|
|
|
<p class="img-caption"><strong>Figure 2.</strong> DRM framework</p>
|
|
|
|
<p>For details, refer to the <a
|
|
href="http://developer.android.com/reference/android/drm/package-summary.html">Android
|
|
DRM package reference</a>.</p>
|
|
|
|
<h2 id="plug-ins">Plug-ins</h2>
|
|
<p>As shown in the figure below, the DRM framework uses a plug-in architecture
|
|
to support various DRM schemes. The DRM manager service runs in an independent
|
|
process to ensure isolated execution of DRM plug-ins. Each API call from
|
|
DrmManagerClient to DrmManagerService goes across process boundaries by using
|
|
the binder IPC mechanism. The DrmManagerClient provides a Java programming
|
|
language implementation as a common interface to runtime applications; it
|
|
also provides a DrmManagerClient-native implementation as the interface to
|
|
native modules. The caller of DRM framework accesses only the DrmManagerClient
|
|
and does not have to be aware of each DRM scheme. </p>
|
|
|
|
<img src="images/ape_fwk_drm_plugins.png" alt="Android DRM Plug-in" />
|
|
|
|
<p class="img-caption"><strong>Figure 3.</strong> DRM framework with plug-ins</p>
|
|
|
|
<p>Plug-ins are loaded automatically when DrmManagerService is launched. As
|
|
shown in the figure below, the DRM plug-in manager loads/unloads all the
|
|
available plug-ins. The DRM framework loads plug-ins automatically by finding
|
|
them under:</p>
|
|
<pre class="devsite-click-to-copy">
|
|
/system/lib/drm/plugins/native/
|
|
</pre>
|
|
|
|
<img src="images/ape_fwk_drm_plugins_life.png" alt="Android DRM Plug-in Lifecycle" />
|
|
|
|
<p class="img-caption"><strong>Figure 4.</strong> DRM plug-in lifecycle</p>
|
|
|
|
<p>The plug-in developer should ensure the plug-in is located in the DRM
|
|
framework plug-in discovery directory. See implementation instructions below for details.</p>
|
|
|
|
<h2 id="implementation">Implementation</h2>
|
|
|
|
<h3 id="IDrmEngine">IDrmEngine</h3>
|
|
|
|
<p>IDrmEngine is an interface with a set of APIs for DRM use cases. Plug-in
|
|
developers must implement the interfaces specified in IDrmEngine and the
|
|
listener interfaces specified below. The interface definition is available in
|
|
the source tree at:<p/>
|
|
<pre class="devsite-click-to-copy">
|
|
<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/common/include
|
|
</pre>
|
|
|
|
<h3 id="DrmInfo">DRM Info</h3>
|
|
<p>DrmInfo is a wrapper class that wraps the protocol for communicating with the
|
|
DRM server. Server registration, deregistration, license acquisition, or any other
|
|
server-related transaction can be achieved by processing an instance of DrmInfo.
|
|
The protocol should be described by the plug-in in XML format. Each DRM plug-in
|
|
would accomplish the transaction by interpreting the protocol. The DRM framework
|
|
defines an API to retrieve an instance of DrmInfo called acquireDrmInfo().</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
|
|
</pre>
|
|
<p>Retrieves necessary information for registration, deregistration or rights
|
|
acquisition information. See <a
|
|
href="http://developer.android.com/reference/android/drm/DrmInfoRequest.html">DrmInfoRequest</a> for more information.</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
|
|
</pre>
|
|
<p>processDrmInfo() behaves asynchronously and the results of the transaction can
|
|
be retrieved either from OnEventListener or OnErrorListener.</p>
|
|
|
|
<h3 id="drm-rights">DRM rights</h3>
|
|
|
|
<p>The association of DRM content and the license is required to allow playback
|
|
of DRM content. Once the association has been made, the license will be handled in
|
|
the DRM framework so the Media Player application is abstracted from the existence
|
|
of license.</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
int checkRightsStatus(int uniqueId, const String8& path, int action);
|
|
</pre>
|
|
|
|
<p>Check whether the given content has valid rights or not. The input
|
|
parameters are the content file path where the content was saved and the action
|
|
to query rights for, for example: Action::DEFAULT, Action::PLAY. Returns the
|
|
status of the rights for the protected content, such as
|
|
RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED.</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
status_t saveRights(int uniqueId, const DrmRights& drmRights, const String8& rightsPath, const String8& contentPath);
|
|
</pre>
|
|
|
|
<p>Save DRM rights to the specified rights path and make association with content path.
|
|
The input parameters are the DrmRights to be saved, the rights file path where rights
|
|
are to be saved, and the content file path where content was saved.</p>
|
|
|
|
<h3 id="metadata">License Metadata</h3>
|
|
<p>License metadata such as license expiry time, repeatable count and etc., may be
|
|
embedded inside the rights of the protected content. The Android DRM framework
|
|
provides APIs to return constraints associated with input content. See <a
|
|
href="http://developer.android.com/reference/android/drm/DrmManagerClient.html">DrmManagerClient</a>
|
|
for more information.</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
DrmConstraints* getConstraints(int uniqueId, const String path, int
|
|
action);
|
|
</pre>
|
|
<p>The getConstraint function call returns key-value pairs of constraints
|
|
embedded in protected content. To retrieve the constraints, the uniqueIds (the
|
|
Unique identifier for a session and path of the protected content) are required.
|
|
The action, defined as Action::DEFAULT, Action::PLAY, etc., is also required.</p>
|
|
|
|
<img src="images/ape_fwk_drm_retrieve_license.png" alt="Android DRM License Metadata" />
|
|
|
|
<p class="img-caption"><strong>Figure 5.</strong> Retrieve license metadata</p>
|
|
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
DrmMetadata* getMetadata(int uniqueId, const String path);
|
|
</pre>
|
|
<p>Get metadata information associated with input content for a given path of the
|
|
protected content to return key-value pairs of metadata.</p>
|
|
|
|
<h3 id="metadata">Decrypt session</h3>
|
|
<p>To maintain the decryption session, the caller of the DRM framework must
|
|
invoke openDecryptSession() at the beginning of the decryption sequence.
|
|
openDecryptSession() asks each DRM plug-in if it can handle input DRM
|
|
content.</p>
|
|
<pre class="devsite-click-to-copy prettyprint">
|
|
status_t openDecryptSession(
|
|
int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length);
|
|
</pre>
|
|
|
|
<p>The above call allows you to save DRM rights to specified rights path and make
|
|
association with content path. DrmRights parameter is the rights to be saved,
|
|
file path where rights should be and content file path where content should be
|
|
saved.</p>
|
|
|
|
<h3 id="listeners">DRM plug-in Listeners</h3>
|
|
|
|
<p>Some APIs in DRM framework behave asynchronously in a DRM transaction. An
|
|
application can register three listener classes to DRM framework.</p>
|
|
|
|
<ul>
|
|
<li>OnEventListener for results of asynchronous APIs</li>
|
|
<li>OnErrorListener for receiving errors of asynchronous APIs</li>
|
|
<li>OnInfoListener for any supplementary information during DRM
|
|
transactions.</li>
|
|
</ul>
|
|
|
|
<h3 id="source">Source</h3>
|
|
|
|
<p>The Android DRM framework includes a couple of samples, a passthru plug-in
|
|
and a forward lock plug-in, which can be found at:</p>
|
|
<pre class="devsite-click-to-copy">
|
|
<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/passthru
|
|
<var>PLATFORM_ROOT</var>/frameworks/av/drm/libdrmframework/plugins/forward-lock
|
|
</pre>
|
|
|
|
<h3 id="build">Build and Integration</h3>
|
|
|
|
<p>Add the following to the Android.mk of the plug-in implementation. The
|
|
passthruplugin is used as a sample.</p>
|
|
|
|
<pre class="devsite-click-to-copy">
|
|
PRODUCT_COPY_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/<var>PLUGIN_LIBRARY</var>:system/lib/drm/plugins/native/<var>PLUGIN_LIBRARY</var>
|
|
</pre>
|
|
<p>e.g.,</p>
|
|
<pre class="devsite-click-to-copy">
|
|
PRODUCT_COPY_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libdrmpassthruplugin.so:system/lib/drm/plugins/native/libdrmpassthruplugin.so
|
|
</pre>
|
|
<p>Plug-in developers must locate their respective plug-ins under this
|
|
directory like so:</p>
|
|
<pre class="devsite-click-to-copy">
|
|
/system/lib/drm/plugins/native/libdrmpassthruplugin.so
|
|
</pre>
|
|
|
|
</body>
|
|
</html>
|