1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #ifndef DRM_API_H_ 18*38e8c45fSAndroid Build Coastguard Worker #define DRM_API_H_ 19*38e8c45fSAndroid Build Coastguard Worker 20*38e8c45fSAndroid Build Coastguard Worker #include <utils/List.h> 21*38e8c45fSAndroid Build Coastguard Worker #include <utils/String8.h> 22*38e8c45fSAndroid Build Coastguard Worker #include <utils/Vector.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <utils/KeyedVector.h> 24*38e8c45fSAndroid Build Coastguard Worker #include <utils/RefBase.h> 25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Mutex.h> 26*38e8c45fSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ABase.h> 27*38e8c45fSAndroid Build Coastguard Worker 28*38e8c45fSAndroid Build Coastguard Worker // Loadable DrmEngine shared libraries should define the entry points 29*38e8c45fSAndroid Build Coastguard Worker // createDrmFactory and createCryptoFactory as shown below: 30*38e8c45fSAndroid Build Coastguard Worker // 31*38e8c45fSAndroid Build Coastguard Worker // extern "C" { 32*38e8c45fSAndroid Build Coastguard Worker // extern android::DrmFactory *createDrmFactory(); 33*38e8c45fSAndroid Build Coastguard Worker // extern android::CryptoFactory *createCryptoFactory(); 34*38e8c45fSAndroid Build Coastguard Worker // } 35*38e8c45fSAndroid Build Coastguard Worker 36*38e8c45fSAndroid Build Coastguard Worker namespace android { 37*38e8c45fSAndroid Build Coastguard Worker 38*38e8c45fSAndroid Build Coastguard Worker class DrmPlugin; 39*38e8c45fSAndroid Build Coastguard Worker class DrmPluginListener; 40*38e8c45fSAndroid Build Coastguard Worker 41*38e8c45fSAndroid Build Coastguard Worker // DRMs are implemented in DrmEngine plugins, which are dynamically 42*38e8c45fSAndroid Build Coastguard Worker // loadable shared libraries that implement the entry points 43*38e8c45fSAndroid Build Coastguard Worker // createDrmFactory and createCryptoFactory. createDrmFactory 44*38e8c45fSAndroid Build Coastguard Worker // constructs and returns an instance of a DrmFactory object. Similarly, 45*38e8c45fSAndroid Build Coastguard Worker // createCryptoFactory creates an instance of a CryptoFactory object. 46*38e8c45fSAndroid Build Coastguard Worker // When a MediaCrypto or MediaDrm object needs to be constructed, all 47*38e8c45fSAndroid Build Coastguard Worker // available DrmEngines present in the plugins directory on the device 48*38e8c45fSAndroid Build Coastguard Worker // are scanned for a matching DrmEngine that can support the crypto 49*38e8c45fSAndroid Build Coastguard Worker // scheme. When a match is found, the DrmEngine's createCryptoPlugin and 50*38e8c45fSAndroid Build Coastguard Worker // createDrmPlugin methods are used to create CryptoPlugin or 51*38e8c45fSAndroid Build Coastguard Worker // DrmPlugin instances to support that DRM scheme. 52*38e8c45fSAndroid Build Coastguard Worker 53*38e8c45fSAndroid Build Coastguard Worker class DrmFactory { 54*38e8c45fSAndroid Build Coastguard Worker public: DrmFactory()55*38e8c45fSAndroid Build Coastguard Worker DrmFactory() {} ~DrmFactory()56*38e8c45fSAndroid Build Coastguard Worker virtual ~DrmFactory() {} 57*38e8c45fSAndroid Build Coastguard Worker 58*38e8c45fSAndroid Build Coastguard Worker // DrmFactory::isCryptoSchemeSupported can be called to determine 59*38e8c45fSAndroid Build Coastguard Worker // if the plugin factory is able to construct plugins that support a 60*38e8c45fSAndroid Build Coastguard Worker // given crypto scheme, which is specified by a UUID. 61*38e8c45fSAndroid Build Coastguard Worker virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; 62*38e8c45fSAndroid Build Coastguard Worker 63*38e8c45fSAndroid Build Coastguard Worker // DrmFactory::isContentTypeSupported can be called to determine 64*38e8c45fSAndroid Build Coastguard Worker // if the plugin factory is able to construct plugins that support a 65*38e8c45fSAndroid Build Coastguard Worker // given media container format specified by mimeType 66*38e8c45fSAndroid Build Coastguard Worker virtual bool isContentTypeSupported(const String8 &mimeType) = 0; 67*38e8c45fSAndroid Build Coastguard Worker 68*38e8c45fSAndroid Build Coastguard Worker // Construct a DrmPlugin for the crypto scheme specified by UUID. 69*38e8c45fSAndroid Build Coastguard Worker virtual status_t createDrmPlugin( 70*38e8c45fSAndroid Build Coastguard Worker const uint8_t uuid[16], DrmPlugin **plugin) = 0; 71*38e8c45fSAndroid Build Coastguard Worker 72*38e8c45fSAndroid Build Coastguard Worker private: 73*38e8c45fSAndroid Build Coastguard Worker DrmFactory(const DrmFactory &); 74*38e8c45fSAndroid Build Coastguard Worker DrmFactory &operator=(const DrmFactory &); 75*38e8c45fSAndroid Build Coastguard Worker }; 76*38e8c45fSAndroid Build Coastguard Worker 77*38e8c45fSAndroid Build Coastguard Worker class DrmPlugin { 78*38e8c45fSAndroid Build Coastguard Worker public: 79*38e8c45fSAndroid Build Coastguard Worker enum EventType { 80*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventProvisionRequired = 1, 81*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventKeyNeeded, 82*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventKeyExpired, 83*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventVendorDefined, 84*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventSessionReclaimed, 85*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventExpirationUpdate, 86*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventKeysChange, 87*38e8c45fSAndroid Build Coastguard Worker kDrmPluginEventSessionLostState, 88*38e8c45fSAndroid Build Coastguard Worker }; 89*38e8c45fSAndroid Build Coastguard Worker 90*38e8c45fSAndroid Build Coastguard Worker // Drm keys can be for offline content or for online streaming. 91*38e8c45fSAndroid Build Coastguard Worker // Offline keys are persisted on the device and may be used when the device 92*38e8c45fSAndroid Build Coastguard Worker // is disconnected from the network. The Release type is used to request 93*38e8c45fSAndroid Build Coastguard Worker // that offline keys be no longer restricted to offline use. 94*38e8c45fSAndroid Build Coastguard Worker enum KeyType { 95*38e8c45fSAndroid Build Coastguard Worker kKeyType_Offline, 96*38e8c45fSAndroid Build Coastguard Worker kKeyType_Streaming, 97*38e8c45fSAndroid Build Coastguard Worker kKeyType_Release 98*38e8c45fSAndroid Build Coastguard Worker }; 99*38e8c45fSAndroid Build Coastguard Worker 100*38e8c45fSAndroid Build Coastguard Worker // Enumerate KeyRequestTypes to allow an app to determine the 101*38e8c45fSAndroid Build Coastguard Worker // type of a key request returned from getKeyRequest. 102*38e8c45fSAndroid Build Coastguard Worker enum KeyRequestType { 103*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_Unknown, 104*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_Initial, 105*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_Renewal, 106*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_Release, 107*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_None, 108*38e8c45fSAndroid Build Coastguard Worker kKeyRequestType_Update, 109*38e8c45fSAndroid Build Coastguard Worker }; 110*38e8c45fSAndroid Build Coastguard Worker 111*38e8c45fSAndroid Build Coastguard Worker // Enumerate KeyStatusTypes which indicate the state of a key 112*38e8c45fSAndroid Build Coastguard Worker enum KeyStatusType 113*38e8c45fSAndroid Build Coastguard Worker { 114*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_Usable, 115*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_Expired, 116*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_OutputNotAllowed, 117*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_StatusPending, 118*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_InternalError, 119*38e8c45fSAndroid Build Coastguard Worker kKeyStatusType_UsableInFuture 120*38e8c45fSAndroid Build Coastguard Worker }; 121*38e8c45fSAndroid Build Coastguard Worker 122*38e8c45fSAndroid Build Coastguard Worker // Used by sendKeysChange to report the usability status of each 123*38e8c45fSAndroid Build Coastguard Worker // key to the app. 124*38e8c45fSAndroid Build Coastguard Worker struct KeyStatus 125*38e8c45fSAndroid Build Coastguard Worker { 126*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> mKeyId; 127*38e8c45fSAndroid Build Coastguard Worker KeyStatusType mType; 128*38e8c45fSAndroid Build Coastguard Worker }; 129*38e8c45fSAndroid Build Coastguard Worker 130*38e8c45fSAndroid Build Coastguard Worker // Enumerate HDCP output protection levels 131*38e8c45fSAndroid Build Coastguard Worker enum HdcpLevel { 132*38e8c45fSAndroid Build Coastguard Worker // Failure to access HDCP level, an error occurred 133*38e8c45fSAndroid Build Coastguard Worker kHdcpLevelUnknown, 134*38e8c45fSAndroid Build Coastguard Worker // HDCP is not supported on this device, content is unprotected 135*38e8c45fSAndroid Build Coastguard Worker kHdcpNone, 136*38e8c45fSAndroid Build Coastguard Worker // HDCP version 1.0 137*38e8c45fSAndroid Build Coastguard Worker kHdcpV1, 138*38e8c45fSAndroid Build Coastguard Worker // HDCP version 2.0 Type 1. 139*38e8c45fSAndroid Build Coastguard Worker kHdcpV2, 140*38e8c45fSAndroid Build Coastguard Worker // HDCP version 2.1 Type 1. 141*38e8c45fSAndroid Build Coastguard Worker kHdcpV2_1, 142*38e8c45fSAndroid Build Coastguard Worker // HDCP version 2.2 Type 1. 143*38e8c45fSAndroid Build Coastguard Worker kHdcpV2_2, 144*38e8c45fSAndroid Build Coastguard Worker // HDCP version 2.3 Type 1. 145*38e8c45fSAndroid Build Coastguard Worker kHdcpV2_3, 146*38e8c45fSAndroid Build Coastguard Worker // No digital output, implicitly secure 147*38e8c45fSAndroid Build Coastguard Worker kHdcpNoOutput = 0x7fff 148*38e8c45fSAndroid Build Coastguard Worker }; 149*38e8c45fSAndroid Build Coastguard Worker 150*38e8c45fSAndroid Build Coastguard Worker // SecurityLevel indicates the level of robustness of the DRM 151*38e8c45fSAndroid Build Coastguard Worker // implementation on the device 152*38e8c45fSAndroid Build Coastguard Worker enum SecurityLevel { 153*38e8c45fSAndroid Build Coastguard Worker // Failure to access security level, an error occurred 154*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelUnknown, 155*38e8c45fSAndroid Build Coastguard Worker // The maximum security level of the device. This is the default when 156*38e8c45fSAndroid Build Coastguard Worker // a session is opened if no security level is specified 157*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelMax, 158*38e8c45fSAndroid Build Coastguard Worker // Software-based whitebox crypto 159*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelSwSecureCrypto, 160*38e8c45fSAndroid Build Coastguard Worker // Software-based whitebox crypto and an obfuscated decoder 161*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelSwSecureDecode, 162*38e8c45fSAndroid Build Coastguard Worker // DRM key management and crypto operations are performed within a 163*38e8c45fSAndroid Build Coastguard Worker // hardware backed trusted execution environment 164*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelHwSecureCrypto, 165*38e8c45fSAndroid Build Coastguard Worker // DRM key management, crypto operations and decoding of content 166*38e8c45fSAndroid Build Coastguard Worker // are performed within a hardware backed trusted execution environment 167*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelHwSecureDecode, 168*38e8c45fSAndroid Build Coastguard Worker // DRM key management, crypto operations, decoding of content and all 169*38e8c45fSAndroid Build Coastguard Worker // handling of the media (compressed and uncompressed) is handled within 170*38e8c45fSAndroid Build Coastguard Worker // a hardware backed trusted execution environment. 171*38e8c45fSAndroid Build Coastguard Worker kSecurityLevelHwSecureAll 172*38e8c45fSAndroid Build Coastguard Worker }; 173*38e8c45fSAndroid Build Coastguard Worker 174*38e8c45fSAndroid Build Coastguard Worker // An offline license may be usable or inactive. The keys in a 175*38e8c45fSAndroid Build Coastguard Worker // usable offline license are available for decryption. When 176*38e8c45fSAndroid Build Coastguard Worker // the offline license state is inactive, the keys have been 177*38e8c45fSAndroid Build Coastguard Worker // marked for release using getKeyRequest with 178*38e8c45fSAndroid Build Coastguard Worker // kKeyType_Release but the key response has not been 179*38e8c45fSAndroid Build Coastguard Worker // received. The keys in an inactive offline license are not 180*38e8c45fSAndroid Build Coastguard Worker // usable for decryption. 181*38e8c45fSAndroid Build Coastguard Worker 182*38e8c45fSAndroid Build Coastguard Worker enum OfflineLicenseState { 183*38e8c45fSAndroid Build Coastguard Worker // The offline license state is unknown due to an error 184*38e8c45fSAndroid Build Coastguard Worker kOfflineLicenseStateUnknown, 185*38e8c45fSAndroid Build Coastguard Worker // Offline license state is usable, the keys may be used for decryption. 186*38e8c45fSAndroid Build Coastguard Worker kOfflineLicenseStateUsable, 187*38e8c45fSAndroid Build Coastguard Worker // Offline license state is released, the keys have been marked for 188*38e8c45fSAndroid Build Coastguard Worker // release using getKeyRequest() with kKeyType_Release but the 189*38e8c45fSAndroid Build Coastguard Worker // key response has not been received. 190*38e8c45fSAndroid Build Coastguard Worker kOfflineLicenseStateReleased 191*38e8c45fSAndroid Build Coastguard Worker }; 192*38e8c45fSAndroid Build Coastguard Worker DrmPlugin()193*38e8c45fSAndroid Build Coastguard Worker DrmPlugin() {} ~DrmPlugin()194*38e8c45fSAndroid Build Coastguard Worker virtual ~DrmPlugin() {} 195*38e8c45fSAndroid Build Coastguard Worker 196*38e8c45fSAndroid Build Coastguard Worker // Open a new session with the DrmPlugin object. A session ID is returned 197*38e8c45fSAndroid Build Coastguard Worker // in the sessionId parameter. 198*38e8c45fSAndroid Build Coastguard Worker virtual status_t openSession(Vector<uint8_t> &sessionId) = 0; 199*38e8c45fSAndroid Build Coastguard Worker 200*38e8c45fSAndroid Build Coastguard Worker // Close a session on the DrmPlugin object. 201*38e8c45fSAndroid Build Coastguard Worker virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0; 202*38e8c45fSAndroid Build Coastguard Worker 203*38e8c45fSAndroid Build Coastguard Worker // A key request/response exchange occurs between the app and a License 204*38e8c45fSAndroid Build Coastguard Worker // Server to obtain the keys required to decrypt the content. getKeyRequest() 205*38e8c45fSAndroid Build Coastguard Worker // is used to obtain an opaque key request blob that is delivered to the 206*38e8c45fSAndroid Build Coastguard Worker // license server. 207*38e8c45fSAndroid Build Coastguard Worker // 208*38e8c45fSAndroid Build Coastguard Worker // The scope parameter may be a sessionId or a keySetId, depending on the 209*38e8c45fSAndroid Build Coastguard Worker // specified keyType. When the keyType is kKeyType_Offline or 210*38e8c45fSAndroid Build Coastguard Worker // kKeyType_Streaming, scope should be set to the sessionId the keys will be 211*38e8c45fSAndroid Build Coastguard Worker // provided to. When the keyType is kKeyType_Release, scope should be set to 212*38e8c45fSAndroid Build Coastguard Worker // the keySetId of the keys being released. Releasing keys from a device 213*38e8c45fSAndroid Build Coastguard Worker // invalidates them for all sessions. 214*38e8c45fSAndroid Build Coastguard Worker // 215*38e8c45fSAndroid Build Coastguard Worker // The init data passed to getKeyRequest is container-specific and its 216*38e8c45fSAndroid Build Coastguard Worker // meaning is interpreted based on the mime type provided in the mimeType 217*38e8c45fSAndroid Build Coastguard Worker // parameter to getKeyRequest. It could contain, for example, the content 218*38e8c45fSAndroid Build Coastguard Worker // ID, key ID or other data obtained from the content metadata that is required 219*38e8c45fSAndroid Build Coastguard Worker // in generating the key request. Init may be null when keyType is 220*38e8c45fSAndroid Build Coastguard Worker // kKeyType_Release. 221*38e8c45fSAndroid Build Coastguard Worker // 222*38e8c45fSAndroid Build Coastguard Worker // mimeType identifies the mime type of the content 223*38e8c45fSAndroid Build Coastguard Worker // 224*38e8c45fSAndroid Build Coastguard Worker // keyType specifies if the keys are to be used for streaming or offline content 225*38e8c45fSAndroid Build Coastguard Worker // 226*38e8c45fSAndroid Build Coastguard Worker // optionalParameters are included in the key request message to allow a 227*38e8c45fSAndroid Build Coastguard Worker // client application to provide additional message parameters to the server. 228*38e8c45fSAndroid Build Coastguard Worker // 229*38e8c45fSAndroid Build Coastguard Worker // If successful, the opaque key request blob is returned to the caller. 230*38e8c45fSAndroid Build Coastguard Worker virtual status_t 231*38e8c45fSAndroid Build Coastguard Worker getKeyRequest(Vector<uint8_t> const &scope, 232*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &initData, 233*38e8c45fSAndroid Build Coastguard Worker String8 const &mimeType, KeyType keyType, 234*38e8c45fSAndroid Build Coastguard Worker KeyedVector<String8, String8> const &optionalParameters, 235*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &request, String8 &defaultUrl, 236*38e8c45fSAndroid Build Coastguard Worker KeyRequestType *keyRequestType) = 0; 237*38e8c45fSAndroid Build Coastguard Worker 238*38e8c45fSAndroid Build Coastguard Worker // 239*38e8c45fSAndroid Build Coastguard Worker // After a key response is received by the app, it is provided to the 240*38e8c45fSAndroid Build Coastguard Worker // Drm plugin using provideKeyResponse. 241*38e8c45fSAndroid Build Coastguard Worker // 242*38e8c45fSAndroid Build Coastguard Worker // scope may be a sessionId or a keySetId depending on the type of the 243*38e8c45fSAndroid Build Coastguard Worker // response. Scope should be set to the sessionId when the response is 244*38e8c45fSAndroid Build Coastguard Worker // for either streaming or offline key requests. Scope should be set to the 245*38e8c45fSAndroid Build Coastguard Worker // keySetId when the response is for a release request. 246*38e8c45fSAndroid Build Coastguard Worker // 247*38e8c45fSAndroid Build Coastguard Worker // When the response is for an offline key request, a keySetId is returned 248*38e8c45fSAndroid Build Coastguard Worker // in the keySetId vector parameter that can be used to later restore the 249*38e8c45fSAndroid Build Coastguard Worker // keys to a new session with the method restoreKeys. When the response is 250*38e8c45fSAndroid Build Coastguard Worker // for a streaming or release request, no keySetId is returned. 251*38e8c45fSAndroid Build Coastguard Worker // 252*38e8c45fSAndroid Build Coastguard Worker virtual status_t provideKeyResponse(Vector<uint8_t> const &scope, 253*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &response, 254*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &keySetId) = 0; 255*38e8c45fSAndroid Build Coastguard Worker 256*38e8c45fSAndroid Build Coastguard Worker // Remove the current keys from a session 257*38e8c45fSAndroid Build Coastguard Worker virtual status_t removeKeys(Vector<uint8_t> const &sessionId) = 0; 258*38e8c45fSAndroid Build Coastguard Worker 259*38e8c45fSAndroid Build Coastguard Worker // Restore persisted offline keys into a new session. keySetId identifies 260*38e8c45fSAndroid Build Coastguard Worker // the keys to load, obtained from a prior call to provideKeyResponse(). 261*38e8c45fSAndroid Build Coastguard Worker virtual status_t restoreKeys(Vector<uint8_t> const &sessionId, 262*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &keySetId) = 0; 263*38e8c45fSAndroid Build Coastguard Worker 264*38e8c45fSAndroid Build Coastguard Worker // Request an informative description of the license for the session. The status 265*38e8c45fSAndroid Build Coastguard Worker // is in the form of {name, value} pairs. Since DRM license policies vary by 266*38e8c45fSAndroid Build Coastguard Worker // vendor, the specific status field names are determined by each DRM vendor. 267*38e8c45fSAndroid Build Coastguard Worker // Refer to your DRM provider documentation for definitions of the field names 268*38e8c45fSAndroid Build Coastguard Worker // for a particular DrmEngine. 269*38e8c45fSAndroid Build Coastguard Worker virtual status_t 270*38e8c45fSAndroid Build Coastguard Worker queryKeyStatus(Vector<uint8_t> const &sessionId, 271*38e8c45fSAndroid Build Coastguard Worker KeyedVector<String8, String8> &infoMap) const = 0; 272*38e8c45fSAndroid Build Coastguard Worker 273*38e8c45fSAndroid Build Coastguard Worker // A provision request/response exchange occurs between the app and a 274*38e8c45fSAndroid Build Coastguard Worker // provisioning server to retrieve a device certificate. getProvisionRequest 275*38e8c45fSAndroid Build Coastguard Worker // is used to obtain an opaque key request blob that is delivered to the 276*38e8c45fSAndroid Build Coastguard Worker // provisioning server. 277*38e8c45fSAndroid Build Coastguard Worker // 278*38e8c45fSAndroid Build Coastguard Worker // If successful, the opaque provision request blob is returned to the caller. 279*38e8c45fSAndroid Build Coastguard Worker virtual status_t getProvisionRequest(String8 const &cert_type, 280*38e8c45fSAndroid Build Coastguard Worker String8 const &cert_authority, 281*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &request, 282*38e8c45fSAndroid Build Coastguard Worker String8 &defaultUrl) = 0; 283*38e8c45fSAndroid Build Coastguard Worker 284*38e8c45fSAndroid Build Coastguard Worker // After a provision response is received by the app, it is provided to the 285*38e8c45fSAndroid Build Coastguard Worker // Drm plugin using provideProvisionResponse. 286*38e8c45fSAndroid Build Coastguard Worker virtual status_t provideProvisionResponse(Vector<uint8_t> const &response, 287*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &certificate, 288*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &wrapped_key) = 0; 289*38e8c45fSAndroid Build Coastguard Worker 290*38e8c45fSAndroid Build Coastguard Worker // A means of enforcing the contractual requirement for a concurrent stream 291*38e8c45fSAndroid Build Coastguard Worker // limit per subscriber across devices is provided via SecureStop. SecureStop 292*38e8c45fSAndroid Build Coastguard Worker // is a means of securely monitoring the lifetime of sessions. Since playback 293*38e8c45fSAndroid Build Coastguard Worker // on a device can be interrupted due to reboot, power failure, etc. a means 294*38e8c45fSAndroid Build Coastguard Worker // of persisting the lifetime information on the device is needed. 295*38e8c45fSAndroid Build Coastguard Worker // 296*38e8c45fSAndroid Build Coastguard Worker // A signed version of the sessionID is written to persistent storage on the 297*38e8c45fSAndroid Build Coastguard Worker // device when each MediaCrypto object is created. The sessionID is signed by 298*38e8c45fSAndroid Build Coastguard Worker // the device private key to prevent tampering. 299*38e8c45fSAndroid Build Coastguard Worker // 300*38e8c45fSAndroid Build Coastguard Worker // In the normal case, playback will be completed, the session destroyed and 301*38e8c45fSAndroid Build Coastguard Worker // the Secure Stops will be queried. The App queries secure stops and forwards 302*38e8c45fSAndroid Build Coastguard Worker // the secure stop message to the server which verifies the signature and 303*38e8c45fSAndroid Build Coastguard Worker // notifies the server side database that the session destruction has been 304*38e8c45fSAndroid Build Coastguard Worker // confirmed. The persisted record on the client is only removed after positive 305*38e8c45fSAndroid Build Coastguard Worker // confirmation that the server received the message using releaseSecureStops(). 306*38e8c45fSAndroid Build Coastguard Worker virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; 307*38e8c45fSAndroid Build Coastguard Worker virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0; 308*38e8c45fSAndroid Build Coastguard Worker virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0; 309*38e8c45fSAndroid Build Coastguard Worker virtual status_t releaseAllSecureStops() = 0; 310*38e8c45fSAndroid Build Coastguard Worker 311*38e8c45fSAndroid Build Coastguard Worker // Read a property value given the device property string. There are a few forms 312*38e8c45fSAndroid Build Coastguard Worker // of property access methods, depending on the data type returned. 313*38e8c45fSAndroid Build Coastguard Worker // Since DRM plugin properties may vary, additional field names may be defined 314*38e8c45fSAndroid Build Coastguard Worker // by each DRM vendor. Refer to your DRM provider documentation for definitions 315*38e8c45fSAndroid Build Coastguard Worker // of its additional field names. 316*38e8c45fSAndroid Build Coastguard Worker // 317*38e8c45fSAndroid Build Coastguard Worker // Standard values are: 318*38e8c45fSAndroid Build Coastguard Worker // "vendor" [string] identifies the maker of the plugin 319*38e8c45fSAndroid Build Coastguard Worker // "version" [string] identifies the version of the plugin 320*38e8c45fSAndroid Build Coastguard Worker // "description" [string] describes the plugin 321*38e8c45fSAndroid Build Coastguard Worker // 'deviceUniqueId' [byte array] The device unique identifier is established 322*38e8c45fSAndroid Build Coastguard Worker // during device provisioning and provides a means of uniquely identifying 323*38e8c45fSAndroid Build Coastguard Worker // each device. 324*38e8c45fSAndroid Build Coastguard Worker virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0; 325*38e8c45fSAndroid Build Coastguard Worker virtual status_t getPropertyByteArray(String8 const &name, 326*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &value ) const = 0; 327*38e8c45fSAndroid Build Coastguard Worker 328*38e8c45fSAndroid Build Coastguard Worker // Write a property value given the device property string. There are a few forms 329*38e8c45fSAndroid Build Coastguard Worker // of property setting methods, depending on the data type. 330*38e8c45fSAndroid Build Coastguard Worker // Since DRM plugin properties may vary, additional field names may be defined 331*38e8c45fSAndroid Build Coastguard Worker // by each DRM vendor. Refer to your DRM provider documentation for definitions 332*38e8c45fSAndroid Build Coastguard Worker // of its field names. 333*38e8c45fSAndroid Build Coastguard Worker virtual status_t setPropertyString(String8 const &name, 334*38e8c45fSAndroid Build Coastguard Worker String8 const &value ) = 0; 335*38e8c45fSAndroid Build Coastguard Worker virtual status_t setPropertyByteArray(String8 const &name, 336*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &value ) = 0; 337*38e8c45fSAndroid Build Coastguard Worker 338*38e8c45fSAndroid Build Coastguard Worker // The following methods implement operations on a CryptoSession to support 339*38e8c45fSAndroid Build Coastguard Worker // encrypt, decrypt, sign verify operations on operator-provided 340*38e8c45fSAndroid Build Coastguard Worker // session keys. 341*38e8c45fSAndroid Build Coastguard Worker 342*38e8c45fSAndroid Build Coastguard Worker // 343*38e8c45fSAndroid Build Coastguard Worker // The algorithm string conforms to JCA Standard Names for Cipher 344*38e8c45fSAndroid Build Coastguard Worker // Transforms and is case insensitive. For example "AES/CBC/PKCS5Padding". 345*38e8c45fSAndroid Build Coastguard Worker // 346*38e8c45fSAndroid Build Coastguard Worker // Return OK if the algorithm is supported, otherwise return BAD_VALUE 347*38e8c45fSAndroid Build Coastguard Worker // 348*38e8c45fSAndroid Build Coastguard Worker virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, 349*38e8c45fSAndroid Build Coastguard Worker String8 const &algorithm) = 0; 350*38e8c45fSAndroid Build Coastguard Worker 351*38e8c45fSAndroid Build Coastguard Worker // 352*38e8c45fSAndroid Build Coastguard Worker // The algorithm string conforms to JCA Standard Names for Mac 353*38e8c45fSAndroid Build Coastguard Worker // Algorithms and is case insensitive. For example "HmacSHA256". 354*38e8c45fSAndroid Build Coastguard Worker // 355*38e8c45fSAndroid Build Coastguard Worker // Return OK if the algorithm is supported, otherwise return BAD_VALUE 356*38e8c45fSAndroid Build Coastguard Worker // 357*38e8c45fSAndroid Build Coastguard Worker virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, 358*38e8c45fSAndroid Build Coastguard Worker String8 const &algorithm) = 0; 359*38e8c45fSAndroid Build Coastguard Worker 360*38e8c45fSAndroid Build Coastguard Worker // Encrypt the provided input buffer with the cipher algorithm 361*38e8c45fSAndroid Build Coastguard Worker // specified by setCipherAlgorithm and the key selected by keyId, 362*38e8c45fSAndroid Build Coastguard Worker // and return the encrypted data. 363*38e8c45fSAndroid Build Coastguard Worker virtual status_t encrypt(Vector<uint8_t> const &sessionId, 364*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &keyId, 365*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &input, 366*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &iv, 367*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &output) = 0; 368*38e8c45fSAndroid Build Coastguard Worker 369*38e8c45fSAndroid Build Coastguard Worker // Decrypt the provided input buffer with the cipher algorithm 370*38e8c45fSAndroid Build Coastguard Worker // specified by setCipherAlgorithm and the key selected by keyId, 371*38e8c45fSAndroid Build Coastguard Worker // and return the decrypted data. 372*38e8c45fSAndroid Build Coastguard Worker virtual status_t decrypt(Vector<uint8_t> const &sessionId, 373*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &keyId, 374*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &input, 375*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &iv, 376*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &output) = 0; 377*38e8c45fSAndroid Build Coastguard Worker 378*38e8c45fSAndroid Build Coastguard Worker // Compute a signature on the provided message using the mac algorithm 379*38e8c45fSAndroid Build Coastguard Worker // specified by setMacAlgorithm and the key selected by keyId, 380*38e8c45fSAndroid Build Coastguard Worker // and return the signature. 381*38e8c45fSAndroid Build Coastguard Worker virtual status_t sign(Vector<uint8_t> const &sessionId, 382*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &keyId, 383*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &message, 384*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &signature) = 0; 385*38e8c45fSAndroid Build Coastguard Worker 386*38e8c45fSAndroid Build Coastguard Worker // Compute a signature on the provided message using the mac algorithm 387*38e8c45fSAndroid Build Coastguard Worker // specified by setMacAlgorithm and the key selected by keyId, 388*38e8c45fSAndroid Build Coastguard Worker // and compare with the expected result. Set result to true or 389*38e8c45fSAndroid Build Coastguard Worker // false depending on the outcome. 390*38e8c45fSAndroid Build Coastguard Worker virtual status_t verify(Vector<uint8_t> const &sessionId, 391*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &keyId, 392*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &message, 393*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &signature, 394*38e8c45fSAndroid Build Coastguard Worker bool &match) = 0; 395*38e8c45fSAndroid Build Coastguard Worker 396*38e8c45fSAndroid Build Coastguard Worker 397*38e8c45fSAndroid Build Coastguard Worker // Compute an RSA signature on the provided message using the algorithm 398*38e8c45fSAndroid Build Coastguard Worker // specified by algorithm. 399*38e8c45fSAndroid Build Coastguard Worker virtual status_t signRSA(Vector<uint8_t> const &sessionId, 400*38e8c45fSAndroid Build Coastguard Worker String8 const &algorithm, 401*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &message, 402*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const &wrapped_key, 403*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> &signature) = 0; 404*38e8c45fSAndroid Build Coastguard Worker 405*38e8c45fSAndroid Build Coastguard Worker setListener(const sp<DrmPluginListener> & listener)406*38e8c45fSAndroid Build Coastguard Worker status_t setListener(const sp<DrmPluginListener>& listener) { 407*38e8c45fSAndroid Build Coastguard Worker Mutex::Autolock lock(mEventLock); 408*38e8c45fSAndroid Build Coastguard Worker mListener = listener; 409*38e8c45fSAndroid Build Coastguard Worker return OK; 410*38e8c45fSAndroid Build Coastguard Worker } 411*38e8c45fSAndroid Build Coastguard Worker 412*38e8c45fSAndroid Build Coastguard Worker protected: 413*38e8c45fSAndroid Build Coastguard Worker // Plugins call these methods to deliver events to the java app 414*38e8c45fSAndroid Build Coastguard Worker void sendEvent(EventType eventType, int extra, 415*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *sessionId, 416*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *data); 417*38e8c45fSAndroid Build Coastguard Worker 418*38e8c45fSAndroid Build Coastguard Worker void sendExpirationUpdate(Vector<uint8_t> const *sessionId, 419*38e8c45fSAndroid Build Coastguard Worker int64_t expiryTimeInMS); 420*38e8c45fSAndroid Build Coastguard Worker 421*38e8c45fSAndroid Build Coastguard Worker void sendKeysChange(Vector<uint8_t> const *sessionId, 422*38e8c45fSAndroid Build Coastguard Worker Vector<DrmPlugin::KeyStatus> const *keyStatusList, 423*38e8c45fSAndroid Build Coastguard Worker bool hasNewUsableKey); 424*38e8c45fSAndroid Build Coastguard Worker 425*38e8c45fSAndroid Build Coastguard Worker private: 426*38e8c45fSAndroid Build Coastguard Worker Mutex mEventLock; 427*38e8c45fSAndroid Build Coastguard Worker sp<DrmPluginListener> mListener; 428*38e8c45fSAndroid Build Coastguard Worker 429*38e8c45fSAndroid Build Coastguard Worker DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin); 430*38e8c45fSAndroid Build Coastguard Worker }; 431*38e8c45fSAndroid Build Coastguard Worker 432*38e8c45fSAndroid Build Coastguard Worker class DrmPluginListener: virtual public RefBase 433*38e8c45fSAndroid Build Coastguard Worker { 434*38e8c45fSAndroid Build Coastguard Worker public: 435*38e8c45fSAndroid Build Coastguard Worker virtual void sendEvent(DrmPlugin::EventType eventType, int extra, 436*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *sessionId, 437*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *data) = 0; 438*38e8c45fSAndroid Build Coastguard Worker 439*38e8c45fSAndroid Build Coastguard Worker virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId, 440*38e8c45fSAndroid Build Coastguard Worker int64_t expiryTimeInMS) = 0; 441*38e8c45fSAndroid Build Coastguard Worker 442*38e8c45fSAndroid Build Coastguard Worker virtual void sendKeysChange(Vector<uint8_t> const *sessionId, 443*38e8c45fSAndroid Build Coastguard Worker Vector<DrmPlugin::KeyStatus> const *keyStatusList, 444*38e8c45fSAndroid Build Coastguard Worker bool hasNewUsableKey) = 0; 445*38e8c45fSAndroid Build Coastguard Worker }; 446*38e8c45fSAndroid Build Coastguard Worker sendEvent(EventType eventType,int extra,Vector<uint8_t> const * sessionId,Vector<uint8_t> const * data)447*38e8c45fSAndroid Build Coastguard Worker inline void DrmPlugin::sendEvent(EventType eventType, int extra, 448*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *sessionId, 449*38e8c45fSAndroid Build Coastguard Worker Vector<uint8_t> const *data) { 450*38e8c45fSAndroid Build Coastguard Worker mEventLock.lock(); 451*38e8c45fSAndroid Build Coastguard Worker sp<DrmPluginListener> listener = mListener; 452*38e8c45fSAndroid Build Coastguard Worker mEventLock.unlock(); 453*38e8c45fSAndroid Build Coastguard Worker 454*38e8c45fSAndroid Build Coastguard Worker if (listener != NULL) { 455*38e8c45fSAndroid Build Coastguard Worker listener->sendEvent(eventType, extra, sessionId, data); 456*38e8c45fSAndroid Build Coastguard Worker } 457*38e8c45fSAndroid Build Coastguard Worker } 458*38e8c45fSAndroid Build Coastguard Worker sendExpirationUpdate(Vector<uint8_t> const * sessionId,int64_t expiryTimeInMS)459*38e8c45fSAndroid Build Coastguard Worker inline void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId, 460*38e8c45fSAndroid Build Coastguard Worker int64_t expiryTimeInMS) { 461*38e8c45fSAndroid Build Coastguard Worker mEventLock.lock(); 462*38e8c45fSAndroid Build Coastguard Worker sp<DrmPluginListener> listener = mListener; 463*38e8c45fSAndroid Build Coastguard Worker mEventLock.unlock(); 464*38e8c45fSAndroid Build Coastguard Worker 465*38e8c45fSAndroid Build Coastguard Worker if (listener != NULL) { 466*38e8c45fSAndroid Build Coastguard Worker listener->sendExpirationUpdate(sessionId, expiryTimeInMS); 467*38e8c45fSAndroid Build Coastguard Worker } 468*38e8c45fSAndroid Build Coastguard Worker } 469*38e8c45fSAndroid Build Coastguard Worker sendKeysChange(Vector<uint8_t> const * sessionId,Vector<DrmPlugin::KeyStatus> const * keyStatusList,bool hasNewUsableKey)470*38e8c45fSAndroid Build Coastguard Worker inline void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId, 471*38e8c45fSAndroid Build Coastguard Worker Vector<DrmPlugin::KeyStatus> const *keyStatusList, 472*38e8c45fSAndroid Build Coastguard Worker bool hasNewUsableKey) { 473*38e8c45fSAndroid Build Coastguard Worker mEventLock.lock(); 474*38e8c45fSAndroid Build Coastguard Worker sp<DrmPluginListener> listener = mListener; 475*38e8c45fSAndroid Build Coastguard Worker mEventLock.unlock(); 476*38e8c45fSAndroid Build Coastguard Worker 477*38e8c45fSAndroid Build Coastguard Worker if (listener != NULL) { 478*38e8c45fSAndroid Build Coastguard Worker listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); 479*38e8c45fSAndroid Build Coastguard Worker } 480*38e8c45fSAndroid Build Coastguard Worker } 481*38e8c45fSAndroid Build Coastguard Worker } // namespace android 482*38e8c45fSAndroid Build Coastguard Worker 483*38e8c45fSAndroid Build Coastguard Worker #endif // DRM_API_H_ 484