diff options
Diffstat (limited to 'drm/libdrmframework/plugins')
6 files changed, 1223 insertions, 0 deletions
diff --git a/drm/libdrmframework/plugins/Android.mk b/drm/libdrmframework/plugins/Android.mk new file mode 100644 index 0000000..9ee7961 --- /dev/null +++ b/drm/libdrmframework/plugins/Android.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +include $(call all-subdir-makefiles) diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h new file mode 100644 index 0000000..667958a --- /dev/null +++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DRM_ENGINE_BASE_H__ +#define __DRM_ENGINE_BASE_H__ + +#include <drm/drm_framework_common.h> +#include "IDrmEngine.h" + +namespace android { + +/** + * This class is an interface for plug-in developers + * + * Responsibility of this class is control the sequence of actual plug-in. + * All each plug-in developer has to do is implement onXXX() type virtual interfaces. + */ +class DrmEngineBase : public IDrmEngine { +public: + DrmEngineBase(); + virtual ~DrmEngineBase(); + +public: + DrmConstraints* getConstraints(int uniqueId, const String8* path, int action); + + status_t initialize(int uniqueId); + + status_t setOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener); + + status_t terminate(int uniqueId); + + bool canHandle(int uniqueId, const String8& path); + + DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo); + + void saveRights(int uniqueId, const DrmRights& drmRights, + const String8& rightsPath, const String8& contentPath); + + DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest); + + String8 getOriginalMimeType(int uniqueId, const String8& path); + + int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType); + + int checkRightsStatus(int uniqueId, const String8& path, int action); + + void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve); + + void setPlaybackStatus( + int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position); + + bool validateAction( + int uniqueId, const String8& path, int action, const ActionDescription& description); + + void removeRights(int uniqueId, const String8& path); + + void removeAllRights(int uniqueId); + + void openConvertSession(int uniqueId, int convertId); + + DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData); + + DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId); + + DrmSupportInfo* getSupportInfo(int uniqueId); + + status_t openDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length); + + void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle); + + void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* headerInfo); + + status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer); + + void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId); + + ssize_t pread(int uniqueId, DecryptHandle* decryptHandle, + void* buffer, ssize_t numBytes, off_t offset); + +protected: + ///////////////////////////////////////////////////// + // Interface for plug-in developers // + // each plug-in has to implement following method // + ///////////////////////////////////////////////////// + /** + * Get constraint information associated with input content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Actions defined such as, + * Action::DEFAULT, Action::PLAY, etc + * @return DrmConstraints + * key-value pairs of constraint are embedded in it + * @note + * In case of error, return NULL + */ + virtual DrmConstraints* onGetConstraints( + int uniqueId, const String8* path, int action) = 0; + + /** + * Initialize plug-in + * + * @param[in] uniqueId Unique identifier for a session + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t onInitialize(int uniqueId) = 0; + + /** + * Register a callback to be invoked when the caller required to + * receive necessary information + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] infoListener Listener + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t onSetOnInfoListener( + int uniqueId, const IDrmEngine::OnInfoListener* infoListener) = 0; + + /** + * Terminate the plug-in + * and release resource bound to plug-in + * + * @param[in] uniqueId Unique identifier for a session + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t onTerminate(int uniqueId) = 0; + + /** + * Get whether the given content can be handled by this plugin or not + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path the protected object + * @return bool + * Returns true if this plugin can handle , false in case of not able to handle + */ + virtual bool onCanHandle(int uniqueId, const String8& path) = 0; + + /** + * Executes given drm information based on its type + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmInfo Information needs to be processed + * @return DrmInfoStatus + * instance as a result of processing given input + */ + virtual DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0; + + /** + * Save DRM rights to specified rights path + * and make association with content path + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmRights DrmRights to be saved + * @param[in] rightsPath File path where rights to be saved + * @param[in] contentPath File path where content was saved + */ + virtual void onSaveRights(int uniqueId, const DrmRights& drmRights, + const String8& rightspath, const String8& contentPath) = 0; + + /** + * Retrieves necessary information for registration, unregistration or rights + * acquisition information. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmInfoRequest Request information to retrieve drmInfo + * @return DrmInfo + * instance as a result of processing given input + */ + virtual DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) = 0; + + /** + * Retrieves the mime type embedded inside the original content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @return String8 + * Returns mime-type of the original content, such as "video/mpeg" + */ + virtual String8 onGetOriginalMimeType(int uniqueId, const String8& path) = 0; + + /** + * Retrieves the type of the protected object (content, rights, etc..) + * using specified path or mimetype. At least one parameter should be non null + * to retrieve DRM object type + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the content or null. + * @param[in] mimeType Mime type of the content or null. + * @return type of the DRM content, + * such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT + */ + virtual int onGetDrmObjectType( + int uniqueId, const String8& path, const String8& mimeType) = 0; + + /** + * Check whether the given content has valid rights or not + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Action to perform (Action::DEFAULT, Action::PLAY, etc) + * @return the status of the rights for the protected content, + * such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc. + */ + virtual int onCheckRightsStatus(int uniqueId, const String8& path, int action) = 0; + + /** + * Consumes the rights for a content. + * If the reserve parameter is true the rights is reserved until the same + * application calls this api again with the reserve parameter set to false. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc) + * @param[in] reserve True if the rights should be reserved. + */ + virtual void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, + int action, bool reserve) = 0; + + /** + * Informs the DRM Engine about the playback actions performed on the DRM files. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE) + * @param[in] position Position in the file (in milliseconds) where the start occurs. + * Only valid together with Playback::START. + */ + virtual void onSetPlaybackStatus( + int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) = 0; + + /** + * Validates whether an action on the DRM content is allowed or not. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Action to validate (Action::PLAY, Action::TRANSFER, etc) + * @param[in] description Detailed description of the action + * @return true if the action is allowed. + */ + virtual bool onValidateAction(int uniqueId, const String8& path, + int action, const ActionDescription& description) = 0; + + /** + * Removes the rights associated with the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + */ + virtual void onRemoveRights(int uniqueId, const String8& path) = 0; + + /** + * Removes all the rights information of each plug-in associated with + * DRM framework. Will be used in master reset + * + * @param[in] uniqueId Unique identifier for a session + */ + virtual void onRemoveAllRights(int uniqueId) = 0; + + /** + * This API is for Forward Lock based DRM scheme. + * Each time the application tries to download a new DRM file + * which needs to be converted, then the application has to + * begin with calling this API. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + */ + virtual void onOpenConvertSession(int uniqueId, int convertId) = 0; + + /** + * Accepts and converts the input data which is part of DRM file. + * The resultant converted data and the status is returned in the DrmConvertedInfo + * object. This method will be called each time there are new block + * of data received by the application. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + * @param[in] inputData Input Data which need to be converted + * @return Return object contains the status of the data conversion, + * the output converted data and offset. In this case the + * application will ignore the offset information. + */ + virtual DrmConvertedStatus* onConvertData( + int uniqueId, int convertId, const DrmBuffer* inputData) = 0; + + /** + * Informs the Drm Agent when there is no more data which need to be converted + * or when an error occurs. Upon successful conversion of the complete data, + * the agent will inform that where the header and body signature + * should be added. This signature appending is needed to integrity + * protect the converted file. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + * @return Return object contains the status of the data conversion, + * the header and body signature data. It also informs + * the application on which offset these signature data + * should be appended. + */ + virtual DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId) = 0; + + /** + * Returns the information about the Drm Engine capabilities which includes + * supported MimeTypes and file suffixes. + * + * @param[in] uniqueId Unique identifier for a session + * @return DrmSupportInfo + * instance which holds the capabilities of a plug-in + */ + virtual DrmSupportInfo* onGetSupportInfo(int uniqueId) = 0; + + /** + * Open the decrypt session to decrypt the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the current decryption session + * @param[in] fd File descriptor of the protected content to be decrypted + * @param[in] offset Start position of the content + * @param[in] length The length of the protected content + * @return + * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success + */ + virtual status_t onOpenDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) = 0; + + /** + * Close the decrypt session for the given handle + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + */ + virtual void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0; + + /** + * Initialize decryption for the given unit of the protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptId Handle for the decryption session + * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID + * @param[in] headerInfo Information for initializing decryption of this decrypUnit + */ + virtual void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* headerInfo) = 0; + + /** + * Decrypt the protected content buffers for the given unit + * This method will be called any number of times, based on number of + * encrypted streams received from application. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptId Handle for the decryption session + * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID + * @param[in] encBuffer Encrypted data block + * @param[out] decBuffer Decrypted data block + * @return status_t + * Returns the error code for this API + * DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED + * DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED, + * DRM_ERROR_DECRYPT for failure. + */ + virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0; + + /** + * Finalize decryption for the given unit of the protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID + */ + virtual void onFinalizeDecryptUnit( + int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0; + + /** + * Reads the specified number of bytes from an open DRM file. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[out] buffer Reference to the buffer that should receive the read data. + * @param[in] numBytes Number of bytes to read. + * @param[in] offset Offset with which to update the file position. + * + * @return Number of bytes read. Returns -1 for Failure. + */ + virtual ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle, + void* buffer, ssize_t numBytes, off_t offset) = 0; +}; + +}; + +#endif /* __DRM_ENGINE_BASE_H__ */ + diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h new file mode 100644 index 0000000..0d52f66 --- /dev/null +++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IDRM_ENGINE_H__ +#define __IDRM_ENGINE_H__ + +#include <drm/drm_framework_common.h> + +namespace android { + +class DrmContentIds; +class DrmConstraints; +class DrmRights; +class DrmInfo; +class DrmInfoStatus; +class DrmConvertedStatus; +class DrmInfoRequest; +class DrmSupportInfo; +class DrmInfoEvent; + +/** + * This class is an interface for plug-in user + * + * Responsibility of this class is provide generic interface to DRM Engine Manager. + * Each interface need to be as abstract as possible. + */ +class IDrmEngine { +public: + virtual ~IDrmEngine() { + } + +public: + class OnInfoListener { + + public: + virtual void onInfo(const DrmInfoEvent& event) = 0; + + virtual ~OnInfoListener() { } + }; + +public: + + ////////////////////////////////// + // Implementation of IDrmEngine // + ////////////////////////////////// + + /** + * Initialize plug-in + * + * @param[in] uniqueId Unique identifier for a session + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t initialize(int uniqueId) = 0; + + /** + * Register a callback to be invoked when the caller required to + * receive necessary information + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] infoListener Listener + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t setOnInfoListener( + int uniqueId, const IDrmEngine::OnInfoListener* infoListener) = 0; + + /** + * Terminate the plug-in + * and release resource bound to plug-in + * e.g.) release native resource + * + * @param[in] uniqueId Unique identifier for a session + * @return status_t + * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure + */ + virtual status_t terminate(int uniqueId) = 0; + + /** + * Get constraint information associated with input content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Actions defined such as, + * Action::DEFAULT, Action::PLAY, etc + * @return DrmConstraints + * key-value pairs of constraint are embedded in it + * @note + * In case of error, return NULL + */ + virtual DrmConstraints* getConstraints( + int uniqueId, const String8* path, int action) = 0; + + /** + * Get whether the given content can be handled by this plugin or not + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path the protected object + * @return bool + * true if this plugin can handle , false in case of not able to handle + */ + virtual bool canHandle(int uniqueId, const String8& path) = 0; + + /** + * Executes given drm information based on its type + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmInfo Information needs to be processed + * @return DrmInfoStatus + * instance as a result of processing given input + */ + virtual DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0; + + /** + * Retrieves necessary information for registration, unregistration or rights + * acquisition information. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmInfoRequest Request information to retrieve drmInfo + * @return DrmInfo + * instance as a result of processing given input + */ + virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) = 0; + + /** + * Save DRM rights to specified rights path + * and make association with content path + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] drmRights DrmRights to be saved + * @param[in] rightsPath File path where rights to be saved + * @param[in] contentPath File path where content was saved + */ + virtual void saveRights(int uniqueId, const DrmRights& drmRights, + const String8& rightsPath, const String8& contentPath) = 0; + + /** + * Retrieves the mime type embedded inside the original content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @return String8 + * Returns mime-type of the original content, such as "video/mpeg" + */ + virtual String8 getOriginalMimeType(int uniqueId, const String8& path) = 0; + + /** + * Retrieves the type of the protected object (content, rights, etc..) + * using specified path or mimetype. At least one parameter should be non null + * to retrieve DRM object type + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the content or null. + * @param[in] mimeType Mime type of the content or null. + * @return type of the DRM content, + * such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT + */ + virtual int getDrmObjectType( + int uniqueId, const String8& path, const String8& mimeType) = 0; + + /** + * Check whether the given content has valid rights or not + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Action to perform (Action::DEFAULT, Action::PLAY, etc) + * @return the status of the rights for the protected content, + * such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc. + */ + virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0; + + /** + * Consumes the rights for a content. + * If the reserve parameter is true the rights is reserved until the same + * application calls this api again with the reserve parameter set to false. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc) + * @param[in] reserve True if the rights should be reserved. + */ + virtual void consumeRights( + int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0; + + /** + * Informs the DRM Engine about the playback actions performed on the DRM files. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE) + * @param[in] position Position in the file (in milliseconds) where the start occurs. + * Only valid together with Playback::START. + */ + virtual void setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle, + int playbackStatus, int position) = 0; + + /** + * Validates whether an action on the DRM content is allowed or not. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + * @param[in] action Action to validate (Action::PLAY, Action::TRANSFER, etc) + * @param[in] description Detailed description of the action + * @return true if the action is allowed. + */ + virtual bool validateAction(int uniqueId, const String8& path, + int action, const ActionDescription& description) = 0; + + /** + * Removes the rights associated with the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] path Path of the protected content + */ + virtual void removeRights(int uniqueId, const String8& path) = 0; + + /** + * Removes all the rights information of each plug-in associated with + * DRM framework. Will be used in master reset + * + * @param[in] uniqueId Unique identifier for a session + */ + virtual void removeAllRights(int uniqueId) = 0; + + /** + * This API is for Forward Lock based DRM scheme. + * Each time the application tries to download a new DRM file + * which needs to be converted, then the application has to + * begin with calling this API. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + */ + virtual void openConvertSession(int uniqueId, int convertId) = 0; + + /** + * Accepts and converts the input data which is part of DRM file. + * The resultant converted data and the status is returned in the DrmConvertedInfo + * object. This method will be called each time there are new block + * of data received by the application. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + * @param[in] inputData Input Data which need to be converted + * @return Return object contains the status of the data conversion, + * the output converted data and offset. In this case the + * application will ignore the offset information. + */ + virtual DrmConvertedStatus* convertData( + int uniqueId, int convertId, const DrmBuffer* inputData) = 0; + + /** + * Informs the Drm Agent when there is no more data which need to be converted + * or when an error occurs. Upon successful conversion of the complete data, + * the agent will inform that where the header and body signature + * should be added. This signature appending is needed to integrity + * protect the converted file. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] convertId Handle for the convert session + * @return Return object contains the status of the data conversion, + * the header and body signature data. It also informs + * the application on which offset these signature data + * should be appended. + */ + virtual DrmConvertedStatus* closeConvertSession( int uniqueId, int convertId) = 0; + + /** + * Returns the information about the Drm Engine capabilities which includes + * supported MimeTypes and file suffixes. + * + * @param[in] uniqueId Unique identifier for a session + * @return DrmSupportInfo + * instance which holds the capabilities of a plug-in + */ + virtual DrmSupportInfo* getSupportInfo(int uniqueId) = 0; + + /** + * Open the decrypt session to decrypt the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the current decryption session + * @param[in] fd File descriptor of the protected content to be decrypted + * @param[in] offset Start position of the content + * @param[in] length The length of the protected content + * @return + * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success + */ + virtual status_t openDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) = 0; + + /** + * Close the decrypt session for the given handle + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + */ + virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0; + + /** + * Initialize decryption for the given unit of the protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID + * @param[in] headerInfo Information for initializing decryption of this decrypUnit + */ + virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* headerInfo) = 0; + + /** + * Decrypt the protected content buffers for the given unit + * This method will be called any number of times, based on number of + * encrypted streams received from application. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID + * @param[in] encBuffer Encrypted data block + * @param[out] decBuffer Decrypted data block + * @return status_t + * Returns the error code for this API + * DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED + * DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED, + * DRM_ERROR_DECRYPT for failure. + */ + virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0; + + /** + * Finalize decryption for the given unit of the protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID + */ + virtual void finalizeDecryptUnit( + int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0; + + /** + * Reads the specified number of bytes from an open DRM file. + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the decryption session + * @param[out] buffer Reference to the buffer that should receive the read data. + * @param[in] numBytes Number of bytes to read. + * @param[in] offset Offset with which to update the file position. + * + * @return Number of bytes read. Returns -1 for Failure. + */ + virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle, + void* buffer, ssize_t numBytes, off_t offset) = 0; +}; + +}; + +#endif /* __IDRM_ENGINE_H__ */ + diff --git a/drm/libdrmframework/plugins/passthru/Android.mk b/drm/libdrmframework/plugins/passthru/Android.mk new file mode 100644 index 0000000..7856d37 --- /dev/null +++ b/drm/libdrmframework/plugins/passthru/Android.mk @@ -0,0 +1,48 @@ +# +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + src/DrmPassthruPlugIn.cpp + +LOCAL_MODULE := libdrmpassthruplugin + +LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon + +LOCAL_SHARED_LIBRARIES := \ + libutils + +ifeq ($(TARGET_SIMULATOR),true) + LOCAL_LDLIBS += -ldl +else + LOCAL_SHARED_LIBRARIES += libdl +endif + +LOCAL_PRELINK_MODULE := false + +LOCAL_C_INCLUDES += \ + $(TOP)/frameworks/base/drm/libdrmframework/include \ + $(TOP)/frameworks/base/drm/libdrmframework/plugins/passthru/include \ + $(TOP)/frameworks/base/drm/libdrmframework/plugins/common/include \ + $(TOP)/frameworks/base/include + +# Set the following flag to enable the decryption passthru flow +#LOCAL_CFLAGS += -DENABLE_PASSTHRU_DECRYPTION + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h new file mode 100644 index 0000000..d2c7852 --- /dev/null +++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DRM_PASSTHRU_PLUGIN_H__ +#define __DRM_PASSTHRU_PLUGIN_H__ + +#include <DrmEngineBase.h> + +namespace android { + +class DrmPassthruPlugIn : public DrmEngineBase { + +public: + DrmPassthruPlugIn(); + virtual ~DrmPassthruPlugIn(); + +protected: + DrmConstraints* onGetConstraints(int uniqueId, const String8* path, int action); + + status_t onInitialize(int uniqueId); + + status_t onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener); + + status_t onTerminate(int uniqueId); + + bool onCanHandle(int uniqueId, const String8& path); + + DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo); + + void onSaveRights(int uniqueId, const DrmRights& drmRights, + const String8& rightsPath, const String8& contentPath); + + DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest); + + String8 onGetOriginalMimeType(int uniqueId, const String8& path); + + int onGetDrmObjectType(int uniqueId, const String8& path, const String8& mimeType); + + int onCheckRightsStatus(int uniqueId, const String8& path, int action); + + void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve); + + void onSetPlaybackStatus( + int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position); + + bool onValidateAction( + int uniqueId, const String8& path, int action, const ActionDescription& description); + + void onRemoveRights(int uniqueId, const String8& path); + + void onRemoveAllRights(int uniqueId); + + void onOpenConvertSession(int uniqueId, int convertId); + + DrmConvertedStatus* onConvertData(int uniqueId, int convertId, const DrmBuffer* inputData); + + DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId); + + DrmSupportInfo* onGetSupportInfo(int uniqueId); + + status_t onOpenDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length); + + void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle); + + void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* headerInfo); + + status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer); + + void onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId); + + ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle, + void* buffer, ssize_t numBytes, off_t offset); + +private: + DecryptHandle* openDecryptSessionImpl(); +}; + +}; + +#endif /* __DRM_PASSTHRU_PLUGIN_H__ */ + diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp new file mode 100644 index 0000000..2655d0b --- /dev/null +++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NDEBUG 0 +#define LOG_TAG "DrmPassthruPlugIn" +#include <utils/Log.h> + +#include <drm/DrmRights.h> +#include <drm/DrmConstraints.h> +#include <drm/DrmInfo.h> +#include <drm/DrmInfoEvent.h> +#include <drm/DrmInfoStatus.h> +#include <drm/DrmConvertedStatus.h> +#include <drm/DrmInfoRequest.h> +#include <drm/DrmSupportInfo.h> +#include <DrmPassthruPlugIn.h> + +using namespace android; + + +// This extern "C" is mandatory to be managed by TPlugInManager +extern "C" IDrmEngine* create() { + return new DrmPassthruPlugIn(); +} + +// This extern "C" is mandatory to be managed by TPlugInManager +extern "C" void destroy(IDrmEngine* pPlugIn) { + delete pPlugIn; + pPlugIn = NULL; +} + +DrmPassthruPlugIn::DrmPassthruPlugIn() + : DrmEngineBase() { + +} + +DrmPassthruPlugIn::~DrmPassthruPlugIn() { + +} + +DrmConstraints* DrmPassthruPlugIn::onGetConstraints( + int uniqueId, const String8* path, int action) { + LOGD("DrmPassthruPlugIn::onGetConstraints From Path: %d", uniqueId); + DrmConstraints* drmConstraints = new DrmConstraints(); + + String8 value("dummy_available_time"); + char* charValue = NULL; + charValue = new char[value.length() + 1]; + strncpy(charValue, value.string(), value.length()); + + //Just add dummy available time for verification + drmConstraints->put(&(DrmConstraints::LICENSE_AVAILABLE_TIME), charValue); + + return drmConstraints; +} + +DrmInfoStatus* DrmPassthruPlugIn::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) { + LOGD("DrmPassthruPlugIn::onProcessDrmInfo - Enter : %d", uniqueId); + DrmInfoStatus* drmInfoStatus = NULL; + if (NULL != drmInfo) { + switch (drmInfo->getInfoType()) { + case DrmInfoRequest::TYPE_REGISTRATION_INFO: { + const DrmBuffer* emptyBuffer = new DrmBuffer(); + drmInfoStatus + = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType()); + break; + } + case DrmInfoRequest::TYPE_UNREGISTRATION_INFO: { + const DrmBuffer* emptyBuffer = new DrmBuffer(); + drmInfoStatus + = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType()); + break; + } + case DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO: { + String8 licenseString("dummy_license_string"); + const int bufferSize = licenseString.size(); + char* data = NULL; + data = new char[bufferSize]; + memcpy(data, licenseString.string(), bufferSize); + const DrmBuffer* buffer = new DrmBuffer(data, bufferSize); + drmInfoStatus + = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, buffer, drmInfo->getMimeType()); + break; + } + } + } + LOGD("DrmPassthruPlugIn::onProcessDrmInfo - Exit"); + return drmInfoStatus; +} + +status_t DrmPassthruPlugIn::onSetOnInfoListener( + int uniqueId, const IDrmEngine::OnInfoListener* infoListener) { + LOGD("DrmPassthruPlugIn::onSetOnInfoListener : %d", uniqueId); + return DRM_NO_ERROR; +} + +status_t DrmPassthruPlugIn::onInitialize(int uniqueId) { + LOGD("DrmPassthruPlugIn::onInitialize : %d", uniqueId); + return DRM_NO_ERROR; +} + +status_t DrmPassthruPlugIn::onTerminate(int uniqueId) { + LOGD("DrmPassthruPlugIn::onTerminate : %d", uniqueId); + return DRM_NO_ERROR; +} + +DrmSupportInfo* DrmPassthruPlugIn::onGetSupportInfo(int uniqueId) { + LOGD("DrmPassthruPlugIn::onGetSupportInfo : %d", uniqueId); + DrmSupportInfo* drmSupportInfo = new DrmSupportInfo(); + // Add mimetype's + drmSupportInfo->addMimeType(String8("application/vnd.passthru.drm")); + // Add File Suffixes + drmSupportInfo->addFileSuffix(String8(".passthru")); + // Add plug-in description + drmSupportInfo->setDescription(String8("Passthru plug-in")); + return drmSupportInfo; +} + +void DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& drmRights, + const String8& rightsPath, const String8& contentPath) { + LOGD("DrmPassthruPlugIn::onSaveRights : %d", uniqueId); +} + +DrmInfo* DrmPassthruPlugIn::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) { + LOGD("DrmPassthruPlugIn::onAcquireDrmInfo : %d", uniqueId); + DrmInfo* drmInfo = NULL; + + if (NULL != drmInfoRequest) { + String8 dataString("dummy_acquistion_string"); + int length = dataString.length(); + char* data = NULL; + data = new char[length]; + memcpy(data, dataString.string(), length); + drmInfo = new DrmInfo(drmInfoRequest->getInfoType(), + DrmBuffer(data, length), drmInfoRequest->getMimeType()); + } + return drmInfo; +} + +bool DrmPassthruPlugIn::onCanHandle(int uniqueId, const String8& path) { + LOGD("DrmPassthruPlugIn::canHandle: %s ", path.string()); + String8 extension = path.getPathExtension(); + extension.toLower(); + return (String8(".passthru") == extension); +} + +String8 DrmPassthruPlugIn::onGetOriginalMimeType(int uniqueId, const String8& path) { + LOGD("DrmPassthruPlugIn::onGetOriginalMimeType() : %d", uniqueId); + return String8("video/passthru"); +} + +int DrmPassthruPlugIn::onGetDrmObjectType( + int uniqueId, const String8& path, const String8& mimeType) { + LOGD("DrmPassthruPlugIn::onGetDrmObjectType() : %d", uniqueId); + return DrmObjectType::UNKNOWN; +} + +int DrmPassthruPlugIn::onCheckRightsStatus(int uniqueId, const String8& path, int action) { + LOGD("DrmPassthruPlugIn::onCheckRightsStatus() : %d", uniqueId); + int rightsStatus = RightsStatus::RIGHTS_VALID; + return rightsStatus; +} + +void DrmPassthruPlugIn::onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, + int action, bool reserve) { + LOGD("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId); +} + +void DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle, + int playbackStatus, int position) { + LOGD("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId); +} + +bool DrmPassthruPlugIn::onValidateAction(int uniqueId, const String8& path, + int action, const ActionDescription& description) { + LOGD("DrmPassthruPlugIn::onValidateAction() : %d", uniqueId); + return true; +} + +void DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) { + LOGD("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId); +} + +void DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) { + LOGD("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId); +} + +void DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) { + LOGD("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId); +} + +DrmConvertedStatus* DrmPassthruPlugIn::onConvertData( + int uniqueId, int convertId, const DrmBuffer* inputData) { + LOGD("DrmPassthruPlugIn::onConvertData() : %d", uniqueId); + DrmBuffer* convertedData = NULL; + + if (NULL != inputData && 0 < inputData->length) { + int length = inputData->length; + char* data = NULL; + data = new char[length]; + convertedData = new DrmBuffer(data, length); + memcpy(convertedData->data, inputData->data, length); + } + return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, convertedData, 0 /*offset*/); +} + +DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int convertId) { + LOGD("DrmPassthruPlugIn::onCloseConvertSession() : %d", uniqueId); + return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, NULL, 0 /*offset*/); +} + +status_t DrmPassthruPlugIn::onOpenDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) { + LOGD("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId); + +#ifdef ENABLE_PASSTHRU_DECRYPTION + decryptHandle->mimeType = String8("video/passthru"); + decryptHandle->decryptApiType = DecryptApiType::ELEMENTARY_STREAM_BASED; + decryptHandle->status = DRM_NO_ERROR; + decryptHandle->decryptInfo = NULL; + return DRM_NO_ERROR; +#endif + + return DRM_ERROR_CANNOT_HANDLE; +} + +void DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) { + LOGD("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId); + if (NULL != decryptHandle) { + if (NULL != decryptHandle->decryptInfo) { + delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL; + } + delete decryptHandle; decryptHandle = NULL; + } +} + +void DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* headerInfo) { + LOGD("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId); +} + +status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, + int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) { + LOGD("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId); + /** + * As a workaround implementation passthru would copy the given + * encrypted buffer as it is to decrypted buffer. Note, decBuffer + * memory has to be allocated by the caller. + */ + if (NULL != (*decBuffer) && 0 < (*decBuffer)->length) { + memcpy((*decBuffer)->data, encBuffer->data, encBuffer->length); + (*decBuffer)->length = encBuffer->length; + } + return DRM_NO_ERROR; +} + +void DrmPassthruPlugIn::onFinalizeDecryptUnit( + int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) { + LOGD("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId); +} + +ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* decryptHandle, + void* buffer, ssize_t numBytes, off_t offset) { + LOGD("DrmPassthruPlugIn::onPread() : %d", uniqueId); + return 0; +} + |