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 __FWDLOCKENGINE_H__
18#define __FWDLOCKENGINE_H__
19
20#include <DrmEngineBase.h>
21#include <DrmConstraints.h>
22#include <DrmRights.h>
23#include <DrmInfo.h>
24#include <DrmInfoStatus.h>
25#include <DrmConvertedStatus.h>
26#include <DrmInfoRequest.h>
27#include <DrmSupportInfo.h>
28#include <DrmInfoEvent.h>
29
30#include "SessionMap.h"
31#include "FwdLockConv.h"
32
33namespace android {
34
35/**
36 * Forward Lock Engine class.
37 */
38class FwdLockEngine : public android::DrmEngineBase {
39
40public:
41    FwdLockEngine();
42    virtual ~FwdLockEngine();
43
44protected:
45/**
46 * Get constraint information associated with input content.
47 *
48 * @param uniqueId Unique identifier for a session
49 * @param path Path of the protected content
50 * @param action Actions defined such as,
51 *     Action::DEFAULT, Action::PLAY, etc
52 * @return DrmConstraints
53 *     key-value pairs of constraint are embedded in it
54 * @note
55 *     In case of error, return NULL
56 */
57DrmConstraints* onGetConstraints(int uniqueId, const String8* path, int action);
58
59/**
60 * Get metadata information associated with input content.
61 *
62 * @param uniqueId Unique identifier for a session
63 * @param path Path of the protected content
64 * @return DrmMetadata
65 *      For Forward Lock engine, it returns an empty object
66 * @note
67 *     In case of error, returns NULL
68 */
69DrmMetadata* onGetMetadata(int uniqueId, const String8* path);
70
71/**
72 * Initialize plug-in.
73 *
74 * @param uniqueId Unique identifier for a session
75 * @return status_t
76 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
77 */
78status_t onInitialize(int uniqueId);
79
80/**
81 * Register a callback to be invoked when the caller required to
82 * receive necessary information.
83 *
84 * @param uniqueId Unique identifier for a session
85 * @param infoListener Listener
86 * @return status_t
87 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
88 */
89status_t onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener);
90
91/**
92 * Terminate the plug-in and release resources bound to it.
93 *
94 * @param uniqueId Unique identifier for a session
95 * @return status_t
96 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
97 */
98status_t onTerminate(int uniqueId);
99
100/**
101 * Get whether the given content can be handled by this plugin or not.
102 *
103 * @param uniqueId Unique identifier for a session
104 * @param path Path to the protected object
105 * @return bool
106 *      Returns true if this plugin can handle , false in case of not able to handle
107 */
108bool onCanHandle(int uniqueId, const String8& path);
109
110/**
111 * Processes the given DRM information as appropriate for its type.
112 * Not used for Forward Lock Engine.
113 *
114 * @param uniqueId Unique identifier for a session
115 * @param drmInfo Information that needs to be processed
116 * @return DrmInfoStatus
117 *      instance as a result of processing given input
118 */
119DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo);
120
121/**
122 * Save DRM rights to specified rights path
123 * and make association with content path.
124 *
125 * @param uniqueId Unique identifier for a session
126 * @param drmRights DrmRights to be saved
127 * @param rightsPath File path where rights to be saved
128 * @param contentPath File path where content was saved
129 * @return status_t
130 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
131 */
132status_t onSaveRights(int uniqueId,
133                      const DrmRights& drmRights,
134                      const String8& rightsPath,
135                      const String8& contentPath);
136
137/**
138 * Retrieves necessary information for registration, unregistration or rights
139 * acquisition information.
140 *
141 * @param uniqueId Unique identifier for a session
142 * @param drmInfoRequest Request information to retrieve drmInfo
143 * @return DrmInfo
144 *      instance as a result of processing given input
145 */
146DrmInfo* onAcquireDrmInfo(int uniqueId,
147                          const DrmInfoRequest* drmInfoRequest);
148
149/**
150 * Retrieves the mime type embedded inside the original content.
151 *
152 * @param uniqueId Unique identifier for a session
153 * @param path Path of the conent or null.
154 * @param fd descriptor of the protected content as a file source
155 * @return String8
156 *       Returns mime-type of the original content, such as "video/mpeg"
157 */
158String8 onGetOriginalMimeType(int uniqueId, const String8& path, int fd);
159
160/**
161 * Retrieves the type of the protected object (content, rights, etc..)
162 * using specified path or mimetype. At least one parameter should be non null
163 * to retrieve DRM object type.
164 *
165 * @param uniqueId Unique identifier for a session
166 * @param path Path of the content or null.
167 * @param mimeType Mime type of the content or null.
168 * @return type of the DRM content,
169 *     such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT
170 */
171int onGetDrmObjectType(int uniqueId,
172                       const String8& path,
173                       const String8& mimeType);
174
175/**
176 * Check whether the given content has valid rights or not.
177 *
178 * @param uniqueId Unique identifier for a session
179 * @param path Path of the protected content
180 * @param action Action to perform (Action::DEFAULT, Action::PLAY, etc)
181 * @return the status of the rights for the protected content,
182 *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
183 */
184int onCheckRightsStatus(int uniqueId,
185                        const String8& path,
186                        int action);
187
188/**
189 * Consumes the rights for a content.
190 * If the reserve parameter is true the rights are reserved until the same
191 * application calls this api again with the reserve parameter set to false.
192 *
193 * @param uniqueId Unique identifier for a session
194 * @param decryptHandle Handle for the decryption session
195 * @param action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
196 * @param reserve True if the rights should be reserved.
197 * @return status_t
198 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
199 */
200status_t onConsumeRights(int uniqueId,
201                         DecryptHandle* decryptHandle,
202                         int action,
203                         bool reserve);
204
205/**
206 * Informs the DRM Engine about the playback actions performed on the DRM files.
207 *
208 * @param uniqueId Unique identifier for a session
209 * @param decryptHandle Handle for the decryption session
210 * @param playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
211 * @param position Position in the file (in milliseconds) where the start occurs.
212 *     Only valid together with Playback::START.
213 * @return status_t
214 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
215 */
216#ifdef USE_64BIT_DRM_API
217status_t onSetPlaybackStatus(int uniqueId,
218                             DecryptHandle* decryptHandle,
219                             int playbackStatus,
220                             int64_t position);
221#else
222status_t onSetPlaybackStatus(int uniqueId,
223                             DecryptHandle* decryptHandle,
224                             int playbackStatus,
225                             int position);
226#endif
227
228/**
229 *  Validates whether an action on the DRM content is allowed or not.
230 *
231 * @param uniqueId Unique identifier for a session
232 * @param path Path of the protected content
233 * @param action Action to validate (Action::PLAY, Action::TRANSFER, etc)
234 * @param description Detailed description of the action
235 * @return true if the action is allowed.
236 */
237bool onValidateAction(int uniqueId,
238                      const String8& path,
239                      int action,
240                      const ActionDescription& description);
241
242/**
243 * Removes the rights associated with the given protected content.
244 * Not used for Forward Lock Engine.
245 *
246 * @param uniqueId Unique identifier for a session
247 * @param path Path of the protected content
248 * @return status_t
249 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
250 */
251status_t onRemoveRights(int uniqueId, const String8& path);
252
253/**
254 * Removes all the rights information of each plug-in associated with
255 * DRM framework. Will be used in master reset but does nothing for
256 * Forward Lock Engine.
257 *
258 * @param uniqueId Unique identifier for a session
259 * @return status_t
260 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
261 */
262status_t onRemoveAllRights(int uniqueId);
263
264/**
265 * Starts the Forward Lock file conversion session.
266 * Each time the application tries to download a new DRM file
267 * which needs to be converted, then the application has to
268 * begin with calling this API. The convertId is used as the conversion session key
269 * and must not be the same for different convert sessions.
270 *
271 * @param uniqueId Unique identifier for a session
272 * @param convertId Handle for the convert session
273 * @return status_t
274 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
275 */
276status_t onOpenConvertSession(int uniqueId, int convertId);
277
278/**
279 * Accepts and converts the input data which is part of DRM file.
280 * The resultant converted data and the status is returned in the DrmConvertedInfo
281 * object. This method will be called each time there is a new block
282 * of data received by the application.
283 *
284 * @param uniqueId Unique identifier for a session
285 * @param convertId Handle for the convert session
286 * @param inputData Input Data which need to be converted
287 * @return Return object contains the status of the data conversion,
288 *       the output converted data and offset. In this case the
289 *      application will ignore the offset information.
290 */
291DrmConvertedStatus* onConvertData(int uniqueId,
292                                  int convertId,
293                                  const DrmBuffer* inputData);
294
295/**
296 * Closes the convert session in case of data supply completed or error occurred.
297 * Upon successful conversion of the complete data, it returns signature calculated over
298 * the entire data used over a conversion session. This signature must be copied to the offset
299 * mentioned in the DrmConvertedStatus. Signature is used for data integrity protection.
300 *
301 * @param uniqueId Unique identifier for a session
302 * @param convertId Handle for the convert session
303 * @return Return object contains the status of the data conversion,
304 *      the header and body signature data. It also informs
305 *      the application about the file offset at which this
306 *      signature data should be written.
307 */
308DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId);
309
310/**
311 * Returns the information about the Drm Engine capabilities which includes
312 * supported MimeTypes and file suffixes.
313 *
314 * @param uniqueId Unique identifier for a session
315 * @return DrmSupportInfo
316 *      instance which holds the capabilities of a plug-in
317 */
318DrmSupportInfo* onGetSupportInfo(int uniqueId);
319
320/**
321 * Open the decrypt session to decrypt the given protected content.
322 *
323 * @param uniqueId Unique identifier for a session
324 * @param decryptHandle Handle for the current decryption session
325 * @param fd File descriptor of the protected content to be decrypted
326 * @param offset Start position of the content
327 * @param length The length of the protected content
328 * @return
329 *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
330 */
331#ifdef USE_64BIT_DRM_API
332status_t onOpenDecryptSession(int uniqueId,
333                              DecryptHandle* decryptHandle,
334                              int fd, off64_t offset, off64_t length);
335#else
336status_t onOpenDecryptSession(int uniqueId,
337                              DecryptHandle* decryptHandle,
338                              int fd, int offset, int length);
339#endif
340
341/**
342 * Open the decrypt session to decrypt the given protected content.
343 *
344 * @param uniqueId Unique identifier for a session
345 * @param decryptHandle Handle for the current decryption session
346 * @param uri Path of the protected content to be decrypted
347 * @return
348 *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
349 */
350status_t onOpenDecryptSession(int uniqueId,
351                              DecryptHandle* decryptHandle,
352                              const char* uri);
353
354/**
355 * Close the decrypt session for the given handle.
356 *
357 * @param uniqueId Unique identifier for a session
358 * @param decryptHandle Handle for the decryption session
359 * @return status_t
360 *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
361 */
362status_t onCloseDecryptSession(int uniqueId,
363                               DecryptHandle* decryptHandle);
364
365/**
366 * Initialize decryption for the given unit of the protected content.
367 *
368 * @param uniqueId Unique identifier for a session
369 * @param decryptHandle Handle for the decryption session
370 * @param decryptUnitId ID which specifies decryption unit, such as track ID
371 * @param headerInfo Information for initializing decryption of this decrypUnit
372 * @return
373 *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
374 */
375status_t onInitializeDecryptUnit(int uniqueId,
376                                 DecryptHandle* decryptHandle,
377                                 int decryptUnitId,
378                                 const DrmBuffer* headerInfo);
379
380/**
381 * Decrypt the protected content buffers for the given unit.
382 * This method will be called any number of times, based on number of
383 * encrypted streams received from application.
384 *
385 * @param uniqueId Unique identifier for a session
386 * @param decryptHandle Handle for the decryption session
387 * @param decryptUnitId ID which specifies decryption unit, such as track ID
388 * @param encBuffer Encrypted data block
389 * @param decBuffer Decrypted data block
390 * @return status_t
391 *     Returns the error code for this API
392 *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
393 *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
394 *     DRM_ERROR_DECRYPT for failure.
395 */
396status_t onDecrypt(int uniqueId,
397                   DecryptHandle* decryptHandle,
398                   int decryptUnitId,
399                   const DrmBuffer* encBuffer,
400                   DrmBuffer** decBuffer);
401
402/**
403 * Decrypt the protected content buffers for the given unit.
404 * This method will be called any number of times, based on number of
405 * encrypted streams received from application.
406 *
407 * @param uniqueId Unique identifier for a session
408 * @param decryptId Handle for the decryption session
409 * @param decryptUnitId ID Specifies decryption unit, such as track ID
410 * @param encBuffer Encrypted data block
411 * @param decBuffer Decrypted data block
412 * @param IV Optional buffer
413 * @return status_t
414 *     Returns the error code for this API
415 *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
416 *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
417 *     DRM_ERROR_DECRYPT for failure.
418 */
419status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
420                   int decryptUnitId, const DrmBuffer* encBuffer,
421                   DrmBuffer** decBuffer, DrmBuffer* IV);
422
423/**
424 * Finalize decryption for the given unit of the protected content.
425 *
426 * @param uniqueId Unique identifier for a session
427 * @param decryptHandle Handle for the decryption session
428 * @param decryptUnitId ID Specifies decryption unit, such as track ID
429 * @return
430 *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
431 */
432status_t onFinalizeDecryptUnit(int uniqueId,
433                               DecryptHandle* decryptHandle,
434                               int decryptUnitId);
435
436/**
437 * Reads the specified number of bytes from an open DRM file.
438 *
439 * @param uniqueId Unique identifier for a session
440 * @param decryptHandle Handle for the decryption session
441 * @param buffer Reference to the buffer that should receive the read data.
442 * @param numBytes Number of bytes to read.
443 *
444 * @return Number of bytes read.
445 * @retval -1 Failure.
446 */
447ssize_t onRead(int uniqueId,
448               DecryptHandle* decryptHandle,
449               void* pBuffer,
450               int numBytes);
451
452/**
453 * Updates the file position within an open DRM file.
454 *
455 * @param uniqueId Unique identifier for a session
456 * @param decryptHandle Handle for the decryption session
457 * @param offset Offset with which to update the file position.
458 * @param whence One of SEEK_SET, SEEK_CUR, and SEEK_END.
459 *           These constants are defined in unistd.h.
460 *
461 * @return New file position.
462 * @retval ((off_t)-1) Failure.
463 */
464#ifdef USE_64BIT_DRM_API
465off64_t onLseek(int uniqueId,
466                DecryptHandle* decryptHandle,
467                off64_t offset,
468                int whence);
469#else
470off_t onLseek(int uniqueId,
471              DecryptHandle* decryptHandle,
472              off_t offset,
473              int whence);
474#endif
475
476/**
477 * Reads the specified number of bytes from an open DRM file.
478 *
479 * @param uniqueId Unique identifier for a session
480 * @param decryptHandle Handle for the decryption session
481 * @param buffer Reference to the buffer that should receive the read data.
482 * @param numBytes Number of bytes to read.
483 * @param offset Offset with which to update the file position.
484 *
485 * @return Number of bytes read. Returns -1 for Failure.
486 */
487#ifdef USE_64BIT_DRM_API
488ssize_t onPread(int uniqueId,
489                DecryptHandle* decryptHandle,
490                void* buffer,
491                ssize_t numBytes,
492                off64_t offset);
493#else
494ssize_t onPread(int uniqueId,
495                DecryptHandle* decryptHandle,
496                void* buffer,
497                ssize_t numBytes,
498                off_t offset);
499#endif
500
501private:
502
503    static const String8 Description;
504    static const String8 FileSuffixes[];
505    static const String8 MimeTypes[];
506    static bool IsFileSuffixSupported(const String8& suffix);
507    static bool IsMimeTypeSupported(const String8& mime);
508    static void AddSupportedMimeTypes(DrmSupportInfo *info);
509    static void AddSupportedFileSuffixes(DrmSupportInfo *info);
510
511/**
512 * Session Class for Forward Lock Conversion. An object of this class is created
513 * for every conversion.
514 */
515class ConvertSession {
516    public :
517        int uniqueId;
518        FwdLockConv_Output_t output;
519
520        ConvertSession() {
521            uniqueId = 0;
522            memset(&output, 0, sizeof(FwdLockConv_Output_t));
523        }
524
525        virtual ~ConvertSession() {}
526};
527
528/**
529 * Session Class for Forward Lock decoder. An object of this class is created
530 * for every decoding session.
531 */
532class DecodeSession {
533    public :
534        int fileDesc;
535        off_t offset;
536
537        DecodeSession() {
538            fileDesc = -1;
539            offset = 0;
540        }
541
542        explicit DecodeSession(int fd) {
543            fileDesc = fd;
544            offset = 0;
545        }
546
547        virtual ~DecodeSession() {}
548};
549
550/**
551 * Session Map Tables for Conversion and Decoding of forward lock files.
552 */
553SessionMap<ConvertSession*> convertSessionMap;
554SessionMap<DecodeSession*> decodeSessionMap;
555
556/**
557 * Converts the error code from Forward Lock Converter to DrmConvertStatus error code.
558 *
559 * @param Forward Lock Converter error code
560 *
561 * @return Status code from DrmConvertStatus.
562 */
563static int getConvertedStatus(FwdLockConv_Status_t status);
564};
565
566};
567
568#endif /* __FWDLOCKENGINE_H__ */
569