diff --git a/drm/common/Android.mk b/drm/common/Android.mk
new file mode 100644
index 0000000..808b2c2
--- /dev/null
+++ b/drm/common/Android.mk
@@ -0,0 +1,43 @@
+#
+# 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:= \
+    DrmConstraints.cpp \
+    DrmConvertedStatus.cpp \
+    DrmEngineBase.cpp \
+    DrmInfo.cpp \
+    DrmInfoRequest.cpp \
+    DrmInfoStatus.cpp \
+    DrmRights.cpp \
+    DrmSupportInfo.cpp \
+    IDrmIOService.cpp \
+    IDrmManagerService.cpp \
+    IDrmServiceListener.cpp \
+    DrmInfoEvent.cpp \
+    ReadWriteUtils.cpp
+
+LOCAL_C_INCLUDES := \
+    $(TOP)/frameworks/base/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/plugins/common/include
+
+LOCAL_MODULE:= libdrmframeworkcommon
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/drm/common/DrmConstraints.cpp b/drm/common/DrmConstraints.cpp
new file mode 100644
index 0000000..11ce410
--- /dev/null
+++ b/drm/common/DrmConstraints.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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 <drm/DrmConstraints.h>
+
+using namespace android;
+
+const String8 DrmConstraints::MAX_REPEAT_COUNT("max_repeat_count");
+const String8 DrmConstraints::REMAINING_REPEAT_COUNT("remaining_repeat_count");
+const String8 DrmConstraints::LICENSE_START_TIME("license_start_time");
+const String8 DrmConstraints::LICENSE_EXPIRY_TIME("license_expiry_time");
+const String8 DrmConstraints::LICENSE_AVAILABLE_TIME("license_available_time");
+const String8 DrmConstraints::EXTENDED_METADATA("extended_metadata");
+
+int DrmConstraints::getCount(void) const {
+    return mConstraintMap.size();
+}
+
+status_t DrmConstraints::put(const String8* key, const char* value) {
+    int length = strlen(value);
+    char* charValue = new char[length + 1];
+    if (NULL != charValue) {
+        strncpy(charValue, value, length);
+        charValue[length] = '\0';
+        mConstraintMap.add(*key, charValue);
+    }
+    return DRM_NO_ERROR;
+}
+
+String8 DrmConstraints::get(const String8& key) const {
+    if (NULL != getValue(&key)) {
+        return String8(getValue(&key));
+    }
+    return String8("");
+}
+
+const char* DrmConstraints::getValue(const String8* key) const {
+    if (NAME_NOT_FOUND != mConstraintMap.indexOfKey(*key)) {
+        return mConstraintMap.valueFor(*key);
+    }
+    return NULL;
+}
+
+const char* DrmConstraints::getAsByteArray(const String8* key) const {
+    return getValue(key);
+}
+
+bool DrmConstraints::KeyIterator::hasNext() {
+    return mIndex < mDrmConstraints->mConstraintMap.size();
+}
+
+const String8& DrmConstraints::KeyIterator::next() {
+    const String8& key = mDrmConstraints->mConstraintMap.keyAt(mIndex);
+    mIndex++;
+    return key;
+}
+
+DrmConstraints::KeyIterator DrmConstraints::keyIterator() {
+    return KeyIterator(this);
+}
+
+DrmConstraints::KeyIterator::KeyIterator(const DrmConstraints::KeyIterator& keyIterator)
+    : mDrmConstraints(keyIterator.mDrmConstraints),
+      mIndex(keyIterator.mIndex) {
+    LOGV("DrmConstraints::KeyIterator::KeyIterator");
+}
+
+DrmConstraints::KeyIterator& DrmConstraints::KeyIterator::operator=(
+    const DrmConstraints::KeyIterator& keyIterator) {
+    LOGV("DrmConstraints::KeyIterator::operator=");
+    mDrmConstraints = keyIterator.mDrmConstraints;
+    mIndex = keyIterator.mIndex;
+    return *this;
+}
+
+
+DrmConstraints::Iterator DrmConstraints::iterator() {
+    return Iterator(this);
+}
+
+DrmConstraints::Iterator::Iterator(const DrmConstraints::Iterator& iterator) :
+    mDrmConstraints(iterator.mDrmConstraints),
+    mIndex(iterator.mIndex) {
+    LOGV("DrmConstraints::Iterator::Iterator");
+}
+
+DrmConstraints::Iterator& DrmConstraints::Iterator::operator=(
+    const DrmConstraints::Iterator& iterator) {
+    LOGV("DrmConstraints::Iterator::operator=");
+    mDrmConstraints = iterator.mDrmConstraints;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmConstraints::Iterator::hasNext() {
+    return mIndex < mDrmConstraints->mConstraintMap.size();
+}
+
+String8 DrmConstraints::Iterator::next() {
+    String8 value = String8(mDrmConstraints->mConstraintMap.editValueAt(mIndex));
+    mIndex++;
+    return value;
+}
+
diff --git a/drm/common/DrmConvertedStatus.cpp b/drm/common/DrmConvertedStatus.cpp
new file mode 100644
index 0000000..5d035f5
--- /dev/null
+++ b/drm/common/DrmConvertedStatus.cpp
@@ -0,0 +1,28 @@
+/*
+ * 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 <drm/DrmConvertedStatus.h>
+
+using namespace android;
+
+DrmConvertedStatus::DrmConvertedStatus(
+    int _statusCode, const DrmBuffer* _convertedData, int _offset) :
+    statusCode(_statusCode),
+    convertedData(_convertedData),
+    offset(_offset) {
+
+}
+
diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
new file mode 100644
index 0000000..70398e8
--- /dev/null
+++ b/drm/common/DrmEngineBase.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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 "DrmEngineBase.h"
+
+using namespace android;
+
+DrmEngineBase::DrmEngineBase() {
+
+}
+
+DrmEngineBase::~DrmEngineBase() {
+
+}
+
+DrmConstraints* DrmEngineBase::getConstraints(
+    int uniqueId, const String8* path, int action) {
+    return onGetConstraints(uniqueId, path, action);
+}
+
+status_t DrmEngineBase::initialize(int uniqueId) {
+    return onInitialize(uniqueId);
+}
+
+status_t DrmEngineBase::setOnInfoListener(
+    int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
+    return onSetOnInfoListener(uniqueId, infoListener);
+}
+
+status_t DrmEngineBase::terminate(int uniqueId) {
+    return onTerminate(uniqueId);
+}
+
+bool DrmEngineBase::canHandle(int uniqueId, const String8& path) {
+    return onCanHandle(uniqueId, path);
+}
+
+DrmInfoStatus* DrmEngineBase::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    return onProcessDrmInfo(uniqueId, drmInfo);
+}
+
+void DrmEngineBase::saveRights(
+            int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    return onSaveRights(uniqueId, drmRights, rightsPath, contentPath);
+}
+
+DrmInfo* DrmEngineBase::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    return onAcquireDrmInfo(uniqueId, drmInfoRequest);
+}
+
+String8 DrmEngineBase::getOriginalMimeType(int uniqueId, const String8& path) {
+    return onGetOriginalMimeType(uniqueId, path);
+}
+
+int DrmEngineBase::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
+    return onGetDrmObjectType(uniqueId, path, mimeType);
+}
+
+int DrmEngineBase::checkRightsStatus(int uniqueId, const String8& path, int action) {
+    return onCheckRightsStatus(uniqueId, path, action);
+}
+
+void DrmEngineBase::consumeRights(
+    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    onConsumeRights(uniqueId, decryptHandle, action, reserve);
+}
+
+void DrmEngineBase::setPlaybackStatus(
+    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    onSetPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+}
+
+bool DrmEngineBase::validateAction(
+    int uniqueId, const String8& path,
+    int action, const ActionDescription& description) {
+    return onValidateAction(uniqueId, path, action, description);
+}
+
+void DrmEngineBase::removeRights(int uniqueId, const String8& path) {
+    onRemoveRights(uniqueId, path);
+}
+
+void DrmEngineBase::removeAllRights(int uniqueId) {
+    onRemoveAllRights(uniqueId);
+}
+
+void DrmEngineBase::openConvertSession(int uniqueId, int convertId) {
+    onOpenConvertSession(uniqueId, convertId);
+}
+
+DrmConvertedStatus* DrmEngineBase::convertData(
+    int uniqueId, int convertId, const DrmBuffer* inputData) {
+    return onConvertData(uniqueId, convertId, inputData);
+}
+
+DrmConvertedStatus* DrmEngineBase::closeConvertSession(int uniqueId, int convertId) {
+    return onCloseConvertSession(uniqueId, convertId);
+}
+
+DrmSupportInfo* DrmEngineBase::getSupportInfo(int uniqueId) {
+    return onGetSupportInfo(uniqueId);
+}
+
+status_t DrmEngineBase::openDecryptSession(
+    int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) {
+    return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length);
+}
+
+void DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    onCloseDecryptSession(uniqueId, decryptHandle);
+}
+
+void DrmEngineBase::initializeDecryptUnit(
+    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    onInitializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
+}
+
+status_t DrmEngineBase::decrypt(
+    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    return onDecrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+}
+
+void DrmEngineBase::finalizeDecryptUnit(
+    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    onFinalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+}
+
+ssize_t DrmEngineBase::pread(
+    int uniqueId, DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off_t offset) {
+    return onPread(uniqueId, decryptHandle, buffer, numBytes, offset);
+}
+
diff --git a/drm/common/DrmInfo.cpp b/drm/common/DrmInfo.cpp
new file mode 100644
index 0000000..ddcab33
--- /dev/null
+++ b/drm/common/DrmInfo.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 <drm/DrmInfo.h>
+
+using namespace android;
+
+DrmInfo::DrmInfo(int infoType, const DrmBuffer& drmBuffer, const String8& mimeType) :
+    mInfoType(infoType),
+    mData(drmBuffer),
+    mMimeType(mimeType) {
+
+}
+
+int DrmInfo::getInfoType(void) const {
+    return mInfoType;
+}
+
+String8 DrmInfo::getMimeType(void) const {
+    return mMimeType;
+}
+
+const DrmBuffer& DrmInfo::getData(void) const {
+    return mData;
+}
+
+int DrmInfo::getCount(void) const {
+    return mAttributes.size();
+}
+
+status_t DrmInfo::put(const String8& key, const String8& value) {
+    mAttributes.add(key, value);
+    return DRM_NO_ERROR;
+}
+
+String8 DrmInfo::get(const String8& key) const {
+    if (NAME_NOT_FOUND != mAttributes.indexOfKey(key)) {
+        return mAttributes.valueFor(key);
+    }
+    return String8("");
+}
+
+int DrmInfo::indexOfKey(const String8& key) const {
+    return mAttributes.indexOfKey(key);
+}
+
+DrmInfo::KeyIterator DrmInfo::keyIterator() const {
+    return KeyIterator(this);
+}
+
+DrmInfo::Iterator DrmInfo::iterator() const {
+    return Iterator(this);
+}
+
+// KeyIterator implementation
+DrmInfo::KeyIterator::KeyIterator(const DrmInfo::KeyIterator& keyIterator) :
+    mDrmInfo(keyIterator.mDrmInfo), mIndex(keyIterator.mIndex) {
+
+}
+
+bool DrmInfo::KeyIterator::hasNext() {
+    return (mIndex < mDrmInfo->mAttributes.size());
+}
+
+const String8& DrmInfo::KeyIterator::next() {
+    const String8& key = mDrmInfo->mAttributes.keyAt(mIndex);
+    mIndex++;
+    return key;
+}
+
+DrmInfo::KeyIterator& DrmInfo::KeyIterator::operator=(const DrmInfo::KeyIterator& keyIterator) {
+    mDrmInfo = keyIterator.mDrmInfo;
+    mIndex = keyIterator.mIndex;
+    return *this;
+}
+
+// Iterator implementation
+DrmInfo::Iterator::Iterator(const DrmInfo::Iterator& iterator)
+    : mDrmInfo(iterator.mDrmInfo), mIndex(iterator.mIndex) {
+
+}
+
+DrmInfo::Iterator& DrmInfo::Iterator::operator=(const DrmInfo::Iterator& iterator) {
+    mDrmInfo = iterator.mDrmInfo;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmInfo::Iterator::hasNext() {
+    return mIndex < mDrmInfo->mAttributes.size();
+}
+
+String8& DrmInfo::Iterator::next() {
+    String8& value = mDrmInfo->mAttributes.editValueAt(mIndex);
+    mIndex++;
+    return value;
+}
+
diff --git a/drm/common/DrmInfoEvent.cpp b/drm/common/DrmInfoEvent.cpp
new file mode 100644
index 0000000..eb58129
--- /dev/null
+++ b/drm/common/DrmInfoEvent.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmInfoEvent"
+#include "utils/Log.h"
+
+#include <utils/String8.h>
+#include <drm/DrmInfoEvent.h>
+
+using namespace android;
+
+DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8& message)
+    : mUniqueId(uniqueId),
+      mInfoType(infoType),
+      mMessage(message) {
+
+}
+
+int DrmInfoEvent::getUniqueId() const {
+    return mUniqueId;
+}
+
+int DrmInfoEvent::getType() const {
+    return mInfoType;
+}
+
+const String8& DrmInfoEvent::getMessage() const {
+    return mMessage;
+}
+
diff --git a/drm/common/DrmInfoRequest.cpp b/drm/common/DrmInfoRequest.cpp
new file mode 100644
index 0000000..a646859
--- /dev/null
+++ b/drm/common/DrmInfoRequest.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 <drm/DrmInfoRequest.h>
+
+using namespace android;
+
+const String8 DrmInfoRequest::ACCOUNT_ID("account_id");
+const String8 DrmInfoRequest::SUBSCRIPTION_ID("subscription_id");
+
+DrmInfoRequest::DrmInfoRequest(int infoType, const String8& mimeType) :
+    mInfoType(infoType), mMimeType(mimeType) {
+
+}
+
+String8 DrmInfoRequest::getMimeType(void) const {
+    return mMimeType;
+}
+
+int DrmInfoRequest::getInfoType(void) const {
+    return mInfoType;
+}
+
+int DrmInfoRequest::getCount(void) const {
+    return mRequestInformationMap.size();
+}
+
+status_t DrmInfoRequest::put(const String8& key, const String8& value) {
+    mRequestInformationMap.add(key, value);
+    return DRM_NO_ERROR;
+}
+
+String8 DrmInfoRequest::get(const String8& key) const {
+    if (NAME_NOT_FOUND != mRequestInformationMap.indexOfKey(key)) {
+        return mRequestInformationMap.valueFor(key);
+    }
+    return String8("");
+}
+
+DrmInfoRequest::KeyIterator DrmInfoRequest::keyIterator() const {
+    return KeyIterator(this);
+}
+
+DrmInfoRequest::Iterator DrmInfoRequest::iterator() const {
+    return Iterator(this);
+}
+
+// KeyIterator implementation
+DrmInfoRequest::KeyIterator::KeyIterator(const DrmInfoRequest::KeyIterator& keyIterator)
+    : mDrmInfoRequest(keyIterator.mDrmInfoRequest),
+      mIndex(keyIterator.mIndex) {
+
+}
+
+bool DrmInfoRequest::KeyIterator::hasNext() {
+    return (mIndex < mDrmInfoRequest->mRequestInformationMap.size());
+}
+
+const String8& DrmInfoRequest::KeyIterator::next() {
+    const String8& key = mDrmInfoRequest->mRequestInformationMap.keyAt(mIndex);
+    mIndex++;
+    return key;
+}
+
+DrmInfoRequest::KeyIterator& DrmInfoRequest::KeyIterator::operator=(
+    const DrmInfoRequest::KeyIterator& keyIterator) {
+    mDrmInfoRequest = keyIterator.mDrmInfoRequest;
+    mIndex = keyIterator.mIndex;
+    return *this;
+}
+
+// Iterator implementation
+DrmInfoRequest::Iterator::Iterator(const DrmInfoRequest::Iterator& iterator) :
+    mDrmInfoRequest(iterator.mDrmInfoRequest), mIndex(iterator.mIndex) {
+}
+
+DrmInfoRequest::Iterator& DrmInfoRequest::Iterator::operator=(
+    const DrmInfoRequest::Iterator& iterator) {
+    mDrmInfoRequest = iterator.mDrmInfoRequest;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmInfoRequest::Iterator::hasNext() {
+    return mIndex < mDrmInfoRequest->mRequestInformationMap.size();
+}
+
+String8& DrmInfoRequest::Iterator::next() {
+    String8& value = mDrmInfoRequest->mRequestInformationMap.editValueAt(mIndex);
+    mIndex++;
+    return value;
+}
+
diff --git a/drm/common/DrmInfoStatus.cpp b/drm/common/DrmInfoStatus.cpp
new file mode 100644
index 0000000..f3a1516
--- /dev/null
+++ b/drm/common/DrmInfoStatus.cpp
@@ -0,0 +1,28 @@
+/*
+ * 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 <drm/DrmInfoStatus.h>
+
+using namespace android;
+
+DrmInfoStatus::DrmInfoStatus(
+    int _statusCode, const DrmBuffer* _drmBuffer, const String8& _mimeType) :
+    statusCode(_statusCode),
+    drmBuffer(_drmBuffer),
+    mimeType(_mimeType) {
+
+}
+
diff --git a/drm/common/DrmRights.cpp b/drm/common/DrmRights.cpp
new file mode 100644
index 0000000..dc1e6c5
--- /dev/null
+++ b/drm/common/DrmRights.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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 <drm/DrmRights.h>
+
+using namespace android;
+
+DrmRights::DrmRights(const String8& rightsFilePath, const String8& mimeType,
+            const String8& accountId, const String8& subscriptionId) {
+    /**
+     * TODO Read DrmRights from rights file
+     */
+}
+
+DrmRights::DrmRights(const DrmBuffer& rightsData, const String8& mimeType,
+            const String8& accountId, const String8& subscriptionId) :
+    mData(rightsData),
+    mMimeType(mimeType),
+    mAccountId(accountId),
+    mSubscriptionId(subscriptionId) {
+}
+
+const DrmBuffer& DrmRights::getData(void) const {
+    return mData;
+}
+
+String8 DrmRights::getMimeType(void) const {
+    return mMimeType;
+}
+
+String8 DrmRights::getAccountId(void) const {
+    return mAccountId;
+}
+
+String8 DrmRights::getSubscriptionId(void) const {
+    return mSubscriptionId;
+}
+
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
new file mode 100644
index 0000000..35e83fc
--- /dev/null
+++ b/drm/common/DrmSupportInfo.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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 <drm/DrmSupportInfo.h>
+
+using namespace android;
+
+DrmSupportInfo::DrmSupportInfo() {
+
+}
+
+DrmSupportInfo::DrmSupportInfo(const DrmSupportInfo& drmSupportInfo):
+    mMimeTypeVector(drmSupportInfo.mMimeTypeVector),
+    mFileSuffixVector(drmSupportInfo.mFileSuffixVector),
+    mDescription(drmSupportInfo.mDescription) {
+
+}
+
+bool DrmSupportInfo::operator<(const DrmSupportInfo& drmSupportInfo) const {
+    // Do we need to check mMimeTypeVector & mFileSuffixVector ?
+    // Note Vector doesn't overrides "<" operator
+    return mDescription < drmSupportInfo.mDescription;
+}
+
+bool DrmSupportInfo::operator==(const DrmSupportInfo& drmSupportInfo) const {
+    // Do we need to check mMimeTypeVector & mFileSuffixVector ?
+    // Note Vector doesn't overrides "==" operator
+    return (mDescription == drmSupportInfo.mDescription);
+}
+
+bool DrmSupportInfo::isSupportedMimeType(const String8& mimeType) const {
+    for (int i = 0; i < mMimeTypeVector.size(); i++) {
+        const String8 item = mMimeTypeVector.itemAt(i);
+
+        if (String8("") != mimeType && item.find(mimeType) != -1) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool DrmSupportInfo::isSupportedFileSuffix(const String8& fileType) const {
+    for (int i = 0; i < mFileSuffixVector.size(); i++) {
+        const String8 item = mFileSuffixVector.itemAt(i);
+
+        if (String8("") != fileType && item.find(fileType) != -1) {
+            return true;
+        }
+    }
+    return false;
+}
+
+DrmSupportInfo& DrmSupportInfo::operator=(const DrmSupportInfo& drmSupportInfo) {
+    mMimeTypeVector = drmSupportInfo.mMimeTypeVector;
+    mFileSuffixVector = drmSupportInfo.mFileSuffixVector;
+    mDescription = drmSupportInfo.mDescription;
+    return *this;
+}
+
+int DrmSupportInfo::getMimeTypeCount(void) const {
+    return mMimeTypeVector.size();
+}
+
+int DrmSupportInfo::getFileSuffixCount(void) const {
+    return mFileSuffixVector.size();
+}
+
+status_t DrmSupportInfo::addMimeType(const String8& mimeType) {
+    mMimeTypeVector.push(mimeType);
+    return DRM_NO_ERROR;
+}
+
+status_t DrmSupportInfo::addFileSuffix(const String8& fileSuffix) {
+    mFileSuffixVector.push(fileSuffix);
+    return DRM_NO_ERROR;
+}
+
+status_t DrmSupportInfo::setDescription(const String8& description) {
+    mDescription = description;
+    return DRM_NO_ERROR;
+}
+
+String8 DrmSupportInfo::getDescription() const {
+    return mDescription;
+}
+
+DrmSupportInfo::FileSuffixIterator DrmSupportInfo::getFileSuffixIterator() {
+    return FileSuffixIterator(this);
+}
+
+DrmSupportInfo::MimeTypeIterator DrmSupportInfo::getMimeTypeIterator() {
+    return MimeTypeIterator(this);
+}
+
+DrmSupportInfo::FileSuffixIterator::FileSuffixIterator(
+    const DrmSupportInfo::FileSuffixIterator& iterator) :
+    mDrmSupportInfo(iterator.mDrmSupportInfo),
+    mIndex(iterator.mIndex) {
+
+}
+
+DrmSupportInfo::FileSuffixIterator& DrmSupportInfo::FileSuffixIterator::operator=(
+    const DrmSupportInfo::FileSuffixIterator& iterator) {
+    mDrmSupportInfo = iterator.mDrmSupportInfo;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmSupportInfo::FileSuffixIterator::hasNext() {
+    return mIndex < mDrmSupportInfo->mFileSuffixVector.size();
+}
+
+String8& DrmSupportInfo::FileSuffixIterator::next() {
+    String8& value = mDrmSupportInfo->mFileSuffixVector.editItemAt(mIndex);
+    mIndex++;
+    return value;
+}
+
+DrmSupportInfo::MimeTypeIterator::MimeTypeIterator(
+    const DrmSupportInfo::MimeTypeIterator& iterator) :
+    mDrmSupportInfo(iterator.mDrmSupportInfo),
+    mIndex(iterator.mIndex) {
+
+}
+
+DrmSupportInfo::MimeTypeIterator& DrmSupportInfo::MimeTypeIterator::operator=(
+    const DrmSupportInfo::MimeTypeIterator& iterator) {
+    mDrmSupportInfo = iterator.mDrmSupportInfo;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool DrmSupportInfo::MimeTypeIterator::hasNext() {
+    return mIndex < mDrmSupportInfo->mMimeTypeVector.size();
+}
+
+String8& DrmSupportInfo::MimeTypeIterator::next() {
+    String8& value = mDrmSupportInfo->mMimeTypeVector.editItemAt(mIndex);
+    mIndex++;
+    return value;
+}
+
diff --git a/drm/common/IDrmIOService.cpp b/drm/common/IDrmIOService.cpp
new file mode 100644
index 0000000..7ce45e7
--- /dev/null
+++ b/drm/common/IDrmIOService.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "IDrmIOService"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <drm/drm_framework_common.h>
+#include "IDrmIOService.h"
+
+using namespace android;
+
+void BpDrmIOService::writeToFile(const String8& filePath, const String8& dataBuffer) {
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmIOService::getInterfaceDescriptor());
+    data.writeString8(filePath);
+    data.writeString8(dataBuffer);
+
+    remote()->transact(WRITE_TO_FILE, data, &reply);
+}
+
+String8 BpDrmIOService::readFromFile(const String8& filePath) {
+
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmIOService::getInterfaceDescriptor());
+    data.writeString8(filePath);
+
+    remote()->transact(READ_FROM_FILE, data, &reply);
+    return reply.readString8();
+}
+
+IMPLEMENT_META_INTERFACE(DrmIOService, "drm.IDrmIOService");
+
+status_t BnDrmIOService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+
+    switch (code) {
+    case WRITE_TO_FILE:
+    {
+        CHECK_INTERFACE(IDrmIOService, data, reply);
+
+        writeToFile(data.readString8(), data.readString8());
+        return DRM_NO_ERROR;
+    }
+
+    case READ_FROM_FILE:
+    {
+        CHECK_INTERFACE(IDrmIOService, data, reply);
+
+        String8 dataBuffer = readFromFile(data.readString8());
+        reply->writeString8(dataBuffer);
+        return DRM_NO_ERROR;
+    }
+
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
new file mode 100644
index 0000000..4fc828a
--- /dev/null
+++ b/drm/common/IDrmManagerService.cpp
@@ -0,0 +1,1358 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "IDrmManagerService(Native)"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/IPCThreadState.h>
+
+#include <drm/DrmInfo.h>
+#include <drm/DrmConstraints.h>
+#include <drm/DrmRights.h>
+#include <drm/DrmInfoStatus.h>
+#include <drm/DrmConvertedStatus.h>
+#include <drm/DrmInfoRequest.h>
+#include <drm/DrmSupportInfo.h>
+
+#include "IDrmManagerService.h"
+
+#define INVALID_BUFFER_LENGTH -1
+
+using namespace android;
+
+status_t BpDrmManagerService::loadPlugIns(int uniqueId) {
+    LOGV("load plugins");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    remote()->transact(LOAD_PLUGINS, data, &reply);
+    return reply.readInt32();
+}
+
+status_t BpDrmManagerService::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
+    LOGV("load plugins from path");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(plugInDirPath);
+
+    remote()->transact(LOAD_PLUGINS_FROM_PATH, data, &reply);
+    return reply.readInt32();
+}
+
+status_t BpDrmManagerService::setDrmServiceListener(
+            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
+    LOGV("setDrmServiceListener");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeStrongBinder(drmServiceListener->asBinder());
+    remote()->transact(SET_DRM_SERVICE_LISTENER, data, &reply);
+    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;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(drmEngineFile);
+
+    remote()->transact(INSTALL_DRM_ENGINE, data, &reply);
+    return reply.readInt32();
+}
+
+DrmConstraints* BpDrmManagerService::getConstraints(
+            int uniqueId, const String8* path, const int action) {
+    LOGV("Get Constraints");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(*path);
+    data.writeInt32(action);
+
+    remote()->transact(GET_CONSTRAINTS_FROM_CONTENT, data, &reply);
+
+    DrmConstraints* drmConstraints = NULL;
+    if (0 != reply.dataAvail()) {
+        //Filling Drm Constraints
+        drmConstraints = new DrmConstraints();
+
+        const int size = reply.readInt32();
+        for (int index = 0; index < size; ++index) {
+            const String8 key(reply.readString8());
+            const int bufferSize = reply.readInt32();
+            char* data = NULL;
+            if (0 < bufferSize) {
+                data = new char[bufferSize];
+                reply.read(data, bufferSize);
+            }
+            drmConstraints->put(&key, data);
+        }
+    }
+    return drmConstraints;
+}
+
+bool BpDrmManagerService::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+    LOGV("Can Handle");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeString8(path);
+    data.writeString8(mimeType);
+
+    remote()->transact(CAN_HANDLE, data, &reply);
+
+    return static_cast<bool>(reply.readInt32());
+}
+
+DrmInfoStatus* BpDrmManagerService::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    LOGV("Process DRM Info");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    //Filling DRM info
+    data.writeInt32(drmInfo->getInfoType());
+    const DrmBuffer dataBuffer = drmInfo->getData();
+    const int dataBufferSize = dataBuffer.length;
+    data.writeInt32(dataBufferSize);
+    if (0 < dataBufferSize) {
+        data.write(dataBuffer.data, dataBufferSize);
+    }
+    data.writeString8(drmInfo->getMimeType());
+
+    data.writeInt32(drmInfo->getCount());
+    DrmInfo::KeyIterator keyIt = drmInfo->keyIterator();
+
+    while (keyIt.hasNext()) {
+        const String8 key = keyIt.next();
+        data.writeString8(key);
+        const String8 value = drmInfo->get(key);
+        data.writeString8((value == String8("")) ? String8("NULL") : value);
+    }
+
+    remote()->transact(PROCESS_DRM_INFO, data, &reply);
+
+    DrmInfoStatus* drmInfoStatus = NULL;
+    if (0 != reply.dataAvail()) {
+        //Filling DRM Info Status
+        const int statusCode = reply.readInt32();
+        const String8 mimeType = reply.readString8();
+
+        DrmBuffer* drmBuffer = NULL;
+        if (0 != reply.dataAvail()) {
+            const int bufferSize = reply.readInt32();
+            char* data = NULL;
+            if (0 < bufferSize) {
+                data = new char[bufferSize];
+                reply.read(data, bufferSize);
+            }
+            drmBuffer = new DrmBuffer(data, bufferSize);
+        }
+        drmInfoStatus = new DrmInfoStatus(statusCode, drmBuffer, mimeType);
+    }
+    return drmInfoStatus;
+}
+
+DrmInfo* BpDrmManagerService::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) {
+    LOGV("Acquire DRM Info");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    //Filling DRM Info Request
+    data.writeInt32(drmInforequest->getInfoType());
+    data.writeString8(drmInforequest->getMimeType());
+
+    data.writeInt32(drmInforequest->getCount());
+    DrmInfoRequest::KeyIterator keyIt = drmInforequest->keyIterator();
+
+    while (keyIt.hasNext()) {
+        const String8 key = keyIt.next();
+        data.writeString8(key);
+        const String8 value = drmInforequest->get(key);
+        data.writeString8((value == String8("")) ? String8("NULL") : value);
+    }
+
+    remote()->transact(ACQUIRE_DRM_INFO, data, &reply);
+
+    DrmInfo* drmInfo = NULL;
+    if (0 != reply.dataAvail()) {
+        //Filling DRM Info
+        const int infoType = reply.readInt32();
+        const int bufferSize = reply.readInt32();
+        char* data = NULL;
+
+        if (0 < bufferSize) {
+            data = new char[bufferSize];
+            reply.read(data, bufferSize);
+        }
+        drmInfo = new DrmInfo(infoType, DrmBuffer(data, bufferSize), reply.readString8());
+
+        const int size = reply.readInt32();
+        for (int index = 0; index < size; ++index) {
+            const String8 key(reply.readString8());
+            const String8 value(reply.readString8());
+            drmInfo->put(key, (value == String8("NULL")) ? String8("") : value);
+        }
+    }
+    return drmInfo;
+}
+
+void BpDrmManagerService::saveRights(
+            int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    LOGV("Save Rights");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    //Filling Drm Rights
+    const DrmBuffer dataBuffer = drmRights.getData();
+    data.writeInt32(dataBuffer.length);
+    data.write(dataBuffer.data, dataBuffer.length);
+
+    const String8 mimeType = drmRights.getMimeType();
+    data.writeString8((mimeType == String8("")) ? String8("NULL") : mimeType);
+
+    const String8 accountId = drmRights.getAccountId();
+    data.writeString8((accountId == String8("")) ? String8("NULL") : accountId);
+
+    const String8 subscriptionId = drmRights.getSubscriptionId();
+    data.writeString8((subscriptionId == String8("")) ? String8("NULL") : subscriptionId);
+
+    data.writeString8((rightsPath == String8("")) ? String8("NULL") : rightsPath);
+    data.writeString8((contentPath == String8("")) ? String8("NULL") : contentPath);
+
+    remote()->transact(SAVE_RIGHTS, data, &reply);
+}
+
+String8 BpDrmManagerService::getOriginalMimeType(int uniqueId, const String8& path) {
+    LOGV("Get Original MimeType");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(path);
+
+    remote()->transact(GET_ORIGINAL_MIMETYPE, data, &reply);
+    return reply.readString8();
+}
+
+int BpDrmManagerService::getDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) {
+    LOGV("Get Drm object type");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(path);
+    data.writeString8(mimeType);
+
+    remote()->transact(GET_DRM_OBJECT_TYPE, data, &reply);
+
+    return reply.readInt32();
+}
+
+int BpDrmManagerService::checkRightsStatus(int uniqueId, const String8& path, int action) {
+    LOGV("checkRightsStatus");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(path);
+    data.writeInt32(action);
+
+    remote()->transact(CHECK_RIGHTS_STATUS, data, &reply);
+
+    return reply.readInt32();
+}
+
+void BpDrmManagerService::consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    LOGV("consumeRights");
+        Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    data.writeInt32(action);
+    data.writeInt32(static_cast< int>(reserve));
+
+    remote()->transact(CONSUME_RIGHTS, data, &reply);
+}
+
+void BpDrmManagerService::setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    LOGV("setPlaybackStatus");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    data.writeInt32(playbackStatus);
+    data.writeInt32(position);
+
+    remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
+}
+
+bool BpDrmManagerService::validateAction(
+            int uniqueId, const String8& path,
+            int action, const ActionDescription& description) {
+    LOGV("validateAction");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(path);
+    data.writeInt32(action);
+    data.writeInt32(description.outputType);
+    data.writeInt32(description.configuration);
+
+    remote()->transact(VALIDATE_ACTION, data, &reply);
+
+    return static_cast<bool>(reply.readInt32());
+}
+
+void BpDrmManagerService::removeRights(int uniqueId, const String8& path) {
+    LOGV("removeRights");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(path);
+
+    remote()->transact(REMOVE_RIGHTS, data, &reply);
+}
+
+void BpDrmManagerService::removeAllRights(int uniqueId) {
+    LOGV("removeAllRights");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    remote()->transact(REMOVE_ALL_RIGHTS, data, &reply);
+}
+
+int BpDrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
+    LOGV("openConvertSession");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeString8(mimeType);
+
+    remote()->transact(OPEN_CONVERT_SESSION, data, &reply);
+    return reply.readInt32();
+}
+
+DrmConvertedStatus* BpDrmManagerService::convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) {
+    LOGV("convertData");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeInt32(convertId);
+    data.writeInt32(inputData->length);
+    data.write(inputData->data, inputData->length);
+
+    remote()->transact(CONVERT_DATA, data, &reply);
+
+    DrmConvertedStatus* drmConvertedStatus = NULL;
+
+    if (0 != reply.dataAvail()) {
+        //Filling DRM Converted Status
+        const int statusCode = reply.readInt32();
+        const int offset = reply.readInt32();
+
+        DrmBuffer* convertedData = NULL;
+        if (0 != reply.dataAvail()) {
+            const int bufferSize = reply.readInt32();
+            char* data = NULL;
+            if (0 < bufferSize) {
+                data = new char[bufferSize];
+                reply.read(data, bufferSize);
+            }
+            convertedData = new DrmBuffer(data, bufferSize);
+        }
+        drmConvertedStatus = new DrmConvertedStatus(statusCode, convertedData, offset);
+    }
+    return drmConvertedStatus;
+}
+
+DrmConvertedStatus* BpDrmManagerService::closeConvertSession(int uniqueId, int convertId) {
+    LOGV("closeConvertSession");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    data.writeInt32(convertId);
+
+    remote()->transact(CLOSE_CONVERT_SESSION, data, &reply);
+
+    DrmConvertedStatus* drmConvertedStatus = NULL;
+
+    if (0 != reply.dataAvail()) {
+        //Filling DRM Converted Status
+        const int statusCode = reply.readInt32();
+        const int offset = reply.readInt32();
+
+        DrmBuffer* convertedData = NULL;
+        if (0 != reply.dataAvail()) {
+            const int bufferSize = reply.readInt32();
+            char* data = NULL;
+            if (0 < bufferSize) {
+                data = new char[bufferSize];
+                reply.read(data, bufferSize);
+            }
+            convertedData = new DrmBuffer(data, bufferSize);
+        }
+        drmConvertedStatus = new DrmConvertedStatus(statusCode, convertedData, offset);
+    }
+    return drmConvertedStatus;
+}
+
+status_t BpDrmManagerService::getAllSupportInfo(
+            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+    LOGV("Get All Support Info");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    remote()->transact(GET_ALL_SUPPORT_INFO, data, &reply);
+
+    //Filling DRM Support Info
+    const int arraySize = reply.readInt32();
+    if (0 < arraySize) {
+        *drmSupportInfoArray = new DrmSupportInfo[arraySize];
+
+        for (int index = 0; index < arraySize; ++index) {
+            DrmSupportInfo drmSupportInfo;
+
+            const int fileSuffixVectorSize = reply.readInt32();
+            for (int i = 0; i < fileSuffixVectorSize; ++i) {
+                drmSupportInfo.addFileSuffix(reply.readString8());
+            }
+
+            const int mimeTypeVectorSize = reply.readInt32();
+            for (int i = 0; i < mimeTypeVectorSize; ++i) {
+                drmSupportInfo.addMimeType(reply.readString8());
+            }
+
+            drmSupportInfo.setDescription(reply.readString8());
+            (*drmSupportInfoArray)[index] = drmSupportInfo;
+        }
+    }
+    *length = arraySize;
+    return reply.readInt32();
+}
+
+DecryptHandle* BpDrmManagerService::openDecryptSession(
+            int uniqueId, int fd, int offset, int length) {
+    LOGV("Entering BpDrmManagerService::openDecryptSession");
+    Parcel data, reply;
+
+    const String16 interfaceDescriptor = IDrmManagerService::getInterfaceDescriptor();
+    LOGV("BpDrmManagerService::openDecryptSession: InterfaceDescriptor name is %s",
+        interfaceDescriptor.string());
+    data.writeInterfaceToken(interfaceDescriptor);
+    data.writeInt32(uniqueId);
+    data.writeFileDescriptor(fd);
+    data.writeInt32(offset);
+    data.writeInt32(length);
+
+    LOGV("try to invoke remote onTransact() with code OPEN_DECRYPT_SESSION");
+    remote()->transact(OPEN_DECRYPT_SESSION, 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;
+}
+
+void BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    LOGV("closeDecryptSession");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        LOGV("deleting decryptInfo");
+        delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
+    }
+    delete decryptHandle; decryptHandle = NULL;
+}
+
+void BpDrmManagerService::initializeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    LOGV("initializeDecryptUnit");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+    data.writeInt32(decryptUnitId);
+
+    data.writeInt32(headerInfo->length);
+    data.write(headerInfo->data, headerInfo->length);
+
+    remote()->transact(INITIALIZE_DECRYPT_UNIT, data, &reply);
+}
+
+status_t BpDrmManagerService::decrypt(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    LOGV("decrypt");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    data.writeInt32(decryptUnitId);
+    data.writeInt32((*decBuffer)->length);
+
+    data.writeInt32(encBuffer->length);
+    data.write(encBuffer->data, encBuffer->length);
+
+    remote()->transact(DECRYPT, data, &reply);
+
+    const status_t status = reply.readInt32();
+    LOGV("Return value of decrypt() is %d", status);
+
+    const int size = reply.readInt32();
+    (*decBuffer)->length = size;
+    reply.read((void *)(*decBuffer)->data, size);
+
+    return status;
+}
+
+void BpDrmManagerService::finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    LOGV("finalizeDecryptUnit");
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    data.writeInt32(decryptUnitId);
+
+    remote()->transact(FINALIZE_DECRYPT_UNIT, data, &reply);
+}
+
+ssize_t BpDrmManagerService::pread(
+            int uniqueId, DecryptHandle* decryptHandle, void* buffer,
+            ssize_t numBytes, off_t offset) {
+    LOGV("read");
+    Parcel data, reply;
+    int result;
+
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+
+    data.writeInt32(decryptHandle->decryptId);
+    data.writeString8(decryptHandle->mimeType);
+    data.writeInt32(decryptHandle->decryptApiType);
+    data.writeInt32(decryptHandle->status);
+
+    if (NULL != decryptHandle->decryptInfo) {
+        data.writeInt32(decryptHandle->decryptInfo->decryptBufferLength);
+    } else {
+        data.writeInt32(INVALID_BUFFER_LENGTH);
+    }
+
+    data.writeInt32(numBytes);
+    data.writeInt32(offset);
+
+    remote()->transact(PREAD, data, &reply);
+    result = reply.readInt32();
+    if (0 < result) {
+        reply.read(buffer, result);
+    }
+    return result;
+}
+
+IMPLEMENT_META_INTERFACE(DrmManagerService, "drm.IDrmManagerService");
+
+status_t BnDrmManagerService::onTransact(
+            uint32_t code, const Parcel& data,
+            Parcel* reply, uint32_t flags) {
+    LOGV("Entering BnDrmManagerService::onTransact with code %d", code);
+
+    switch (code) {
+    case LOAD_PLUGINS:
+    {
+        LOGV("BnDrmManagerService::onTransact :LOAD_PLUGINS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        status_t status = loadPlugIns(data.readInt32());
+
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+
+    }
+
+    case LOAD_PLUGINS_FROM_PATH:
+    {
+        LOGV("BnDrmManagerService::onTransact :LOAD_PLUGINS_FROM_PATH");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        status_t status = loadPlugIns(data.readInt32(), data.readString8());
+
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+    }
+
+    case SET_DRM_SERVICE_LISTENER:
+    {
+        LOGV("BnDrmManagerService::onTransact :SET_DRM_SERVICE_LISTENER");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const sp<IDrmServiceListener> drmServiceListener
+            = interface_cast<IDrmServiceListener> (data.readStrongBinder());
+
+        status_t status = setDrmServiceListener(uniqueId, drmServiceListener);
+
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+    }
+
+    case UNLOAD_PLUGINS:
+    {
+        LOGV("BnDrmManagerService::onTransact :UNLOAD_PLUGINS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        status_t status = unloadPlugIns(data.readInt32());
+
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+    }
+
+    case INSTALL_DRM_ENGINE:
+    {
+        LOGV("BnDrmManagerService::onTransact :INSTALL_DRM_ENGINE");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        status_t status = installDrmEngine(data.readInt32(), data.readString8());
+
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+    }
+
+    case GET_CONSTRAINTS_FROM_CONTENT:
+    {
+        LOGV("BnDrmManagerService::onTransact :GET_CONSTRAINTS_FROM_CONTENT");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const String8 path = data.readString8();
+
+        DrmConstraints* drmConstraints = getConstraints(uniqueId, &path, data.readInt32());
+
+        if (NULL != drmConstraints) {
+            //Filling DRM Constraints contents
+            reply->writeInt32(drmConstraints->getCount());
+
+            DrmConstraints::KeyIterator keyIt = drmConstraints->keyIterator();
+            while (keyIt.hasNext()) {
+                const String8 key = keyIt.next();
+                reply->writeString8(key);
+                const char* value = drmConstraints->getAsByteArray(&key);
+                int bufferSize = 0;
+                if (NULL != value) {
+                    bufferSize = strlen(value);
+                }
+                reply->writeInt32(bufferSize + 1);
+                reply->write(value, bufferSize + 1);
+            }
+        }
+        delete drmConstraints; drmConstraints = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case CAN_HANDLE:
+    {
+        LOGV("BnDrmManagerService::onTransact :CAN_HANDLE");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const String8 path = data.readString8();
+        const String8 mimeType = data.readString8();
+
+        bool result = canHandle(uniqueId, path, mimeType);
+
+        reply->writeInt32(result);
+        return DRM_NO_ERROR;
+    }
+
+    case PROCESS_DRM_INFO:
+    {
+        LOGV("BnDrmManagerService::onTransact :PROCESS_DRM_INFO");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        //Filling DRM info
+        const int infoType = data.readInt32();
+        const int bufferSize = data.readInt32();
+        char* buffer = NULL;
+        if (0 < bufferSize) {
+            buffer = (char *)data.readInplace(bufferSize);
+        }
+        const DrmBuffer drmBuffer(buffer, bufferSize);
+        DrmInfo* drmInfo = new DrmInfo(infoType, drmBuffer, data.readString8());
+
+        const int size = data.readInt32();
+        for (int index = 0; index < size; ++index) {
+            const String8 key(data.readString8());
+            const String8 value(data.readString8());
+            drmInfo->put(key, (value == String8("NULL")) ? String8("") : value);
+        }
+
+        DrmInfoStatus* drmInfoStatus = processDrmInfo(uniqueId, drmInfo);
+
+        if (NULL != drmInfoStatus) {
+            //Filling DRM Info Status contents
+            reply->writeInt32(drmInfoStatus->statusCode);
+            reply->writeString8(drmInfoStatus->mimeType);
+
+            if (NULL != drmInfoStatus->drmBuffer) {
+                const DrmBuffer* drmBuffer = drmInfoStatus->drmBuffer;
+                const int bufferSize = drmBuffer->length;
+                reply->writeInt32(bufferSize);
+                if (0 < bufferSize) {
+                    reply->write(drmBuffer->data, bufferSize);
+                }
+                delete [] drmBuffer->data;
+                delete drmBuffer; drmBuffer = NULL;
+            }
+        }
+        delete drmInfo; drmInfo = NULL;
+        delete drmInfoStatus; drmInfoStatus = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case ACQUIRE_DRM_INFO:
+    {
+        LOGV("BnDrmManagerService::onTransact :ACQUIRE_DRM_INFO");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        //Filling DRM info Request
+        DrmInfoRequest* drmInfoRequest = new DrmInfoRequest(data.readInt32(), data.readString8());
+
+        const int size = data.readInt32();
+        for (int index = 0; index < size; ++index) {
+            const String8 key(data.readString8());
+            const String8 value(data.readString8());
+            drmInfoRequest->put(key, (value == String8("NULL")) ? String8("") : value);
+        }
+
+        DrmInfo* drmInfo = acquireDrmInfo(uniqueId, drmInfoRequest);
+
+        if (NULL != drmInfo) {
+            //Filling DRM Info
+            const DrmBuffer drmBuffer = drmInfo->getData();
+            reply->writeInt32(drmInfo->getInfoType());
+
+            const int bufferSize = drmBuffer.length;
+            reply->writeInt32(bufferSize);
+            if (0 < bufferSize) {
+                reply->write(drmBuffer.data, bufferSize);
+            }
+            reply->writeString8(drmInfo->getMimeType());
+            reply->writeInt32(drmInfo->getCount());
+
+            DrmInfo::KeyIterator keyIt = drmInfo->keyIterator();
+            while (keyIt.hasNext()) {
+                const String8 key = keyIt.next();
+                reply->writeString8(key);
+                const String8 value = drmInfo->get(key);
+                reply->writeString8((value == String8("")) ? String8("NULL") : value);
+            }
+            delete [] drmBuffer.data;
+        }
+        delete drmInfoRequest; drmInfoRequest = NULL;
+        delete drmInfo; drmInfo = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case SAVE_RIGHTS:
+    {
+        LOGV("BnDrmManagerService::onTransact :SAVE_RIGHTS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        //Filling DRM Rights
+        const int bufferSize = data.readInt32();
+        const DrmBuffer drmBuffer((char *)data.readInplace(bufferSize), bufferSize);
+
+        const String8 mimeType(data.readString8());
+        const String8 accountId(data.readString8());
+        const String8 subscriptionId(data.readString8());
+        const String8 rightsPath(data.readString8());
+        const String8 contentPath(data.readString8());
+
+        DrmRights drmRights(drmBuffer,
+                            ((mimeType == String8("NULL")) ? String8("") : mimeType),
+                            ((accountId == String8("NULL")) ? String8("") : accountId),
+                            ((subscriptionId == String8("NULL")) ? String8("") : subscriptionId));
+
+        saveRights(uniqueId, drmRights,
+                            ((rightsPath == String8("NULL")) ? String8("") : rightsPath),
+                            ((contentPath == String8("NULL")) ? String8("") : contentPath));
+
+        return DRM_NO_ERROR;
+    }
+
+    case GET_ORIGINAL_MIMETYPE:
+    {
+        LOGV("BnDrmManagerService::onTransact :GET_ORIGINAL_MIMETYPE");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const String8 originalMimeType = getOriginalMimeType(data.readInt32(), data.readString8());
+
+        reply->writeString8(originalMimeType);
+        return DRM_NO_ERROR;
+    }
+
+    case GET_DRM_OBJECT_TYPE:
+    {
+        LOGV("BnDrmManagerService::onTransact :GET_DRM_OBJECT_TYPE");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int drmObjectType
+            = getDrmObjectType(data.readInt32(), data.readString8(), data.readString8());
+
+        reply->writeInt32(drmObjectType);
+        return DRM_NO_ERROR;
+    }
+
+    case CHECK_RIGHTS_STATUS:
+    {
+        LOGV("BnDrmManagerService::onTransact :CHECK_RIGHTS_STATUS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int result
+            = checkRightsStatus(data.readInt32(), data.readString8(), data.readInt32());
+
+        reply->writeInt32(result);
+        return DRM_NO_ERROR;
+    }
+
+    case CONSUME_RIGHTS:
+    {
+        LOGV("BnDrmManagerService::onTransact :CONSUME_RIGHTS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+
+        consumeRights(uniqueId, &handle, data.readInt32(), static_cast<bool>(data.readInt32()));
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case SET_PLAYBACK_STATUS:
+    {
+        LOGV("BnDrmManagerService::onTransact :SET_PLAYBACK_STATUS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+
+        setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case VALIDATE_ACTION:
+    {
+        LOGV("BnDrmManagerService::onTransact :VALIDATE_ACTION");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        bool result = validateAction(
+                                data.readInt32(),
+                                data.readString8(),
+                                data.readInt32(),
+                                ActionDescription(data.readInt32(), data.readInt32()));
+
+        reply->writeInt32(result);
+        return DRM_NO_ERROR;
+    }
+
+    case REMOVE_RIGHTS:
+    {
+        LOGV("BnDrmManagerService::onTransact :REMOVE_RIGHTS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        removeRights(data.readInt32(), data.readString8());
+
+        return DRM_NO_ERROR;
+    }
+
+    case REMOVE_ALL_RIGHTS:
+    {
+        LOGV("BnDrmManagerService::onTransact :REMOVE_ALL_RIGHTS");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        removeAllRights(data.readInt32());
+
+        return DRM_NO_ERROR;
+    }
+
+    case OPEN_CONVERT_SESSION:
+    {
+        LOGV("BnDrmManagerService::onTransact :OPEN_CONVERT_SESSION");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int convertId = openConvertSession(data.readInt32(), data.readString8());
+
+        reply->writeInt32(convertId);
+        return DRM_NO_ERROR;
+    }
+
+    case CONVERT_DATA:
+    {
+        LOGV("BnDrmManagerService::onTransact :CONVERT_DATA");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const int convertId = data.readInt32();
+
+        //Filling input data
+        const int bufferSize = data.readInt32();
+        DrmBuffer* inputData = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
+
+        DrmConvertedStatus*    drmConvertedStatus = convertData(uniqueId, convertId, inputData);
+
+        if (NULL != drmConvertedStatus) {
+            //Filling Drm Converted Ststus
+            reply->writeInt32(drmConvertedStatus->statusCode);
+            reply->writeInt32(drmConvertedStatus->offset);
+
+            if (NULL != drmConvertedStatus->convertedData) {
+                const DrmBuffer* convertedData = drmConvertedStatus->convertedData;
+                const int bufferSize = convertedData->length;
+                reply->writeInt32(bufferSize);
+                if (0 < bufferSize) {
+                    reply->write(convertedData->data, bufferSize);
+                }
+                delete [] convertedData->data;
+                delete convertedData; convertedData = NULL;
+            }
+        }
+        delete inputData; inputData = NULL;
+        delete drmConvertedStatus; drmConvertedStatus = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case CLOSE_CONVERT_SESSION:
+    {
+        LOGV("BnDrmManagerService::onTransact :CLOSE_CONVERT_SESSION");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        DrmConvertedStatus*    drmConvertedStatus
+            = closeConvertSession(data.readInt32(), data.readInt32());
+
+        if (NULL != drmConvertedStatus) {
+            //Filling Drm Converted Ststus
+            reply->writeInt32(drmConvertedStatus->statusCode);
+            reply->writeInt32(drmConvertedStatus->offset);
+
+            if (NULL != drmConvertedStatus->convertedData) {
+                const DrmBuffer* convertedData = drmConvertedStatus->convertedData;
+                const int bufferSize = convertedData->length;
+                reply->writeInt32(bufferSize);
+                if (0 < bufferSize) {
+                    reply->write(convertedData->data, bufferSize);
+                }
+                delete [] convertedData->data;
+                delete convertedData; convertedData = NULL;
+            }
+        }
+        delete drmConvertedStatus; drmConvertedStatus = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case GET_ALL_SUPPORT_INFO:
+    {
+        LOGV("BnDrmManagerService::onTransact :GET_ALL_SUPPORT_INFO");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        int length = 0;
+        DrmSupportInfo* drmSupportInfoArray = NULL;
+
+        status_t status = getAllSupportInfo(uniqueId, &length, &drmSupportInfoArray);
+
+        reply->writeInt32(length);
+        for (int i = 0; i < length; ++i) {
+            DrmSupportInfo drmSupportInfo = drmSupportInfoArray[i];
+
+            reply->writeInt32(drmSupportInfo.getFileSuffixCount());
+            DrmSupportInfo::FileSuffixIterator fileSuffixIt
+                = drmSupportInfo.getFileSuffixIterator();
+            while (fileSuffixIt.hasNext()) {
+                reply->writeString8(fileSuffixIt.next());
+            }
+
+            reply->writeInt32(drmSupportInfo.getMimeTypeCount());
+            DrmSupportInfo::MimeTypeIterator mimeTypeIt = drmSupportInfo.getMimeTypeIterator();
+            while (mimeTypeIt.hasNext()) {
+                reply->writeString8(mimeTypeIt.next());
+            }
+            reply->writeString8(drmSupportInfo.getDescription());
+        }
+        delete [] drmSupportInfoArray; drmSupportInfoArray = NULL;
+        reply->writeInt32(status);
+        return DRM_NO_ERROR;
+    }
+
+    case OPEN_DECRYPT_SESSION:
+    {
+        LOGV("BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+        const int fd = data.readFileDescriptor();
+
+        DecryptHandle* handle
+            = openDecryptSession(uniqueId, fd, data.readInt32(), data.readInt32());
+
+        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");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle* handle = new DecryptHandle();
+        handle->decryptId = data.readInt32();
+        handle->mimeType = data.readString8();
+        handle->decryptApiType = data.readInt32();
+        handle->status = data.readInt32();
+        handle->decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle->decryptInfo = new DecryptInfo();
+            handle->decryptInfo->decryptBufferLength = bufferLength;
+        }
+
+        closeDecryptSession(uniqueId, handle);
+        return DRM_NO_ERROR;
+    }
+
+    case INITIALIZE_DECRYPT_UNIT:
+    {
+        LOGV("BnDrmManagerService::onTransact :INITIALIZE_DECRYPT_UNIT");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+        const int decryptUnitId = data.readInt32();
+
+        //Filling Header info
+        const int bufferSize = data.readInt32();
+        DrmBuffer* headerInfo = NULL;
+        headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
+
+        initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        delete headerInfo; headerInfo = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case DECRYPT:
+    {
+        LOGV("BnDrmManagerService::onTransact :DECRYPT");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+        const int decryptUnitId = data.readInt32();
+        const int decBufferSize = data.readInt32();
+
+        const int encBufferSize = data.readInt32();
+        DrmBuffer* encBuffer
+            = new DrmBuffer((char *)data.readInplace(encBufferSize), encBufferSize);
+
+        char* buffer = NULL;
+        buffer = new char[decBufferSize];
+        DrmBuffer* decBuffer = new DrmBuffer(buffer, decBufferSize);
+
+        const status_t status = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer);
+
+        reply->writeInt32(status);
+
+        const int size = decBuffer->length;
+        reply->writeInt32(size);
+        reply->write(decBuffer->data, size);
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        delete encBuffer; encBuffer = NULL;
+        delete decBuffer; decBuffer = NULL;
+        delete [] buffer; buffer = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case FINALIZE_DECRYPT_UNIT:
+    {
+        LOGV("BnDrmManagerService::onTransact :FINALIZE_DECRYPT_UNIT");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+
+        finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    case PREAD:
+    {
+        LOGV("BnDrmManagerService::onTransact :READ");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+
+        const int uniqueId = data.readInt32();
+
+        DecryptHandle handle;
+        handle.decryptId = data.readInt32();
+        handle.mimeType = data.readString8();
+        handle.decryptApiType = data.readInt32();
+        handle.status = data.readInt32();
+        handle.decryptInfo = NULL;
+
+        const int bufferLength = data.readInt32();
+        if (INVALID_BUFFER_LENGTH != bufferLength) {
+            handle.decryptInfo = new DecryptInfo();
+            handle.decryptInfo->decryptBufferLength = bufferLength;
+        }
+
+        const int numBytes = data.readInt32();
+        char* buffer = new char[numBytes];
+
+        const off_t offset = data.readInt32();
+
+        ssize_t result = pread(uniqueId, &handle, buffer, numBytes, offset);
+        reply->writeInt32(result);
+        if (0 < result) {
+            reply->write(buffer, result);
+        }
+
+        delete handle.decryptInfo; handle.decryptInfo = NULL;
+        delete [] buffer, buffer = NULL;
+        return DRM_NO_ERROR;
+    }
+
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
diff --git a/drm/common/IDrmServiceListener.cpp b/drm/common/IDrmServiceListener.cpp
new file mode 100644
index 0000000..0a69115
--- /dev/null
+++ b/drm/common/IDrmServiceListener.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "IDrmServiceListener"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <drm/drm_framework_common.h>
+#include <drm/DrmInfoEvent.h>
+#include "IDrmServiceListener.h"
+
+using namespace android;
+
+status_t BpDrmServiceListener::notify(const DrmInfoEvent& event) {
+    Parcel data, reply;
+
+    data.writeInterfaceToken(IDrmServiceListener::getInterfaceDescriptor());
+    data.writeInt32(event.getUniqueId());
+    data.writeInt32(event.getType());
+    data.writeString8(event.getMessage());
+
+    remote()->transact(NOTIFY, data, &reply);
+    return reply.readInt32();
+}
+
+IMPLEMENT_META_INTERFACE(DrmServiceListener, "drm.IDrmServiceListener");
+
+status_t BnDrmServiceListener::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+
+    switch (code) {
+    case NOTIFY:
+    {
+        CHECK_INTERFACE(IDrmServiceListener, data, reply);
+        int uniqueId = data.readInt32();
+        int type = data.readInt32();
+        const String8& message = data.readString8();
+
+        status_t status = notify(DrmInfoEvent(uniqueId, type, message));
+        reply->writeInt32(status);
+
+        return DRM_NO_ERROR;
+    }
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
diff --git a/drm/common/ReadWriteUtils.cpp b/drm/common/ReadWriteUtils.cpp
new file mode 100644
index 0000000..4319c1c
--- /dev/null
+++ b/drm/common/ReadWriteUtils.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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 <ReadWriteUtils.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/FileMap.h>
+#include <utils/String8.h>
+
+using namespace android;
+
+#define FAILURE -1
+
+String8 ReadWriteUtils::readBytes(const String8& filePath) {
+    FILE* file = NULL;
+    file = fopen(filePath.string(), "r");
+
+    String8 string("");
+    if (NULL != file) {
+        int fd = fileno(file);
+        struct stat sb;
+
+        if (fstat(fd, &sb) == 0 && sb.st_size > 0) {
+            FileMap* fileMap = new FileMap();
+            if (fileMap->create(filePath.string(), fd, 0, sb.st_size, true)) {
+                char* addr = (char*)fileMap->getDataPtr();
+                string.append(addr, sb.st_size);
+                fileMap->release();
+            }
+        }
+        fclose(file);
+    }
+    return string;
+}
+
+void ReadWriteUtils::writeToFile(const String8& filePath, const String8& data) {
+    FILE* file = NULL;
+    file = fopen(filePath.string(), "w+");
+
+    if (NULL != file) {
+        int fd = fileno(file);
+
+        int size = data.size();
+        if (FAILURE != ftruncate(fd, size)) {
+            FileMap* fileMap = NULL;
+            fileMap = new FileMap();
+            if (fileMap->create(filePath.string(), fd, 0, size, false)) {
+                char* addr = (char*)fileMap->getDataPtr();
+                memcpy(addr, data.string(), size);
+                fileMap->release();
+            }
+        }
+        fclose(file);
+    }
+}
+
+void ReadWriteUtils::appendToFile(const String8& filePath, const String8& data) {
+    FILE* file = NULL;
+    file = fopen(filePath.string(), "a+");
+
+    if (NULL != file) {
+        int fd = fileno(file);
+
+        int offset = lseek(fd, 0, SEEK_END);
+        if (FAILURE != offset) {
+            int newEntrySize = data.size();
+            int fileSize = offset + newEntrySize;
+
+            if (FAILURE != ftruncate(fd, fileSize)) {
+                FileMap* fileMap = NULL;
+                fileMap = new FileMap();
+                if (fileMap->create(filePath.string(), fd, offset, fileSize, false)) {
+                    char* addr = (char*)fileMap->getDataPtr();
+                    memcpy(addr, data.string(), data.size());
+                    fileMap->release();
+                }
+            }
+        }
+        fclose(file);
+    }
+}
+
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
new file mode 100644
index 0000000..5df2ff8
--- /dev/null
+++ b/drm/drmserver/Android.mk
@@ -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.
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    main_drmserver.cpp \
+    DrmManager.cpp \
+    DrmManagerService.cpp \
+    StringTokenizer.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libutils \
+    libbinder
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
+
+LOCAL_C_INCLUDES := \
+    $(TOP)/frameworks/base/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/plugins/common/include
+
+LOCAL_MODULE:= drmserver
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
new file mode 100644
index 0000000..44886f9
--- /dev/null
+++ b/drm/drmserver/DrmManager.cpp
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmManager(Native)"
+#include "utils/Log.h"
+
+#include <utils/String8.h>
+#include <drm/DrmInfo.h>
+#include <drm/DrmInfoEvent.h>
+#include <drm/DrmRights.h>
+#include <drm/DrmConstraints.h>
+#include <drm/DrmInfoStatus.h>
+#include <drm/DrmInfoRequest.h>
+#include <drm/DrmSupportInfo.h>
+#include <drm/DrmConvertedStatus.h>
+#include <IDrmEngine.h>
+
+#include "DrmManager.h"
+#include "ReadWriteUtils.h"
+
+#define DECRYPT_FILE_ERROR -1
+
+using namespace android;
+
+const String8 DrmManager::EMPTY_STRING("");
+
+DrmManager::DrmManager() :
+    mDecryptSessionId(0),
+    mConvertId(0) {
+
+}
+
+DrmManager::~DrmManager() {
+
+}
+
+status_t DrmManager::loadPlugIns(int uniqueId) {
+    String8 pluginDirPath("/system/lib/drm/plugins/native");
+    return loadPlugIns(uniqueId, pluginDirPath);
+}
+
+status_t DrmManager::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
+    if (mSupportInfoToPlugInIdMap.isEmpty()) {
+        mPlugInManager.loadPlugIns(plugInDirPath);
+
+        initializePlugIns(uniqueId);
+
+        populate(uniqueId);
+    } else {
+        initializePlugIns(uniqueId);
+    }
+
+    return DRM_NO_ERROR;
+}
+
+status_t DrmManager::setDrmServiceListener(
+            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
+    Mutex::Autolock _l(mLock);
+    mServiceListeners.add(uniqueId, drmServiceListener);
+    return DRM_NO_ERROR;
+}
+
+status_t DrmManager::unloadPlugIns(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);
+    }
+
+    mConvertSessionMap.clear();
+    mDecryptSessionMap.clear();
+    mSupportInfoToPlugInIdMap.clear();
+    mPlugInManager.unloadPlugIns();
+    return DRM_NO_ERROR;
+}
+
+DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
+    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.getConstraints(uniqueId, path, action);
+    }
+    return NULL;
+}
+
+status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
+    mPlugInManager.loadPlugIn(absolutePath);
+
+    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
+    rDrmEngine.initialize(uniqueId);
+    rDrmEngine.setOnInfoListener(uniqueId, this);
+
+    DrmSupportInfo* info = rDrmEngine.getSupportInfo(uniqueId);
+    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
+
+    return DRM_NO_ERROR;
+}
+
+bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+    const String8 plugInId = getSupportedPlugInId(mimeType);
+    bool result = (EMPTY_STRING != plugInId) ? true : false;
+
+    if (NULL != path) {
+        if (result) {
+            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+            result = rDrmEngine.canHandle(uniqueId, path);
+        } else {
+            result = canHandle(uniqueId, path);
+        }
+    }
+    return result;
+}
+
+DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
+    }
+    return NULL;
+}
+
+bool DrmManager::canHandle(int uniqueId, const String8& path) {
+    bool result = false;
+    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
+
+    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
+        result = rDrmEngine.canHandle(uniqueId, path);
+
+        if (result) {
+            break;
+        }
+    }
+    return result;
+}
+
+DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
+    }
+    return NULL;
+}
+
+void DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
+    }
+}
+
+String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
+    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.getOriginalMimeType(uniqueId, path);
+    }
+    return EMPTY_STRING;
+}
+
+int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
+    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
+    }
+    return DrmObjectType::UNKNOWN;
+}
+
+int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
+    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
+    }
+    return RightsStatus::RIGHTS_INVALID;
+}
+
+void DrmManager::consumeRights(
+    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
+    }
+}
+
+void DrmManager::setPlaybackStatus(
+    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+    }
+}
+
+bool DrmManager::validateAction(
+    int uniqueId, const String8& path, int action, const ActionDescription& description) {
+    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        return rDrmEngine.validateAction(uniqueId, path, action, description);
+    }
+    return false;
+}
+
+void DrmManager::removeRights(int uniqueId, const String8& path) {
+    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+        rDrmEngine.removeRights(uniqueId, path);
+    }
+}
+
+void DrmManager::removeAllRights(int uniqueId) {
+    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
+
+    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
+        rDrmEngine.removeAllRights(uniqueId);
+    }
+}
+
+int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
+    int convertId = -1;
+
+    const String8 plugInId = getSupportedPlugInId(mimeType);
+    if (EMPTY_STRING != plugInId) {
+        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+
+        Mutex::Autolock _l(mConvertLock);
+        ++mConvertId;
+        convertId = mConvertId;
+        mConvertSessionMap.add(mConvertId, &rDrmEngine);
+
+        rDrmEngine.openConvertSession(uniqueId, mConvertId);
+    }
+    return convertId;
+}
+
+DrmConvertedStatus* DrmManager::convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) {
+    DrmConvertedStatus *drmConvertedStatus = NULL;
+
+    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
+        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
+    }
+    return drmConvertedStatus;
+}
+
+DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
+    DrmConvertedStatus *drmConvertedStatus = NULL;
+
+    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
+        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
+        mConvertSessionMap.removeItem(convertId);
+    }
+    return drmConvertedStatus;
+}
+
+status_t DrmManager::getAllSupportInfo(
+                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
+    int size = plugInPathList.size();
+    int validPlugins = 0;
+
+    if (0 < size) {
+        Vector<DrmSupportInfo> drmSupportInfoList;
+
+        for (int i = 0; i < size; ++i) {
+            String8 plugInPath = plugInPathList[i];
+            DrmSupportInfo* drmSupportInfo
+                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(uniqueId);
+            if (NULL != drmSupportInfo) {
+                drmSupportInfoList.add(*drmSupportInfo);
+                delete drmSupportInfo; drmSupportInfo = NULL;
+            }
+        }
+
+        validPlugins = drmSupportInfoList.size();
+        if (0 < validPlugins) {
+            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
+            for (int i = 0; i < validPlugins; ++i) {
+                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
+            }
+        }
+    }
+    *length = validPlugins;
+    return DRM_NO_ERROR;
+}
+
+DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, int offset, int length) {
+    LOGV("Entering DrmManager::openDecryptSession");
+    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++) {
+            String8 plugInId = plugInIdList.itemAt(index);
+            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
+            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
+
+            LOGV("plug-in %s return value = %d", plugInId.string(), result);
+
+            if (DRM_NO_ERROR == result) {
+                ++mDecryptSessionId;
+                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
+                LOGV("plug-in %s is selected", plugInId.string());
+                break;
+            }
+        }
+    }
+
+    if (DRM_ERROR_CANNOT_HANDLE == result) {
+        delete handle; handle = NULL;
+        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
+    }
+
+    return handle;
+}
+
+void DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        drmEngine->closeDecryptSession(uniqueId, decryptHandle);
+
+        mDecryptSessionMap.removeItem(decryptHandle->decryptId);
+    }
+}
+
+void DrmManager::initializeDecryptUnit(
+    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
+    }
+}
+
+status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        status = drmEngine->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+    }
+    return status;
+}
+
+void DrmManager::finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    }
+}
+
+ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) {
+    ssize_t result = DECRYPT_FILE_ERROR;
+
+    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
+        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
+        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+    }
+    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("");
+
+    if (EMPTY_STRING != mimeType) {
+        plugInId = getSupportedPlugInId(mimeType);
+    } else {
+        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    }
+    return plugInId;
+}
+
+String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
+    String8 plugInId("");
+
+    if (EMPTY_STRING != mimeType) {
+        for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
+
+            if (drmSupportInfo.isSupportedMimeType(mimeType)) {
+                plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
+                break;
+            }
+        }
+    }
+    return plugInId;
+}
+
+String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
+    String8 plugInId("");
+    const String8 fileSuffix = path.getPathExtension();
+
+    for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+        const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
+
+        if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
+            String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
+            IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
+
+            if (drmEngine.canHandle(uniqueId, path)) {
+                plugInId = key;
+                break;
+            }
+        }
+    }
+    return plugInId;
+}
+
+void DrmManager::onInfo(const DrmInfoEvent& event) {
+    Mutex::Autolock _l(mLock);
+    for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
+        int uniqueId = mServiceListeners.keyAt(index);
+
+        if (uniqueId == event.getUniqueId()) {
+            sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
+            serviceListener->notify(event);
+        }
+    }
+}
+
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
new file mode 100644
index 0000000..9d000e9
--- /dev/null
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmManagerService(Native)"
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <utils/threads.h>
+#include <binder/IServiceManager.h>
+#include <sys/stat.h>
+#include "DrmManagerService.h"
+#include "DrmManager.h"
+
+using namespace android;
+
+#define SUCCESS 0
+#define DRM_DIRECTORY_PERMISSION 0700
+
+void DrmManagerService::instantiate() {
+    LOGV("instantiate");
+
+    int res = mkdir("/data/drm/plugins", DRM_DIRECTORY_PERMISSION);
+    if (SUCCESS == res || EEXIST == errno) {
+        res = mkdir("/data/drm/plugins/native", DRM_DIRECTORY_PERMISSION);
+        if (SUCCESS == res || EEXIST == errno) {
+            res = mkdir("/data/drm/plugins/native/databases", DRM_DIRECTORY_PERMISSION);
+            if (SUCCESS == res || EEXIST == errno) {
+                defaultServiceManager()
+                    ->addService(String16("drm.drmManager"), new DrmManagerService());
+            }
+        }
+    }
+}
+
+DrmManagerService::DrmManagerService() {
+    LOGV("created");
+    mDrmManager = NULL;
+    mDrmManager = new DrmManager();
+}
+
+DrmManagerService::~DrmManagerService() {
+    LOGV("Destroyed");
+    delete mDrmManager; mDrmManager = NULL;
+}
+
+status_t DrmManagerService::loadPlugIns(int uniqueId) {
+    LOGV("Entering load plugins");
+    return mDrmManager->loadPlugIns(uniqueId);
+}
+
+status_t DrmManagerService::loadPlugIns(int uniqueId, const String8& plugInDirPath) {
+    LOGV("Entering load plugins from path");
+    return mDrmManager->loadPlugIns(uniqueId, plugInDirPath);
+}
+
+status_t DrmManagerService::setDrmServiceListener(
+            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
+    LOGV("Entering setDrmServiceListener");
+    mDrmManager->setDrmServiceListener(uniqueId, drmServiceListener);
+    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);
+}
+
+DrmConstraints* DrmManagerService::getConstraints(
+            int uniqueId, const String8* path, const int action) {
+    LOGV("Entering getConstraints from content");
+    return mDrmManager->getConstraints(uniqueId, path, action);
+}
+
+bool DrmManagerService::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+    LOGV("Entering canHandle");
+    return mDrmManager->canHandle(uniqueId, path, mimeType);
+}
+
+DrmInfoStatus* DrmManagerService::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    LOGV("Entering processDrmInfo");
+    return mDrmManager->processDrmInfo(uniqueId, drmInfo);
+}
+
+DrmInfo* DrmManagerService::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    LOGV("Entering acquireDrmInfo");
+    return mDrmManager->acquireDrmInfo(uniqueId, drmInfoRequest);
+}
+
+void DrmManagerService::saveRights(
+            int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    LOGV("Entering saveRights");
+    return mDrmManager->saveRights(uniqueId, drmRights, rightsPath, contentPath);
+}
+
+String8 DrmManagerService::getOriginalMimeType(int uniqueId, const String8& path) {
+    LOGV("Entering getOriginalMimeType");
+    return mDrmManager->getOriginalMimeType(uniqueId, path);
+}
+
+int DrmManagerService::getDrmObjectType(
+           int uniqueId, const String8& path, const String8& mimeType) {
+    LOGV("Entering getDrmObjectType");
+    return mDrmManager->getDrmObjectType(uniqueId, path, mimeType);
+}
+
+int DrmManagerService::checkRightsStatus(
+            int uniqueId, const String8& path, int action) {
+    LOGV("Entering checkRightsStatus");
+    return mDrmManager->checkRightsStatus(uniqueId, path, action);
+}
+
+void DrmManagerService::consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    LOGV("Entering consumeRights");
+    mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
+}
+
+void DrmManagerService::setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    LOGV("Entering setPlaybackStatus");
+    mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+}
+
+bool DrmManagerService::validateAction(
+            int uniqueId, const String8& path,
+            int action, const ActionDescription& description) {
+    LOGV("Entering validateAction");
+    return mDrmManager->validateAction(uniqueId, path, action, description);
+}
+
+void DrmManagerService::removeRights(int uniqueId, const String8& path) {
+    LOGV("Entering removeRights");
+    mDrmManager->removeRights(uniqueId, path);
+}
+
+void DrmManagerService::removeAllRights(int uniqueId) {
+    LOGV("Entering removeAllRights");
+    mDrmManager->removeAllRights(uniqueId);
+}
+
+int DrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
+    LOGV("Entering openConvertSession");
+    return mDrmManager->openConvertSession(uniqueId, mimeType);
+}
+
+DrmConvertedStatus* DrmManagerService::convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) {
+    LOGV("Entering convertData");
+    return mDrmManager->convertData(uniqueId, convertId, inputData);
+}
+
+DrmConvertedStatus* DrmManagerService::closeConvertSession(int uniqueId, int convertId) {
+    LOGV("Entering closeConvertSession");
+    return mDrmManager->closeConvertSession(uniqueId, convertId);
+}
+
+status_t DrmManagerService::getAllSupportInfo(
+            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+    LOGV("Entering getAllSupportInfo");
+    return mDrmManager->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
+}
+
+DecryptHandle* DrmManagerService::openDecryptSession(
+            int uniqueId, int fd, int offset, int length) {
+    LOGV("Entering DrmManagerService::openDecryptSession");
+    return mDrmManager->openDecryptSession(uniqueId, fd, offset, length);
+}
+
+void DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    LOGV("Entering closeDecryptSession");
+    mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
+}
+
+void DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    LOGV("Entering initializeDecryptUnit");
+    mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
+}
+
+status_t DrmManagerService::decrypt(
+            int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    LOGV("Entering decrypt");
+    return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+}
+
+void DrmManagerService::finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    LOGV("Entering finalizeDecryptUnit");
+    mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+}
+
+ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) {
+    LOGV("Entering pread");
+    return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+}
+
diff --git a/drm/drmserver/StringTokenizer.cpp b/drm/drmserver/StringTokenizer.cpp
new file mode 100644
index 0000000..367c9bd
--- /dev/null
+++ b/drm/drmserver/StringTokenizer.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "StringTokenizer.h"
+
+using namespace android;
+
+StringTokenizer::StringTokenizer(const String8& string, const String8& delimiter) {
+    splitString(string, delimiter);
+}
+
+void StringTokenizer::splitString(const String8& string, const String8& delimiter) {
+    for (unsigned int i = 0; i < string.length(); i++) {
+        unsigned int position = string.find(delimiter.string(), i);
+        if (string.length() != position) {
+            String8 token(string.string()+i, position-i);
+            if (token.length()) {
+                mStringTokenizerVector.push(token);
+                i = position + delimiter.length() - 1;
+            }
+        } else {
+            mStringTokenizerVector.push(String8(string.string()+i, string.length()-i));
+            break;
+        }
+    }
+}
+
+StringTokenizer::Iterator StringTokenizer::iterator() {
+    return Iterator(this);
+}
+
+StringTokenizer::Iterator::Iterator(const StringTokenizer::Iterator& iterator) :
+    mStringTokenizer(iterator.mStringTokenizer),
+    mIndex(iterator.mIndex) {
+    LOGV("StringTokenizer::Iterator::Iterator");
+}
+
+StringTokenizer::Iterator& StringTokenizer::Iterator::operator=(
+            const StringTokenizer::Iterator& iterator) {
+    LOGV("StringTokenizer::Iterator::operator=");
+    mStringTokenizer = iterator.mStringTokenizer;
+    mIndex = iterator.mIndex;
+    return *this;
+}
+
+bool StringTokenizer::Iterator::hasNext() {
+    return mIndex < mStringTokenizer->mStringTokenizerVector.size();
+}
+
+String8& StringTokenizer::Iterator::next() {
+    String8& value = mStringTokenizer->mStringTokenizerVector.editItemAt(mIndex);
+    mIndex++;
+    return value;
+}
+
diff --git a/drm/drmserver/main_drmserver.cpp b/drm/drmserver/main_drmserver.cpp
new file mode 100644
index 0000000..6d10646
--- /dev/null
+++ b/drm/drmserver/main_drmserver.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 <sys/types.h>
+#include <unistd.h>
+#include <grp.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include <private/android_filesystem_config.h>
+
+#include <DrmManagerService.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+    sp<ProcessState> proc(ProcessState::self());
+    sp<IServiceManager> sm = defaultServiceManager();
+    LOGI("ServiceManager: %p", sm.get());
+    DrmManagerService::instantiate();
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+}
+
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
new file mode 100644
index 0000000..99133ba
--- /dev/null
+++ b/drm/libdrmframework/Android.mk
@@ -0,0 +1,49 @@
+#
+# 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:= \
+    DrmManagerClientImpl.cpp \
+    DrmManagerClient.cpp
+
+LOCAL_MODULE:= libdrmframework
+
+LOCAL_SHARED_LIBRARIES := \
+    libutils \
+    libbinder
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_STATIC_LIBRARIES := \
+    libdrmframeworkcommon
+
+LOCAL_C_INCLUDES += \
+    $(TOP)/frameworks/base/drm/libdrmframework/include \
+    $(TOP)/frameworks/base/include
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
new file mode 100644
index 0000000..06c7c50
--- /dev/null
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmManagerClient(Native)"
+#include <utils/Log.h>
+
+#include <utils/String8.h>
+#include <binder/IServiceManager.h>
+#include <drm/DrmManagerClient.h>
+
+#include "DrmManagerClientImpl.h"
+
+using namespace android;
+
+DrmManagerClient::DrmManagerClient() {
+    int uniqueId = 0;
+    mDrmManagerClientImpl = NULL;
+
+    mDrmManagerClientImpl = DrmManagerClientImpl::create(&uniqueId);
+    mUniqueId = uniqueId;
+
+    loadPlugIns();
+}
+
+DrmManagerClient::~DrmManagerClient() {
+    unloadPlugIns();
+    DrmManagerClientImpl::remove(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);
+}
+
+bool DrmManagerClient::canHandle(const String8& path, const String8& mimeType) {
+    return mDrmManagerClientImpl->canHandle(mUniqueId, path, mimeType);
+}
+
+DrmInfoStatus* DrmManagerClient::processDrmInfo(const DrmInfo* drmInfo) {
+    return mDrmManagerClientImpl->processDrmInfo(mUniqueId, drmInfo);
+}
+
+DrmInfo* DrmManagerClient::acquireDrmInfo(const DrmInfoRequest* drmInfoRequest) {
+    return mDrmManagerClientImpl->acquireDrmInfo(mUniqueId, drmInfoRequest);
+}
+
+void DrmManagerClient::saveRights(
+        const DrmRights& drmRights, const String8& rightsPath, const String8& contentPath) {
+    return mDrmManagerClientImpl->saveRights(mUniqueId, drmRights, rightsPath, contentPath);
+}
+
+String8 DrmManagerClient::getOriginalMimeType(const String8& path) {
+    return mDrmManagerClientImpl->getOriginalMimeType(mUniqueId, path);
+}
+
+int DrmManagerClient::getDrmObjectType(const String8& path, const String8& mimeType) {
+    return mDrmManagerClientImpl->getDrmObjectType( mUniqueId, path, mimeType);
+}
+
+int DrmManagerClient::checkRightsStatus(const String8& path, int action) {
+    return mDrmManagerClientImpl->checkRightsStatus(mUniqueId, path, action);
+}
+
+void DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+    mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
+}
+
+void DrmManagerClient::setPlaybackStatus(
+            DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    mDrmManagerClientImpl->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
+}
+
+bool DrmManagerClient::validateAction(
+            const String8& path, int action, const ActionDescription& description) {
+    return mDrmManagerClientImpl->validateAction(mUniqueId, path, action, description);
+}
+
+void DrmManagerClient::removeRights(const String8& path) {
+    mDrmManagerClientImpl->removeRights(mUniqueId, path);
+}
+
+void DrmManagerClient::removeAllRights() {
+    mDrmManagerClientImpl->removeAllRights(mUniqueId);
+}
+
+int DrmManagerClient::openConvertSession(const String8& mimeType) {
+    return mDrmManagerClientImpl->openConvertSession(mUniqueId, mimeType);
+}
+
+DrmConvertedStatus* DrmManagerClient::convertData(int convertId, const DrmBuffer* inputData) {
+    return mDrmManagerClientImpl->convertData(mUniqueId, convertId, inputData);
+}
+
+DrmConvertedStatus* DrmManagerClient::closeConvertSession(int convertId) {
+    return mDrmManagerClientImpl->closeConvertSession(mUniqueId, convertId);
+}
+
+status_t DrmManagerClient::getAllSupportInfo(int* length, DrmSupportInfo** drmSupportInfoArray) {
+    return mDrmManagerClientImpl->getAllSupportInfo(mUniqueId, length, drmSupportInfoArray);
+}
+
+DecryptHandle* DrmManagerClient::openDecryptSession(int fd, int offset, int length) {
+    return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
+}
+
+void DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
+    mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
+}
+
+void DrmManagerClient::initializeDecryptUnit(
+            DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    mDrmManagerClientImpl->initializeDecryptUnit(
+        mUniqueId, decryptHandle, decryptUnitId, headerInfo);
+}
+
+status_t DrmManagerClient::decrypt(
+    DecryptHandle* decryptHandle, int decryptUnitId,
+    const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    return mDrmManagerClientImpl->decrypt(
+            mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+}
+
+void DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
+    mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
+}
+
+ssize_t DrmManagerClient::pread(
+            DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off_t offset) {
+    return mDrmManagerClientImpl->pread(mUniqueId, decryptHandle, buffer, numBytes, offset);
+}
+
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
new file mode 100644
index 0000000..7274b49
--- /dev/null
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmManagerClientImpl(Native)"
+#include <utils/Log.h>
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <binder/IServiceManager.h>
+
+#include "DrmManagerClientImpl.h"
+
+using namespace android;
+
+#define INVALID_VALUE -1
+
+Mutex DrmManagerClientImpl::mMutex;
+Vector<int> DrmManagerClientImpl::mUniqueIdVector;
+sp<IDrmManagerService> DrmManagerClientImpl::mDrmManagerService;
+const String8 DrmManagerClientImpl::EMPTY_STRING("");
+
+DrmManagerClientImpl* DrmManagerClientImpl::create(int* pUniqueId) {
+    if (0 == *pUniqueId) {
+        int uniqueId = 0;
+        bool foundUniqueId = false;
+        srand(time(NULL));
+
+        while (!foundUniqueId) {
+            const int size = mUniqueIdVector.size();
+            uniqueId = rand() % 100;
+
+            int index = 0;
+            for (; index < size; ++index) {
+                if (mUniqueIdVector.itemAt(index) == uniqueId) {
+                    foundUniqueId = false;
+                    break;
+                }
+            }
+            if (index == size) {
+                foundUniqueId = true;
+            }
+        }
+        *pUniqueId = uniqueId;
+    }
+    mUniqueIdVector.push(*pUniqueId);
+    return new DrmManagerClientImpl();
+}
+
+void DrmManagerClientImpl::remove(int uniqueId) {
+    for (int i = 0; i < mUniqueIdVector.size(); i++) {
+        if (uniqueId == mUniqueIdVector.itemAt(i)) {
+            mUniqueIdVector.removeAt(i);
+            break;
+        }
+    }
+}
+
+DrmManagerClientImpl::DrmManagerClientImpl() {
+
+}
+
+DrmManagerClientImpl::~DrmManagerClientImpl() {
+
+}
+
+const sp<IDrmManagerService>& DrmManagerClientImpl::getDrmManagerService() {
+    mMutex.lock();
+    if (NULL == mDrmManagerService.get()) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder;
+        do {
+            binder = sm->getService(String16("drm.drmManager"));
+            if (binder != 0) {
+                break;
+            }
+            LOGW("DrmManagerService not published, waiting...");
+            struct timespec reqt;
+            reqt.tv_sec  = 0;
+            reqt.tv_nsec = 500000000; //0.5 sec
+            nanosleep(&reqt, NULL);
+        } while (true);
+
+        mDrmManagerService = interface_cast<IDrmManagerService>(binder);
+    }
+    mMutex.unlock();
+    return mDrmManagerService;
+}
+
+status_t DrmManagerClientImpl::loadPlugIns(int uniqueId) {
+    return getDrmManagerService()->loadPlugIns(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;
+}
+
+status_t DrmManagerClientImpl::setOnInfoListener(
+            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+    Mutex::Autolock _l(mLock);
+    mOnInfoListener = infoListener;
+    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) {
+        status = getDrmManagerService()->installDrmEngine(uniqueId, drmEngineFile);
+    }
+    return status;
+}
+
+DrmConstraints* DrmManagerClientImpl::getConstraints(
+        int uniqueId, const String8* path, const int action) {
+    DrmConstraints *drmConstraints = NULL;
+    if ((NULL != path) && (EMPTY_STRING != *path)) {
+        drmConstraints = getDrmManagerService()->getConstraints(uniqueId, path, action);
+    }
+    return drmConstraints;
+}
+
+bool DrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+    bool retCode = false;
+    if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
+        retCode = getDrmManagerService()->canHandle(uniqueId, path, mimeType);
+    }
+    return retCode;
+}
+
+DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    DrmInfoStatus *drmInfoStatus = NULL;
+    if (NULL != drmInfo) {
+        drmInfoStatus = getDrmManagerService()->processDrmInfo(uniqueId, drmInfo);
+    }
+    return drmInfoStatus;
+}
+
+DrmInfo* DrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    DrmInfo* drmInfo = NULL;
+    if (NULL != drmInfoRequest) {
+        drmInfo = getDrmManagerService()->acquireDrmInfo(uniqueId, drmInfoRequest);
+    }
+    return drmInfo;
+}
+
+void DrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    if (EMPTY_STRING != contentPath) {
+        getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
+    }
+}
+
+String8 DrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path) {
+    String8 mimeType = EMPTY_STRING;
+    if (EMPTY_STRING != path) {
+        mimeType = getDrmManagerService()->getOriginalMimeType(uniqueId, path);
+    }
+    return mimeType;
+}
+
+int DrmManagerClientImpl::getDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) {
+    int drmOjectType = DrmObjectType::UNKNOWN;
+    if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
+         drmOjectType = getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
+    }
+    return drmOjectType;
+}
+
+int DrmManagerClientImpl::checkRightsStatus(
+            int uniqueId, const String8& path, int action) {
+    int rightsStatus = RightsStatus::RIGHTS_INVALID;
+    if (EMPTY_STRING != path) {
+        rightsStatus = getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
+    }
+    return rightsStatus;
+}
+
+void DrmManagerClientImpl::consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    if (NULL != decryptHandle) {
+        getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
+    }
+}
+
+void DrmManagerClientImpl::setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    if (NULL != decryptHandle) {
+        getDrmManagerService()->setPlaybackStatus(
+                uniqueId, decryptHandle, playbackStatus, position);
+    }
+}
+
+bool DrmManagerClientImpl::validateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description) {
+    bool retCode = false;
+    if (EMPTY_STRING != path) {
+        retCode = getDrmManagerService()->validateAction(uniqueId, path, action, description);
+    }
+    return retCode;
+}
+
+void DrmManagerClientImpl::removeRights(int uniqueId, const String8& path) {
+    if (EMPTY_STRING != path) {
+        getDrmManagerService()->removeRights(uniqueId, path);
+    }
+}
+
+void DrmManagerClientImpl::removeAllRights(int uniqueId) {
+    getDrmManagerService()->removeAllRights(uniqueId);
+}
+
+int DrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+    int retCode = INVALID_VALUE;
+    if (EMPTY_STRING != mimeType) {
+        retCode = getDrmManagerService()->openConvertSession(uniqueId, mimeType);
+    }
+    return retCode;
+}
+
+DrmConvertedStatus* DrmManagerClientImpl::convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) {
+    DrmConvertedStatus* drmConvertedStatus = NULL;
+    if (NULL != inputData) {
+         drmConvertedStatus = getDrmManagerService()->convertData(uniqueId, convertId, inputData);
+    }
+    return drmConvertedStatus;
+}
+
+DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+    return getDrmManagerService()->closeConvertSession(uniqueId, convertId);
+}
+
+status_t DrmManagerClientImpl::getAllSupportInfo(
+            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if ((NULL != drmSupportInfoArray) && (NULL != length)) {
+        status = getDrmManagerService()->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
+    }
+    return status;
+}
+
+DecryptHandle* DrmManagerClientImpl::openDecryptSession(
+            int uniqueId, int fd, int offset, int length) {
+    LOGV("Entering DrmManagerClientImpl::openDecryptSession");
+    return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length);
+}
+
+void DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    if (NULL != decryptHandle) {
+        getDrmManagerService()->closeDecryptSession( uniqueId, decryptHandle);
+    }
+}
+
+void DrmManagerClientImpl::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    if ((NULL != decryptHandle) && (NULL != headerInfo)) {
+        getDrmManagerService()->initializeDecryptUnit(
+                uniqueId, decryptHandle, decryptUnitId, headerInfo);
+    }
+}
+
+status_t DrmManagerClientImpl::decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if ((NULL != decryptHandle) && (NULL != encBuffer)
+        && (NULL != decBuffer) && (NULL != *decBuffer)) {
+        status = getDrmManagerService()->decrypt(
+                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+    }
+    return status;
+}
+
+void DrmManagerClientImpl::finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    if (NULL != decryptHandle) {
+        getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    }
+}
+
+ssize_t DrmManagerClientImpl::pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) {
+    ssize_t retCode = INVALID_VALUE;
+    if ((NULL != decryptHandle) && (NULL != buffer) && (0 < numBytes)) {
+        retCode = getDrmManagerService()->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+    }
+    return retCode;
+}
+
+status_t DrmManagerClientImpl::notify(const DrmInfoEvent& event) {
+    if (NULL != mOnInfoListener.get()) {
+        Mutex::Autolock _l(mLock);
+        sp<DrmManagerClient::OnInfoListener> listener = mOnInfoListener;
+        listener->onInfo(event);
+    }
+    return DRM_NO_ERROR;
+}
+
diff --git a/drm/libdrmframework/include/DrmIOService.h b/drm/libdrmframework/include/DrmIOService.h
new file mode 100644
index 0000000..244124e
--- /dev/null
+++ b/drm/libdrmframework/include/DrmIOService.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 __DRM_IO_SERVICE_H__
+#define __DRM_IO_SERVICE_H__
+
+#include "IDrmIOService.h"
+
+namespace android {
+
+/**
+ * This is the implementation class for DRM IO service.
+ *
+ * The instance of this class is created while starting the DRM IO service.
+ *
+ */
+class DrmIOService : public BnDrmIOService {
+public:
+    static void instantiate();
+
+private:
+    DrmIOService();
+    virtual ~DrmIOService();
+
+public:
+    void writeToFile(const String8& filePath, const String8& dataBuffer);
+    String8 readFromFile(const String8& filePath);
+};
+
+};
+
+#endif /* __DRM_IO_SERVICE_H__ */
+
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
new file mode 100644
index 0000000..2ba9e99
--- /dev/null
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -0,0 +1,153 @@
+/*
+ * 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_MANAGER_H__
+#define __DRM_MANAGER_H__
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <drm/drm_framework_common.h>
+#include "IDrmEngine.h"
+#include "PlugInManager.h"
+#include "IDrmServiceListener.h"
+
+namespace android {
+
+class IDrmManager;
+class DrmRegistrationInfo;
+class DrmUnregistrationInfo;
+class DrmRightsAcquisitionInfo;
+class DrmContentIds;
+class DrmConstraints;
+class DrmRights;
+class DrmInfo;
+class DrmInfoStatus;
+class DrmConvertedStatus;
+class DrmInfoRequest;
+class DrmSupportInfo;
+class ActionDescription;
+
+/**
+ * This is implementation class for DRM Manager. This class delegates the
+ * functionality to corresponding DRM Engine.
+ *
+ * The DrmManagerService class creates an instance of this class.
+ *
+ */
+class DrmManager : public IDrmEngine::OnInfoListener {
+public:
+    DrmManager();
+    virtual ~DrmManager();
+
+public:
+
+    status_t loadPlugIns(int uniqueId);
+
+    status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+
+    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);
+
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+
+    void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    String8 getOriginalMimeType(int uniqueId, const String8& path);
+
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int checkRightsStatus(int uniqueId, const String8& path, int action);
+
+    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    bool validateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    void removeRights(int uniqueId, const String8& path);
+
+    void removeAllRights(int uniqueId);
+
+    int openConvertSession(int uniqueId, const String8& mimeType);
+
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
+
+    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer,DrmBuffer** decBuffer);
+
+    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+
+    void onInfo(const DrmInfoEvent& event);
+
+private:
+    String8 getSupportedPlugInId(int uniqueId, const String8& path, const String8& mimeType);
+
+    String8 getSupportedPlugInId(const String8& mimeType);
+
+    String8 getSupportedPlugInIdFromPath(int uniqueId, const String8& path);
+
+    void populate(int uniqueId);
+
+    bool canHandle(int uniqueId, const String8& path);
+
+    void initializePlugIns(int uniqueId);
+
+private:
+    static const String8 EMPTY_STRING;
+
+    int mDecryptSessionId;
+    int mConvertId;
+    Mutex mLock;
+    Mutex mDecryptLock;
+    Mutex mConvertLock;
+    TPlugInManager<IDrmEngine> mPlugInManager;
+    KeyedVector< DrmSupportInfo, String8 > mSupportInfoToPlugInIdMap;
+    KeyedVector< int, IDrmEngine*> mConvertSessionMap;
+    KeyedVector< int, sp<IDrmServiceListener> > mServiceListeners;
+    KeyedVector< int, IDrmEngine*> mDecryptSessionMap;
+};
+
+};
+
+#endif /* __DRM_MANAGER_H__ */
+
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
new file mode 100644
index 0000000..e70e6e1
--- /dev/null
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -0,0 +1,400 @@
+/*
+ * 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_MANAGER_CLIENT_IMPL_H__
+#define __DRM_MANAGER_CLIENT_IMPL_H__
+
+#include <binder/IMemory.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+#include "IDrmManagerService.h"
+
+namespace android {
+
+class DrmInfoEvent;
+/**
+ * This is implementation class for DrmManagerClient class.
+ *
+ * Only the JNI layer creates an instance of this class to delegate
+ * functionality to Native later.
+ *
+ */
+class DrmManagerClientImpl : public BnDrmServiceListener {
+private:
+    DrmManagerClientImpl();
+
+public:
+    static DrmManagerClientImpl* create(int* pUniqueId);
+
+    static void remove(int uniqueId);
+
+    virtual ~DrmManagerClientImpl();
+
+public:
+    /**
+     * Initialize DRM Manager
+     *     load available plug-ins from default plugInDirPath
+     *
+     * @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);
+
+    /**
+     * Finalize DRM Manager
+     *     release resources associated with each plug-in
+     *     unload all plug-ins and etc.
+     *
+     * @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);
+
+    /**
+     * 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
+     */
+    status_t setOnInfoListener(
+            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener);
+
+    /**
+     * 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
+     */
+    DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
+
+    /**
+     * Check whether the given mimetype or path can be handled
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the content needs to be handled
+     * @param[in] mimetype Mimetype of the content needs to be handled
+     * @return
+     *     True if DrmManager can handle given path or mime type.
+     */
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    /**
+     * 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
+     */
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    /**
+     * 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
+     */
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+
+    /**
+     * 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
+     */
+    void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    /**
+     * Retrieves the mime type embedded inside the original content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path the path of the protected content
+     * @return String8
+     *     Returns mime-type of the original content, such as "video/mpeg"
+     */
+    String8 getOriginalMimeType(int uniqueId, const String8& path);
+
+    /**
+     * 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
+     */
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    /**
+     * 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.
+     */
+    int checkRightsStatus(int uniqueId, const String8& path, int action);
+
+    /**
+     * 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.
+     */
+    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    /**
+     * 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.
+     */
+    void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    /**
+     * 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.
+     */
+    bool validateAction(
+        int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    /**
+     * 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
+     */
+    void removeRights(int uniqueId, const String8& path);
+
+    /**
+     * 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
+     */
+    void removeAllRights(int uniqueId);
+
+    /**
+     * 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] mimeType Description/MIME type of the input data packet
+     * @return Return handle for the convert session
+     */
+    int openConvertSession(int uniqueId, const String8& mimeType);
+
+    /**
+     * 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.
+     */
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    /**
+     * 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.
+     */
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    /**
+     * Retrieves all DrmSupportInfo instance that native DRM framework can handle.
+     * This interface is meant to be used by JNI layer
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[out] length Number of elements in drmSupportInfoArray
+     * @param[out] drmSupportInfoArray Array contains all DrmSupportInfo
+     *             that native DRM framework can handle
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a 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
+     *     Handle for the decryption session
+     */
+    DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
+
+    /**
+     * Close the decrypt session for the given handle
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     */
+    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    /**
+     * 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
+     */
+    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    /**
+     * Decrypt the protected content buffers for the given unit
+     * This method will be called any number of times, based on number of
+     * encrypted streams received from application.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @param[in] encBuffer Encrypted data block
+     * @param[out] decBuffer Decrypted data block
+     * @return status_t
+     *     Returns the error code for this API
+     *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
+     *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
+     *     DRM_ERROR_DECRYPT for failure.
+     */
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+    /**
+     * 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
+     */
+    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    /**
+     * 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.
+     */
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+
+    /**
+     * Notify the event to the registered listener
+     *
+     * @param[in] event The event to be notified
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t notify(const DrmInfoEvent& event);
+
+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
+     * @param[in] drmEngine Shared Object(so) File in which DRM Engine defined
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
+
+private:
+    Mutex mLock;
+    sp<DrmManagerClient::OnInfoListener> mOnInfoListener;
+
+private:
+    static Mutex mMutex;
+    static Vector<int> mUniqueIdVector;
+    static sp<IDrmManagerService> mDrmManagerService;
+    static const sp<IDrmManagerService>& getDrmManagerService();
+    static const String8 EMPTY_STRING;
+};
+
+};
+
+#endif /* __DRM_MANAGER_CLIENT_IMPL_H__ */
+
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
new file mode 100644
index 0000000..fef121c
--- /dev/null
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -0,0 +1,119 @@
+/*
+ * 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_MANAGER_SERVICE_H__
+#define __DRM_MANAGER_SERVICE_H__
+
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include "IDrmManagerService.h"
+#include "IDrmServiceListener.h"
+
+namespace android {
+
+class DrmManager;
+class String8;
+class Mutex;
+
+/**
+ * This is the implementation class for DRM manager service. This delegates
+ * the responsibility to DrmManager.
+ *
+ * The instance of this class is created while starting the DRM manager service.
+ *
+ */
+class DrmManagerService : public BnDrmManagerService {
+public:
+    static void instantiate();
+
+private:
+    DrmManagerService();
+    virtual ~DrmManagerService();
+
+public:
+    status_t loadPlugIns(int uniqueId);
+
+    status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+
+    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);
+
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest);
+
+    void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    String8 getOriginalMimeType(int uniqueId, const String8& path);
+
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int checkRightsStatus(int uniqueId, const String8& path,int action);
+
+    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    bool validateAction(int uniqueId, const String8& path,
+            int action, const ActionDescription& description);
+
+    void removeRights(int uniqueId, const String8& path);
+
+    void removeAllRights(int uniqueId);
+
+    int openConvertSession(int uniqueId, const String8& mimeType);
+
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
+
+    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+
+private:
+    DrmManager* mDrmManager;
+};
+
+};
+
+#endif /* __DRM_MANAGER_SERVICE_H__ */
+
diff --git a/drm/libdrmframework/include/IDrmIOService.h b/drm/libdrmframework/include/IDrmIOService.h
new file mode 100644
index 0000000..5e0d907
--- /dev/null
+++ b/drm/libdrmframework/include/IDrmIOService.h
@@ -0,0 +1,86 @@
+/*
+ * 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_IO_SERVICE_H__
+#define __IDRM_IO_SERVICE_H__
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+/**
+ * This is the interface class for DRM IO service.
+ *
+ */
+class IDrmIOService : public IInterface
+{
+public:
+    enum {
+        WRITE_TO_FILE = IBinder::FIRST_CALL_TRANSACTION,
+        READ_FROM_FILE
+    };
+
+public:
+    DECLARE_META_INTERFACE(DrmIOService);
+
+public:
+    /**
+     * Writes the data into the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @param[in] dataBuffer Data to write
+     */
+    virtual void writeToFile(const String8& filePath, const String8& dataBuffer) = 0;
+
+    /**
+     * Reads the data from the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @return Data read from the file
+     */
+    virtual String8 readFromFile(const String8& filePath) = 0;
+};
+
+/**
+ * This is the Binder implementation class for DRM IO service.
+ */
+class BpDrmIOService: public BpInterface<IDrmIOService>
+{
+public:
+    BpDrmIOService(const sp<IBinder>& impl)
+            : BpInterface<IDrmIOService>(impl) {}
+
+    virtual void writeToFile(const String8& filePath, const String8& dataBuffer);
+
+    virtual String8 readFromFile(const String8& filePath);
+};
+
+/**
+ * This is the Binder implementation class for DRM IO service.
+ */
+class BnDrmIOService: public BnInterface<IDrmIOService>
+{
+public:
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
+};
+
+};
+
+#endif /* __IDRM_IO_SERVICE_H__ */
+
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
new file mode 100644
index 0000000..a4d128a
--- /dev/null
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -0,0 +1,242 @@
+/*
+ * 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_MANAGER_SERVICE_H__
+#define __IDRM_MANAGER_SERVICE_H__
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <drm/drm_framework_common.h>
+#include "IDrmServiceListener.h"
+
+namespace android {
+
+class DrmContentIds;
+class DrmConstraints;
+class DrmRights;
+class DrmInfo;
+class DrmInfoStatus;
+class DrmInfoRequest;
+class DrmSupportInfo;
+class DrmConvertedStatus;
+class String8;
+class ActionDescription;
+
+/**
+ * This is the interface class for DRM Manager service.
+ *
+ */
+class IDrmManagerService : public IInterface
+{
+public:
+    enum {
+        LOAD_PLUGINS = IBinder::FIRST_CALL_TRANSACTION,
+        LOAD_PLUGINS_FROM_PATH,
+        SET_DRM_SERVICE_LISTENER,
+        UNLOAD_PLUGINS,
+        INSTALL_DRM_ENGINE,
+        GET_CONSTRAINTS_FROM_CONTENT,
+        CAN_HANDLE,
+        PROCESS_DRM_INFO,
+        ACQUIRE_DRM_INFO,
+        SAVE_RIGHTS,
+        GET_ORIGINAL_MIMETYPE,
+        GET_DRM_OBJECT_TYPE,
+        CHECK_RIGHTS_STATUS,
+        CONSUME_RIGHTS,
+        SET_PLAYBACK_STATUS,
+        VALIDATE_ACTION,
+        REMOVE_RIGHTS,
+        REMOVE_ALL_RIGHTS,
+        OPEN_CONVERT_SESSION,
+        CONVERT_DATA,
+        CLOSE_CONVERT_SESSION,
+        GET_ALL_SUPPORT_INFO,
+        OPEN_DECRYPT_SESSION,
+        CLOSE_DECRYPT_SESSION,
+        INITIALIZE_DECRYPT_UNIT,
+        DECRYPT,
+        FINALIZE_DECRYPT_UNIT,
+        PREAD
+    };
+
+public:
+    DECLARE_META_INTERFACE(DrmManagerService);
+
+public:
+    virtual status_t loadPlugIns(int uniqueId) = 0;
+
+    virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath) = 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(
+            int uniqueId, const String8* path, const int action) = 0;
+
+    virtual bool canHandle(int uniqueId, const String8& path, const String8& mimeType) = 0;
+
+    virtual DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0;
+
+    virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) = 0;
+
+    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) = 0;
+
+    virtual String8 getOriginalMimeType(int uniqueId, const String8& path) = 0;
+
+    virtual int getDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) = 0;
+
+    virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0;
+
+    virtual void consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+
+    virtual void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) = 0;
+
+    virtual bool validateAction(
+            int uniqueId, const String8& path,
+            int action, const ActionDescription& description) = 0;
+
+    virtual void removeRights(int uniqueId, const String8& path) = 0;
+
+    virtual void removeAllRights(int uniqueId) = 0;
+
+    virtual int openConvertSession(int uniqueId, const String8& mimeType) = 0;
+
+    virtual DrmConvertedStatus* convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) = 0;
+
+    virtual DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId) = 0;
+
+    virtual status_t getAllSupportInfo(
+            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) = 0;
+
+    virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length) = 0;
+
+    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+
+    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) = 0;
+
+    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0;
+
+    virtual void finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+
+    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes,off_t offset) = 0;
+};
+
+/**
+ * This is the Binder implementation class for DRM Manager service.
+ */
+class BpDrmManagerService: public BpInterface<IDrmManagerService>
+{
+public:
+    BpDrmManagerService(const sp<IBinder>& impl)
+            : BpInterface<IDrmManagerService>(impl) {}
+
+    virtual status_t loadPlugIns(int uniqueId);
+
+    virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
+
+    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);
+
+    virtual bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    virtual DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest);
+
+    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    virtual String8 getOriginalMimeType(int uniqueId, const String8& path);
+
+    virtual int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    virtual int checkRightsStatus(int uniqueId, const String8& path, int action);
+
+    virtual void consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    virtual void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    virtual bool validateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    virtual void removeRights(int uniqueId, const String8& path);
+
+    virtual void removeAllRights(int uniqueId);
+
+    virtual int openConvertSession(int uniqueId, const String8& mimeType);
+
+    virtual DrmConvertedStatus* convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    virtual DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    virtual status_t getAllSupportInfo(
+            int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
+
+    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+    virtual void finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+};
+
+/**
+ * This is the Binder implementation class for DRM Manager service.
+ */
+class BnDrmManagerService: public BnInterface<IDrmManagerService>
+{
+public:
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
+};
+
+};
+
+#endif /* __IDRM_MANAGER_SERVICE_H__ */
+
diff --git a/drm/libdrmframework/include/IDrmServiceListener.h b/drm/libdrmframework/include/IDrmServiceListener.h
new file mode 100644
index 0000000..7f7109f
--- /dev/null
+++ b/drm/libdrmframework/include/IDrmServiceListener.h
@@ -0,0 +1,71 @@
+/*
+ * 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_SERVICE_LISTENER_H__
+#define __IDRM_SERVICE_LISTENER_H__
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class DrmInfoEvent;
+
+/**
+ * This is the interface class for DRM service listener.
+ *
+ */
+class IDrmServiceListener : public IInterface
+{
+public:
+    enum {
+        NOTIFY = IBinder::FIRST_CALL_TRANSACTION,
+    };
+
+public:
+    DECLARE_META_INTERFACE(DrmServiceListener);
+
+public:
+    virtual status_t notify(const DrmInfoEvent& event) = 0;
+};
+
+/**
+ * This is the Binder implementation class for DRM service listener.
+ */
+class BpDrmServiceListener: public BpInterface<IDrmServiceListener>
+{
+public:
+    BpDrmServiceListener(const sp<IBinder>& impl)
+            : BpInterface<IDrmServiceListener>(impl) {}
+
+    virtual status_t notify(const DrmInfoEvent& event);
+};
+
+/**
+ * This is the Binder implementation class for DRM service listener.
+ */
+class BnDrmServiceListener: public BnInterface<IDrmServiceListener>
+{
+public:
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
+};
+
+};
+
+#endif /* __IDRM_SERVICE_LISTENER_H__ */
+
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
new file mode 100644
index 0000000..9ad195f
--- /dev/null
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -0,0 +1,273 @@
+/*
+ * 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 __PLUGIN_MANAGER_H__
+#define __PLUGIN_MANAGER_H__
+
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+const char* const PLUGIN_MANAGER_CREATE = "create";
+const char* const PLUGIN_MANAGER_DESTROY = "destroy";
+const char* const PLUGIN_EXTENSION = ".so";
+
+/**
+ * This is the template class for Plugin manager.
+ *
+ * The DrmManager uses this class to handle the plugins.
+ *
+ */
+template<typename Type>
+class TPlugInManager {
+private:
+    typedef void*      HANDLE;
+    typedef Type*      create_t(void);
+    typedef void       destroy_t(Type*);
+    typedef create_t*  FPCREATE;
+    typedef destroy_t* FPDESTORY;
+
+    typedef struct _PlugInContainer {
+        String8   sPath;
+        HANDLE    hHandle;
+        FPCREATE  fpCreate;
+        FPDESTORY fpDestory;
+        Type*     pInstance;
+
+        _PlugInContainer():
+            sPath("")
+            ,hHandle(NULL)
+            ,fpCreate(NULL)
+            ,fpDestory(NULL)
+            ,pInstance(NULL)
+            {}
+    } PlugInContainer;
+
+    typedef KeyedVector<String8, PlugInContainer*> PlugInMap;
+    PlugInMap m_plugInMap;
+
+    typedef Vector<String8> PlugInIdList;
+    PlugInIdList m_plugInIdList;
+
+public:
+    /**
+     * Load all the plug-ins in the specified directory
+     *
+     * @param[in] rsPlugInDirPath
+     *     Directory path which plug-ins (dynamic library) are stored
+     * @note Plug-ins should be implemented according to the specification
+     */
+    void loadPlugIns(const String8& rsPlugInDirPath) {
+        Vector<String8> plugInFileList = getPlugInPathList(rsPlugInDirPath);
+
+        if (!plugInFileList.isEmpty()) {
+            for (unsigned int i = 0; i < plugInFileList.size(); ++i) {
+                loadPlugIn(plugInFileList[i]);
+            }
+        }
+    }
+
+    /**
+     * Unload all the plug-ins
+     *
+     */
+    void unloadPlugIns() {
+        for (unsigned int i = 0; i < m_plugInIdList.size(); ++i) {
+            unloadPlugIn(m_plugInIdList[i]);
+        }
+        m_plugInIdList.clear();
+    }
+
+    /**
+     * Get all the IDs of available plug-ins
+     *
+     * @return[in] plugInIdList
+     *     String type Vector in which all plug-in IDs are stored
+     */
+    Vector<String8> getPlugInIdList() const {
+        return m_plugInIdList;
+    }
+
+    /**
+     * Get a plug-in reference of specified ID
+     *
+     * @param[in] rsPlugInId
+     *     Plug-in ID to be used
+     * @return plugIn
+     *     Reference of specified plug-in instance
+     */
+    Type& getPlugIn(const String8& rsPlugInId) {
+        if (!contains(rsPlugInId)) {
+            // This error case never happens
+        }
+        return *(m_plugInMap.valueFor(rsPlugInId)->pInstance);
+    }
+
+public:
+    /**
+     * Load a plug-in stored in the specified path
+     *
+     * @param[in] rsPlugInPath
+     *     Plug-in (dynamic library) file path
+     * @note Plug-in should be implemented according to the specification
+     */
+    void loadPlugIn(const String8& rsPlugInPath) {
+        if (contains(rsPlugInPath)) {
+            return;
+        }
+
+        PlugInContainer* pPlugInContainer = new PlugInContainer();
+
+        pPlugInContainer->hHandle = dlopen(rsPlugInPath.string(), RTLD_LAZY);
+
+        if (NULL == pPlugInContainer->hHandle) {
+            delete pPlugInContainer;
+            pPlugInContainer = NULL;
+            return;
+        }
+
+        pPlugInContainer->sPath = rsPlugInPath;
+        pPlugInContainer->fpCreate
+                = (FPCREATE)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_CREATE);
+        pPlugInContainer->fpDestory
+                = (FPDESTORY)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_DESTROY);
+
+        if (NULL != pPlugInContainer->fpCreate && NULL != pPlugInContainer->fpDestory) {
+            pPlugInContainer->pInstance = (Type*)pPlugInContainer->fpCreate();
+            m_plugInIdList.add(rsPlugInPath);
+            m_plugInMap.add(rsPlugInPath, pPlugInContainer);
+        } else {
+            dlclose(pPlugInContainer->hHandle);
+            delete pPlugInContainer;
+            pPlugInContainer = NULL;
+            return;
+        }
+    }
+
+    /**
+     * Unload a plug-in stored in the specified path
+     *
+     * @param[in] rsPlugInPath
+     *     Plug-in (dynamic library) file path
+     */
+    void unloadPlugIn(const String8& rsPlugInPath) {
+        if (!contains(rsPlugInPath)) {
+            return;
+        }
+
+        PlugInContainer* pPlugInContainer = m_plugInMap.valueFor(rsPlugInPath);
+        pPlugInContainer->fpDestory(pPlugInContainer->pInstance);
+        dlclose(pPlugInContainer->hHandle);
+
+        m_plugInMap.removeItem(rsPlugInPath);
+        delete pPlugInContainer;
+        pPlugInContainer = NULL;
+    }
+
+private:
+    /**
+     * True if TPlugInManager contains rsPlugInId
+     */
+    bool contains(const String8& rsPlugInId) {
+        return m_plugInMap.indexOfKey(rsPlugInId) != NAME_NOT_FOUND;
+    }
+
+    /**
+     * Return file path list of plug-ins stored in the specified directory
+     *
+     * @param[in] rsDirPath
+     *     Directory path in which plug-ins are stored
+     * @return plugInFileList
+     *     String type Vector in which file path of plug-ins are stored
+     */
+    Vector<String8> getPlugInPathList(const String8& rsDirPath) {
+        Vector<String8> fileList;
+        DIR* pDir = opendir(rsDirPath.string());
+        struct dirent* pEntry = new dirent();
+
+        while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
+            if (!isPlugIn(pEntry)) {
+                continue;
+            }
+            String8 plugInPath;
+            plugInPath += rsDirPath;
+            plugInPath += "/";
+            plugInPath += pEntry->d_name;
+
+            fileList.add(plugInPath);
+        }
+
+        if (NULL != pDir) {
+            closedir(pDir);
+        }
+        delete pEntry;
+        pEntry = NULL;
+
+        return fileList;
+    }
+
+    /**
+     * True if the input name denotes plug-in
+     */
+    bool isPlugIn(const struct dirent* pEntry) const {
+        String8 sName(pEntry->d_name);
+        int extentionPos = sName.size() - String8(PLUGIN_EXTENSION).size();
+        if (extentionPos < 0) {
+            return false;
+        }
+        return extentionPos == (int)sName.find(PLUGIN_EXTENSION);
+    }
+
+    /**
+     * True if the input entry is "." or ".."
+     */
+    bool isDotOrDDot(const struct dirent* pEntry) const {
+        String8 sName(pEntry->d_name);
+        return "." == sName || ".." == sName;
+    }
+
+    /**
+     * True if input entry is directory
+     */
+    bool isDirectory(const struct dirent* pEntry) const {
+        return DT_DIR == pEntry->d_type;
+    }
+
+    /**
+     * True if input entry is regular file
+     */
+    bool isRegularFile(const struct dirent* pEntry) const {
+        return DT_REG == pEntry->d_type;
+    }
+
+    /**
+     * True if input entry is link
+     */
+    bool isLink(const struct dirent* pEntry) const {
+        return DT_LNK == pEntry->d_type;
+    }
+};
+
+};
+
+#endif /* __PLUGIN_MANAGER_H__ */
+
diff --git a/drm/libdrmframework/include/ReadWriteUtils.h b/drm/libdrmframework/include/ReadWriteUtils.h
new file mode 100644
index 0000000..022149e
--- /dev/null
+++ b/drm/libdrmframework/include/ReadWriteUtils.h
@@ -0,0 +1,71 @@
+/*
+ * 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 __READ_WRITE_UTILS_H__
+#define __READ_WRITE_UTILS_H__
+
+#include <utils/FileMap.h>
+#include <drm/drm_framework_common.h>
+
+namespace android {
+
+/**
+ * This is an utility class which performs IO operations.
+ *
+ */
+class ReadWriteUtils {
+public:
+    /**
+     * Constructor for ReadWriteUtils
+     */
+    ReadWriteUtils() {}
+
+    /**
+     * Destructor for ReadWriteUtils
+     */
+    virtual ~ReadWriteUtils();
+
+public:
+    /**
+     * Reads the data from the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @return Data read from the file
+     */
+    static String8 readBytes(const String8& filePath);
+    /**
+     * Writes the data into the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @param[in] dataBuffer Data to write
+     */
+    static void writeToFile(const String8& filePath, const String8& data);
+    /**
+     * Appends the data into the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @param[in] dataBuffer Data to append
+     */
+    static void appendToFile(const String8& filePath, const String8& data);
+
+private:
+    FileMap* mFileMap;
+};
+
+};
+
+#endif /* __READ_WRITE_UTILS_H__ */
+
diff --git a/drm/libdrmframework/include/StringTokenizer.h b/drm/libdrmframework/include/StringTokenizer.h
new file mode 100644
index 0000000..70e7558
--- /dev/null
+++ b/drm/libdrmframework/include/StringTokenizer.h
@@ -0,0 +1,87 @@
+/*
+ * 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 __STRING_TOKENIZER_H__
+#define __STRING_TOKENIZER_H__
+
+#include <drm/drm_framework_common.h>
+
+namespace android {
+
+/**
+ * This is an utility class for String manipulation.
+ *
+ */
+class StringTokenizer {
+public:
+    /**
+     * Iterator for string tokens
+     */
+    class Iterator {
+        friend class StringTokenizer;
+    private:
+        Iterator(StringTokenizer* StringTokenizer)
+         : mStringTokenizer(StringTokenizer), mIndex(0) {}
+
+    public:
+        Iterator(const Iterator& iterator);
+        Iterator& operator=(const Iterator& iterator);
+        virtual ~Iterator() {}
+
+    public:
+        bool hasNext();
+        String8& next();
+
+    private:
+        StringTokenizer* mStringTokenizer;
+        unsigned int mIndex;
+    };
+
+public:
+    /**
+     * Constructor for StringTokenizer
+     *
+     * @param[in] string Complete string data
+     * @param[in] delimeter Delimeter used to split the string
+     */
+    StringTokenizer(const String8& string, const String8& delimeter);
+
+    /**
+     * Destructor for StringTokenizer
+     */
+    ~StringTokenizer() {}
+
+private:
+    /**
+     * Splits the string according to the delimeter
+     */
+    void splitString(const String8& string, const String8& delimeter);
+
+public:
+    /**
+     * Returns Iterator object to walk through the split string values
+     *
+     * @return Iterator object
+     */
+    Iterator iterator();
+
+private:
+    Vector<String8> mStringTokenizerVector;
+};
+
+};
+#endif /* __STRING_TOKENIZER_H__ */
+
diff --git a/drm/libdrmframework/plugins/Android.mk b/drm/libdrmframework/plugins/Android.mk
new file mode 100644
index 0000000..9ee7961
--- /dev/null
+++ b/drm/libdrmframework/plugins/Android.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+include $(call all-subdir-makefiles)
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
new file mode 100644
index 0000000..667958a
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DRM_ENGINE_BASE_H__
+#define __DRM_ENGINE_BASE_H__
+
+#include <drm/drm_framework_common.h>
+#include "IDrmEngine.h"
+
+namespace android {
+
+/**
+ * This class is an interface for plug-in developers
+ *
+ * Responsibility of this class is control the sequence of actual plug-in.
+ * All each plug-in developer has to do is implement onXXX() type virtual interfaces.
+ */
+class DrmEngineBase : public IDrmEngine {
+public:
+    DrmEngineBase();
+    virtual ~DrmEngineBase();
+
+public:
+    DrmConstraints* getConstraints(int uniqueId, const String8* path, int action);
+
+    status_t initialize(int uniqueId);
+
+    status_t setOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener);
+
+    status_t terminate(int uniqueId);
+
+    bool canHandle(int uniqueId, const String8& path);
+
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+
+    String8 getOriginalMimeType(int uniqueId, const String8& path);
+
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int checkRightsStatus(int uniqueId, const String8& path, int action);
+
+    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    void setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    bool validateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    void removeRights(int uniqueId, const String8& path);
+
+    void removeAllRights(int uniqueId);
+
+    void openConvertSession(int uniqueId, int convertId);
+
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    DrmSupportInfo* getSupportInfo(int uniqueId);
+
+    status_t openDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
+
+    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+
+protected:
+    /////////////////////////////////////////////////////
+    // Interface for plug-in developers                //
+    // each plug-in has to implement following method  //
+    /////////////////////////////////////////////////////
+    /**
+     * Get constraint information associated with input content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Actions defined such as,
+     *     Action::DEFAULT, Action::PLAY, etc
+     * @return DrmConstraints
+     *     key-value pairs of constraint are embedded in it
+     * @note
+     *     In case of error, return NULL
+     */
+    virtual DrmConstraints* onGetConstraints(
+            int uniqueId, const String8* path, int action) = 0;
+
+    /**
+     * Initialize plug-in
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t onInitialize(int uniqueId) = 0;
+
+    /**
+     * Register a callback to be invoked when the caller required to
+     * receive necessary information
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] infoListener Listener
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t onSetOnInfoListener(
+            int uniqueId, const IDrmEngine::OnInfoListener* infoListener) = 0;
+
+    /**
+     * Terminate the plug-in
+     * and release resource bound to plug-in
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t onTerminate(int uniqueId) = 0;
+
+    /**
+     * Get whether the given content can be handled by this plugin or not
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path the protected object
+     * @return bool
+     *     Returns true if this plugin can handle , false in case of not able to handle
+     */
+    virtual bool onCanHandle(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Executes given drm information based on its type
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmInfo Information needs to be processed
+     * @return DrmInfoStatus
+     *     instance as a result of processing given input
+     */
+    virtual DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0;
+
+    /**
+     * Save DRM rights to specified rights path
+     * and make association with content path
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmRights DrmRights to be saved
+     * @param[in] rightsPath File path where rights to be saved
+     * @param[in] contentPath File path where content was saved
+     */
+    virtual void onSaveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightspath, const String8& contentPath) = 0;
+
+    /**
+     * Retrieves necessary information for registration, unregistration or rights
+     * acquisition information.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmInfoRequest Request information to retrieve drmInfo
+     * @return DrmInfo
+     *     instance as a result of processing given input
+     */
+    virtual DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) = 0;
+
+    /**
+     * Retrieves the mime type embedded inside the original content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @return String8
+     *     Returns mime-type of the original content, such as "video/mpeg"
+     */
+    virtual String8 onGetOriginalMimeType(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Retrieves the type of the protected object (content, rights, etc..)
+     * using specified path or mimetype. At least one parameter should be non null
+     * to retrieve DRM object type
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the content or null.
+     * @param[in] mimeType Mime type of the content or null.
+     * @return type of the DRM content,
+     *     such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT
+     */
+    virtual int onGetDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) = 0;
+
+    /**
+     * Check whether the given content has valid rights or not
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to perform (Action::DEFAULT, Action::PLAY, etc)
+     * @return the status of the rights for the protected content,
+     *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
+     */
+    virtual int onCheckRightsStatus(int uniqueId, const String8& path, int action) = 0;
+
+    /**
+     * Consumes the rights for a content.
+     * If the reserve parameter is true the rights is reserved until the same
+     * application calls this api again with the reserve parameter set to false.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
+     * @param[in] reserve True if the rights should be reserved.
+     */
+    virtual void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+            int action, bool reserve) = 0;
+
+    /**
+     * Informs the DRM Engine about the playback actions performed on the DRM files.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
+     * @param[in] position Position in the file (in milliseconds) where the start occurs.
+     *     Only valid together with Playback::START.
+     */
+    virtual void onSetPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) = 0;
+
+    /**
+     * Validates whether an action on the DRM content is allowed or not.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to validate (Action::PLAY, Action::TRANSFER, etc)
+     * @param[in] description Detailed description of the action
+     * @return true if the action is allowed.
+     */
+    virtual bool onValidateAction(int uniqueId, const String8& path,
+            int action, const ActionDescription& description) = 0;
+
+    /**
+     * Removes the rights associated with the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     */
+    virtual void onRemoveRights(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Removes all the rights information of each plug-in associated with
+     * DRM framework. Will be used in master reset
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     */
+    virtual void onRemoveAllRights(int uniqueId) = 0;
+
+    /**
+     * This API is for Forward Lock based DRM scheme.
+     * Each time the application tries to download a new DRM file
+     * which needs to be converted, then the application has to
+     * begin with calling this API.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     */
+    virtual void onOpenConvertSession(int uniqueId, int convertId) = 0;
+
+    /**
+     * Accepts and converts the input data which is part of DRM file.
+     * The resultant converted data and the status is returned in the DrmConvertedInfo
+     * object. This method will be called each time there are new block
+     * of data received by the application.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     * @param[in] inputData Input Data which need to be converted
+     * @return Return object contains the status of the data conversion,
+     *     the output converted data and offset. In this case the
+     *     application will ignore the offset information.
+     */
+    virtual DrmConvertedStatus* onConvertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) = 0;
+
+    /**
+     * Informs the Drm Agent when there is no more data which need to be converted
+     * or when an error occurs. Upon successful conversion of the complete data,
+     * the agent will inform that where the header and body signature
+     * should be added. This signature appending is needed to integrity
+     * protect the converted file.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     * @return Return object contains the status of the data conversion,
+     *     the header and body signature data. It also informs
+     *     the application on which offset these signature data
+     *     should be appended.
+     */
+    virtual DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId) = 0;
+
+    /**
+     * Returns the information about the Drm Engine capabilities which includes
+     * supported MimeTypes and file suffixes.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return DrmSupportInfo
+     *     instance which holds the capabilities of a plug-in
+     */
+    virtual DrmSupportInfo* onGetSupportInfo(int uniqueId) = 0;
+
+    /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the current decryption session
+     * @param[in] fd File descriptor of the protected content to be decrypted
+     * @param[in] offset Start position of the content
+     * @param[in] length The length of the protected content
+     * @return
+     *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+     */
+    virtual status_t onOpenDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) = 0;
+
+    /**
+     * Close the decrypt session for the given handle
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     */
+    virtual void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+
+    /**
+     * Initialize decryption for the given unit of the protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptId Handle for the decryption session
+     * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
+     * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     */
+    virtual void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) = 0;
+
+    /**
+     * Decrypt the protected content buffers for the given unit
+     * This method will be called any number of times, based on number of
+     * encrypted streams received from application.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptId Handle for the decryption session
+     * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
+     * @param[in] encBuffer Encrypted data block
+     * @param[out] decBuffer Decrypted data block
+     * @return status_t
+     *     Returns the error code for this API
+     *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
+     *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
+     *     DRM_ERROR_DECRYPT for failure.
+     */
+    virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0;
+
+    /**
+     * Finalize decryption for the given unit of the protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
+     */
+    virtual void onFinalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+
+    /**
+     * Reads the specified number of bytes from an open DRM file.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[out] buffer Reference to the buffer that should receive the read data.
+     * @param[in] numBytes Number of bytes to read.
+     * @param[in] offset Offset with which to update the file position.
+     *
+     * @return Number of bytes read. Returns -1 for Failure.
+     */
+    virtual ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) = 0;
+};
+
+};
+
+#endif /* __DRM_ENGINE_BASE_H__ */
+
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
new file mode 100644
index 0000000..0d52f66
--- /dev/null
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __IDRM_ENGINE_H__
+#define __IDRM_ENGINE_H__
+
+#include <drm/drm_framework_common.h>
+
+namespace android {
+
+class DrmContentIds;
+class DrmConstraints;
+class DrmRights;
+class DrmInfo;
+class DrmInfoStatus;
+class DrmConvertedStatus;
+class DrmInfoRequest;
+class DrmSupportInfo;
+class DrmInfoEvent;
+
+/**
+ * This class is an interface for plug-in user
+ *
+ * Responsibility of this class is provide generic interface to DRM Engine Manager.
+ * Each interface need to be as abstract as possible.
+ */
+class IDrmEngine {
+public:
+    virtual ~IDrmEngine() {
+    }
+
+public:
+    class OnInfoListener {
+
+    public:
+        virtual void onInfo(const DrmInfoEvent& event) = 0;
+
+        virtual ~OnInfoListener() { }
+    };
+
+public:
+
+    //////////////////////////////////
+    // Implementation of IDrmEngine //
+    //////////////////////////////////
+
+    /**
+     * Initialize plug-in
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t initialize(int uniqueId) = 0;
+
+    /**
+     * Register a callback to be invoked when the caller required to
+     * receive necessary information
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] infoListener Listener
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t setOnInfoListener(
+            int uniqueId, const IDrmEngine::OnInfoListener* infoListener) = 0;
+
+    /**
+     * Terminate the plug-in
+     * and release resource bound to plug-in
+     * e.g.) release native resource
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    virtual status_t terminate(int uniqueId) = 0;
+
+    /**
+     * Get constraint information associated with input content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Actions defined such as,
+     *     Action::DEFAULT, Action::PLAY, etc
+     * @return DrmConstraints
+     *     key-value pairs of constraint are embedded in it
+     * @note
+     *     In case of error, return NULL
+     */
+    virtual DrmConstraints* getConstraints(
+            int uniqueId, const String8* path, int action) = 0;
+
+    /**
+     * Get whether the given content can be handled by this plugin or not
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path the protected object
+     * @return bool
+     *     true if this plugin can handle , false in case of not able to handle
+     */
+    virtual bool canHandle(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Executes given drm information based on its type
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmInfo Information needs to be processed
+     * @return DrmInfoStatus
+     *     instance as a result of processing given input
+     */
+    virtual DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo) = 0;
+
+    /**
+     * Retrieves necessary information for registration, unregistration or rights
+     * acquisition information.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmInfoRequest Request information to retrieve drmInfo
+     * @return DrmInfo
+     *     instance as a result of processing given input
+     */
+    virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) = 0;
+
+    /**
+     * Save DRM rights to specified rights path
+     * and make association with content path
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] drmRights DrmRights to be saved
+     * @param[in] rightsPath File path where rights to be saved
+     * @param[in] contentPath File path where content was saved
+     */
+    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) = 0;
+
+    /**
+     * Retrieves the mime type embedded inside the original content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @return String8
+     *     Returns mime-type of the original content, such as "video/mpeg"
+     */
+    virtual String8 getOriginalMimeType(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Retrieves the type of the protected object (content, rights, etc..)
+     * using specified path or mimetype. At least one parameter should be non null
+     * to retrieve DRM object type
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the content or null.
+     * @param[in] mimeType Mime type of the content or null.
+     * @return type of the DRM content,
+     *     such as DrmObjectType::CONTENT, DrmObjectType::RIGHTS_OBJECT
+     */
+    virtual int getDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) = 0;
+
+    /**
+     * Check whether the given content has valid rights or not
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to perform (Action::DEFAULT, Action::PLAY, etc)
+     * @return the status of the rights for the protected content,
+     *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
+     */
+    virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0;
+
+    /**
+     * Consumes the rights for a content.
+     * If the reserve parameter is true the rights is reserved until the same
+     * application calls this api again with the reserve parameter set to false.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
+     * @param[in] reserve True if the rights should be reserved.
+     */
+    virtual void consumeRights(
+            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
+
+    /**
+     * Informs the DRM Engine about the playback actions performed on the DRM files.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
+     * @param[in] position Position in the file (in milliseconds) where the start occurs.
+     *     Only valid together with Playback::START.
+     */
+    virtual void setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+            int playbackStatus, int position) = 0;
+
+    /**
+     * Validates whether an action on the DRM content is allowed or not.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to validate (Action::PLAY, Action::TRANSFER, etc)
+     * @param[in] description Detailed description of the action
+     * @return true if the action is allowed.
+     */
+    virtual bool validateAction(int uniqueId, const String8& path,
+            int action, const ActionDescription& description) = 0;
+
+    /**
+     * Removes the rights associated with the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] path Path of the protected content
+     */
+    virtual void removeRights(int uniqueId, const String8& path) = 0;
+
+    /**
+     * Removes all the rights information of each plug-in associated with
+     * DRM framework. Will be used in master reset
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     */
+    virtual void removeAllRights(int uniqueId) = 0;
+
+    /**
+     * This API is for Forward Lock based DRM scheme.
+     * Each time the application tries to download a new DRM file
+     * which needs to be converted, then the application has to
+     * begin with calling this API.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     */
+    virtual void openConvertSession(int uniqueId, int convertId) = 0;
+
+    /**
+     * Accepts and converts the input data which is part of DRM file.
+     * The resultant converted data and the status is returned in the DrmConvertedInfo
+     * object. This method will be called each time there are new block
+     * of data received by the application.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     * @param[in] inputData Input Data which need to be converted
+     * @return Return object contains the status of the data conversion,
+     *     the output converted data and offset. In this case the
+     *     application will ignore the offset information.
+     */
+    virtual DrmConvertedStatus* convertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) = 0;
+
+    /**
+     * Informs the Drm Agent when there is no more data which need to be converted
+     * or when an error occurs. Upon successful conversion of the complete data,
+     * the agent will inform that where the header and body signature
+     * should be added. This signature appending is needed to integrity
+     * protect the converted file.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] convertId Handle for the convert session
+     * @return Return object contains the status of the data conversion,
+     *     the header and body signature data. It also informs
+     *     the application on which offset these signature data
+     *     should be appended.
+     */
+    virtual DrmConvertedStatus* closeConvertSession( int uniqueId, int convertId) = 0;
+
+    /**
+     * Returns the information about the Drm Engine capabilities which includes
+     * supported MimeTypes and file suffixes.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @return DrmSupportInfo
+     *     instance which holds the capabilities of a plug-in
+     */
+    virtual DrmSupportInfo* getSupportInfo(int uniqueId) = 0;
+
+    /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the current decryption session
+     * @param[in] fd File descriptor of the protected content to be decrypted
+     * @param[in] offset Start position of the content
+     * @param[in] length The length of the protected content
+     * @return
+     *     DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success
+     */
+    virtual status_t openDecryptSession(
+        int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) = 0;
+
+    /**
+     * Close the decrypt session for the given handle
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     */
+    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+
+    /**
+     * Initialize decryption for the given unit of the protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     */
+    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) = 0;
+
+    /**
+     * Decrypt the protected content buffers for the given unit
+     * This method will be called any number of times, based on number of
+     * encrypted streams received from application.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @param[in] encBuffer Encrypted data block
+     * @param[out] decBuffer Decrypted data block
+     * @return status_t
+     *     Returns the error code for this API
+     *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
+     *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
+     *     DRM_ERROR_DECRYPT for failure.
+     */
+    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0;
+
+    /**
+     * Finalize decryption for the given unit of the protected content
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     */
+    virtual void finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
+
+    /**
+     * Reads the specified number of bytes from an open DRM file.
+     *
+     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[out] buffer Reference to the buffer that should receive the read data.
+     * @param[in] numBytes Number of bytes to read.
+     * @param[in] offset Offset with which to update the file position.
+     *
+     * @return Number of bytes read. Returns -1 for Failure.
+     */
+    virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) = 0;
+};
+
+};
+
+#endif /* __IDRM_ENGINE_H__ */
+
diff --git a/drm/libdrmframework/plugins/passthru/Android.mk b/drm/libdrmframework/plugins/passthru/Android.mk
new file mode 100644
index 0000000..7856d37
--- /dev/null
+++ b/drm/libdrmframework/plugins/passthru/Android.mk
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    src/DrmPassthruPlugIn.cpp
+
+LOCAL_MODULE := libdrmpassthruplugin
+
+LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
+
+LOCAL_SHARED_LIBRARIES := \
+    libutils
+
+ifeq ($(TARGET_SIMULATOR),true)
+ LOCAL_LDLIBS += -ldl
+else
+ LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_C_INCLUDES += \
+    $(TOP)/frameworks/base/drm/libdrmframework/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/plugins/passthru/include \
+    $(TOP)/frameworks/base/drm/libdrmframework/plugins/common/include \
+    $(TOP)/frameworks/base/include
+
+# Set the following flag to enable the decryption passthru flow
+#LOCAL_CFLAGS += -DENABLE_PASSTHRU_DECRYPTION
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
new file mode 100644
index 0000000..d2c7852
--- /dev/null
+++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DRM_PASSTHRU_PLUGIN_H__
+#define __DRM_PASSTHRU_PLUGIN_H__
+
+#include <DrmEngineBase.h>
+
+namespace android {
+
+class DrmPassthruPlugIn : public DrmEngineBase {
+
+public:
+    DrmPassthruPlugIn();
+    virtual ~DrmPassthruPlugIn();
+
+protected:
+    DrmConstraints* onGetConstraints(int uniqueId, const String8* path, int action);
+
+    status_t onInitialize(int uniqueId);
+
+    status_t onSetOnInfoListener(int uniqueId, const IDrmEngine::OnInfoListener* infoListener);
+
+    status_t onTerminate(int uniqueId);
+
+    bool onCanHandle(int uniqueId, const String8& path);
+
+    DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    void onSaveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+
+    String8 onGetOriginalMimeType(int uniqueId, const String8& path);
+
+    int onGetDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int onCheckRightsStatus(int uniqueId, const String8& path, int action);
+
+    void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    void onSetPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    bool onValidateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    void onRemoveRights(int uniqueId, const String8& path);
+
+    void onRemoveAllRights(int uniqueId);
+
+    void onOpenConvertSession(int uniqueId, int convertId);
+
+    DrmConvertedStatus* onConvertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* onCloseConvertSession(int uniqueId, int convertId);
+
+    DrmSupportInfo* onGetSupportInfo(int uniqueId);
+
+    status_t onOpenDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
+
+    void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+     void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+     status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+     void onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset);
+
+private:
+    DecryptHandle* openDecryptSessionImpl();
+};
+
+};
+
+#endif /* __DRM_PASSTHRU_PLUGIN_H__ */
+
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
new file mode 100644
index 0000000..2655d0b
--- /dev/null
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "DrmPassthruPlugIn"
+#include <utils/Log.h>
+
+#include <drm/DrmRights.h>
+#include <drm/DrmConstraints.h>
+#include <drm/DrmInfo.h>
+#include <drm/DrmInfoEvent.h>
+#include <drm/DrmInfoStatus.h>
+#include <drm/DrmConvertedStatus.h>
+#include <drm/DrmInfoRequest.h>
+#include <drm/DrmSupportInfo.h>
+#include <DrmPassthruPlugIn.h>
+
+using namespace android;
+
+
+// This extern "C" is mandatory to be managed by TPlugInManager
+extern "C" IDrmEngine* create() {
+    return new DrmPassthruPlugIn();
+}
+
+// This extern "C" is mandatory to be managed by TPlugInManager
+extern "C" void destroy(IDrmEngine* pPlugIn) {
+    delete pPlugIn;
+    pPlugIn = NULL;
+}
+
+DrmPassthruPlugIn::DrmPassthruPlugIn()
+    : DrmEngineBase() {
+
+}
+
+DrmPassthruPlugIn::~DrmPassthruPlugIn() {
+
+}
+
+DrmConstraints* DrmPassthruPlugIn::onGetConstraints(
+        int uniqueId, const String8* path, int action) {
+    LOGD("DrmPassthruPlugIn::onGetConstraints From Path: %d", uniqueId);
+    DrmConstraints* drmConstraints = new DrmConstraints();
+
+    String8 value("dummy_available_time");
+    char* charValue = NULL;
+    charValue = new char[value.length() + 1];
+    strncpy(charValue, value.string(), value.length());
+
+    //Just add dummy available time for verification
+    drmConstraints->put(&(DrmConstraints::LICENSE_AVAILABLE_TIME), charValue);
+
+    return drmConstraints;
+}
+
+DrmInfoStatus* DrmPassthruPlugIn::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+    LOGD("DrmPassthruPlugIn::onProcessDrmInfo - Enter : %d", uniqueId);
+    DrmInfoStatus* drmInfoStatus = NULL;
+    if (NULL != drmInfo) {
+        switch (drmInfo->getInfoType()) {
+        case DrmInfoRequest::TYPE_REGISTRATION_INFO: {
+            const DrmBuffer* emptyBuffer = new DrmBuffer();
+            drmInfoStatus
+                = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType());
+            break;
+        }
+        case DrmInfoRequest::TYPE_UNREGISTRATION_INFO: {
+            const DrmBuffer* emptyBuffer = new DrmBuffer();
+            drmInfoStatus
+                = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, emptyBuffer, drmInfo->getMimeType());
+            break;
+        }
+        case DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO: {
+            String8 licenseString("dummy_license_string");
+            const int bufferSize = licenseString.size();
+            char* data = NULL;
+            data = new char[bufferSize];
+            memcpy(data, licenseString.string(), bufferSize);
+            const DrmBuffer* buffer = new DrmBuffer(data, bufferSize);
+            drmInfoStatus
+                = new DrmInfoStatus(DrmInfoStatus::STATUS_OK, buffer, drmInfo->getMimeType());
+            break;
+        }
+        }
+    }
+    LOGD("DrmPassthruPlugIn::onProcessDrmInfo - Exit");
+    return drmInfoStatus;
+}
+
+status_t DrmPassthruPlugIn::onSetOnInfoListener(
+            int uniqueId, const IDrmEngine::OnInfoListener* infoListener) {
+    LOGD("DrmPassthruPlugIn::onSetOnInfoListener : %d", uniqueId);
+    return DRM_NO_ERROR;
+}
+
+status_t DrmPassthruPlugIn::onInitialize(int uniqueId) {
+    LOGD("DrmPassthruPlugIn::onInitialize : %d", uniqueId);
+    return DRM_NO_ERROR;
+}
+
+status_t DrmPassthruPlugIn::onTerminate(int uniqueId) {
+    LOGD("DrmPassthruPlugIn::onTerminate : %d", uniqueId);
+    return DRM_NO_ERROR;
+}
+
+DrmSupportInfo* DrmPassthruPlugIn::onGetSupportInfo(int uniqueId) {
+    LOGD("DrmPassthruPlugIn::onGetSupportInfo : %d", uniqueId);
+    DrmSupportInfo* drmSupportInfo = new DrmSupportInfo();
+    // Add mimetype's
+    drmSupportInfo->addMimeType(String8("application/vnd.passthru.drm"));
+    // Add File Suffixes
+    drmSupportInfo->addFileSuffix(String8(".passthru"));
+    // Add plug-in description
+    drmSupportInfo->setDescription(String8("Passthru plug-in"));
+    return drmSupportInfo;
+}
+
+void DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath) {
+    LOGD("DrmPassthruPlugIn::onSaveRights : %d", uniqueId);
+}
+
+DrmInfo* DrmPassthruPlugIn::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+    LOGD("DrmPassthruPlugIn::onAcquireDrmInfo : %d", uniqueId);
+    DrmInfo* drmInfo = NULL;
+
+    if (NULL != drmInfoRequest) {
+        String8 dataString("dummy_acquistion_string");
+        int length = dataString.length();
+        char* data = NULL;
+        data = new char[length];
+        memcpy(data, dataString.string(), length);
+        drmInfo = new DrmInfo(drmInfoRequest->getInfoType(),
+            DrmBuffer(data, length), drmInfoRequest->getMimeType());
+    }
+    return drmInfo;
+}
+
+bool DrmPassthruPlugIn::onCanHandle(int uniqueId, const String8& path) {
+    LOGD("DrmPassthruPlugIn::canHandle: %s ", path.string());
+    String8 extension = path.getPathExtension();
+    extension.toLower();
+    return (String8(".passthru") == extension);
+}
+
+String8 DrmPassthruPlugIn::onGetOriginalMimeType(int uniqueId, const String8& path) {
+    LOGD("DrmPassthruPlugIn::onGetOriginalMimeType() : %d", uniqueId);
+    return String8("video/passthru");
+}
+
+int DrmPassthruPlugIn::onGetDrmObjectType(
+            int uniqueId, const String8& path, const String8& mimeType) {
+    LOGD("DrmPassthruPlugIn::onGetDrmObjectType() : %d", uniqueId);
+    return DrmObjectType::UNKNOWN;
+}
+
+int DrmPassthruPlugIn::onCheckRightsStatus(int uniqueId, const String8& path, int action) {
+    LOGD("DrmPassthruPlugIn::onCheckRightsStatus() : %d", uniqueId);
+    int rightsStatus = RightsStatus::RIGHTS_VALID;
+    return rightsStatus;
+}
+
+void DrmPassthruPlugIn::onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+            int action, bool reserve) {
+    LOGD("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
+}
+
+void DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+            int playbackStatus, int position) {
+    LOGD("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
+}
+
+bool DrmPassthruPlugIn::onValidateAction(int uniqueId, const String8& path,
+            int action, const ActionDescription& description) {
+    LOGD("DrmPassthruPlugIn::onValidateAction() : %d", uniqueId);
+    return true;
+}
+
+void DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) {
+    LOGD("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId);
+}
+
+void DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) {
+    LOGD("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId);
+}
+
+void DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) {
+    LOGD("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId);
+}
+
+DrmConvertedStatus* DrmPassthruPlugIn::onConvertData(
+            int uniqueId, int convertId, const DrmBuffer* inputData) {
+    LOGD("DrmPassthruPlugIn::onConvertData() : %d", uniqueId);
+    DrmBuffer* convertedData = NULL;
+
+    if (NULL != inputData && 0 < inputData->length) {
+        int length = inputData->length;
+        char* data = NULL;
+        data = new char[length];
+        convertedData = new DrmBuffer(data, length);
+        memcpy(convertedData->data, inputData->data, length);
+    }
+    return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, convertedData, 0 /*offset*/);
+}
+
+DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int convertId) {
+    LOGD("DrmPassthruPlugIn::onCloseConvertSession() : %d", uniqueId);
+    return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, NULL, 0 /*offset*/);
+}
+
+status_t DrmPassthruPlugIn::onOpenDecryptSession(
+            int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length) {
+    LOGD("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId);
+
+#ifdef ENABLE_PASSTHRU_DECRYPTION
+    decryptHandle->mimeType = String8("video/passthru");
+    decryptHandle->decryptApiType = DecryptApiType::ELEMENTARY_STREAM_BASED;
+    decryptHandle->status = DRM_NO_ERROR;
+    decryptHandle->decryptInfo = NULL;
+    return DRM_NO_ERROR;
+#endif
+
+    return DRM_ERROR_CANNOT_HANDLE;
+}
+
+void DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    LOGD("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
+    if (NULL != decryptHandle) {
+        if (NULL != decryptHandle->decryptInfo) {
+            delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
+        }
+        delete decryptHandle; decryptHandle = NULL;
+    }
+}
+
+void DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    LOGD("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
+}
+
+status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    LOGD("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
+    /**
+     * As a workaround implementation passthru would copy the given
+     * encrypted buffer as it is to decrypted buffer. Note, decBuffer
+     * memory has to be allocated by the caller.
+     */
+    if (NULL != (*decBuffer) && 0 < (*decBuffer)->length) {
+        memcpy((*decBuffer)->data, encBuffer->data, encBuffer->length);
+        (*decBuffer)->length = encBuffer->length;
+    }
+    return DRM_NO_ERROR;
+}
+
+void DrmPassthruPlugIn::onFinalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    LOGD("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
+}
+
+ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off_t offset) {
+    LOGD("DrmPassthruPlugIn::onPread() : %d", uniqueId);
+    return 0;
+}
+
diff --git a/include/drm/DrmConstraints.h b/include/drm/DrmConstraints.h
new file mode 100644
index 0000000..a9ec942
--- /dev/null
+++ b/include/drm/DrmConstraints.h
@@ -0,0 +1,183 @@
+/*
+ * 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_CONSTRAINTS_H__
+#define __DRM_CONSTRAINTS_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class which contains the constraints information.
+ *
+ * As a result of DrmManagerClient::getConstraints(const String8*, const int)
+ * an instance of DrmConstraints would be returned.
+ *
+ */
+class DrmConstraints {
+public:
+    /**
+     * The following variables are replica of android.drm.DrmStore.ConstraintsColumns
+     * Any changes should also be incorporated with Java Layer as well
+     */
+    /**
+     * The max repeat count
+     */
+    static const String8 MAX_REPEAT_COUNT;
+    /**
+     * The remaining repeat count
+     */
+    static const String8 REMAINING_REPEAT_COUNT;
+
+    /**
+     * The time before which the protected file can not be played/viewed
+     */
+    static const String8 LICENSE_START_TIME;
+
+    /**
+     * The time after which the protected file can not be played/viewed
+     */
+    static const String8 LICENSE_EXPIRY_TIME;
+
+    /**
+     * The available time for license
+     */
+    static const String8 LICENSE_AVAILABLE_TIME;
+
+    /**
+     * The data stream for extended metadata
+     */
+    static const String8 EXTENDED_METADATA;
+
+public:
+    /**
+     * Iterator for key
+     */
+    class KeyIterator {
+        friend class DrmConstraints;
+    private:
+        KeyIterator(DrmConstraints* drmConstraints)
+            : mDrmConstraints(drmConstraints), mIndex(0) {}
+
+    public:
+        KeyIterator(const KeyIterator& keyIterator);
+        KeyIterator& operator=(const KeyIterator& keyIterator);
+        virtual ~KeyIterator() {}
+
+    public:
+        bool hasNext();
+        const String8& next();
+
+    private:
+        DrmConstraints* mDrmConstraints;
+        unsigned int mIndex;
+    };
+
+    /**
+     * Iterator for constraints
+     */
+    class Iterator {
+        friend class DrmConstraints;
+    private:
+        Iterator(DrmConstraints* drmConstraints)
+            : mDrmConstraints(drmConstraints), mIndex(0) {}
+
+    public:
+        Iterator(const Iterator& iterator);
+        Iterator& operator=(const Iterator& iterator);
+        virtual ~Iterator() {}
+
+    public:
+        bool hasNext();
+        String8 next();
+
+    private:
+        DrmConstraints* mDrmConstraints;
+        unsigned int mIndex;
+    };
+
+public:
+    DrmConstraints() {}
+    virtual ~DrmConstraints() {
+        DrmConstraints::KeyIterator keyIt = this->keyIterator();
+
+        while (keyIt.hasNext()) {
+            String8 key = keyIt.next();
+                const char* value = this->getAsByteArray(&key);
+                if (NULL != value) {
+                    delete[] value;
+                    value = NULL;
+                }
+        }
+        mConstraintMap.clear();
+    }
+public:
+    /**
+     * Returns the number of constraints contained in this instance
+     *
+     * @return Number of constraints
+     */
+    int getCount(void) const;
+
+    /**
+     * Adds constraint information as <key, value> pair to this instance
+     *
+     * @param[in] key Key to add
+     * @param[in] value Value to add
+     * @return Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t put(const String8* key, const char* value);
+
+    /**
+     * Retrieves the value of given key
+     *
+     * @param key Key whose value to be retrieved
+     * @return The value
+     */
+    String8 get(const String8& key) const;
+
+     /**
+     * Retrieves the value as byte array of given key
+     * @param key Key whose value to be retrieved as byte array
+     * @return The byte array value
+     */
+    const char* getAsByteArray(const String8* key) const;
+
+    /**
+     * Returns KeyIterator object to walk through the keys associated with this instance
+     *
+     * @return KeyIterator object
+     */
+    KeyIterator keyIterator();
+
+    /**
+     * Returns Iterator object to walk through the values associated with this instance
+     *
+     * @return Iterator object
+     */
+    Iterator iterator();
+private:
+    const char* getValue(const String8* key) const;
+private:
+    typedef KeyedVector<String8, const char*> DrmConstraintsMap;
+    DrmConstraintsMap mConstraintMap;
+};
+
+};
+
+#endif /* __DRM_CONSTRAINTS_H__ */
+
diff --git a/include/drm/DrmConvertedStatus.h b/include/drm/DrmConvertedStatus.h
new file mode 100644
index 0000000..679e48d
--- /dev/null
+++ b/include/drm/DrmConvertedStatus.h
@@ -0,0 +1,67 @@
+/*
+ * 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_CONVERTED_STATUS_H__
+#define __DRM_CONVERTED_STATUS_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class which wraps the status of the conversion, the converted
+ * data/checksum data and the offset. Offset is going to be used in the case of close
+ * session where the agent will inform where the header and body signature should be added
+ *
+ * As a result of DrmManagerClient::convertData(int, const DrmBuffer*) and
+ * DrmManagerClient::closeConvertSession(int) an instance of DrmConvertedStatus
+ * would be returned.
+ *
+ */
+class DrmConvertedStatus {
+public:
+    // Should be in sync with DrmConvertedStatus.java
+    static const int STATUS_OK = 1;
+    static const int STATUS_INPUTDATA_ERROR = 2;
+    static const int STATUS_ERROR = 3;
+
+public:
+    /**
+     * Constructor for DrmConvertedStatus
+     *
+     * @param[in] _statusCode Status of the conversion
+     * @param[in] _convertedData Converted data/checksum data
+     * @param[in] _offset Offset value
+     */
+    DrmConvertedStatus(int _statusCode, const DrmBuffer* _convertedData, int _offset);
+
+    /**
+     * Destructor for DrmConvertedStatus
+     */
+    virtual ~DrmConvertedStatus() {
+
+    }
+
+public:
+    int statusCode;
+    const DrmBuffer* convertedData;
+    int offset;
+};
+
+};
+
+#endif /* __DRM_CONVERTED_STATUS_H__ */
+
diff --git a/include/drm/DrmInfo.h b/include/drm/DrmInfo.h
new file mode 100644
index 0000000..7b48541
--- /dev/null
+++ b/include/drm/DrmInfo.h
@@ -0,0 +1,176 @@
+/*
+ * 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_INFO_H__
+#define __DRM_INFO_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class in which necessary information required to transact
+ * between device and online DRM server is described. DRM Framework achieves
+ * server registration, license acquisition and any other server related transaction
+ * by passing an instance of this class to DrmManagerClient::processDrmInfo(const DrmInfo*).
+ *
+ * The Caller can retrieve the DrmInfo instance by using
+ * DrmManagerClient::acquireDrmInfo(const DrmInfoRequest*) by passing DrmInfoRequest instance.
+ *
+ */
+class DrmInfo {
+public:
+    /**
+     * Constructor for DrmInfo
+     *
+     * @param[in] infoType Type of information
+     * @param[in] drmBuffer Trigger data
+     * @param[in] mimeType MIME type
+     */
+    DrmInfo(int infoType, const DrmBuffer& drmBuffer, const String8& mimeType);
+
+    /**
+     * Destructor for DrmInfo
+     */
+    virtual ~DrmInfo() {}
+
+public:
+    /**
+     * Iterator for key
+     */
+    class KeyIterator {
+        friend class DrmInfo;
+
+    private:
+        KeyIterator(const DrmInfo* drmInfo)
+            : mDrmInfo(const_cast <DrmInfo*> (drmInfo)), mIndex(0) {}
+
+    public:
+        KeyIterator(const KeyIterator& keyIterator);
+        KeyIterator& operator=(const KeyIterator& keyIterator);
+        virtual ~KeyIterator() {}
+
+    public:
+        bool hasNext();
+        const String8& next();
+
+    private:
+        DrmInfo* mDrmInfo;
+        unsigned int mIndex;
+    };
+
+    /**
+     * Iterator
+     */
+    class Iterator {
+        friend class DrmInfo;
+
+    private:
+        Iterator(const DrmInfo* drmInfo)
+            : mDrmInfo(const_cast <DrmInfo*> (drmInfo)), mIndex(0) {}
+
+    public:
+        Iterator(const Iterator& iterator);
+        Iterator& operator=(const Iterator& iterator);
+        virtual ~Iterator() {}
+
+    public:
+        bool hasNext();
+        String8& next();
+
+    private:
+        DrmInfo* mDrmInfo;
+        unsigned int mIndex;
+    };
+
+public:
+    /**
+     * Returns information type associated with this instance
+     *
+     * @return Information type
+     */
+    int getInfoType(void) const;
+
+    /**
+     * Returns MIME type associated with this instance
+     *
+     * @return MIME type
+     */
+    String8 getMimeType(void) const;
+
+    /**
+     * Returns the trigger data associated with this instance
+     *
+     * @return Trigger data
+     */
+    const DrmBuffer& getData(void) const;
+
+    /**
+     * Returns the number of attributes contained in this instance
+     *
+     * @return Number of attributes
+     */
+    int getCount(void) const;
+
+    /**
+     * Adds optional information as <key, value> pair to this instance
+     *
+     * @param[in] key Key to add
+     * @param[in] value Value to add
+     * @return Returns the error code
+     */
+    status_t put(const String8& key, const String8& value);
+
+    /**
+     * Retrieves the value of given key
+     *
+     * @param key Key whose value to be retrieved
+     * @return The value
+     */
+    String8 get(const String8& key) const;
+
+    /**
+     * Returns KeyIterator object to walk through the keys associated with this instance
+     *
+     * @return KeyIterator object
+     */
+    KeyIterator keyIterator() const;
+
+    /**
+     * Returns Iterator object to walk through the values associated with this instance
+     *
+     * @return Iterator object
+     */
+    Iterator iterator() const;
+
+    /**
+     * Returns index of the given key
+     *
+     * @return index
+     */
+    int indexOfKey(const String8& key) const;
+
+protected:
+    int mInfoType;
+    DrmBuffer mData;
+    String8 mMimeType;
+    KeyedVector<String8, String8> mAttributes;
+};
+
+};
+
+#endif /* __DRM_INFO_H__ */
+
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
new file mode 100644
index 0000000..5e8817c
--- /dev/null
+++ b/include/drm/DrmInfoEvent.h
@@ -0,0 +1,99 @@
+/*
+ * 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_INFO_EVENT_H__
+#define __DRM_INFO_EVENT_H__
+
+namespace android {
+
+class String8;
+
+/**
+ * This is an entity class which would be passed to caller in
+ * DrmManagerClient::OnInfoListener::onInfo(const DrmInfoEvent&).
+ */
+class DrmInfoEvent {
+public:
+    //! TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT, when registration has been
+    //! already done by another account ID.
+    static const int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 0x0000001;
+    //! TYPE_REMOVE_RIGHTS, when the rights needs to be removed completely.
+    static const int TYPE_REMOVE_RIGHTS = 0x0000002;
+    //! TYPE_RIGHTS_INSTALLED, when the rights are downloaded and installed ok.
+    static const int TYPE_RIGHTS_INSTALLED = 0x0000003;
+    //! TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights
+    static const int TYPE_RIGHTS_NOT_INSTALLED = 0x0000004;
+    //! TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights
+    static const int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 0x0000005;
+    //! TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent
+    static const int TYPE_NOT_SUPPORTED = 0x0000006;
+    //! TYPE_WAIT_FOR_RIGHTS, rights object is on it's way to phone,
+    //! wait before calling checkRights again
+    static const int TYPE_WAIT_FOR_RIGHTS = 0x0000007;
+    //! TYPE_OUT_OF_MEMORY, when memory allocation fail during renewal.
+    //! Can in the future perhaps be used to trigger garbage collector
+    static const int TYPE_OUT_OF_MEMORY = 0x0000008;
+    //! 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 = 0x0000009;
+
+public:
+    /**
+     * Constructor for DrmInfoEvent
+     *
+     * @param[in] uniqueId Unique session identifier
+     * @param[in] infoType Type of information
+     * @param[in] message Message description
+     */
+    DrmInfoEvent(int uniqueId, int infoType, const String8& message);
+
+    /**
+     * Destructor for DrmInfoEvent
+     */
+    virtual ~DrmInfoEvent() {}
+
+public:
+    /**
+     * Returns the Unique Id associated with this instance
+     *
+     * @return Unique Id
+     */
+    int getUniqueId() const;
+
+    /**
+     * Returns the Type of information associated with this object
+     *
+     * @return Type of information
+     */
+    int getType() const;
+
+    /**
+     * Returns the message description associated with this object
+     *
+     * @return Message description
+     */
+    const String8& getMessage() const;
+
+private:
+    int mUniqueId;
+    int mInfoType;
+    const String8& mMessage;
+};
+
+};
+
+#endif /* __DRM_INFO_EVENT_H__ */
+
diff --git a/include/drm/DrmInfoRequest.h b/include/drm/DrmInfoRequest.h
new file mode 100644
index 0000000..3e48ecc
--- /dev/null
+++ b/include/drm/DrmInfoRequest.h
@@ -0,0 +1,177 @@
+/*
+ * 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_INFO_REQUEST_H__
+#define __DRM_INFO_REQUEST_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class used to pass required parameters to get
+ * the necessary information to communicate with online DRM server
+ *
+ * An instance of this class is passed to
+ * DrmManagerClient::acquireDrmInfo(const DrmInfoRequest*) to get the
+ * instance of DrmInfo.
+ *
+ */
+class DrmInfoRequest {
+public:
+    // Changes in following constants should be in sync with DrmInfoRequest.java
+    static const int TYPE_REGISTRATION_INFO = 1;
+    static const int TYPE_UNREGISTRATION_INFO = 2;
+    static const int TYPE_RIGHTS_ACQUISITION_INFO = 3;
+    static const int TYPE_RIGHTS_ACQUISITION_PROGRESS_INFO = 4;
+
+    /**
+     * Key to pass the unique id for the account or the user
+     */
+    static const String8 ACCOUNT_ID;
+    /**
+     * Key to pass the subscription id
+     */
+    static const String8 SUBSCRIPTION_ID;
+
+public:
+    /**
+     * Constructor for DrmInfoRequest
+     *
+     * @param[in] infoType Type of information
+     * @param[in] mimeType MIME type
+     */
+    DrmInfoRequest(int infoType, const String8& mimeType);
+
+    /**
+     * Destructor for DrmInfoRequest
+     */
+    virtual ~DrmInfoRequest() {}
+
+public:
+    /**
+     * Iterator for key
+     */
+    class KeyIterator {
+        friend class DrmInfoRequest;
+
+    private:
+        KeyIterator(const DrmInfoRequest* drmInfoRequest)
+            : mDrmInfoRequest(const_cast <DrmInfoRequest*> (drmInfoRequest)), mIndex(0) {}
+
+    public:
+        KeyIterator(const KeyIterator& keyIterator);
+        KeyIterator& operator=(const KeyIterator& keyIterator);
+        virtual ~KeyIterator() {}
+
+    public:
+        bool hasNext();
+        const String8& next();
+
+    private:
+        DrmInfoRequest* mDrmInfoRequest;
+        unsigned int mIndex;
+    };
+
+    /**
+     * Iterator
+     */
+    class Iterator {
+        friend class DrmInfoRequest;
+
+    private:
+        Iterator(const DrmInfoRequest* drmInfoRequest)
+            : mDrmInfoRequest(const_cast <DrmInfoRequest*> (drmInfoRequest)), mIndex(0) {}
+
+    public:
+        Iterator(const Iterator& iterator);
+        Iterator& operator=(const Iterator& iterator);
+        virtual ~Iterator() {}
+
+    public:
+        bool hasNext();
+        String8& next();
+
+    private:
+        DrmInfoRequest* mDrmInfoRequest;
+        unsigned int mIndex;
+    };
+
+public:
+    /**
+     * Returns information type associated with this instance
+     *
+     * @return Information type
+     */
+    int getInfoType(void) const;
+
+    /**
+     * Returns MIME type associated with this instance
+     *
+     * @return MIME type
+     */
+    String8 getMimeType(void) const;
+
+    /**
+     * Returns the number of entries in DrmRequestInfoMap
+     *
+     * @return Number of entries
+     */
+    int getCount(void) const;
+
+    /**
+     * Adds optional information as <key, value> pair to this instance
+     *
+     * @param[in] key Key to add
+     * @param[in] value Value to add
+     * @return Returns the error code
+     */
+    status_t put(const String8& key, const String8& value);
+
+    /**
+     * Retrieves the value of given key
+     *
+     * @param key Key whose value to be retrieved
+     * @return The value
+     */
+    String8 get(const String8& key) const;
+
+    /**
+     * Returns KeyIterator object to walk through the keys associated with this instance
+     *
+     * @return KeyIterator object
+     */
+    KeyIterator keyIterator() const;
+
+    /**
+     * Returns Iterator object to walk through the values associated with this instance
+     *
+     * @return Iterator object
+     */
+    Iterator iterator() const;
+
+private:
+    int mInfoType;
+    String8 mMimeType;
+
+    typedef KeyedVector<String8, String8> DrmRequestInfoMap;
+    DrmRequestInfoMap mRequestInformationMap;
+};
+
+};
+
+#endif /* __DRM_INFO_REQUEST_H__ */
+
diff --git a/include/drm/DrmInfoStatus.h b/include/drm/DrmInfoStatus.h
new file mode 100644
index 0000000..806aea1
--- /dev/null
+++ b/include/drm/DrmInfoStatus.h
@@ -0,0 +1,65 @@
+/*
+ * 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_INFO_STATUS_H__
+#define __DRM_INFO_STATUS_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class which wraps the result of communication between device
+ * and online DRM server.
+ *
+ * As a result of DrmManagerClient::processDrmInfo(const DrmInfo*) an instance of
+ * DrmInfoStatus would be returned. This class holds DrmBuffer which could be
+ * used to instantiate DrmRights in license acquisition.
+ *
+ */
+class DrmInfoStatus {
+public:
+    // Should be in sync with DrmInfoStatus.java
+    static const int STATUS_OK = 1;
+    static const int STATUS_ERROR = 2;
+
+public:
+    /**
+     * Constructor for DrmInfoStatus
+     *
+     * @param[in] _statusCode Status of the communication
+     * @param[in] _drmBuffer Rights information
+     * @param[in] _mimeType MIME type
+     */
+    DrmInfoStatus(int _statusCode, const DrmBuffer* _drmBuffer, const String8& _mimeType);
+
+    /**
+     * Destructor for DrmInfoStatus
+     */
+    virtual ~DrmInfoStatus() {
+
+    }
+
+public:
+    int statusCode;
+    const DrmBuffer* drmBuffer;
+    String8 mimeType;
+};
+
+};
+
+#endif /* __DRM_INFO_STATUS_H__ */
+
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
new file mode 100644
index 0000000..7d14c44
--- /dev/null
+++ b/include/drm/DrmManagerClient.h
@@ -0,0 +1,351 @@
+/*
+ * 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_MANAGER_CLIENT_H__
+#define __DRM_MANAGER_CLIENT_H__
+
+#include <binder/IInterface.h>
+#include "drm_framework_common.h"
+
+namespace android {
+
+class DrmInfo;
+class DrmRights;
+class DrmInfoEvent;
+class DrmInfoStatus;
+class DrmInfoRequest;
+class DrmSupportInfo;
+class DrmConstraints;
+class DrmConvertedStatus;
+class DrmManagerClientImpl;
+
+/**
+ * The Native application will instantiate this class and access DRM Framework
+ * services through this class.
+ *
+ */
+class DrmManagerClient {
+public:
+    DrmManagerClient();
+
+    virtual ~DrmManagerClient();
+
+public:
+    class OnInfoListener: virtual public RefBase {
+
+    public:
+        virtual void onInfo(const DrmInfoEvent& event) = 0;
+    };
+
+/**
+ * APIs which will be used by native modules (e.g. StageFright)
+ *
+ */
+public:
+    /**
+     * Open the decrypt session to decrypt the given protected content
+     *
+     * @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
+     *     Handle for the decryption session
+     */
+    DecryptHandle* openDecryptSession(int fd, int offset, int length);
+
+    /**
+     * Close the decrypt session for the given handle
+     *
+     * @param[in] decryptHandle Handle for the decryption session
+     */
+    void closeDecryptSession(DecryptHandle* decryptHandle);
+
+    /**
+     * 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] 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.
+     */
+    void consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
+
+    /**
+     * Informs the DRM engine about the playback actions performed on the DRM files.
+     *
+     * @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.
+     */
+    void setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int position);
+
+    /**
+     * Initialize decryption for the given unit of the protected content
+     *
+     * @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
+     */
+    void initializeDecryptUnit(
+            DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
+
+    /**
+     * 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] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @param[in] encBuffer Encrypted data block
+     * @param[out] decBuffer Decrypted data block
+     * @return status_t
+     *     Returns the error code for this API
+     *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
+     *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
+     *     DRM_ERROR_DECRYPT for failure.
+     */
+    status_t decrypt(
+            DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+
+    /**
+     * Finalize decryption for the given unit of the protected content
+     *
+     * @param[in] decryptHandle Handle for the decryption session
+     * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     */
+    void finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
+
+    /**
+     * Reads the specified number of bytes from an open DRM file.
+     *
+     * @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.
+     */
+    ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off_t offset);
+
+    /**
+     * Validates whether an action on the DRM content is allowed or not.
+     *
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to validate. (Action::DEFAULT, Action::PLAY, etc)
+     * @param[in] description Detailed description of the action
+     * @return true if the action is allowed.
+     */
+    bool validateAction(const String8& path, int action, const ActionDescription& description);
+
+/**
+ * APIs which are just the underlying implementation for the Java API
+ *
+ */
+public:
+    /**
+     * Register a callback to be invoked when the caller required to
+     * receive necessary information
+     *
+     * @param[in] infoListener Listener
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t setOnInfoListener(const sp<DrmManagerClient::OnInfoListener>& infoListener);
+
+    /**
+     * Get constraint information associated with input content
+     *
+     * @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
+     */
+    DrmConstraints* getConstraints(const String8* path, const int action);
+
+    /**
+     * Check whether the given mimetype or path can be handled
+     *
+     * @param[in] path Path of the content needs to be handled
+     * @param[in] mimetype Mimetype of the content needs to be handled
+     * @return
+     *     True if DrmManager can handle given path or mime type.
+     */
+    bool canHandle(const String8& path, const String8& mimeType);
+
+    /**
+     * Executes given drm information based on its type
+     *
+     * @param[in] drmInfo Information needs to be processed
+     * @return DrmInfoStatus
+     *     instance as a result of processing given input
+     */
+    DrmInfoStatus* processDrmInfo(const DrmInfo* drmInfo);
+
+    /**
+     * Retrieves necessary information for registration, unregistration or rights
+     * acquisition information.
+     *
+     * @param[in] drmInfoRequest Request information to retrieve drmInfo
+     * @return DrmInfo
+     *     instance as a result of processing given input
+     */
+    DrmInfo* acquireDrmInfo(const DrmInfoRequest* drmInfoRequest);
+
+    /**
+     * Save DRM rights to specified rights path
+     * and make association with content path
+     *
+     * @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
+     */
+    void saveRights(
+        const DrmRights& drmRights, const String8& rightsPath, const String8& contentPath);
+
+    /**
+     * Retrieves the mime type embedded inside the original content
+     *
+     * @param[in] path the path of the protected content
+     * @return String8
+     *     Returns mime-type of the original content, such as "video/mpeg"
+     */
+    String8 getOriginalMimeType(const String8& path);
+
+    /**
+     * Retrieves the type of the protected object (content, rights, etc..)
+     * by using specified path or mimetype. At least one parameter should be non null
+     * to retrieve DRM object type
+     *
+     * @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
+     */
+    int getDrmObjectType(const String8& path, const String8& mimeType);
+
+    /**
+     * Check whether the given content has valid rights or not
+     *
+     * @param[in] path Path of the protected content
+     * @param[in] action Action to perform
+     * @return the status of the rights for the protected content,
+     *     such as RightsStatus::RIGHTS_VALID, RightsStatus::RIGHTS_EXPIRED, etc.
+     */
+    int checkRightsStatus(const String8& path, int action);
+
+    /**
+     * Removes the rights associated with the given protected content
+     *
+     * @param[in] path Path of the protected content
+     */
+    void removeRights(const String8& path);
+
+    /**
+     * Removes all the rights information of each plug-in associated with
+     * DRM framework. Will be used in master reset
+     *
+     */
+    void removeAllRights();
+
+    /**
+     * This API is for Forward Lock DRM.
+     * 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] convertId Handle for the convert session
+     * @param[in] mimeType Description/MIME type of the input data packet
+     * @return Return handle for the convert session
+     */
+    int openConvertSession(const String8& mimeType);
+
+    /**
+     * Passes the input data which need to be converted. 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] 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.
+     */
+    DrmConvertedStatus* convertData(int convertId, const DrmBuffer* inputData);
+
+    /**
+     * When there is no more data which need to be converted or when an
+     * error occurs that time the application has to inform the Drm agent
+     * via this API. 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] 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.
+     */
+    DrmConvertedStatus* closeConvertSession(int convertId);
+
+    /**
+     * Retrieves all DrmSupportInfo instance that native DRM framework can handle.
+     * This interface is meant to be used by JNI layer
+     *
+     * @param[out] length Number of elements in drmSupportInfoArray
+     * @param[out] drmSupportInfoArray Array contains all DrmSupportInfo
+     *     that native DRM framework can handle
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    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;
+    DrmManagerClientImpl* mDrmManagerClientImpl;
+};
+
+};
+
+#endif /* __DRM_MANAGER_CLIENT_H__ */
+
diff --git a/include/drm/DrmRights.h b/include/drm/DrmRights.h
new file mode 100644
index 0000000..e04a066
--- /dev/null
+++ b/include/drm/DrmRights.h
@@ -0,0 +1,105 @@
+/*
+ * 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_RIGHTS_H__
+#define __DRM_RIGHTS_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class which wraps the license information which was
+ * retrieved from the online DRM server.
+ *
+ * Caller can instantiate DrmRights by invoking DrmRights(const DrmBuffer&, String)
+ * constructor by using the result of DrmManagerClient::ProcessDrmInfo(const DrmInfo*) API.
+ * Caller can also instantiate DrmRights using the file path which contains rights information.
+ *
+ */
+class DrmRights {
+public:
+    /**
+     * Constructor for DrmRights
+     *
+     * @param[in] rightsFilePath Path of the file containing rights data
+     * @param[in] mimeType MIME type
+     * @param[in] accountId Account Id of the user
+     * @param[in] subscriptionId Subscription Id of the user
+     */
+    DrmRights(
+            const String8& rightsFilePath, const String8& mimeType,
+            const String8& accountId = String8("_NO_USER"),
+            const String8& subscriptionId = String8(""));
+
+    /**
+     * Constructor for DrmRights
+     *
+     * @param[in] rightsData Rights data
+     * @param[in] mimeType MIME type
+     * @param[in] accountId Account Id of the user
+     * @param[in] subscriptionId Subscription Id of the user
+     */
+    DrmRights(
+            const DrmBuffer& rightsData, const String8& mimeType,
+            const String8& accountId = String8("_NO_USER"),
+            const String8& subscriptionId = String8(""));
+
+    /**
+     * Destructor for DrmRights
+     */
+    virtual ~DrmRights() {}
+
+public:
+    /**
+     * Returns the rights data associated with this instance
+     *
+     * @return Rights data
+     */
+    const DrmBuffer& getData(void) const;
+
+    /**
+     * Returns MIME type associated with this instance
+     *
+     * @return MIME type
+     */
+    String8 getMimeType(void) const;
+
+    /**
+     * Returns the account-id associated with this instance
+     *
+     * @return Account Id
+     */
+    String8 getAccountId(void) const;
+
+    /**
+     * Returns the subscription-id associated with this object
+     *
+     * @return Subscription Id
+     */
+    String8 getSubscriptionId(void) const;
+
+private:
+    DrmBuffer mData;
+    String8 mMimeType;
+    String8 mAccountId;
+    String8 mSubscriptionId;
+};
+
+};
+
+#endif /* __DRM_RIGHTS_H__ */
+
diff --git a/include/drm/DrmSupportInfo.h b/include/drm/DrmSupportInfo.h
new file mode 100644
index 0000000..bf12b0b
--- /dev/null
+++ b/include/drm/DrmSupportInfo.h
@@ -0,0 +1,191 @@
+/*
+ * 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_SUPPORT_INFO_H__
+#define __DRM_SUPPORT_INFO_H__
+
+#include "drm_framework_common.h"
+
+namespace android {
+
+/**
+ * This is an utility class which wraps the capability of each plug-in,
+ * such as mimetype's and file suffixes it could handle.
+ *
+ * Plug-in developer could return the capability of the plugin by passing
+ * DrmSupportInfo instance.
+ *
+ */
+class DrmSupportInfo {
+public:
+    /**
+     * Iterator for mMimeTypeVector
+     */
+    class MimeTypeIterator {
+        friend class DrmSupportInfo;
+    private:
+        MimeTypeIterator(DrmSupportInfo* drmSupportInfo)
+           : mDrmSupportInfo(drmSupportInfo), mIndex(0) {}
+    public:
+        MimeTypeIterator(const MimeTypeIterator& iterator);
+        MimeTypeIterator& operator=(const MimeTypeIterator& iterator);
+        virtual ~MimeTypeIterator() {}
+
+    public:
+        bool hasNext();
+        String8& next();
+
+    private:
+        DrmSupportInfo* mDrmSupportInfo;
+        unsigned int mIndex;
+    };
+
+    /**
+     * Iterator for mFileSuffixVector
+     */
+    class FileSuffixIterator {
+       friend class DrmSupportInfo;
+
+    private:
+        FileSuffixIterator(DrmSupportInfo* drmSupportInfo)
+            : mDrmSupportInfo(drmSupportInfo), mIndex(0) {}
+    public:
+        FileSuffixIterator(const FileSuffixIterator& iterator);
+        FileSuffixIterator& operator=(const FileSuffixIterator& iterator);
+        virtual ~FileSuffixIterator() {}
+
+    public:
+        bool hasNext();
+        String8& next();
+
+    private:
+        DrmSupportInfo* mDrmSupportInfo;
+        unsigned int mIndex;
+    };
+
+public:
+    /**
+     * Constructor for DrmSupportInfo
+     */
+    DrmSupportInfo();
+
+    /**
+     * Copy constructor for DrmSupportInfo
+     */
+    DrmSupportInfo(const DrmSupportInfo& drmSupportInfo);
+
+    /**
+     * Destructor for DrmSupportInfo
+     */
+    virtual ~DrmSupportInfo() {}
+
+    DrmSupportInfo& operator=(const DrmSupportInfo& drmSupportInfo);
+    bool operator<(const DrmSupportInfo& drmSupportInfo) const;
+    bool operator==(const DrmSupportInfo& drmSupportInfo) const;
+
+    /**
+     * Returns FileSuffixIterator object to walk through file suffix values
+     * associated with this instance
+     *
+     * @return FileSuffixIterator object
+     */
+    FileSuffixIterator getFileSuffixIterator();
+
+    /**
+     * Returns MimeTypeIterator object to walk through mimetype values
+     * associated with this instance
+     *
+     * @return MimeTypeIterator object
+     */
+    MimeTypeIterator getMimeTypeIterator();
+
+public:
+    /**
+     * Returns the number of mimetypes supported.
+     *
+     * @return Number of mimetypes supported
+     */
+    int getMimeTypeCount(void) const;
+
+    /**
+     * Returns the number of file types supported.
+     *
+     * @return Number of file types supported
+     */
+    int getFileSuffixCount(void) const;
+
+    /**
+     * Adds the mimetype to the list of supported mimetypes
+     *
+     * @param[in] mimeType mimetype to be added
+     * @return Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t addMimeType(const String8& mimeType);
+
+    /**
+     * Adds the filesuffix to the list of supported file types
+     *
+     * @param[in] filesuffix file suffix to be added
+     * @return Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t addFileSuffix(const String8& fileSuffix);
+
+    /**
+     * Set the unique description about the plugin
+     *
+     * @param[in] description Unique description
+     * @return Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
+     */
+    status_t setDescription(const String8& description);
+
+    /**
+     * Returns the unique description associated with the plugin
+     *
+     * @return Unique description
+     */
+    String8 getDescription() const;
+
+    /**
+     * Returns whether given mimetype is supported or not
+     *
+     * @param[in] mimeType MIME type
+     * @return
+     *        true - if mime-type is supported
+     *        false - if mime-type is not supported
+     */
+    bool isSupportedMimeType(const String8& mimeType) const;
+
+    /**
+     * Returns whether given file type is supported or not
+     *
+     * @param[in] fileType File type
+     * @return
+     *     true if file type is supported
+     *     false if file type is not supported
+     */
+    bool isSupportedFileSuffix(const String8& fileType) const;
+
+private:
+    Vector<String8> mMimeTypeVector;
+    Vector<String8> mFileSuffixVector;
+
+    String8 mDescription;
+};
+
+};
+
+#endif /* __DRM_SUPPORT_INFO_H__ */
+
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
new file mode 100644
index 0000000..8b8a9f5
--- /dev/null
+++ b/include/drm/drm_framework_common.h
@@ -0,0 +1,300 @@
+/*
+ * 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_FRAMEWORK_COMMON_H__
+#define __DRM_FRAMEWORK_COMMON_H__
+
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/Errors.h>
+
+#define INVALID_VALUE -1
+
+namespace android {
+
+/**
+ * Error code for DRM Frameowrk
+ */
+enum {
+    DRM_ERROR_BASE = -2000,
+
+    DRM_ERROR_UNKNOWN                       = DRM_ERROR_BASE,
+    DRM_ERROR_LICENSE_EXPIRED               = DRM_ERROR_BASE - 1,
+    DRM_ERROR_SESSION_NOT_OPENED            = DRM_ERROR_BASE - 2,
+    DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED  = DRM_ERROR_BASE - 3,
+    DRM_ERROR_DECRYPT                       = DRM_ERROR_BASE - 4,
+    DRM_ERROR_CANNOT_HANDLE                 = DRM_ERROR_BASE - 5,
+
+    DRM_NO_ERROR                            = NO_ERROR
+};
+
+/**
+ * Defines DRM Buffer
+ */
+class DrmBuffer {
+public:
+    char* data;
+    int length;
+
+    DrmBuffer() :
+        data(NULL),
+        length(0) {
+    }
+
+    DrmBuffer(char* dataBytes, int dataLength) :
+        data(dataBytes),
+        length(dataLength) {
+    }
+
+};
+
+/**
+ * Defines detailed description of the action
+ */
+class ActionDescription {
+public:
+    ActionDescription(int _outputType, int _configuration) :
+        outputType(_outputType),
+        configuration(_configuration) {
+    }
+
+public:
+    int outputType;   /* BLUETOOTH , HDMI*/
+    int configuration; /* RESOLUTION_720_480 , RECORDABLE etc.*/
+};
+
+/**
+ * Defines constants related to DRM types
+ */
+class DrmObjectType {
+private:
+    DrmObjectType();
+
+public:
+    /**
+     * Field specifies the unknown type
+     */
+    static const int UNKNOWN = 0x00;
+    /**
+     * Field specifies the protected content type
+     */
+    static const int CONTENT = 0x01;
+    /**
+     * Field specifies the rights information
+     */
+    static const int RIGHTS_OBJECT = 0x02;
+    /**
+     * Field specifies the trigger information
+     */
+    static const int TRIGGER_OBJECT = 0x03;
+};
+
+/**
+ * Defines constants related to play back
+ */
+class Playback {
+private:
+    Playback();
+
+public:
+    /**
+     * Constant field signifies playback start
+     */
+    static const int START = 0x00;
+    /**
+     * Constant field signifies playback stop
+     */
+    static const int STOP = 0x01;
+    /**
+     * Constant field signifies playback paused
+     */
+    static const int PAUSE = 0x02;
+    /**
+     * Constant field signifies playback resumed
+     */
+    static const int RESUME = 0x03;
+};
+
+/**
+ * Defines actions that can be performed on protected content
+ */
+class Action {
+private:
+    Action();
+
+public:
+    /**
+     * Constant field signifies that the default action
+     */
+    static const int DEFAULT = 0x00;
+    /**
+     * Constant field signifies that the content can be played
+     */
+    static const int PLAY = 0x01;
+    /**
+     * Constant field signifies that the content can be set as ring tone
+     */
+    static const int RINGTONE = 0x02;
+    /**
+     * Constant field signifies that the content can be transfered
+     */
+    static const int TRANSFER = 0x03;
+    /**
+     * Constant field signifies that the content can be set as output
+     */
+    static const int OUTPUT = 0x04;
+    /**
+     * Constant field signifies that preview is allowed
+     */
+    static const int PREVIEW = 0x05;
+    /**
+     * Constant field signifies that the content can be executed
+     */
+    static const int EXECUTE = 0x06;
+    /**
+     * Constant field signifies that the content can displayed
+     */
+    static const int DISPLAY = 0x07;
+};
+
+/**
+ * Defines constants related to status of the rights
+ */
+class RightsStatus {
+private:
+    RightsStatus();
+
+public:
+    /**
+     * Constant field signifies that the rights are valid
+     */
+    static const int RIGHTS_VALID = 0x00;
+    /**
+     * Constant field signifies that the rights are invalid
+     */
+    static const int RIGHTS_INVALID = 0x01;
+    /**
+     * Constant field signifies that the rights are expired for the content
+     */
+    static const int RIGHTS_EXPIRED = 0x02;
+    /**
+     * Constant field signifies that the rights are not acquired for the content
+     */
+    static const int RIGHTS_NOT_ACQUIRED = 0x03;
+};
+
+/**
+ * Defines API set for decryption
+ */
+class DecryptApiType {
+private:
+    DecryptApiType();
+
+public:
+    /**
+     * Decrypt API set for non encrypted content
+     */
+    static const int NON_ENCRYPTED = 0x00;
+    /**
+     * Decrypt API set for ES based DRM
+     */
+    static const int ELEMENTARY_STREAM_BASED = 0x01;
+    /**
+     * POSIX based Decrypt API set for container based DRM
+     */
+    static const int CONTAINER_BASED = 0x02;
+};
+
+/**
+ * Defines decryption information
+ */
+class DecryptInfo {
+public:
+    /**
+     * size of memory to be allocated to get the decrypted content.
+     */
+    int decryptBufferLength;
+    /**
+     * reserved for future purpose
+     */
+};
+
+/**
+ * Defines decryption handle
+ */
+class DecryptHandle {
+public:
+    /**
+     * Decryption session Handle
+     */
+    int decryptId;
+    /**
+     * Mimetype of the content to be used to select the media extractor
+     * For e.g., "video/mpeg" or "audio/mp3"
+     */
+    String8 mimeType;
+    /**
+     * Defines which decryption pattern should be used to decrypt the given content
+     * DrmFramework provides two different set of decryption APIs.
+     *   1. Decrypt APIs for elementary stream based DRM
+     *      (file format is not encrypted but ES is encrypted)
+     *         e.g., Marlin DRM (MP4 file format), WM-DRM (asf file format)
+     *
+     *         DecryptAPI::TYPE_ELEMENTARY_STREAM_BASED
+     *             Decryption API set for ES based DRM
+     *                 initializeDecryptUnit(), decrypt(), and finalizeDecryptUnit()
+     *   2. Decrypt APIs for container based DRM (file format itself is encrypted)
+     *         e.g., OMA DRM (dcf file format)
+     *
+     *         DecryptAPI::TYPE_CONTAINER_BASED
+     *             POSIX based Decryption API set for container based DRM
+     *                 pread()
+     */
+    int decryptApiType;
+    /**
+     * Defines the status of the rights like
+     *     RIGHTS_VALID, RIGHTS_INVALID, RIGHTS_EXPIRED or RIGHTS_NOT_ACQUIRED
+     */
+    int status;
+    /**
+     * Information required to decrypt content
+     * e.g. size of memory to be allocated to get the decrypted content.
+     */
+    DecryptInfo* decryptInfo;
+
+public:
+    DecryptHandle():
+            decryptId(INVALID_VALUE),
+            mimeType(""),
+            decryptApiType(INVALID_VALUE),
+            status(INVALID_VALUE) {
+
+    }
+
+    bool operator<(const DecryptHandle& handle) const {
+        return (decryptId < handle.decryptId);
+    }
+
+    bool operator==(const DecryptHandle& handle) const {
+        return (decryptId == handle.decryptId);
+    }
+};
+
+};
+
+#endif /* __DRM_FRAMEWORK_COMMON_H__ */
+
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 6f581d3..c5112a5 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -81,13 +81,13 @@
 }
 
 static bool fileMatchesExtension(const char* path, const char* extensions) {
-    char* extension = strrchr(path, '.');
+    const char* extension = strrchr(path, '.');
     if (!extension) return false;
     ++extension;    // skip the dot
     if (extension[0] == 0) return false;
 
     while (extensions[0]) {
-        char* comma = strchr(extensions, ',');
+        const char* comma = strchr(extensions, ',');
         size_t length = (comma ? comma - extensions : strlen(extensions));
         if (length == strlen(extension) && strncasecmp(extension, extensions, length) == 0) return true;
         extensions += length;
