1bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker/*
256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * Copyright (C) 2013 The Android Open Source Project
356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker *
456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * you may not use this file except in compliance with the License.
656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * You may obtain a copy of the License at
756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker *
856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker *
1056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * Unless required by applicable law or agreed to in writing, software
1156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
1256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * See the License for the specific language governing permissions and
1456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker * limitations under the License.
1556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker */
1656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
1756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#ifndef DRM_API_H_
1856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#define DRM_API_H_
1956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
2056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <utils/List.h>
2156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <utils/String8.h>
2256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <utils/Vector.h>
2356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <utils/KeyedVector.h>
2456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <utils/RefBase.h>
257eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker#include <utils/Mutex.h>
2656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#include <media/stagefright/foundation/ABase.h>
2756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
2856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//  Loadable DrmEngine shared libraries should define the entry points
2956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//  createDrmFactory and createCryptoFactory as shown below:
3056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//
3156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//  extern "C" {
3256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//      extern android::DrmFactory *createDrmFactory();
3356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//      extern android::CryptoFactory *createCryptoFactory();
3456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker//  }
3556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
3656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinkernamespace android {
3756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
387eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    class DrmPlugin;
397eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    class DrmPluginListener;
4056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
4156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // DRMs are implemented in DrmEngine plugins, which are dynamically
4256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // loadable shared libraries that implement the entry points
4356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // createDrmFactory and createCryptoFactory.  createDrmFactory
4456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // constructs and returns an instance of a DrmFactory object.  Similarly,
4556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // createCryptoFactory creates an instance of a CryptoFactory object.
4656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // When a MediaCrypto or MediaDrm object needs to be constructed, all
4756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // available DrmEngines present in the plugins directory on the device
4856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // are scanned for a matching DrmEngine that can support the crypto
4956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // scheme.  When a match is found, the DrmEngine's createCryptoPlugin and
5056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // createDrmPlugin methods are used to create CryptoPlugin or
5156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    // DrmPlugin instances to support that DRM scheme.
5256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
5356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    class DrmFactory {
5456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    public:
5556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        DrmFactory() {}
5656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual ~DrmFactory() {}
5756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
5856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // DrmFactory::isCryptoSchemeSupported can be called to determine
5956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // if the plugin factory is able to construct plugins that support a
6056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // given crypto scheme, which is specified by a UUID.
6156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0;
6256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
63611d3d481605049c8ca77f27131282993f448664Jeff Tinker        // DrmFactory::isContentTypeSupported can be called to determine
64611d3d481605049c8ca77f27131282993f448664Jeff Tinker        // if the plugin factory is able to construct plugins that support a
65611d3d481605049c8ca77f27131282993f448664Jeff Tinker        // given media container format specified by mimeType
66611d3d481605049c8ca77f27131282993f448664Jeff Tinker        virtual bool isContentTypeSupported(const String8 &mimeType) = 0;
67611d3d481605049c8ca77f27131282993f448664Jeff Tinker
6856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Construct a DrmPlugin for the crypto scheme specified by UUID.
6956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t createDrmPlugin(
7056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker                const uint8_t uuid[16], DrmPlugin **plugin) = 0;
7156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
7256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    private:
7356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        DrmFactory(const DrmFactory &);
7456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        DrmFactory &operator=(const DrmFactory &);
7556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    };
7656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
7756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    class DrmPlugin {
7856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    public:
7956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        enum EventType {
807eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker            kDrmPluginEventProvisionRequired = 1,
81bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker            kDrmPluginEventKeyNeeded,
82bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker            kDrmPluginEventKeyExpired,
8346722ff44a979c4674c5668189f631d8f77929fdRonghua Wu            kDrmPluginEventVendorDefined,
849a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kDrmPluginEventSessionReclaimed,
859a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kDrmPluginEventExpirationUpdate,
869a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kDrmPluginEventKeysChange,
8756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        };
8856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
89bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Drm keys can be for offline content or for online streaming.
90bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Offline keys are persisted on the device and may be used when the device
91b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // is disconnected from the network.  The Release type is used to request
92b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // that offline keys be no longer restricted to offline use.
93bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        enum KeyType {
94bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker            kKeyType_Offline,
95b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker            kKeyType_Streaming,
96b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker            kKeyType_Release
9756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        };
9856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
9906a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker        // Enumerate KeyRequestTypes to allow an app to determine the
10006a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker        // type of a key request returned from getKeyRequest.
10106a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker        enum KeyRequestType {
10206a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker            kKeyRequestType_Unknown,
10306a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker            kKeyRequestType_Initial,
10406a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker            kKeyRequestType_Renewal,
10506a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker            kKeyRequestType_Release
10606a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker        };
10706a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker
1089a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        // Enumerate KeyStatusTypes which indicate the state of a key
1099a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        enum KeyStatusType
1109a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        {
1119a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kKeyStatusType_Usable,
1129a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kKeyStatusType_Expired,
1139a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kKeyStatusType_OutputNotAllowed,
1149a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kKeyStatusType_StatusPending,
1159a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            kKeyStatusType_InternalError
1169a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        };
1179a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
1189a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        // Used by sendKeysChange to report the usability status of each
1199a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        // key to the app.
1209a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        struct KeyStatus
1219a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        {
1229a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            Vector<uint8_t> mKeyId;
1239a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            KeyStatusType mType;
1249a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        };
1259a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
12656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        DrmPlugin() {}
12756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual ~DrmPlugin() {}
12856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
12956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Open a new session with the DrmPlugin object.  A session ID is returned
13056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // in the sessionId parameter.
13156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t openSession(Vector<uint8_t> &sessionId) = 0;
13256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
13356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Close a session on the DrmPlugin object.
13456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
13556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
136bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // A key request/response exchange occurs between the app and a License
137bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Server to obtain the keys required to decrypt the content.  getKeyRequest()
138bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // is used to obtain an opaque key request blob that is delivered to the
13956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // license server.
14056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
141b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // The scope parameter may be a sessionId or a keySetId, depending on the
142b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // specified keyType.  When the keyType is kKeyType_Offline or
143b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // kKeyType_Streaming, scope should be set to the sessionId the keys will be
144b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // provided to.  When the keyType is kKeyType_Release, scope should be set to
145b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // the keySetId of the keys being released.  Releasing keys from a device
146b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // invalidates them for all sessions.
147b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
148bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // The init data passed to getKeyRequest is container-specific and its
14956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // meaning is interpreted based on the mime type provided in the mimeType
150bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // parameter to getKeyRequest.  It could contain, for example, the content
15156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // ID, key ID or other data obtained from the content metadata that is required
152b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // in generating the key request.  Init may be null when keyType is
153b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // kKeyType_Release.
154b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
155b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // mimeType identifies the mime type of the content
15656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
157b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // keyType specifies if the keys are to be used for streaming or offline content
15856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
159bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // optionalParameters are included in the key request message to allow a
160bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // client application to provide additional message parameters to the server.
16156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
162bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // If successful, the opaque key request blob is returned to the caller.
16356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t
164b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker            getKeyRequest(Vector<uint8_t> const &scope,
165bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                          Vector<uint8_t> const &initData,
166bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                          String8 const &mimeType, KeyType keyType,
167bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                          KeyedVector<String8, String8> const &optionalParameters,
16806a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker                          Vector<uint8_t> &request, String8 &defaultUrl,
16906a8cd6d19a20843d137f7e65f4c81da685c291eJeff Tinker                          KeyRequestType *keyRequestType) = 0;
17056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
171b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
172bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // After a key response is received by the app, it is provided to the
173b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // Drm plugin using provideKeyResponse.
174b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
175b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // scope may be a sessionId or a keySetId depending on the type of the
176b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // response.  Scope should be set to the sessionId when the response is
177b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // for either streaming or offline key requests.  Scope should be set to the
178b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // keySetId when the response is for a release request.
179b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
180b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // When the response is for an offline key request, a keySetId is returned
181b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // in the keySetId vector parameter that can be used to later restore the
182b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // keys to a new session with the method restoreKeys. When the response is
183b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // for a streaming or release request, no keySetId is returned.
184b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        //
185b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        virtual status_t provideKeyResponse(Vector<uint8_t> const &scope,
186bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                            Vector<uint8_t> const &response,
187bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                            Vector<uint8_t> &keySetId) = 0;
18856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
189b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        // Remove the current keys from a session
190b84d1cad1d481f75aa03d55ac07e4ff58dbfb84aJeff Tinker        virtual status_t removeKeys(Vector<uint8_t> const &sessionId) = 0;
191bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
192bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Restore persisted offline keys into a new session.  keySetId identifies
193bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // the keys to load, obtained from a prior call to provideKeyResponse().
194bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
195bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                     Vector<uint8_t> const &keySetId) = 0;
19656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
19756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Request an informative description of the license for the session.  The status
19856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // is in the form of {name, value} pairs.  Since DRM license policies vary by
19956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // vendor, the specific status field names are determined by each DRM vendor.
20056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Refer to your DRM provider documentation for definitions of the field names
20156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // for a particular DrmEngine.
20256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t
203bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker            queryKeyStatus(Vector<uint8_t> const &sessionId,
204bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                           KeyedVector<String8, String8> &infoMap) const = 0;
20556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
20656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // A provision request/response exchange occurs between the app and a
20756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // provisioning server to retrieve a device certificate.  getProvisionRequest
208bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // is used to obtain an opaque key request blob that is delivered to the
20956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // provisioning server.
21056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
21156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // If successful, the opaque provision request blob is returned to the caller.
212c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker        virtual status_t getProvisionRequest(String8 const &cert_type,
213c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                             String8 const &cert_authority,
214c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                             Vector<uint8_t> &request,
21556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker                                             String8 &defaultUrl) = 0;
21656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
21756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // After a provision response is received by the app, it is provided to the
21856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Drm plugin using provideProvisionResponse.
219c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker        virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
220c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                                  Vector<uint8_t> &certificate,
221c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                                  Vector<uint8_t> &wrapped_key) = 0;
22256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
22356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // A means of enforcing the contractual requirement for a concurrent stream
22456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // limit per subscriber across devices is provided via SecureStop.  SecureStop
22556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // is a means of securely monitoring the lifetime of sessions. Since playback
22656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // on a device can be interrupted due to reboot, power failure, etc. a means
22756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // of persisting the lifetime information on the device is needed.
22856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
22956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // A signed version of the sessionID is written to persistent storage on the
23056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // device when each MediaCrypto object is created. The sessionID is signed by
23156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // the device private key to prevent tampering.
23256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
23356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // In the normal case, playback will be completed, the session destroyed and
23456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // the Secure Stops will be queried. The App queries secure stops and forwards
23556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // the secure stop message to the server which verifies the signature and
23656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // notifies the server side database that the session destruction has been
23756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // confirmed. The persisted record on the client is only removed after positive
23856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // confirmation that the server received the message using releaseSecureStops().
23956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
24057481590b98518865e266004e7ca4737abd5508dJeff Tinker        virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
24156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
24257481590b98518865e266004e7ca4737abd5508dJeff Tinker        virtual status_t releaseAllSecureStops() = 0;
24356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
24456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Read a property value given the device property string.  There are a few forms
24556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // of property access methods, depending on the data type returned.
24656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Since DRM plugin properties may vary, additional field names may be defined
24756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // by each DRM vendor.  Refer to your DRM provider documentation for definitions
24856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // of its additional field names.
24956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //
25056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Standard values are:
25156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   "vendor" [string] identifies the maker of the plugin
25256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   "version" [string] identifies the version of the plugin
25356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   "description" [string] describes the plugin
25456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   'deviceUniqueId' [byte array] The device unique identifier is established
25556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   during device provisioning and provides a means of uniquely identifying
25656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        //   each device.
25756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0;
25856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t getPropertyByteArray(String8 const &name,
25956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker                                              Vector<uint8_t> &value ) const = 0;
26056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
26156c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Write  a property value given the device property string.  There are a few forms
26256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // of property setting methods, depending on the data type.
26356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // Since DRM plugin properties may vary, additional field names may be defined
26456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // by each DRM vendor.  Refer to your DRM provider documentation for definitions
26556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        // of its field names.
26656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t setPropertyString(String8 const &name,
26756c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker                                           String8 const &value ) = 0;
26856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        virtual status_t setPropertyByteArray(String8 const &name,
26956c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker                                              Vector<uint8_t> const &value ) = 0;
27056c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
271bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // The following methods implement operations on a CryptoSession to support
272bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // encrypt, decrypt, sign verify operations on operator-provided
273bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // session keys.
274bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
275bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
276bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // The algorithm string conforms to JCA Standard Names for Cipher
277bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Transforms and is case insensitive.  For example "AES/CBC/PKCS5Padding".
278bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
279bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Return OK if the algorithm is supported, otherwise return BAD_VALUE
280bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
281bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
282bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                            String8 const &algorithm) = 0;
283bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
284bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
285bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // The algorithm string conforms to JCA Standard Names for Mac
286bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Algorithms and is case insensitive.  For example "HmacSHA256".
287bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
288bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Return OK if the algorithm is supported, otherwise return BAD_VALUE
289bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        //
290bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
291bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                         String8 const &algorithm) = 0;
292bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
293bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Encrypt the provided input buffer with the cipher algorithm
294bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // specified by setCipherAlgorithm and the key selected by keyId,
295bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // and return the encrypted data.
296bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t encrypt(Vector<uint8_t> const &sessionId,
297bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &keyId,
298bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &input,
299bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &iv,
300bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> &output) = 0;
301bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
302bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Decrypt the provided input buffer with the cipher algorithm
303bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // specified by setCipherAlgorithm and the key selected by keyId,
304bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // and return the decrypted data.
305bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t decrypt(Vector<uint8_t> const &sessionId,
306bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &keyId,
307bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &input,
308bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> const &iv,
309bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                 Vector<uint8_t> &output) = 0;
310bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
311bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Compute a signature on the provided message using the mac algorithm
312bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // specified by setMacAlgorithm and the key selected by keyId,
313bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // and return the signature.
314bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t sign(Vector<uint8_t> const &sessionId,
315bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                              Vector<uint8_t> const &keyId,
316bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                              Vector<uint8_t> const &message,
317bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                              Vector<uint8_t> &signature) = 0;
318bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
319bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // Compute a signature on the provided message using the mac algorithm
320bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // specified by setMacAlgorithm and the key selected by keyId,
321bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // and compare with the expected result.  Set result to true or
322bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        // false depending on the outcome.
323bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker        virtual status_t verify(Vector<uint8_t> const &sessionId,
324bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                Vector<uint8_t> const &keyId,
325bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                Vector<uint8_t> const &message,
326bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                Vector<uint8_t> const &signature,
327bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker                                bool &match) = 0;
328bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
329bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
330c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker        // Compute an RSA signature on the provided message using the algorithm
331c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker        // specified by algorithm.
332c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker        virtual status_t signRSA(Vector<uint8_t> const &sessionId,
333c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                 String8 const &algorithm,
334c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                 Vector<uint8_t> const &message,
335c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                 Vector<uint8_t> const &wrapped_key,
336c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker                                 Vector<uint8_t> &signature) = 0;
337c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker
338c2f10f20ec9be98f363d6739ba1552955efe6532Jeff Tinker
3397eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        status_t setListener(const sp<DrmPluginListener>& listener) {
3407eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker            Mutex::Autolock lock(mEventLock);
3417eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker            mListener = listener;
3427eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker            return OK;
3437eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        }
3447eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker
3457eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    protected:
3469a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        // Plugins call these methods to deliver events to the java app
3477eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        void sendEvent(EventType eventType, int extra,
3487eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker                       Vector<uint8_t> const *sessionId,
3497eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker                       Vector<uint8_t> const *data);
350bcbd78bd246f1e68e44b4a6d6257dbfcec8e65b3Jeff Tinker
3519a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
3529a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                  int64_t expiryTimeInMS);
3539a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
3549a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        void sendKeysChange(Vector<uint8_t> const *sessionId,
3559a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                            Vector<DrmPlugin::KeyStatus> const *keyStatusList,
3569a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                            bool hasNewUsableKey);
3579a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
35856c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    private:
3597eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        Mutex mEventLock;
3607eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        sp<DrmPluginListener> mListener;
3617eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker
36256c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker        DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin);
36356c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker    };
36456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
3657eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    class DrmPluginListener: virtual public RefBase
3667eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    {
3677eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    public:
3687eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        virtual void sendEvent(DrmPlugin::EventType eventType, int extra,
3699a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                               Vector<uint8_t> const *sessionId,
3707eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker                               Vector<uint8_t> const *data) = 0;
3719a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
3729a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
3739a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                          int64_t expiryTimeInMS) = 0;
3749a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
3759a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
3769a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                    Vector<DrmPlugin::KeyStatus> const *keyStatusList,
3779a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                    bool hasNewUsableKey) = 0;
3787eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    };
3797eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker
3807eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    inline void DrmPlugin::sendEvent(EventType eventType, int extra,
3817eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker                                     Vector<uint8_t> const *sessionId,
3827eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker                                     Vector<uint8_t> const *data) {
3837eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        mEventLock.lock();
3847eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        sp<DrmPluginListener> listener = mListener;
3857eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        mEventLock.unlock();
3867eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker
3877eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        if (listener != NULL) {
3887eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker            listener->sendEvent(eventType, extra, sessionId, data);
3897eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker        }
3907eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker    }
3917eafcae5ffb7f6f12ee573dea685dc6989a0ee91Jeff Tinker
3929a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker    inline void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
3939a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                                int64_t expiryTimeInMS) {
3949a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        mEventLock.lock();
3959a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        sp<DrmPluginListener> listener = mListener;
3969a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        mEventLock.unlock();
3979a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
3989a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        if (listener != NULL) {
3999a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            listener->sendExpirationUpdate(sessionId, expiryTimeInMS);
4009a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        }
4019a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker    }
4029a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
4039a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker    inline void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,
4049a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                          Vector<DrmPlugin::KeyStatus> const *keyStatusList,
4059a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker                                          bool hasNewUsableKey) {
4069a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        mEventLock.lock();
4079a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        sp<DrmPluginListener> listener = mListener;
4089a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        mEventLock.unlock();
4099a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker
4109a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        if (listener != NULL) {
4119a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker            listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
4129a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker        }
4139a498ef11566a5ae82c24b0651c58280309dfd04Jeff Tinker    }
41456c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker}  // namespace android
41556c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker
41656c78c47d8c22621a8a23375d8a6c63d99a9335dJeff Tinker#endif // DRM_API_H_
417