1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __DRM_ENGINE_BASE_H__
18 #define __DRM_ENGINE_BASE_H__
19 
20 #include <drm/drm_framework_common.h>
21 #include "IDrmEngine.h"
22 
23 namespace android {
24 
25 /**
26  * This class is an interface for plug-in developers
27  *
28  * Responsibility of this class is control the sequence of actual plug-in.
29  * All each plug-in developer has to do is implement onXXX() type virtual interfaces.
30  */
31 class DrmEngineBase : public IDrmEngine {
32 public:
33     DrmEngineBase();
34     virtual ~DrmEngineBase();
35 
36 public:
37     DrmConstraints* getConstraints(int uniqueId, const String8* path, int action);
38 
39     DrmMetadata* getMetadata(int uniqueId, const String8* path);
40 
41     status_t initialize(int uniqueId);
42 
43     status_t setOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener);
44 
45     status_t terminate(int uniqueId);
46 
47     bool canHandle(int uniqueId, const String8& path);
48 
49     DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
50 
51     status_t saveRights(int uniqueId, const DrmRights& drmRights,
52             const String8& rightsPath, const String8& contentPath);
53 
54     DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
55 
56     String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
57 
58     int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
59 
60     int checkRightsStatus(int uniqueId, const String8& path, int action);
61 
62     status_t consumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle, int action,
63             bool reserve);
64 
65     status_t setPlaybackStatus(
66             int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus, int64_t position);
67 
68     bool validateAction(
69             int uniqueId, const String8& path, int action, const ActionDescription& description);
70 
71     status_t removeRights(int uniqueId, const String8& path);
72 
73     status_t removeAllRights(int uniqueId);
74 
75     status_t openConvertSession(int uniqueId, int convertId);
76 
77     DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
78 
79     DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
80 
81     DrmSupportInfo* getSupportInfo(int uniqueId);
82 
83     status_t openDecryptSession(
84             int uniqueId, sp<DecryptHandle>& decryptHandle,
85             int fd, off64_t offset, off64_t length, const char* mime);
86 
87     status_t openDecryptSession(
88             int uniqueId, sp<DecryptHandle>& decryptHandle,
89             const char* uri, const char* mime);
90 
91     status_t openDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle,
92             const DrmBuffer& buf, const String8& mimeType);
93 
94     status_t closeDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle);
95 
96     status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
97             int decryptUnitId, const DrmBuffer* headerInfo);
98 
99     status_t decrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
100             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
101 
102     status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
103             int decryptUnitId);
104 
105     ssize_t pread(int uniqueId, sp<DecryptHandle>& decryptHandle,
106             void* buffer, ssize_t numBytes, off64_t offset);
107 
108 protected:
109     /////////////////////////////////////////////////////
110     // Interface for plug-in developers                //
111     // each plug-in has to implement following method  //
112     /////////////////////////////////////////////////////
113     /**
114      * Get constraint information associated with input content
115      *
116      * @param[in] uniqueId Unique identifier for a session
117      * @param[in] path Path of the protected content
118      * @param[in] action Actions defined such as,
119      *     Action::DEFAULT, Action::PLAY, etc
120      * @return DrmConstraints
121      *     key-value pairs of constraint are embedded in it
122      * @note
123      *     In case of error, return NULL
124      */
125     virtual DrmConstraints* onGetConstraints(
126             int uniqueId, const String8* path, int action) = 0;
127 
128     /**
129      * Get metadata information associated with input content
130      *
131      * @param[in] uniqueId Unique identifier for a session
132      * @param[in] path Path of the protected content
133      * @return DrmMetadata
134      *         key-value pairs of metadata
135      * @note
136      *     In case of error, return NULL
137      */
138     virtual DrmMetadata* onGetMetadata(int uniqueId, const String8* path) = 0;
139 
140     /**
141      * Initialize plug-in
142      *
143      * @param[in] uniqueId Unique identifier for a session
144      * @return status_t
145      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
146      */
147     virtual status_t onInitialize(int uniqueId) = 0;
148 
149     /**
150      * Register a callback to be invoked when the caller required to
151      * receive necessary information
152      *
153      * @param[in] uniqueId Unique identifier for a session. uniqueId is a random
154      *                     number generated in the DRM service. If the DrmManagerClient
155      *                     is created in native code, uniqueId will be a number ranged
156      *                     from 0x1000 to 0x1fff. If it comes from Java code, the uniqueId
157      *                     will be a number ranged from 0x00 to 0xfff. So bit 0x1000 in
158      *                     uniqueId could be used in DRM plugins to differentiate native
159      *                     OnInfoListener and Java OnInfoListener.
160      * @param[in] infoListener Listener
161      * @return status_t
162      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
163      */
164     virtual status_t onSetOnInfoListener(
165             int uniqueId, const IDrmEngine::OnInfoListener* infoListener) = 0;
166 
167     /**
168      * Terminate the plug-in
169      * and release resource bound to plug-in
170      *
171      * @param[in] uniqueId Unique identifier for a session
172      * @return status_t
173      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
174      */
175     virtual status_t onTerminate(int uniqueId) = 0;
176 
177     /**
178      * Get whether the given content can be handled by this plugin or not
179      *
180      * @param[in] uniqueId Unique identifier for a session
181      * @param[in] path Path the protected object
182      * @return bool
183      *     Returns true if this plugin can handle , false in case of not able to handle
184      */
185     virtual bool onCanHandle(int uniqueId, const String8& path) = 0;
186 
187     /**
188      * Executes given drm information based on its type
189      *
190      * @param[in] uniqueId Unique identifier for a session
191      * @param[in] drmInfo Information needs to be processed
192      * @return DrmInfoStatus
193      *     instance as a result of processing given input
194      */
195     virtual DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0;
196 
197     /**
198      * Save DRM rights to specified rights path
199      * and make association with content path
200      *
201      * @param[in] uniqueId Unique identifier for a session
202      * @param[in] drmRights DrmRights to be saved
203      * @param[in] rightsPath File path where rights to be saved
204      * @param[in] contentPath File path where content was saved
205      * @return status_t
206      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
207      */
208     virtual status_t onSaveRights(int uniqueId, const DrmRights& drmRights,
209             const String8& rightspath, const String8& contentPath) = 0;
210 
211     /**
212      * Retrieves necessary information for registration, unregistration or rights
213      * acquisition information.
214      *
215      * @param[in] uniqueId Unique identifier for a session
216      * @param[in] drmInfoRequest Request information to retrieve drmInfo
217      * @return DrmInfo
218      *     instance as a result of processing given input
219      */
220     virtual DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) = 0;
221 
222     /**
223      * Retrieves the mime type embedded inside the original content
224      *
225      * @param[in] uniqueId Unique identifier for a session
226      * @param[in] path Path of the protected content
227      * @param[in] fd descriptor of the protected content as a file source
228      * @return String8
229      *     Returns mime-type of the original content, such as "video/mpeg"
230      */
231     virtual String8 onGetOriginalMimeType(int uniqueId, const String8& path, int fd) = 0;
232 
233     /**
234      * Retrieves the type of the protected object (content, rights, etc..)
235      * using specified path or mimetype. At least one parameter should be non null
236      * to retrieve DRM object type
237      *
238      * @param[in] uniqueId Unique identifier for a session
239      * @param[in] path Path of the content or null.
240      * @param[in] mimeType Mime type of the content or null.
241      * @return type of the DRM content,
242      *     such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT
243      */
244     virtual int onGetDrmObjectType(
245             int uniqueId, const String8& path, const String8& mimeType) = 0;
246 
247     /**
248      * Check whether the given content has valid rights or not
249      *
250      * @param[in] uniqueId Unique identifier for a session
251      * @param[in] path Path of the protected content
252      * @param[in] action Action to perform (Action::DEFAULT, Action::PLAY, etc)
253      * @return the status of the rights for the protected content,
254      *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
255      */
256     virtual int onCheckRightsStatus(int uniqueId, const String8& path, int action) = 0;
257 
258     /**
259      * Consumes the rights for a content.
260      * If the reserve parameter is true the rights is reserved until the same
261      * application calls this api again with the reserve parameter set to false.
262      *
263      * @param[in] uniqueId Unique identifier for a session
264      * @param[in] decryptHandle Handle for the decryption session
265      * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
266      * @param[in] reserve True if the rights should be reserved.
267      * @return status_t
268      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
269      */
270     virtual status_t onConsumeRights(int uniqueId, sp<DecryptHandle>& decryptHandle,
271             int action, bool reserve) = 0;
272 
273     /**
274      * Informs the DRM Engine about the playback actions performed on the DRM files.
275      *
276      * @param[in] uniqueId Unique identifier for a session
277      * @param[in] decryptHandle Handle for the decryption session
278      * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
279      * @param[in] position Position in the file (in milliseconds) where the start occurs.
280      *     Only valid together with Playback::START.
281      * @return status_t
282      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
283      */
284     virtual status_t onSetPlaybackStatus(
285             int uniqueId, sp<DecryptHandle>& decryptHandle, int playbackStatus,
286             int64_t position) = 0;
287 
288     /**
289      * Validates whether an action on the DRM content is allowed or not.
290      *
291      * @param[in] uniqueId Unique identifier for a session
292      * @param[in] path Path of the protected content
293      * @param[in] action Action to validate (Action::PLAY, Action::TRANSFER, etc)
294      * @param[in] description Detailed description of the action
295      * @return true if the action is allowed.
296      */
297     virtual bool onValidateAction(int uniqueId, const String8& path,
298             int action, const ActionDescription& description) = 0;
299 
300     /**
301      * Removes the rights associated with the given protected content
302      *
303      * @param[in] uniqueId Unique identifier for a session
304      * @param[in] path Path of the protected content
305      * @return status_t
306      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
307      */
308     virtual status_t onRemoveRights(int uniqueId, const String8& path) = 0;
309 
310     /**
311      * Removes all the rights information of each plug-in associated with
312      * DRM framework. Will be used in master reset
313      *
314      * @param[in] uniqueId Unique identifier for a session
315      * @return status_t
316      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
317      */
318     virtual status_t onRemoveAllRights(int uniqueId) = 0;
319 
320     /**
321      * This API is for Forward Lock based DRM scheme.
322      * Each time the application tries to download a new DRM file
323      * which needs to be converted, then the application has to
324      * begin with calling this API.
325      *
326      * @param[in] uniqueId Unique identifier for a session
327      * @param[in] convertId Handle for the convert session
328      * @return status_t
329      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
330      */
331     virtual status_t onOpenConvertSession(int uniqueId, int convertId) = 0;
332 
333     /**
334      * Accepts and converts the input data which is part of DRM file.
335      * The resultant converted data and the status is returned in the DrmConvertedInfo
336      * object. This method will be called each time there are new block
337      * of data received by the application.
338      *
339      * @param[in] uniqueId Unique identifier for a session
340      * @param[in] convertId Handle for the convert session
341      * @param[in] inputData Input Data which need to be converted
342      * @return Return object contains the status of the data conversion,
343      *     the output converted data and offset. In this case the
344      *     application will ignore the offset information.
345      */
346     virtual DrmConvertedStatus* onConvertData(
347             int uniqueId, int convertId, const DrmBuffer* inputData) = 0;
348 
349     /**
350      * Informs the Drm Agent when there is no more data which need to be converted
351      * or when an error occurs. Upon successful conversion of the complete data,
352      * the agent will inform that where the header and body signature
353      * should be added. This signature appending is needed to integrity
354      * protect the converted file.
355      *
356      * @param[in] uniqueId Unique identifier for a session
357      * @param[in] convertId Handle for the convert session
358      * @return Return object contains the status of the data conversion,
359      *     the header and body signature data. It also informs
360      *     the application on which offset these signature data
361      *     should be appended.
362      */
363     virtual DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId) = 0;
364 
365     /**
366      * Returns the information about the Drm Engine capabilities which includes
367      * supported MimeTypes and file suffixes.
368      *
369      * @param[in] uniqueId Unique identifier for a session
370      * @return DrmSupportInfo
371      *     instance which holds the capabilities of a plug-in
372      */
373     virtual DrmSupportInfo* onGetSupportInfo(int uniqueId) = 0;
374 
375     /**
376      * Open the decrypt session to decrypt the given protected content
377      *
378      * @param[in] uniqueId Unique identifier for a session
379      * @param[in] decryptHandle Handle for the current decryption session
380      * @param[in] fd File descriptor of the protected content to be decrypted
381      * @param[in] offset Start position of the content
382      * @param[in] length The length of the protected content
383      * @return
384      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
385      */
386     virtual status_t onOpenDecryptSession(
387             int uniqueId, sp<DecryptHandle>& decryptHandle,
388             int fd, off64_t offset, off64_t length) = 0;
389 
390     /**
391      * Open the decrypt session to decrypt the given protected content
392      *
393      * @param[in] uniqueId Unique identifier for a session
394      * @param[in] decryptHandle Handle for the current decryption session
395      * @param[in] fd File descriptor of the protected content to be decrypted
396      * @param[in] offset Start position of the content
397      * @param[in] length The length of the protected content
398      * @param[in] mime Mime type of the protected content
399      *     drm plugin may do some optimization since the mime type is known.
400      * @return
401      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
402      */
onOpenDecryptSession(int,sp<DecryptHandle> &,int,off64_t,off64_t,const char *)403     virtual status_t onOpenDecryptSession(
404             int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
405             int /* fd */, off64_t /* offset */, off64_t /* length */,
406             const char* /* mime */) {
407 
408         return DRM_ERROR_CANNOT_HANDLE;
409     }
410 
411     /**
412      * Open the decrypt session to decrypt the given protected content
413      *
414      * @param[in] uniqueId Unique identifier for a session
415      * @param[in] decryptHandle Handle for the current decryption session
416      * @param[in] uri Path of the protected content to be decrypted
417      * @return
418      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
419      */
420     virtual status_t onOpenDecryptSession(
421             int uniqueId, sp<DecryptHandle>& decryptHandle,
422             const char* uri) = 0;
423 
424     /**
425      * Open the decrypt session to decrypt the given protected content
426      *
427      * @param[in] uniqueId Unique identifier for a session
428      * @param[in] decryptHandle Handle for the current decryption session
429      * @param[in] uri Path of the protected content to be decrypted
430      * @param[in] mime Mime type of the protected content. The corresponding
431      *     drm plugin may do some optimization since the mime type is known.
432      * @return
433      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
434      */
onOpenDecryptSession(int,sp<DecryptHandle> &,const char *,const char *)435     virtual status_t onOpenDecryptSession(
436             int /* uniqueId */, sp<DecryptHandle>& /* decryptHandle */,
437             const char* /* uri */, const char* /* mime */) {
438 
439         return DRM_ERROR_CANNOT_HANDLE;
440     }
441 
442     /**
443      * Open the decrypt session to decrypt the given protected content
444      *
445      * @param[in] uniqueId Unique identifier for a session
446      * @param[in] decryptHandle Handle for the current decryption session
447      * @param[in] buf Data to initiate decrypt session
448      * @param[in] mimeType Mime type of the protected content
449      * @return
450      *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
451      */
onOpenDecryptSession(int,sp<DecryptHandle> &,const DrmBuffer &,const String8 &)452     virtual status_t onOpenDecryptSession(int /* uniqueId */,
453             sp<DecryptHandle>& /* decryptHandle */,
454             const DrmBuffer& /* buf */,
455             const String8& /* mimeType */) {
456         return DRM_ERROR_CANNOT_HANDLE;
457     }
458 
459     /**
460      * Close the decrypt session for the given handle
461      *
462      * @param[in] uniqueId Unique identifier for a session
463      * @param[in] decryptHandle Handle for the decryption session
464      * @return status_t
465      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
466      */
467     virtual status_t onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) = 0;
468 
469     /**
470      * Initialize decryption for the given unit of the protected content
471      *
472      * @param[in] uniqueId Unique identifier for a session
473      * @param[in] decryptId Handle for the decryption session
474      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
475      * @param[in] headerInfo Information for initializing decryption of this decrypUnit
476      * @return status_t
477      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
478      */
479     virtual status_t onInitializeDecryptUnit(int uniqueId, sp<DecryptHandle>& decryptHandle,
480             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
481 
482     /**
483      * Decrypt the protected content buffers for the given unit
484      * This method will be called any number of times, based on number of
485      * encrypted streams received from application.
486      *
487      * @param[in] uniqueId Unique identifier for a session
488      * @param[in] decryptId Handle for the decryption session
489      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
490      * @param[in] encBuffer Encrypted data block
491      * @param[out] decBuffer Decrypted data block
492      * @param[in] IV Optional buffer
493      * @return status_t
494      *     Returns the error code for this API
495      *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
496      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
497      *     DRM_ERROR_DECRYPT for failure.
498      */
499     virtual status_t onDecrypt(int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId,
500             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
501 
502     /**
503      * Finalize decryption for the given unit of the protected content
504      *
505      * @param[in] uniqueId Unique identifier for a session
506      * @param[in] decryptHandle Handle for the decryption session
507      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
508      * @return status_t
509      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
510      */
511     virtual status_t onFinalizeDecryptUnit(
512             int uniqueId, sp<DecryptHandle>& decryptHandle, int decryptUnitId) = 0;
513 
514     /**
515      * Reads the specified number of bytes from an open DRM file.
516      *
517      * @param[in] uniqueId Unique identifier for a session
518      * @param[in] decryptHandle Handle for the decryption session
519      * @param[out] buffer Reference to the buffer that should receive the read data.
520      * @param[in] numBytes Number of bytes to read.
521      * @param[in] offset Offset with which to update the file position.
522      *
523      * @return Number of bytes read. Returns -1 for Failure.
524      */
525     virtual ssize_t onPread(int uniqueId, sp<DecryptHandle>& decryptHandle,
526             void* buffer, ssize_t numBytes, off64_t offset) = 0;
527 };
528 
529 };
530 
531 #endif /* __DRM_ENGINE_BASE_H__ */
532 
533