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