Update of DRM framework

 - Overload openDecryptSession() with uri parameter
   in order to accept URI of DRM content,
   Following API is added,
       DecryptHandle*openDecryptSession(const char* uri);.
 - Unify texisting three event types of processDrmInfo()
   so that caller of DRM framework does not have to handle many event types.
 - Let DrmManagerService call load/unload plugins API so that
   client of DRM framework does not have to manage plug-in load/unload.
 - Trivial fix in DrmManagerClient.java is also incorporated.

Changes are made by Sony Corporation.

Change-Id: If62b47fa0360718fdc943e6e6143671d7db26adc
diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
index 17cdf54..10c64ee 100644
--- a/drm/common/DrmEngineBase.cpp
+++ b/drm/common/DrmEngineBase.cpp
@@ -120,6 +120,11 @@
     return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length);
 }
 
+status_t DrmEngineBase::openDecryptSession(
+    int uniqueId, DecryptHandle* decryptHandle, const char* uri) {
+    return onOpenDecryptSession(uniqueId, decryptHandle, uri);
+}
+
 status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     return onCloseDecryptSession(uniqueId, decryptHandle);
 }
diff --git a/drm/common/DrmInfoStatus.cpp b/drm/common/DrmInfoStatus.cpp
index f3a1516..8ec7311 100644
--- a/drm/common/DrmInfoStatus.cpp
+++ b/drm/common/DrmInfoStatus.cpp
@@ -19,8 +19,9 @@
 using namespace android;
 
 DrmInfoStatus::DrmInfoStatus(
-    int _statusCode, const DrmBuffer* _drmBuffer, const String8& _mimeType) :
+    int _statusCode, int _infoType, const DrmBuffer* _drmBuffer, const String8& _mimeType) :
     statusCode(_statusCode),
+    infoType(_infoType),
     drmBuffer(_drmBuffer),
     mimeType(_mimeType) {
 
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index c28527c..b8ae852 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -53,27 +53,18 @@
     remote()->transact(REMOVE_UNIQUEID, data, &reply);
 }
 
-status_t BpDrmManagerService::loadPlugIns(int uniqueId) {
-    LOGV("load plugins");
+void BpDrmManagerService::addClient(int uniqueId) {
     Parcel data, reply;
-
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
-
-    remote()->transact(LOAD_PLUGINS, data, &reply);
-    return reply.readInt32();
+    remote()->transact(ADD_CLIENT, data, &reply);
 }
 
-status_t BpDrmManagerService::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
-    LOGV("load plugins from path");
+void BpDrmManagerService::removeClient(int uniqueId) {
     Parcel data, reply;
-
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
-    data.writeString8(plugInDirPath);
-
-    remote()->transact(LOAD_PLUGINS_FROM_PATH, data, &reply);
-    return reply.readInt32();
+    remote()->transact(REMOVE_CLIENT, data, &reply);
 }
 
 status_t BpDrmManagerService::setDrmServiceListener(
@@ -88,17 +79,6 @@
     return reply.readInt32();
 }
 
-status_t BpDrmManagerService::unloadPlugIns(int uniqueId) {
-    LOGV("unload plugins");
-    Parcel data, reply;
-
-    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
-    data.writeInt32(uniqueId);
-
-    remote()->transact(UNLOAD_PLUGINS, data, &reply);
-    return reply.readInt32();
-}
-
 status_t BpDrmManagerService::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
     LOGV("Install DRM Engine");
     Parcel data, reply;
@@ -191,6 +171,7 @@
     if (0 != reply.dataAvail()) {
         //Filling DRM Info Status
         const int statusCode = reply.readInt32();
+        const int infoType = reply.readInt32();
         const String8 mimeType = reply.readString8();
 
         DrmBuffer* drmBuffer = NULL;
@@ -203,7 +184,7 @@
             }
             drmBuffer = new DrmBuffer(data, bufferSize);
         }
-        drmInfoStatus = new DrmInfoStatus(statusCode, drmBuffer, mimeType);
+        drmInfoStatus = new DrmInfoStatus(statusCode, infoType, drmBuffer, mimeType);
     }
     return drmInfoStatus;
 }
@@ -538,8 +519,7 @@
     LOGV("Entering BpDrmManagerService::openDecryptSession");
     Parcel data, reply;
 
-    const String16 interfaceDescriptor = IDrmManagerService::getInterfaceDescriptor();
-    data.writeInterfaceToken(interfaceDescriptor);
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
     data.writeFileDescriptor(fd);
     data.writeInt32(offset);
@@ -565,6 +545,34 @@
     return handle;
 }
 
+DecryptHandle* BpDrmManagerService::openDecryptSession(int uniqueId, const char* uri) {
+    LOGV("Entering BpDrmManagerService::openDecryptSession");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(String8(uri));
+
+    remote()->transact(OPEN_DECRYPT_SESSION_FROM_URI, data, &reply);
+
+    DecryptHandle* handle = NULL;
+    if (0 != reply.dataAvail()) {
+        handle = new DecryptHandle();
+        handle->decryptId = reply.readInt32();
+        handle->mimeType = reply.readString8();
+        handle->decryptApiType = reply.readInt32();
+        handle->status = reply.readInt32();
+        handle->decryptInfo = NULL;
+        if (0 != reply.dataAvail()) {
+            handle->decryptInfo = new DecryptInfo();
+            handle->decryptInfo->decryptBufferLength = reply.readInt32();
+        }
+    } else {
+        LOGE("no decryptHandle is generated in service side");
+    }
+    return handle;
+}
+
 status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGV("closeDecryptSession");
     Parcel data, reply;
@@ -746,25 +754,19 @@
         return DRM_NO_ERROR;
     }
 
-    case LOAD_PLUGINS:
+    case ADD_CLIENT:
     {
-        LOGV("BnDrmManagerService::onTransact :LOAD_PLUGINS");
+        LOGV("BnDrmManagerService::onTransact :ADD_CLIENT");
         CHECK_INTERFACE(IDrmManagerService, data, reply);
-
-        status_t status = loadPlugIns(data.readInt32());
-
-        reply->writeInt32(status);
+        addClient(data.readInt32());
         return DRM_NO_ERROR;
     }
 
-    case LOAD_PLUGINS_FROM_PATH:
+    case REMOVE_CLIENT:
     {
-        LOGV("BnDrmManagerService::onTransact :LOAD_PLUGINS_FROM_PATH");
+        LOGV("BnDrmManagerService::onTransact :REMOVE_CLIENT");
         CHECK_INTERFACE(IDrmManagerService, data, reply);
-
-        status_t status = loadPlugIns(data.readInt32(), data.readString8());
-
-        reply->writeInt32(status);
+        removeClient(data.readInt32());
         return DRM_NO_ERROR;
     }
 
@@ -783,18 +785,6 @@
         return DRM_NO_ERROR;
     }
 
-    case UNLOAD_PLUGINS:
-    {
-        LOGV("BnDrmManagerService::onTransact :UNLOAD_PLUGINS");
-        CHECK_INTERFACE(IDrmManagerService, data, reply);
-
-        const int uniqueId = data.readInt32();
-        status_t status = unloadPlugIns(uniqueId);
-
-        reply->writeInt32(status);
-        return DRM_NO_ERROR;
-    }
-
     case INSTALL_DRM_ENGINE:
     {
         LOGV("BnDrmManagerService::onTransact :INSTALL_DRM_ENGINE");
@@ -881,6 +871,7 @@
         if (NULL != drmInfoStatus) {
             //Filling DRM Info Status contents
             reply->writeInt32(drmInfoStatus->statusCode);
+            reply->writeInt32(drmInfoStatus->infoType);
             reply->writeString8(drmInfoStatus->mimeType);
 
             if (NULL != drmInfoStatus->drmBuffer) {
@@ -1239,6 +1230,32 @@
         return DRM_NO_ERROR;
     }
 
+    case OPEN_DECRYPT_SESSION_FROM_URI:
+    {
+        LOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FROM_URI");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const String8 uri = data.readString8();
+
+        DecryptHandle* handle = openDecryptSession(uniqueId, uri.string());
+
+        if (NULL != handle) {
+            reply->writeInt32(handle->decryptId);
+            reply->writeString8(handle->mimeType);
+            reply->writeInt32(handle->decryptApiType);
+            reply->writeInt32(handle->status);
+            if (NULL != handle->decryptInfo) {
+                reply->writeInt32(handle->decryptInfo->decryptBufferLength);
+                delete handle->decryptInfo; handle->decryptInfo = NULL;
+            }
+        } else {
+            LOGE("NULL decryptHandle is returned");
+        }
+        delete handle; handle = NULL;
+        return DRM_NO_ERROR;
+    }
+
     case CLOSE_DECRYPT_SESSION:
     {
         LOGV("BnDrmManagerService::onTransact :CLOSE_DECRYPT_SESSION");
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 52527dc..b7a035f 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -85,22 +85,31 @@
     }
 }
 
-status_t DrmManager::loadPlugIns(int uniqueId) {
+status_t DrmManager::loadPlugIns() {
     String8 pluginDirPath("/system/lib/drm/plugins/native");
-    return loadPlugIns(uniqueId, pluginDirPath);
+    return loadPlugIns(pluginDirPath);
 }
 
-status_t DrmManager::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
+status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
     if (mSupportInfoToPlugInIdMap.isEmpty()) {
         mPlugInManager.loadPlugIns(plugInDirPath);
-
-        initializePlugIns(uniqueId);
-
-        populate(uniqueId);
-    } else {
-        initializePlugIns(uniqueId);
+        Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
+        for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+            String8 plugInPath = plugInPathList[i];
+            DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
+            if (NULL != info) {
+                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
+            }
+        }
     }
+    return DRM_NO_ERROR;
+}
 
+status_t DrmManager::unloadPlugIns() {
+    mConvertSessionMap.clear();
+    mDecryptSessionMap.clear();
+    mPlugInManager.unloadPlugIns();
+    mSupportInfoToPlugInIdMap.clear();
     return DRM_NO_ERROR;
 }
 
@@ -111,21 +120,23 @@
     return DRM_NO_ERROR;
 }
 
-status_t DrmManager::unloadPlugIns(int uniqueId) {
-    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
+void DrmManager::addClient(int uniqueId) {
+    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
+        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
+        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
+            rDrmEngine.initialize(uniqueId);
+            rDrmEngine.setOnInfoListener(uniqueId, this);
+        }
+    }
+}
 
+void DrmManager::removeClient(int uniqueId) {
+    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
     for (unsigned int index = 0; index < plugInIdList.size(); index++) {
         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
         rDrmEngine.terminate(uniqueId);
     }
-
-    if (0 >= mUniqueIdVector.size()) {
-        mConvertSessionMap.clear();
-        mDecryptSessionMap.clear();
-        mSupportInfoToPlugInIdMap.clear();
-        mPlugInManager.unloadPlugIns();
-    }
-    return DRM_NO_ERROR;
 }
 
 DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
@@ -144,7 +155,7 @@
     rDrmEngine.initialize(uniqueId);
     rDrmEngine.setOnInfoListener(uniqueId, this);
 
-    DrmSupportInfo* info = rDrmEngine.getSupportInfo(uniqueId);
+    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
     mSupportInfoToPlugInIdMap.add(*info, absolutePath);
 
     return DRM_NO_ERROR;
@@ -154,7 +165,7 @@
     const String8 plugInId = getSupportedPlugInId(mimeType);
     bool result = (EMPTY_STRING != plugInId) ? true : false;
 
-    if (NULL != path) {
+    if (0 < path.length()) {
         if (result) {
             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
             result = rDrmEngine.canHandle(uniqueId, path);
@@ -340,7 +351,7 @@
         for (int i = 0; i < size; ++i) {
             String8 plugInPath = plugInPathList[i];
             DrmSupportInfo* drmSupportInfo
-                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(uniqueId);
+                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
             if (NULL != drmSupportInfo) {
                 drmSupportInfoList.add(*drmSupportInfo);
                 delete drmSupportInfo; drmSupportInfo = NULL;
@@ -360,12 +371,12 @@
 }
 
 DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, int offset, int length) {
+    Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_CANNOT_HANDLE;
     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
 
     DecryptHandle* handle = new DecryptHandle();
     if (NULL != handle) {
-        Mutex::Autolock _l(mDecryptLock);
         handle->decryptId = mDecryptSessionId + 1;
 
         for (unsigned int index = 0; index < plugInIdList.size(); index++) {
@@ -380,16 +391,43 @@
             }
         }
     }
-
     if (DRM_NO_ERROR != result) {
         delete handle; handle = NULL;
         LOGE("DrmManager::openDecryptSession: no capable plug-in found");
     }
+    return handle;
+}
 
+DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
+    Mutex::Autolock _l(mDecryptLock);
+    status_t result = DRM_ERROR_CANNOT_HANDLE;
+    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
+
+    DecryptHandle* handle = new DecryptHandle();
+    if (NULL != handle) {
+        handle->decryptId = mDecryptSessionId + 1;
+
+        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+            String8 plugInId = plugInIdList.itemAt(index);
+            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
+
+            if (DRM_NO_ERROR == result) {
+                ++mDecryptSessionId;
+                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
+                break;
+            }
+        }
+    }
+    if (DRM_NO_ERROR != result) {
+        delete handle; handle = NULL;
+        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
+    }
     return handle;
 }
 
 status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    Mutex::Autolock _l(mDecryptLock);
     status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
@@ -443,28 +481,6 @@
     return result;
 }
 
-void DrmManager::initializePlugIns(int uniqueId) {
-    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
-
-    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
-        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
-        rDrmEngine.initialize(uniqueId);
-        rDrmEngine.setOnInfoListener(uniqueId, this);
-    }
-}
-
-void DrmManager::populate(int uniqueId) {
-    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
-
-    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
-        String8 plugInPath = plugInPathList[i];
-        DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(uniqueId);
-        if (NULL != info) {
-            mSupportInfoToPlugInIdMap.add(*info, plugInPath);
-        }
-    }
-}
-
 String8 DrmManager::getSupportedPlugInId(
             int uniqueId, const String8& path, const String8& mimeType) {
     String8 plugInId("");
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 843dddb..8cf510d 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -27,36 +27,21 @@
 
 using namespace android;
 
-#define SUCCESS 0
-#define DRM_DIRECTORY_PERMISSION 0700
-#define DRM_PLUGINS_ROOT "/data/drm/plugins"
-#define DRM_PLUGINS_NATIVE "/data/drm/plugins/native"
-#define DRM_PLUGINS_NATIVE_DATABASES "/data/drm/plugins/native/databases"
-
 void DrmManagerService::instantiate() {
     LOGV("instantiate");
-
-    int res = mkdir(DRM_PLUGINS_ROOT, DRM_DIRECTORY_PERMISSION);
-    if (SUCCESS == res || EEXIST == errno) {
-        res = mkdir(DRM_PLUGINS_NATIVE, DRM_DIRECTORY_PERMISSION);
-        if (SUCCESS == res || EEXIST == errno) {
-            res = mkdir(DRM_PLUGINS_NATIVE_DATABASES, DRM_DIRECTORY_PERMISSION);
-            if (SUCCESS == res || EEXIST == errno) {
-                defaultServiceManager()
-                    ->addService(String16("drm.drmManager"), new DrmManagerService());
-            }
-        }
-    }
+    defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
 }
 
-DrmManagerService::DrmManagerService() {
+DrmManagerService::DrmManagerService() :
+        mDrmManager(NULL) {
     LOGV("created");
-    mDrmManager = NULL;
     mDrmManager = new DrmManager();
+    mDrmManager->loadPlugIns();
 }
 
 DrmManagerService::~DrmManagerService() {
     LOGV("Destroyed");
+    mDrmManager->unloadPlugIns();
     delete mDrmManager; mDrmManager = NULL;
 }
 
@@ -68,14 +53,12 @@
     mDrmManager->removeUniqueId(uniqueId);
 }
 
-status_t DrmManagerService::loadPlugIns(int uniqueId) {
-    LOGV("Entering load plugins");
-    return mDrmManager->loadPlugIns(uniqueId);
+void DrmManagerService::addClient(int uniqueId) {
+    mDrmManager->addClient(uniqueId);
 }
 
-status_t DrmManagerService::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
-    LOGV("Entering load plugins from path");
-    return mDrmManager->loadPlugIns(uniqueId, plugInDirPath);
+void DrmManagerService::removeClient(int uniqueId) {
+    mDrmManager->removeClient(uniqueId);
 }
 
 status_t DrmManagerService::setDrmServiceListener(
@@ -85,11 +68,6 @@
     return DRM_NO_ERROR;
 }
 
-status_t DrmManagerService::unloadPlugIns(int uniqueId) {
-    LOGV("Entering unload plugins");
-    return mDrmManager->unloadPlugIns(uniqueId);
-}
-
 status_t DrmManagerService::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
     LOGV("Entering installDrmEngine");
     return mDrmManager->installDrmEngine(uniqueId, drmEngineFile);
@@ -197,6 +175,12 @@
     return mDrmManager->openDecryptSession(uniqueId, fd, offset, length);
 }
 
+DecryptHandle* DrmManagerService::openDecryptSession(
+            int uniqueId, const char* uri) {
+    LOGV("Entering DrmManagerService::openDecryptSession with uri");
+    return mDrmManager->openDecryptSession(uniqueId, uri);
+}
+
 status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGV("Entering closeDecryptSession");
     return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index c996994..f0439eb 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -22,36 +22,23 @@
 
 using namespace android;
 
-DrmManagerClient::DrmManagerClient() {
-    int uniqueId = 0;
-    mDrmManagerClientImpl = NULL;
-
-    mDrmManagerClientImpl = DrmManagerClientImpl::create(&uniqueId);
-    mUniqueId = uniqueId;
-
-    loadPlugIns();
+DrmManagerClient::DrmManagerClient():
+        mUniqueId(0), mDrmManagerClientImpl(NULL) {
+    mDrmManagerClientImpl = DrmManagerClientImpl::create(&mUniqueId);
+    mDrmManagerClientImpl->addClient(mUniqueId);
 }
 
 DrmManagerClient::~DrmManagerClient() {
     DrmManagerClientImpl::remove(mUniqueId);
-    unloadPlugIns();
-
+    mDrmManagerClientImpl->removeClient(mUniqueId);
     delete mDrmManagerClientImpl; mDrmManagerClientImpl = NULL;
 }
 
-status_t DrmManagerClient::loadPlugIns() {
-    return mDrmManagerClientImpl->loadPlugIns(mUniqueId);
-}
-
 status_t DrmManagerClient::setOnInfoListener(
                     const sp<DrmManagerClient::OnInfoListener>& infoListener) {
     return mDrmManagerClientImpl->setOnInfoListener(mUniqueId, infoListener);
 }
 
-status_t DrmManagerClient::unloadPlugIns() {
-    return mDrmManagerClientImpl->unloadPlugIns(mUniqueId);
-}
-
 DrmConstraints* DrmManagerClient::getConstraints(const String8* path, const int action) {
     return mDrmManagerClientImpl->getConstraints(mUniqueId, path, action);
 }
@@ -86,6 +73,7 @@
 }
 
 status_t DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+    Mutex::Autolock _l(mDecryptLock);
     return mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
 }
 
@@ -128,12 +116,17 @@
     return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
 }
 
+DecryptHandle* DrmManagerClient::openDecryptSession(const char* uri) {
+    return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri);
+}
+
 status_t DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
     return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
 }
 
 status_t DrmManagerClient::initializeDecryptUnit(
             DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    Mutex::Autolock _l(mDecryptLock);
     return mDrmManagerClientImpl->initializeDecryptUnit(
             mUniqueId, decryptHandle, decryptUnitId, headerInfo);
 }
@@ -141,16 +134,19 @@
 status_t DrmManagerClient::decrypt(
     DecryptHandle* decryptHandle, int decryptUnitId,
     const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+    Mutex::Autolock _l(mDecryptLock);
     return mDrmManagerClientImpl->decrypt(
             mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
 status_t DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
+    Mutex::Autolock _l(mDecryptLock);
     return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmManagerClient::pread(
             DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off_t offset) {
+    Mutex::Autolock _l(mDecryptLock);
     return mDrmManagerClientImpl->pread(mUniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index 272adcd..b3ae9a7 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -46,14 +46,6 @@
     getDrmManagerService()->removeUniqueId(uniqueId);
 }
 
-DrmManagerClientImpl::DrmManagerClientImpl() {
-
-}
-
-DrmManagerClientImpl::~DrmManagerClientImpl() {
-
-}
-
 const sp<IDrmManagerService>& DrmManagerClientImpl::getDrmManagerService() {
     mMutex.lock();
     if (NULL == mDrmManagerService.get()) {
@@ -77,16 +69,12 @@
     return mDrmManagerService;
 }
 
-status_t DrmManagerClientImpl::loadPlugIns(int uniqueId) {
-    return getDrmManagerService()->loadPlugIns(uniqueId);
+void DrmManagerClientImpl::addClient(int uniqueId) {
+    getDrmManagerService()->addClient(uniqueId);
 }
 
-status_t DrmManagerClientImpl::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
-    status_t status = DRM_ERROR_UNKNOWN;
-    if (EMPTY_STRING != plugInDirPath) {
-        status = getDrmManagerService()->loadPlugIns(uniqueId, plugInDirPath);
-    }
-    return status;
+void DrmManagerClientImpl::removeClient(int uniqueId) {
+    getDrmManagerService()->removeClient(uniqueId);
 }
 
 status_t DrmManagerClientImpl::setOnInfoListener(
@@ -96,10 +84,6 @@
     return getDrmManagerService()->setDrmServiceListener(uniqueId, this);
 }
 
-status_t DrmManagerClientImpl::unloadPlugIns(int uniqueId) {
-    return getDrmManagerService()->unloadPlugIns(uniqueId);
-}
-
 status_t DrmManagerClientImpl::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
     status_t status = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != drmEngineFile) {
@@ -251,6 +235,14 @@
     return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length);
 }
 
+DecryptHandle* DrmManagerClientImpl::openDecryptSession(int uniqueId, const char* uri) {
+    DecryptHandle* handle = NULL;
+    if (NULL != uri) {
+        handle = getDrmManagerService()->openDecryptSession(uniqueId, uri);
+    }
+    return handle;
+}
+
 status_t DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle) {
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index dc3e460..d782f5b 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -57,15 +57,19 @@
 
     void removeUniqueId(int uniqueId);
 
-    status_t loadPlugIns(int uniqueId);
+    void addClient(int uniqueId);
 
-    status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+    void removeClient(int uniqueId);
+
+    status_t loadPlugIns();
+
+    status_t loadPlugIns(const String8& plugInDirPath);
+
+    status_t unloadPlugIns();
 
     status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
 
-    status_t unloadPlugIns(int uniqueId);
-
     status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
 
     DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
@@ -107,6 +111,8 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
+    DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
@@ -129,12 +135,8 @@
 
     String8 getSupportedPlugInIdFromPath(int uniqueId, const String8& path);
 
-    void populate(int uniqueId);
-
     bool canHandle(int uniqueId, const String8& path);
 
-    void initializePlugIns(int uniqueId);
-
 private:
     static Vector<int> mUniqueIdVector;
     static const String8 EMPTY_STRING;
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 492c7f5..1c6be46 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -35,36 +35,29 @@
  */
 class DrmManagerClientImpl : public BnDrmServiceListener {
 private:
-    DrmManagerClientImpl();
+    DrmManagerClientImpl() { }
 
 public:
     static DrmManagerClientImpl* create(int* pUniqueId);
 
     static void remove(int uniqueId);
 
-    virtual ~DrmManagerClientImpl();
+    virtual ~DrmManagerClientImpl() { }
 
 public:
     /**
-     * Initialize DRM Manager
-     *     load available plug-ins from default plugInDirPath
+     * Adds the client respective to given unique id.
      *
      * @param[in] uniqueId Unique identifier for a session
-     * @return status_t
-     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t loadPlugIns(int uniqueId);
+    void addClient(int uniqueId);
 
     /**
-     * Finalize DRM Manager
-     *     release resources associated with each plug-in
-     *     unload all plug-ins and etc.
+     * Removes the client respective to given unique id.
      *
      * @param[in] uniqueId Unique identifier for a session
-     * @return status_t
-     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t unloadPlugIns(int uniqueId);
+    void removeClient(int uniqueId);
 
     /**
      * Register a callback to be invoked when the caller required to
@@ -301,6 +294,16 @@
     DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] uri Path of the protected content to be decrypted
+     * @return
+     *     Handle for the decryption session
+     */
+    DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
@@ -379,17 +382,6 @@
 
 private:
     /**
-     * Initialize DRM Manager
-     *     load available plug-ins from plugInDirPath
-     *
-     * @param[in] uniqueId Unique identifier for a session
-     * @param[in] plugInDirPath Directory from where to load plug-ins
-     * @return status_t
-     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
-     */
-    status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
-
-    /**
      * Install new DRM Engine Plug-in at the runtime
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index f455e15..4a3aeae 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -50,15 +50,13 @@
 
     void removeUniqueId(int uniqueId);
 
-    status_t loadPlugIns(int uniqueId);
+    void addClient(int uniqueId);
 
-    status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+    void removeClient(int uniqueId);
 
     status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
 
-    status_t unloadPlugIns(int uniqueId);
-
     status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
 
     DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
@@ -100,6 +98,8 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
+    DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index 5c668ed..1275488 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -46,10 +46,9 @@
     enum {
         ADD_UNIQUEID = IBinder::FIRST_CALL_TRANSACTION,
         REMOVE_UNIQUEID,
-        LOAD_PLUGINS,
-        LOAD_PLUGINS_FROM_PATH,
+        ADD_CLIENT,
+        REMOVE_CLIENT,
         SET_DRM_SERVICE_LISTENER,
-        UNLOAD_PLUGINS,
         INSTALL_DRM_ENGINE,
         GET_CONSTRAINTS_FROM_CONTENT,
         CAN_HANDLE,
@@ -69,6 +68,7 @@
         CLOSE_CONVERT_SESSION,
         GET_ALL_SUPPORT_INFO,
         OPEN_DECRYPT_SESSION,
+        OPEN_DECRYPT_SESSION_FROM_URI,
         CLOSE_DECRYPT_SESSION,
         INITIALIZE_DECRYPT_UNIT,
         DECRYPT,
@@ -84,15 +84,13 @@
 
     virtual void removeUniqueId(int uniqueId) = 0;
 
-    virtual status_t loadPlugIns(int uniqueId) = 0;
+    virtual void addClient(int uniqueId) = 0;
 
-    virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath) = 0;
+    virtual void removeClient(int uniqueId) = 0;
 
     virtual status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& infoListener) = 0;
 
-    virtual status_t unloadPlugIns(int uniqueId) = 0;
-
     virtual status_t installDrmEngine(int uniqueId, const String8& drmEngineFile) = 0;
 
     virtual DrmConstraints* getConstraints(
@@ -140,6 +138,8 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length) = 0;
 
+    virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri) = 0;
+
     virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
 
     virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
@@ -168,15 +168,13 @@
 
     virtual void removeUniqueId(int uniqueId);
 
-    virtual status_t loadPlugIns(int uniqueId);
+    virtual void addClient(int uniqueId);
 
-    virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+    virtual void removeClient(int uniqueId);
 
     virtual status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& infoListener);
 
-    virtual status_t unloadPlugIns(int uniqueId);
-
     virtual status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
 
     virtual DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
@@ -221,6 +219,8 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
+    virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+
     virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index b355534..5851af5 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -80,6 +80,9 @@
     status_t openDecryptSession(
             int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
 
+    status_t openDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, const char* uri);
+
     status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
@@ -355,6 +358,18 @@
             int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int 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] 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;
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
index b711500..cc03ef2 100644
--- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -315,6 +315,18 @@
         int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int 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] 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 openDecryptSession(
+        int uniqueId, DecryptHandle* decryptHandle, const char* uri) = 0;
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] uniqueId Unique identifier for a session
diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
index eed1628..ddb7fd3 100644
--- a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
+++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
@@ -74,6 +74,9 @@
     status_t onOpenDecryptSession(
             int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
 
+    status_t onOpenDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, const char* uri);
+
     status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
index 4c7714d..41f8e91 100644
--- a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -74,14 +74,14 @@
         switch (drmInfo->getInfoType()) {
         case DrmInfoRequest::TYPE_REGISTRATION_INFO: {
             const DrmBuffer* emptyBuffer = new DrmBuffer();
-            drmInfoStatus
-                = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType());
+            drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
+                    DrmInfoRequest::TYPE_REGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
             break;
         }
         case DrmInfoRequest::TYPE_UNREGISTRATION_INFO: {
             const DrmBuffer* emptyBuffer = new DrmBuffer();
-            drmInfoStatus
-                = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType());
+            drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
+                    DrmInfoRequest::TYPE_UNREGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
             break;
         }
         case DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO: {
@@ -91,8 +91,8 @@
             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());
+            drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
+                    DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, buffer, drmInfo->getMimeType());
             break;
         }
         }
@@ -243,6 +243,11 @@
     return DRM_ERROR_CANNOT_HANDLE;
 }
 
+status_t DrmPassthruPlugIn::onOpenDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, const char* uri) {
+    return DRM_ERROR_CANNOT_HANDLE;
+}
+
 status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGD("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
     if (NULL != decryptHandle) {
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index c722bd3..7b409ff 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -59,8 +59,8 @@
     //! TYPE_NO_INTERNET_CONNECTION, when the Internet connection is missing and no attempt
     //! can be made to renew rights
     static const int TYPE_NO_INTERNET_CONNECTION = 2005;
-    //! TYPE_REGISTRATION_FAILED, when registration with server failed.
-    static const int TYPE_REGISTRATION_FAILED = 2006;
+    //! TYPE_PROCESS_DRM_INFO_FAILED, when failed to process DrmInfo.
+    static const int TYPE_PROCESS_DRM_INFO_FAILED = 2006;
 
 public:
     /**
diff --git a/include/drm/DrmInfoStatus.h b/include/drm/DrmInfoStatus.h
index 806aea1..88c0f40 100644
--- a/include/drm/DrmInfoStatus.h
+++ b/include/drm/DrmInfoStatus.h
@@ -41,10 +41,11 @@
      * Constructor for DrmInfoStatus
      *
      * @param[in] _statusCode Status of the communication
+     * @param[in] _infoType Type of the DRM information processed
      * @param[in] _drmBuffer Rights information
      * @param[in] _mimeType MIME type
      */
-    DrmInfoStatus(int _statusCode, const DrmBuffer* _drmBuffer, const String8& _mimeType);
+    DrmInfoStatus(int _statusCode, int _infoType, const DrmBuffer* _drmBuffer, const String8& _mimeType);
 
     /**
      * Destructor for DrmInfoStatus
@@ -55,6 +56,7 @@
 
 public:
     int statusCode;
+    int infoType;
     const DrmBuffer* drmBuffer;
     String8 mimeType;
 };
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index c2ad084..5963c42 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -17,6 +17,7 @@
 #ifndef __DRM_MANAGER_CLIENT_H__
 #define __DRM_MANAGER_CLIENT_H__
 
+#include <utils/threads.h>
 #include <binder/IInterface.h>
 #include "drm_framework_common.h"
 
@@ -67,6 +68,15 @@
     DecryptHandle* openDecryptSession(int fd, int offset, int length);
 
     /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uri Path of the protected content to be decrypted
+     * @return
+     *     Handle for the decryption session
+     */
+    DecryptHandle* openDecryptSession(const char* uri);
+
+    /**
      * Close the decrypt session for the given handle
      *
      * @param[in] decryptHandle Handle for the decryption session
@@ -339,27 +349,8 @@
     status_t getAllSupportInfo(int* length, DrmSupportInfo** drmSupportInfoArray);
 
 private:
-    /**
-     * Initialize DRM Manager
-     *     load available plug-ins from default plugInDirPath
-     *
-     * @return status_t
-     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
-     */
-    status_t loadPlugIns();
-
-    /**
-     * Finalize DRM Manager
-     *    release resources associated with each plug-in
-     *    unload all plug-ins and etc.
-     *
-     * @return status_t
-     *    Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
-     */
-    status_t unloadPlugIns();
-
-private:
     int mUniqueId;
+    Mutex mDecryptLock;
     DrmManagerClientImpl* mDrmManagerClientImpl;
 };