summaryrefslogtreecommitdiffstats
path: root/drm/libdrmframework/plugins/common
diff options
context:
space:
mode:
authorAnatol Pomozov <anatol.pomozov@gmail.com>2012-03-28 09:12:55 -0700
committerAnatol Pomozov <anatol.pomozov@gmail.com>2012-03-28 12:02:47 -0700
commitb0b2b4d890cf3bfb274797a759642b4e733343d7 (patch)
tree12ad21cbad346f02d542aa4d672ffd76407d58a9 /drm/libdrmframework/plugins/common
parent51f8eec23a2bcc2cc190373cdd1195972d9b8804 (diff)
parent5a5491c17d74bd2c80cf451c6ddbba22d5d5f08a (diff)
downloadframeworks_av-b0b2b4d890cf3bfb274797a759642b4e733343d7.zip
frameworks_av-b0b2b4d890cf3bfb274797a759642b4e733343d7.tar.gz
frameworks_av-b0b2b4d890cf3bfb274797a759642b4e733343d7.tar.bz2
Merge media files with history from frameworks/base.git
Diffstat (limited to 'drm/libdrmframework/plugins/common')
-rw-r--r--drm/libdrmframework/plugins/common/Android.mk16
-rw-r--r--drm/libdrmframework/plugins/common/include/DrmEngineBase.h508
-rw-r--r--drm/libdrmframework/plugins/common/include/IDrmEngine.h420
-rw-r--r--drm/libdrmframework/plugins/common/util/Android.mk52
-rw-r--r--drm/libdrmframework/plugins/common/util/include/MimeTypeUtil.h46
-rw-r--r--drm/libdrmframework/plugins/common/util/include/SessionMap.h189
-rw-r--r--drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp166
7 files changed, 1397 insertions, 0 deletions
diff --git a/drm/libdrmframework/plugins/common/Android.mk b/drm/libdrmframework/plugins/common/Android.mk
new file mode 100644
index 0000000..9ee7961
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/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..08f6e6d
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -0,0 +1,508 @@
+/*
+ * 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);
+
+ DrmMetadata* getMetadata(int uniqueId, const String8* path);
+
+ 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);
+
+ status_t 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);
+
+ status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+ status_t setPlaybackStatus(
+ int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+
+ bool validateAction(
+ int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+ status_t removeRights(int uniqueId, const String8& path);
+
+ status_t removeAllRights(int uniqueId);
+
+ status_t 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, off64_t offset, off64_t length, const char* mime);
+
+ status_t openDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ const char* uri, const char* mime);
+
+ status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+ status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+ int decryptUnitId, const DrmBuffer* headerInfo);
+
+ status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+ const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
+
+ status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+ ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+ void* buffer, ssize_t numBytes, off64_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;
+
+ /**
+ * Get metadata information associated with input content
+ *
+ * @param[in] uniqueId Unique identifier for a session
+ * @param[in] path Path of the protected content
+ * @return DrmMetadata
+ * key-value pairs of metadata
+ * @note
+ * In case of error, return NULL
+ */
+ virtual DrmMetadata* onGetMetadata(int uniqueId, const String8* path) = 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. uniqueId is a random
+ * number generated in the DRM service. If the DrmManagerClient
+ * is created in native code, uniqueId will be a number ranged
+ * from 0x1000 to 0x1fff. If it comes from Java code, the uniqueId
+ * will be a number ranged from 0x00 to 0xfff. So bit 0x1000 in
+ * uniqueId could be used in DRM plugins to differentiate native
+ * OnInfoListener and Java OnInfoListener.
+ * @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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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.
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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.
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t onSetPlaybackStatus(
+ int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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, off64_t offset, off64_t length) = 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
+ * @param[in] mime Mime type of the protected content
+ * drm plugin may do some optimization since the mime type is known.
+ * @return
+ * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+ */
+ virtual status_t onOpenDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ int fd, off64_t offset, off64_t length,
+ const char* mime) {
+
+ return DRM_ERROR_CANNOT_HANDLE;
+ }
+
+ /**
+ * 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] uri Path of the protected content to be decrypted
+ * @return
+ * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+ */
+ virtual status_t onOpenDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ const char* uri) = 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] uri Path of the protected content to be decrypted
+ * @param[in] mime Mime type of the protected content. The corresponding
+ * drm plugin may do some optimization since the mime type is known.
+ * @return
+ * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+ */
+ virtual status_t onOpenDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ const char* uri, const char* mime) {
+
+ return DRM_ERROR_CANNOT_HANDLE;
+ }
+
+ /**
+ * Close the decrypt session for the given handle
+ *
+ * @param[in] uniqueId Unique identifier for a session
+ * @param[in] decryptHandle Handle for the decryption session
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @param[in] IV Optional buffer
+ * @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, DrmBuffer* IV) = 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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, off64_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..dcf5977
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -0,0 +1,420 @@
+/*
+ * 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 DrmConstraints;
+class DrmMetadata;
+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 metadata information associated with input content
+ *
+ * @param[in] uniqueId Unique identifier for a session
+ * @param[in] path Path of the protected content
+ * @return DrmMetadata
+ * key-value pairs of metadata
+ * @note
+ * In case of error, return NULL
+ */
+ virtual DrmMetadata* getMetadata(int uniqueId, const String8* path) = 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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.
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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.
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+ int playbackStatus, int64_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @param[in] mime Mime type of the protected content if it is
+ * not NULL or empty
+ * @return
+ * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+ */
+ virtual status_t openDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ int fd, off64_t offset, off64_t length, const char* mime) = 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] uri Path of the protected content to be decrypted
+ * @param[in] mime Mime type of the protected content if it is
+ * not NULL or empty
+ * @return
+ * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+ */
+ virtual status_t openDecryptSession(
+ int uniqueId, DecryptHandle* decryptHandle,
+ const char* uri, const char* mime) = 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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
+ * @param[in] IV Optional buffer
+ * @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, DrmBuffer* IV) = 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
+ * @return status_t
+ * Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+ */
+ virtual status_t 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, off64_t offset) = 0;
+};
+
+};
+
+#endif /* __IDRM_ENGINE_H__ */
+
diff --git a/drm/libdrmframework/plugins/common/util/Android.mk b/drm/libdrmframework/plugins/common/util/Android.mk
new file mode 100644
index 0000000..15dda80
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/util/Android.mk
@@ -0,0 +1,52 @@
+#
+# 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/MimeTypeUtil.cpp
+
+LOCAL_MODULE := libdrmutility
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ libdl \
+ libdvm \
+ libandroid_runtime \
+ libnativehelper \
+ liblog
+
+
+base := frameworks/base
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE) \
+ $(base)/include \
+ $(base)/include/drm \
+ $(base)/include/drm/plugins \
+ $(LOCAL_PATH)/include
+
+
+ifneq ($(TARGET_BUILD_VARIANT),user)
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/tools
+
+endif
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/drm/libdrmframework/plugins/common/util/include/MimeTypeUtil.h b/drm/libdrmframework/plugins/common/util/include/MimeTypeUtil.h
new file mode 100644
index 0000000..4d12a61
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/util/include/MimeTypeUtil.h
@@ -0,0 +1,46 @@
+/*
+ * 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 __MIMETYPEUTIL_H__
+#define __MIMETYPEUTIL_H__
+
+#include <utils/String8.h>
+
+namespace android {
+
+class MimeTypeUtil {
+
+public:
+
+ MimeTypeUtil() {}
+
+ virtual ~MimeTypeUtil() {}
+
+/**
+ * May convert the mimetype if there is a well known
+ * replacement mimetype otherwise the original mimetype
+ * is returned.
+ *
+ * @param mimeType - mimetype in lower case to convert.
+ *
+ * @return mimetype or null.
+ */
+static String8 convertMimeType(String8& mimeType);
+
+};
+};
+
+#endif /* __MIMETYPEUTIL_H__ */
diff --git a/drm/libdrmframework/plugins/common/util/include/SessionMap.h b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
new file mode 100644
index 0000000..e563894
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
@@ -0,0 +1,189 @@
+/*
+ * 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 __SESSIONMAP_H__
+#define __SESSIONMAP_H__
+
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+/**
+ * A thread safe wrapper template class for session handlings for Drm Engines. It wraps a
+ * pointer type over KeyedVector. It keeps pointer as data in the vector and free up memory
+ * allocated pointer can be of any type of structure/class meant for keeping session data.
+ * so session object here means pointer to the session data.
+ */
+template <typename TValue>
+class SessionMap {
+
+public:
+ SessionMap() {}
+
+ virtual ~SessionMap() {
+ Mutex::Autolock lock(mLock);
+ destroyMap();
+ }
+
+ /**
+ * Adds a new value in the session map table. It expects memory to be allocated already
+ * for the session object
+ *
+ * @param key - key or Session ID
+ * @param value - session object to add
+ *
+ * @return boolean result of adding value. returns false if key is already exist.
+ */
+ bool addValue(int key, TValue value) {
+ Mutex::Autolock lock(mLock);
+ if (!isCreatedInternal(key)) {
+ map.add(key, value);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * returns the session object by the key
+ *
+ * @param key - key or Session ID
+ *
+ * @return session object as per the key
+ */
+ TValue getValue(int key) {
+ Mutex::Autolock lock(mLock);
+ return getValueInternal(key);
+ }
+
+ /**
+ * returns the number of objects in the session map table
+ *
+ * @return count of number of session objects.
+ */
+ int getSize() {
+ Mutex::Autolock lock(mLock);
+ return map.size();
+ }
+
+ /**
+ * returns the session object by the index in the session map table
+ *
+ * @param index - index of the value required
+ *
+ * @return session object as per the index
+ */
+ TValue getValueAt(unsigned int index) {
+ TValue value = NULL;
+ Mutex::Autolock lock(mLock);
+
+ if (map.size() > index) {
+ value = map.valueAt(index);
+ }
+ return value;
+ }
+
+ /**
+ * deletes the object from session map. It also frees up memory for the session object.
+ *
+ * @param key - key of the value to be deleted
+ *
+ */
+ void removeValue(int key) {
+ Mutex::Autolock lock(mLock);
+ deleteValue(getValueInternal(key));
+ map.removeItem(key);
+ }
+
+ /**
+ * decides if session is already created.
+ *
+ * @param key - key of the value for the session
+ *
+ * @return boolean result of whether session is created
+ */
+ bool isCreated(int key) {
+ Mutex::Autolock lock(mLock);
+ return isCreatedInternal(key);
+ }
+
+ SessionMap<TValue> & operator=(const SessionMap<TValue> & objectCopy) {
+ Mutex::Autolock lock(mLock);
+
+ destroyMap();
+ map = objectCopy.map;
+ return *this;
+ }
+
+private:
+ KeyedVector<int, TValue> map;
+ Mutex mLock;
+
+ /**
+ * free up the memory for the session object.
+ * Make sure if any reference to the session object anywhere, otherwise it will be a
+ * dangle pointer after this call.
+ *
+ * @param value - session object to free
+ *
+ */
+ void deleteValue(TValue value) {
+ delete value;
+ }
+
+ /**
+ * free up the memory for the entire map.
+ * free up any resources in the sessions before calling this funtion.
+ *
+ */
+ void destroyMap() {
+ int size = map.size();
+
+ for (int i = 0; i < size; i++) {
+ deleteValue(map.valueAt(i));
+ }
+ map.clear();
+ }
+
+ /**
+ * decides if session is already created.
+ *
+ * @param key - key of the value for the session
+ *
+ * @return boolean result of whether session is created
+ */
+ bool isCreatedInternal(int key) {
+ return(0 <= map.indexOfKey(key));
+ }
+
+ /**
+ * returns the session object by the key
+ *
+ * @param key - key or Session ID
+ *
+ * @return session object as per the key
+ */
+ TValue getValueInternal(int key) {
+ TValue value = NULL;
+ if (isCreatedInternal(key)) {
+ value = (TValue) map.valueFor(key);
+ }
+ return value;
+ }
+};
+
+};
+
+#endif /* __SESSIONMAP_H__ */
diff --git a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
new file mode 100644
index 0000000..576ed15
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
@@ -0,0 +1,166 @@
+/*
+ * 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 <MimeTypeUtil.h>
+#include <utils/Log.h>
+
+namespace android {
+
+#undef LOG_TAG
+#define LOG_TAG "MimeTypeUtil"
+
+#ifdef DRM_OMA_FL_ENGINE_DEBUG
+#define LOG_NDEBUG 0
+#define LOG_DEBUG(...) ALOGD(__VA_ARGS__)
+#else
+#define LOG_DEBUG(...)
+#endif
+
+enum {
+ MIMETYPE_AUDIO = 0,
+ MIMETYPE_APPLICATION = 1,
+ MIMETYPE_IMAGE = 2,
+ MIMETYPE_VIDEO = 3,
+ MIMETYPE_LAST = -1,
+};
+
+struct MimeGroup{
+ int type; // Audio, video,.. use the enum values
+ const char* pGroup; // "audio/", "video/",.. should contain the last "/"
+ int size; // Number of bytes. e.g. "audio/" = 6 bytes
+};
+
+struct MimeTypeList{
+ int type;
+ const char* pMimeExt; // Everything after the '/' e.g. audio/x-mpeg -> "x-mpeg"
+ int size; // Number of bytes. e.g. "x-mpeg" = 6 bytes
+ const char* pMimeType; // Mimetype that should be returned
+};
+
+
+// Known mimetypes by android
+static const char mime_type_audio_mpeg[] = "audio/mpeg";
+static const char mime_type_audio_3gpp[] = "audio/3gpp";
+static const char mime_type_audio_amr[] = "audio/amr-wb";
+static const char mime_type_audio_aac[] = "audio/mp4a-latm";
+static const char mime_type_audio_wav[] = "audio/wav";
+
+static const char mime_type_video_mpeg4[] = "video/mpeg4";
+static const char mime_type_video_3gpp[] = "video/3gpp";
+
+// Known mimetype groups
+static const char mime_group_audio[] = "audio/";
+static const char mime_group_application[] = "application/";
+static const char mime_group_image[] = "image/";
+static const char mime_group_video[] = "video/";
+static const char mime_type_unsupported[] = "unsupported/drm.mimetype";
+
+static struct MimeGroup mimeGroup[] = {
+ {MIMETYPE_AUDIO, mime_group_audio, sizeof(mime_group_audio)-1},
+ {MIMETYPE_APPLICATION, mime_group_application, sizeof(mime_group_application)-1},
+ {MIMETYPE_IMAGE, mime_group_image, sizeof(mime_group_image)-1},
+ {MIMETYPE_VIDEO, mime_group_video, sizeof(mime_group_video)-1},
+ {MIMETYPE_LAST, NULL, 0} // Must be last entry
+};
+
+// List of all mimetypes that should be converted.
+static struct MimeTypeList mimeTypeList[] = {
+ // Mp3 mime types
+ {MIMETYPE_AUDIO, "mp3", sizeof("mp3")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "x-mpeg", sizeof("x-mpeg")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "x-mp3", sizeof("x-mp3")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "mpg", sizeof("mpg")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "mpg3", sizeof("mpg")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "x-mpg", sizeof("x-mpg")-1, mime_type_audio_mpeg},
+ {MIMETYPE_AUDIO, "x-mpegaudio", sizeof("x-mpegaudio")-1, mime_type_audio_mpeg},
+
+ // 3gpp audio mime types
+ {MIMETYPE_AUDIO, "3gp", sizeof("3gp")-1, mime_type_audio_3gpp},
+
+ // Amr audio mime types
+ {MIMETYPE_AUDIO, "amr", sizeof("amr")-1, mime_type_audio_amr},
+
+ // Aac audio mime types
+ {MIMETYPE_AUDIO, "aac", sizeof("aac")-1, mime_type_audio_aac},
+
+ // Wav audio mime types
+ {MIMETYPE_AUDIO, "x-wav", sizeof("x-wav")-1, mime_type_audio_wav},
+
+ // Mpeg4 video mime types
+ {MIMETYPE_VIDEO, "mpg4", sizeof("mpg4")-1, mime_type_video_mpeg4},
+ {MIMETYPE_VIDEO, "mp4v-es", sizeof("mp4v-es")-1, mime_type_video_mpeg4},
+
+ // 3gpp video mime types
+ {MIMETYPE_VIDEO, "3gp", sizeof("3gp")-1, mime_type_video_3gpp},
+
+ // Must be last entry
+ {MIMETYPE_LAST, NULL, 0, NULL}
+};
+
+/**
+ * May convert the mimetype if there is a well known
+ * replacement mimetype otherwise the original mimetype
+ * is returned.
+ *
+ * If the mimetype is of unsupported group i.e. application/*
+ * then "unsupported/drm.mimetype" will be returned.
+ *
+ * @param mimeType - mimetype in lower case to convert.
+ *
+ * @return mimetype or "unsupported/drm.mimetype".
+ */
+String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
+ String8 result = mimeType;
+ const char* pMimeType;
+ struct MimeGroup* pGroup;
+ struct MimeTypeList* pMimeItem;
+ int len;
+ pMimeType = mimeType.string();
+ if (NULL != pMimeType) {
+ if ((0 == strncmp(pMimeType, mime_group_audio, (sizeof mime_group_audio) - 1)) ||
+ (0 == strncmp(pMimeType, mime_group_video, (sizeof mime_group_video) - 1))) {
+ /* Check which group the mimetype is */
+ pGroup = mimeGroup;
+ while (MIMETYPE_LAST != pGroup->type) {
+ if (0 == strncmp(pMimeType, pGroup->pGroup, pGroup->size)) {
+ break;
+ }
+ pGroup++;
+ }
+
+ /* Go through the mimetype list. Only check items of the correct group */
+ if (MIMETYPE_LAST != pGroup->type) {
+ pMimeItem = mimeTypeList;
+ len = strlen (pMimeType+pGroup->size);
+ while (MIMETYPE_LAST != pMimeItem->type) {
+ if ((pGroup->type == pMimeItem->type) &&
+ (len == pMimeItem->size) &&
+ (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
+ result = String8(pMimeItem->pMimeType);
+ break;
+ }
+ pMimeItem++;
+ }
+ }
+ } else {
+ result = String8(mime_type_unsupported);
+ }
+ LOG_DEBUG("convertMimeType got mimetype %s, converted into mimetype %s",
+ pMimeType, result.string());
+ }
+ return result;
+}
+};