resolved conflicts for merge of 845fdba7 to master

Change-Id: I716b6ceb03bd733f9e7f49008112c8f2c53ad9ce
diff --git a/drm/libdrmframework/plugins/common/util/include/SessionMap.h b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
index 3dff58c..e563894 100644
--- a/drm/libdrmframework/plugins/common/util/include/SessionMap.h
+++ b/drm/libdrmframework/plugins/common/util/include/SessionMap.h
@@ -13,141 +13,175 @@
  * 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 wrapper template class for handling DRM Engine sessions.
+ * 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 NODE>
+template <typename TValue>
 class SessionMap {
 
 public:
-    KeyedVector<int, NODE> map;
-
     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, NODE value) {
-    bool result = false;
-
-    if (!isCreated(key)) {
-        map.add(key, value);
-        result = true;
+    /**
+     * 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;
     }
 
-    return result;
-}
-
-
-/**
- * returns the session object by the key
- *
- * @param key - key or Session ID
- *
- * @return session object as per the key
- */
-NODE getValue(int key) {
-    NODE value = NULL;
-
-    if (isCreated(key)) {
-        value = (NODE) map.valueFor(key);
+    /**
+     * 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);
     }
 
-    return value;
-}
-
-/**
- * returns the number of objects in the session map table
- *
- * @return count of number of session objects.
- */
-int getSize() {
-    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
- */
-NODE getValueAt(unsigned int index) {
-    NODE value = NULL;
-
-    if (map.size() > index) {
-      value = map.valueAt(index);
+    /**
+     * 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();
     }
 
-    return value;
-}
+    /**
+     * 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);
 
-/**
- * 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) {
-    deleteValue(getValue(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) {
-    return (0 <= map.indexOfKey(key));
-}
-
-/**
- * empty the entire session table. It releases all the memory for session objects.
- */
-void destroyMap() {
-    int size = map.size();
-    int i = 0;
-
-    for (i = 0; i < size; i++) {
-        deleteValue(map.valueAt(i));
+        if (map.size() > index) {
+            value = map.valueAt(index);
+        }
+        return value;
     }
 
-    map.clear();
-}
+    /**
+     * 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);
+    }
 
-/**
- * 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(NODE value) {
-    delete value;
-}
+    /**
+     * 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;
+    }
 };
 
 };
diff --git a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
index 4ee903e..57ef799 100644
--- a/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
+++ b/drm/libdrmframework/plugins/common/util/src/MimeTypeUtil.cpp
@@ -22,6 +22,13 @@
 #undef LOG_TAG
 #define LOG_TAG "MimeTypeUtil"
 
+#ifdef DRM_OMA_FL_ENGINE_DEBUG
+#define LOG_NDEBUG 0
+#define LOG_DEBUG(...) LOGD(__VA_ARGS__)
+#else
+#define LOG_DEBUG(...)
+#endif
+
 enum {
     MIMETYPE_AUDIO       = 0,
     MIMETYPE_APPLICATION = 1,
@@ -59,6 +66,7 @@
 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},
@@ -107,48 +115,52 @@
  * 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 null.
+ * @return mimetype or "unsupported/drm.mimetype".
  */
 String8 MimeTypeUtil::convertMimeType(String8& mimeType) {
     String8 result = mimeType;
-    const char* pTmp;
     const char* pMimeType;
     struct MimeGroup* pGroup;
     struct MimeTypeList* pMimeItem;
     int len;
-
     pMimeType = mimeType.string();
     if (NULL != pMimeType) {
-        /* 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 ((len == pMimeItem->size) &&
-                    (0 == strcmp(pMimeType+pGroup->size, pMimeItem->pMimeExt))) {
-                    result = String8(pMimeItem->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;
                 }
-                pMimeItem++;
+                pGroup++;
             }
-        }
-        LOGI("convertMimeType got mimetype %s, converted into mimetype %s",
-             pMimeType, result.string());
-    }
 
+            /* 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;
 }
 };
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
index 9805a40..e359dbd 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
@@ -17,6 +17,9 @@
 
 include $(CLEAR_VARS)
 
+# The flag below turns on local debug printouts
+#LOCAL_CFLAGS += -DDRM_OMA_FL_ENGINE_DEBUG
+
 base := frameworks/base
 
 # Determine whether the DRM framework uses 64-bit data types for file offsets and do the same.
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
index 31c3c14..e184545 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/src/FwdLockEngine.cpp
@@ -41,6 +41,13 @@
 #undef LOG_TAG
 #define LOG_TAG "FwdLockEngine"
 
+#ifdef DRM_OMA_FL_ENGINE_DEBUG
+#define LOG_NDEBUG 0
+#define LOG_VERBOSE(...) LOGV(__VA_ARGS__)
+#else
+#define LOG_VERBOSE(...)
+#endif
+
 using namespace android;
 // This extern "C" is mandatory to be managed by TPlugInManager
 extern "C" IDrmEngine* create() {
@@ -53,14 +60,25 @@
 }
 
 FwdLockEngine::FwdLockEngine() {
-    LOGV("FwdLockEngine Construction");
+    LOG_VERBOSE("FwdLockEngine Construction");
 }
 
 FwdLockEngine::~FwdLockEngine() {
-    LOGV("FwdLockEngine Destruction");
+    LOG_VERBOSE("FwdLockEngine Destruction");
 
-    convertSessionMap.destroyMap();
-    decodeSessionMap.destroyMap();
+    int size = decodeSessionMap.getSize();
+
+    for (int i = 0; i < size; i++) {
+        DecodeSession *session = (DecodeSession*) decodeSessionMap.getValueAt(i);
+        FwdLockFile_detach(session->fileDesc);
+        ::close(session->fileDesc);
+    }
+
+    size = convertSessionMap.getSize();
+    for (int i = 0; i < size; i++) {
+        ConvertSession *convSession = (ConvertSession*) convertSessionMap.getValueAt(i);
+        FwdLockConv_CloseSession(convSession->uniqueId, &(convSession->output));
+    }
 }
 
 int FwdLockEngine::getConvertedStatus(FwdLockConv_Status_t status) {
@@ -74,12 +92,12 @@
         case FwdLockConv_Status_InvalidArgument:
         case FwdLockConv_Status_UnsupportedFileFormat:
         case FwdLockConv_Status_UnsupportedContentTransferEncoding:
-            LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \
+            LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
                   "Returning STATUS_INPUTDATA_ERROR", status);
             retStatus = DrmConvertedStatus::STATUS_INPUTDATA_ERROR;
             break;
         default:
-            LOGD("FwdLockEngine getConvertedStatus: file conversion Error %d. " \
+            LOGE("FwdLockEngine getConvertedStatus: file conversion Error %d. "
                   "Returning STATUS_ERROR", status);
             retStatus = DrmConvertedStatus::STATUS_ERROR;
             break;
@@ -91,7 +109,7 @@
 DrmConstraints* FwdLockEngine::onGetConstraints(int uniqueId, const String8* path, int action) {
     DrmConstraints* drmConstraints = NULL;
 
-    LOGV("FwdLockEngine::onGetConstraints");
+    LOG_VERBOSE("FwdLockEngine::onGetConstraints");
 
     if (NULL != path &&
         (RightsStatus::RIGHTS_VALID == onCheckRightsStatus(uniqueId, *path, action))) {
@@ -105,7 +123,7 @@
 DrmMetadata* FwdLockEngine::onGetMetadata(int uniqueId, const String8* path) {
     DrmMetadata* drmMetadata = NULL;
 
-    LOGV("FwdLockEngine::onGetMetadata");
+    LOG_VERBOSE("FwdLockEngine::onGetMetadata");
 
     if (NULL != path) {
         // Returns empty metadata to show no error condition.
@@ -116,13 +134,12 @@
 }
 
 android::status_t FwdLockEngine::onInitialize(int uniqueId) {
-    LOGV("FwdLockEngine::onInitialize");
-
+    LOG_VERBOSE("FwdLockEngine::onInitialize");
 
     if (FwdLockGlue_InitializeKeyEncryption()) {
-        LOGV("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
+        LOG_VERBOSE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption succeeded");
     } else {
-        LOGD("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
+        LOGE("FwdLockEngine::onInitialize -- FwdLockGlue_InitializeKeyEncryption failed:"
              "errno = %d", errno);
     }
 
@@ -132,13 +149,13 @@
 android::status_t
 FwdLockEngine::onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
     // Not used
-    LOGV("FwdLockEngine::onSetOnInfoListener");
+    LOG_VERBOSE("FwdLockEngine::onSetOnInfoListener");
 
     return DRM_NO_ERROR;
 }
 
 android::status_t FwdLockEngine::onTerminate(int uniqueId) {
-    LOGV("FwdLockEngine::onTerminate");
+    LOG_VERBOSE("FwdLockEngine::onTerminate");
 
     return DRM_NO_ERROR;
 }
@@ -146,7 +163,7 @@
 DrmSupportInfo* FwdLockEngine::onGetSupportInfo(int uniqueId) {
     DrmSupportInfo* pSupportInfo = new DrmSupportInfo();
 
-    LOGV("FwdLockEngine::onGetSupportInfo");
+    LOG_VERBOSE("FwdLockEngine::onGetSupportInfo");
 
     // fill all Forward Lock mimetypes and extensions
     if (NULL != pSupportInfo) {
@@ -182,7 +199,7 @@
 
     drmInfoStatus = new DrmInfoStatus((int)DrmInfoStatus::STATUS_OK, 0, NULL, String8(""));
 
-    LOGV("FwdLockEngine::onProcessDrmInfo");
+    LOG_VERBOSE("FwdLockEngine::onProcessDrmInfo");
 
     return drmInfoStatus;
 }
@@ -193,7 +210,7 @@
             const String8& rightsPath,
             const String8& contentPath) {
     // No rights to save. Return
-    LOGV("FwdLockEngine::onSaveRights");
+    LOG_VERBOSE("FwdLockEngine::onSaveRights");
     return DRM_ERROR_UNKNOWN;
 }
 
@@ -201,7 +218,7 @@
     DrmInfo* drmInfo = NULL;
 
     // Nothing to be done for Forward Lock file
-    LOGV("FwdLockEngine::onAcquireDrmInfo");
+    LOG_VERBOSE("FwdLockEngine::onAcquireDrmInfo");
 
     return drmInfo;
 }
@@ -211,7 +228,7 @@
                                        int action) {
     int result = RightsStatus::RIGHTS_INVALID;
 
-    LOGV("FwdLockEngine::onCheckRightsStatus");
+    LOG_VERBOSE("FwdLockEngine::onCheckRightsStatus");
 
     // Only Transfer action is not allowed for forward Lock files.
     if (onCanHandle(uniqueId, path)) {
@@ -241,7 +258,7 @@
                                         int action,
                                         bool reserve) {
     // No rights consumption
-    LOGV("FwdLockEngine::onConsumeRights");
+    LOG_VERBOSE("FwdLockEngine::onConsumeRights");
     return DRM_NO_ERROR;
 }
 
@@ -249,14 +266,14 @@
                                      const String8& path,
                                      int action,
                                      const ActionDescription& description) {
-    LOGV("FwdLockEngine::onValidateAction");
+    LOG_VERBOSE("FwdLockEngine::onValidateAction");
 
     // For the forwardlock engine checkRights and ValidateAction are the same.
     return (onCheckRightsStatus(uniqueId, path, action) == RightsStatus::RIGHTS_VALID);
 }
 
 String8 FwdLockEngine::onGetOriginalMimeType(int uniqueId, const String8& path) {
-    LOGV("FwdLockEngine::onGetOriginalMimeType");
+    LOG_VERBOSE("FwdLockEngine::onGetOriginalMimeType");
     String8 mimeString = String8("");
     int fileDesc = FwdLockFile_open(path.string());
 
@@ -280,7 +297,7 @@
                                       const String8& mimeType) {
     String8 mimeStr = String8(mimeType);
 
-    LOGV("FwdLockEngine::onGetDrmObjectType");
+    LOG_VERBOSE("FwdLockEngine::onGetDrmObjectType");
 
     mimeStr.toLower();
 
@@ -301,13 +318,13 @@
 
 status_t FwdLockEngine::onRemoveRights(int uniqueId, const String8& path) {
     // No Rights to remove
-    LOGV("FwdLockEngine::onRemoveRights");
+    LOG_VERBOSE("FwdLockEngine::onRemoveRights");
     return DRM_NO_ERROR;
 }
 
 status_t FwdLockEngine::onRemoveAllRights(int uniqueId) {
     // No rights to remove
-    LOGV("FwdLockEngine::onRemoveAllRights");
+    LOG_VERBOSE("FwdLockEngine::onRemoveAllRights");
     return DRM_NO_ERROR;
 }
 
@@ -319,14 +336,14 @@
                                             int playbackStatus, int position) {
 #endif
     // Not used
-    LOGV("FwdLockEngine::onSetPlaybackStatus");
+    LOG_VERBOSE("FwdLockEngine::onSetPlaybackStatus");
     return DRM_NO_ERROR;
 }
 
 status_t FwdLockEngine::onOpenConvertSession(int uniqueId,
                                          int convertId) {
     status_t result = DRM_ERROR_UNKNOWN;
-    LOGV("FwdLockEngine::onOpenConvertSession");
+    LOG_VERBOSE("FwdLockEngine::onOpenConvertSession");
     if (!convertSessionMap.isCreated(convertId)) {
         ConvertSession *newSession = new ConvertSession();
         if (FwdLockConv_Status_OK ==
@@ -334,7 +351,7 @@
             convertSessionMap.addValue(convertId, newSession);
             result = DRM_NO_ERROR;
         } else {
-            LOGD("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
+            LOGE("FwdLockEngine::onOpenConvertSession -- FwdLockConv_OpenSession failed.");
             delete newSession;
         }
     }
@@ -383,7 +400,7 @@
     DrmBuffer *convResult = new DrmBuffer(NULL, 0);
     int offset = -1;
 
-    LOGV("FwdLockEngine::onCloseConvertSession");
+    LOG_VERBOSE("FwdLockEngine::onCloseConvertSession");
 
     if (convertSessionMap.isCreated(convertId)) {
         ConvertSession *convSession = convertSessionMap.getValue(convertId);
@@ -424,14 +441,14 @@
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     int fileDesc = -1;
 
-    LOGV("FwdLockEngine::onOpenDecryptSession");
+    LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession");
 
     if ((-1 < fd) &&
         (NULL != decryptHandle) &&
         (!decodeSessionMap.isCreated(decryptHandle->decryptId))) {
         fileDesc = dup(fd);
     } else {
-        LOGD("FwdLockEngine::onOpenDecryptSession parameter error");
+        LOGE("FwdLockEngine::onOpenDecryptSession parameter error");
         return result;
     }
 
@@ -453,7 +470,7 @@
             decryptHandle->decryptInfo = NULL;
             result = DRM_NO_ERROR;
         } else {
-            LOGD("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
+            LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Integrity Check failed for the fd");
             FwdLockFile_detach(fileDesc);
             delete decodeSession;
         }
@@ -463,7 +480,7 @@
         ::close(fileDesc);
     }
 
-    LOGV("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
+    LOG_VERBOSE("FwdLockEngine::onOpenDecryptSession Exit. result = %d", result);
 
     return result;
 }
@@ -500,7 +517,7 @@
 status_t FwdLockEngine::onCloseDecryptSession(int uniqueId,
                                               DecryptHandle* decryptHandle) {
     status_t result = DRM_ERROR_UNKNOWN;
-    LOGV("FwdLockEngine::onCloseDecryptSession");
+    LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession");
 
     if (NULL != decryptHandle && decodeSessionMap.isCreated(decryptHandle->decryptId)) {
         DecodeSession* session = decodeSessionMap.getValue(decryptHandle->decryptId);
@@ -525,7 +542,7 @@
         decryptHandle = NULL;
     }
 
-    LOGV("FwdLockEngine::onCloseDecryptSession Exit");
+    LOG_VERBOSE("FwdLockEngine::onCloseDecryptSession Exit");
     return result;
 }
 
@@ -533,13 +550,13 @@
                                                 DecryptHandle* decryptHandle,
                                                 int decryptUnitId,
                                                 const DrmBuffer* headerInfo) {
-    LOGV("FwdLockEngine::onInitializeDecryptUnit");
+    LOGE("FwdLockEngine::onInitializeDecryptUnit is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
 status_t FwdLockEngine::onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
-    LOGV("FwdLockEngine::onDecrypt");
+    LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
@@ -548,14 +565,14 @@
                                   int decryptUnitId,
                                   const DrmBuffer* encBuffer,
                                   DrmBuffer** decBuffer) {
-    LOGV("FwdLockEngine::onDecrypt");
+    LOGE("FwdLockEngine::onDecrypt is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
 status_t FwdLockEngine::onFinalizeDecryptUnit(int uniqueId,
                                               DecryptHandle* decryptHandle,
                                               int decryptUnitId) {
-    LOGV("FwdLockEngine::onFinalizeDecryptUnit");
+    LOGE("FwdLockEngine::onFinalizeDecryptUnit is not supported for this DRM scheme");
     return DRM_ERROR_UNKNOWN;
 }
 
@@ -633,11 +650,11 @@
         if (((off_t)-1) != decoderSession->offset) {
             bytesRead = onRead(uniqueId, decryptHandle, buffer, numBytes);
             if (bytesRead < 0) {
-                LOGD("FwdLockEngine::onPread error reading");
+                LOGE("FwdLockEngine::onPread error reading");
             }
         }
     } else {
-        LOGD("FwdLockEngine::onPread decryptId not found");
+        LOGE("FwdLockEngine::onPread decryptId not found");
     }
 
     return bytesRead;
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
index 14ea9e9..299116d 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/converter/FwdLockConv.c
@@ -275,17 +275,18 @@
 }
 
 /**
- * Checks whether a given character is valid in a boundary. Note that the boundary may contain
- * leading and internal spaces.
+ * Checks whether a given character is valid in a boundary. Allows some non-standard characters that
+ * are invalid according to RFC 2046 but nevertheless used by one vendor's DRM packager. Note that
+ * the boundary may contain leading and internal spaces.
  *
  * @param[in] ch The character to check.
  *
  * @return A Boolean value indicating whether the given character is valid in a boundary.
  */
 static int FwdLockConv_IsBoundaryChar(int ch) {
-    return isalnum(ch) || ch == '\'' ||
-            ch == '(' || ch == ')' || ch == '+' || ch == '_' || ch == ',' || ch == '-' ||
-            ch == '.' || ch == '/' || ch == ':' || ch == '=' || ch == '?' || ch == ' ';
+    return isalnum(ch) || ch == '\'' || ch == '(' || ch == ')' || ch == '+' || ch == '_' ||
+            ch == ',' || ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == '=' ||
+            ch == '?' || ch == ' ' || ch == '%' || ch == '[' || ch == '&' || ch == '*' || ch == '^';
 }
 
 /**
@@ -1085,6 +1086,13 @@
         status = FwdLockConv_MatchBinaryEncodedData(pSession, ch, pOutput);
         break;
     case FwdLockConv_ParserState_WantsBase64EncodedData:
+        if (ch == '\n' && pSession->scannerState != FwdLockConv_ScannerState_WantsLF) {
+            // Repair base64-encoded data that doesn't have carriage returns in its line breaks.
+            status = FwdLockConv_MatchBase64EncodedData(pSession, '\r', pOutput);
+            if (status != FwdLockConv_Status_OK) {
+                break;
+            }
+        }
         status = FwdLockConv_MatchBase64EncodedData(pSession, ch, pOutput);
         break;
     case FwdLockConv_ParserState_Done:
@@ -1199,7 +1207,7 @@
             status = FwdLockConv_Status_SyntaxError;
         } else {
             // Finalize the data signature.
-            size_t signatureSize;
+            unsigned int signatureSize = SHA1_HASH_SIZE;
             HMAC_Final(&pSession->signingContext, pOutput->fromCloseSession.signatures,
                        &signatureSize);
             if (signatureSize != SHA1_HASH_SIZE) {
@@ -1214,9 +1222,9 @@
                 HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
                             pSession->encryptedSessionKeyLength);
                 HMAC_Update(&pSession->signingContext, pOutput->fromCloseSession.signatures,
-                            signatureSize);
-                HMAC_Final(&pSession->signingContext, &pOutput->fromCloseSession.
-                           signatures[signatureSize], &signatureSize);
+                            SHA1_HASH_SIZE);
+                HMAC_Final(&pSession->signingContext,
+                           &pOutput->fromCloseSession.signatures[SHA1_HASH_SIZE], &signatureSize);
                 if (signatureSize != SHA1_HASH_SIZE) {
                     status = FwdLockConv_Status_ProgramError;
                 } else {
diff --git a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
index 98284e7..dacf00e 100644
--- a/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
+++ b/drm/libdrmframework/plugins/forward-lock/internal-format/decoder/FwdLockFile.c
@@ -114,7 +114,7 @@
 }
 
 /**
- * Finds the file session associated to the given file descriptor.
+ * Finds the file session associated with the given file descriptor.
  *
  * @param[in] fileDesc A file descriptor.
  *
@@ -389,7 +389,7 @@
                 result = FALSE;
             } else {
                 ssize_t numBytesRead;
-                size_t signatureSize = SHA1_HASH_SIZE;
+                unsigned int signatureSize = SHA1_HASH_SIZE;
                 while ((numBytesRead =
                         read(pSession->fileDesc, pData->buffer, SIG_CALC_BUFFER_SIZE)) > 0) {
                     HMAC_Update(&pSession->signingContext, pData->buffer, (size_t)numBytesRead);
@@ -399,7 +399,7 @@
                 } else {
                     HMAC_Final(&pSession->signingContext, pData->signature, &signatureSize);
                     assert(signatureSize == SHA1_HASH_SIZE);
-                    result = memcmp(pData->signature, pSession->dataSignature, signatureSize) == 0;
+                    result = memcmp(pData->signature, pSession->dataSignature, SHA1_HASH_SIZE) == 0;
                 }
                 HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
                 (void)lseek64(pSession->fileDesc, pSession->dataOffset + pSession->filePos,
@@ -419,16 +419,16 @@
     } else {
         FwdLockFile_Session_t *pSession = sessionPtrs[sessionId];
         unsigned char signature[SHA1_HASH_SIZE];
-        size_t signatureSize = SHA1_HASH_SIZE;
+        unsigned int signatureSize = SHA1_HASH_SIZE;
         HMAC_Update(&pSession->signingContext, pSession->topHeader, TOP_HEADER_SIZE);
         HMAC_Update(&pSession->signingContext, (unsigned char *)pSession->pContentType,
                     pSession->contentTypeLength);
         HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
                     pSession->encryptedSessionKeyLength);
-        HMAC_Update(&pSession->signingContext, pSession->dataSignature, signatureSize);
+        HMAC_Update(&pSession->signingContext, pSession->dataSignature, SHA1_HASH_SIZE);
         HMAC_Final(&pSession->signingContext, signature, &signatureSize);
         assert(signatureSize == SHA1_HASH_SIZE);
-        result = memcmp(signature, pSession->headerSignature, signatureSize) == 0;
+        result = memcmp(signature, pSession->headerSignature, SHA1_HASH_SIZE) == 0;
         HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
     }
     return result;