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