Merge "Telephony: Remove unused mRuimFileHandler reference from CDMAPhone"
diff --git a/api/current.xml b/api/current.xml
index c1ae0f3b..19bef42 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -55630,6 +55630,161 @@
 >
 </field>
 </class>
+<class name="DrmErrorEvent"
+ extends="android.drm.DrmEvent"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="DrmErrorEvent"
+ type="android.drm.DrmErrorEvent"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uniqueId" type="int">
+</parameter>
+<parameter name="type" type="int">
+</parameter>
+<parameter name="message" type="java.lang.String">
+</parameter>
+</constructor>
+<field name="TYPE_DRM_INFO_ACQUISITION_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2012"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_FINALIZE_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2010"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_INITIALIZE_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2009"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_NOT_SUPPORTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2003"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_NO_INTERNET_CONNECTION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2005"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_OUT_OF_MEMORY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2004"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_REGISTRATION_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2006"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_REMOVE_ALL_RIGHTS_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2011"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_RIGHTS_ACQUISITION_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2008"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_RIGHTS_NOT_INSTALLED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2001"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_RIGHTS_RENEWAL_NOT_ALLOWED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2002"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_UNREGISTRATION_FAILED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2007"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="DrmEvent"
  extends="java.lang.Object"
  abstract="false"
@@ -55685,6 +55840,105 @@
  visibility="public"
 >
 </method>
+<field name="DRM_INFO_OBJECT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;drm_info_object&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DRM_INFO_STATUS_OBJECT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;drm_info_status_object&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_ALL_RIGHTS_REMOVED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1006"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_DRM_INFO_ACQUIRED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1007"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_FINALIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1001"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_INITIALIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1003"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_REGISTERED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1002"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_RIGHTS_ACQUIRED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1005"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_UNREGISTERED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1004"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="DrmInfo"
  extends="java.lang.Object"
@@ -55828,6 +56082,17 @@
 <parameter name="message" type="java.lang.String">
 </parameter>
 </constructor>
+<field name="TYPE_ACCOUNT_ALREADY_REGISTERED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT"
  type="int"
  transient="false"
@@ -55839,39 +56104,6 @@
  visibility="public"
 >
 </field>
-<field name="TYPE_NOT_SUPPORTED"
- type="int"
- transient="false"
- volatile="false"
- value="6"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="TYPE_NO_INTERNET_CONNECTION"
- type="int"
- transient="false"
- volatile="false"
- value="9"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="TYPE_OUT_OF_MEMORY"
- type="int"
- transient="false"
- volatile="false"
- value="8"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="TYPE_REMOVE_RIGHTS"
  type="int"
  transient="false"
@@ -55894,33 +56126,11 @@
  visibility="public"
 >
 </field>
-<field name="TYPE_RIGHTS_NOT_INSTALLED"
- type="int"
- transient="false"
- volatile="false"
- value="4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="TYPE_RIGHTS_RENEWAL_NOT_ALLOWED"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="TYPE_WAIT_FOR_RIGHTS"
  type="int"
  transient="false"
  volatile="false"
- value="7"
+ value="4"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -56181,7 +56391,7 @@
 </parameter>
 </constructor>
 <method name="acquireDrmInfo"
- return="android.drm.DrmInfo"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56208,6 +56418,21 @@
 <parameter name="mimeType" type="java.lang.String">
 </parameter>
 </method>
+<method name="canHandle"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+</method>
 <method name="checkRightsStatus"
  return="int"
  abstract="false"
@@ -56231,11 +56456,39 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+</method>
+<method name="checkRightsStatus"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
 <parameter name="path" type="java.lang.String">
 </parameter>
 <parameter name="action" type="int">
 </parameter>
 </method>
+<method name="checkRightsStatus"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="action" type="int">
+</parameter>
+</method>
 <method name="closeConvertSession"
  return="android.drm.DrmConvertedStatus"
  abstract="false"
@@ -56290,6 +56543,21 @@
 <parameter name="action" type="int">
 </parameter>
 </method>
+<method name="getConstraints"
+ return="android.content.ContentValues"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="action" type="int">
+</parameter>
+</method>
 <method name="getDrmObjectType"
  return="int"
  abstract="false"
@@ -56305,6 +56573,21 @@
 <parameter name="mimeType" type="java.lang.String">
 </parameter>
 </method>
+<method name="getDrmObjectType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+</method>
 <method name="getOriginalMimeType"
  return="java.lang.String"
  abstract="false"
@@ -56318,8 +56601,21 @@
 <parameter name="path" type="java.lang.String">
 </parameter>
 </method>
+<method name="getOriginalMimeType"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+</method>
 <method name="loadPlugIns"
- return="void"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56343,7 +56639,7 @@
 </parameter>
 </method>
 <method name="processDrmInfo"
- return="android.drm.DrmInfoStatus"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56356,7 +56652,7 @@
 </parameter>
 </method>
 <method name="removeAllRights"
- return="void"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56367,7 +56663,7 @@
 >
 </method>
 <method name="removeRights"
- return="void"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56379,8 +56675,21 @@
 <parameter name="path" type="java.lang.String">
 </parameter>
 </method>
+<method name="removeRights"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+</method>
 <method name="saveRights"
- return="void"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56398,11 +56707,37 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
+<method name="setOnErrorListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="errorListener" type="android.drm.DrmManagerClient.OnErrorListener">
+</parameter>
+</method>
+<method name="setOnEventListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventListener" type="android.drm.DrmManagerClient.OnEventListener">
+</parameter>
+</method>
 <method name="setOnInfoListener"
  return="void"
  abstract="false"
  native="false"
- synchronized="false"
+ synchronized="true"
  static="false"
  final="false"
  deprecated="not deprecated"
@@ -56412,7 +56747,7 @@
 </parameter>
 </method>
 <method name="unloadPlugIns"
- return="void"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -56422,7 +56757,77 @@
  visibility="public"
 >
 </method>
+<field name="ERROR_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-2000"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
+<interface name="DrmManagerClient.OnErrorListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onError"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="client" type="android.drm.DrmManagerClient">
+</parameter>
+<parameter name="event" type="android.drm.DrmErrorEvent">
+</parameter>
+</method>
+</interface>
+<interface name="DrmManagerClient.OnEventListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onEvent"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="client" type="android.drm.DrmManagerClient">
+</parameter>
+<parameter name="event" type="android.drm.DrmEvent">
+</parameter>
+<parameter name="attributes" type="java.util.HashMap&lt;java.lang.String, java.lang.Object&gt;">
+</parameter>
+</method>
+</interface>
 <interface name="DrmManagerClient.OnInfoListener"
  abstract="true"
  static="true"
@@ -113596,6 +114001,17 @@
  visibility="public"
 >
 </constructor>
+<field name="BATTERY_HEALTH_COLD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="BATTERY_HEALTH_DEAD"
  type="int"
  transient="false"
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 22c30a5..c1fa5b4 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -24,9 +24,7 @@
 import android.provider.Settings;
 import android.util.Log;
 
-import java.net.InetAddress;
 import java.net.URI;
-import java.net.UnknownHostException;
 
 import junit.framework.Assert;
 
@@ -162,15 +160,15 @@
             final URI uri = URI.create(url);
             final String host = uri.getHost();
             if (host != null) {
-                if (host.equalsIgnoreCase("localhost")) {
-                    return true;
-                }
-                if (InetAddress.getByName(host).isLoopbackAddress()) {
+                // TODO: InetAddress.isLoopbackAddress should be used to check
+                // for localhost. However no public factory methods exist which
+                // can be used without triggering DNS lookup if host is not localhost.
+                if (host.equalsIgnoreCase("localhost") ||
+                        host.equals("127.0.0.1") ||
+                        host.equals("[::1]")) {
                     return true;
                 }
             }
-        } catch (UnknownHostException uex) {
-            // Ignore (INetworkSystem.ipStringToByteArray)
         } catch (IllegalArgumentException iex) {
             // Ignore (URI.create)
         }
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 44b73c5..bd57b33 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -99,6 +99,7 @@
     public static final int BATTERY_HEALTH_DEAD = 4;
     public static final int BATTERY_HEALTH_OVER_VOLTAGE = 5;
     public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
+    public static final int BATTERY_HEALTH_COLD = 7;
 
     // values of the "plugged" field in the ACTION_BATTERY_CHANGED intent.
     // These must be powers of 2.
diff --git a/drm/common/DrmConstraints.cpp b/drm/common/DrmConstraints.cpp
index 11ce410..4a4d798 100644
--- a/drm/common/DrmConstraints.cpp
+++ b/drm/common/DrmConstraints.cpp
@@ -75,12 +75,10 @@
 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;
@@ -94,12 +92,10 @@
 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;
diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp
index 70398e8..17cdf544 100644
--- a/drm/common/DrmEngineBase.cpp
+++ b/drm/common/DrmEngineBase.cpp
@@ -52,7 +52,7 @@
     return onProcessDrmInfo(uniqueId, drmInfo);
 }
 
-void DrmEngineBase::saveRights(
+status_t DrmEngineBase::saveRights(
             int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     return onSaveRights(uniqueId, drmRights, rightsPath, contentPath);
@@ -74,14 +74,14 @@
     return onCheckRightsStatus(uniqueId, path, action);
 }
 
-void DrmEngineBase::consumeRights(
+status_t DrmEngineBase::consumeRights(
     int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
-    onConsumeRights(uniqueId, decryptHandle, action, reserve);
+    return onConsumeRights(uniqueId, decryptHandle, action, reserve);
 }
 
-void DrmEngineBase::setPlaybackStatus(
+status_t DrmEngineBase::setPlaybackStatus(
     int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
-    onSetPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+    return onSetPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
 }
 
 bool DrmEngineBase::validateAction(
@@ -90,16 +90,16 @@
     return onValidateAction(uniqueId, path, action, description);
 }
 
-void DrmEngineBase::removeRights(int uniqueId, const String8& path) {
-    onRemoveRights(uniqueId, path);
+status_t DrmEngineBase::removeRights(int uniqueId, const String8& path) {
+    return onRemoveRights(uniqueId, path);
 }
 
-void DrmEngineBase::removeAllRights(int uniqueId) {
-    onRemoveAllRights(uniqueId);
+status_t DrmEngineBase::removeAllRights(int uniqueId) {
+    return onRemoveAllRights(uniqueId);
 }
 
-void DrmEngineBase::openConvertSession(int uniqueId, int convertId) {
-    onOpenConvertSession(uniqueId, convertId);
+status_t DrmEngineBase::openConvertSession(int uniqueId, int convertId) {
+    return onOpenConvertSession(uniqueId, convertId);
 }
 
 DrmConvertedStatus* DrmEngineBase::convertData(
@@ -120,24 +120,24 @@
     return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length);
 }
 
-void DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
-    onCloseDecryptSession(uniqueId, decryptHandle);
+status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    return onCloseDecryptSession(uniqueId, decryptHandle);
 }
 
-void DrmEngineBase::initializeDecryptUnit(
+status_t DrmEngineBase::initializeDecryptUnit(
     int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
-    onInitializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
+    return 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);
+    const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+    return onDecrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
-void DrmEngineBase::finalizeDecryptUnit(
+status_t DrmEngineBase::finalizeDecryptUnit(
     int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
-    onFinalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    return onFinalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmEngineBase::pread(
diff --git a/drm/common/DrmInfoEvent.cpp b/drm/common/DrmInfoEvent.cpp
index eb58129..8d115a8 100644
--- a/drm/common/DrmInfoEvent.cpp
+++ b/drm/common/DrmInfoEvent.cpp
@@ -14,10 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
-#define LOG_TAG "DrmInfoEvent"
-#include "utils/Log.h"
-
 #include <utils/String8.h>
 #include <drm/DrmInfoEvent.h>
 
diff --git a/drm/common/DrmRights.cpp b/drm/common/DrmRights.cpp
index dc1e6c5..3aecb3d 100644
--- a/drm/common/DrmRights.cpp
+++ b/drm/common/DrmRights.cpp
@@ -15,14 +15,21 @@
  */
 
 #include <drm/DrmRights.h>
+#include <ReadWriteUtils.h>
 
 using namespace android;
 
 DrmRights::DrmRights(const String8& rightsFilePath, const String8& mimeType,
-            const String8& accountId, const String8& subscriptionId) {
-    /**
-     * TODO Read DrmRights from rights file
-     */
+            const String8& accountId, const String8& subscriptionId) :
+    mMimeType(mimeType),
+    mAccountId(accountId),
+    mSubscriptionId(subscriptionId),
+    mRightsFromFile(NULL) {
+    int rightsLength = 0;
+    if (String8("") != rightsFilePath) {
+        rightsLength = ReadWriteUtils::readBytes(rightsFilePath, &mRightsFromFile);
+    }
+    mData = DrmBuffer(mRightsFromFile, rightsLength);
 }
 
 DrmRights::DrmRights(const DrmBuffer& rightsData, const String8& mimeType,
@@ -30,7 +37,12 @@
     mData(rightsData),
     mMimeType(mimeType),
     mAccountId(accountId),
-    mSubscriptionId(subscriptionId) {
+    mSubscriptionId(subscriptionId),
+    mRightsFromFile(NULL) {
+}
+
+DrmRights::~DrmRights() {
+    delete[] mRightsFromFile; mRightsFromFile = NULL;
 }
 
 const DrmBuffer& DrmRights::getData(void) const {
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index 35e83fc..ffc8953 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -42,7 +42,7 @@
 }
 
 bool DrmSupportInfo::isSupportedMimeType(const String8& mimeType) const {
-    for (int i = 0; i < mMimeTypeVector.size(); i++) {
+    for (unsigned int i = 0; i < mMimeTypeVector.size(); i++) {
         const String8 item = mMimeTypeVector.itemAt(i);
 
         if (String8("") != mimeType && item.find(mimeType) != -1) {
@@ -53,7 +53,7 @@
 }
 
 bool DrmSupportInfo::isSupportedFileSuffix(const String8& fileType) const {
-    for (int i = 0; i < mFileSuffixVector.size(); i++) {
+    for (unsigned int i = 0; i < mFileSuffixVector.size(); i++) {
         const String8 item = mFileSuffixVector.itemAt(i);
 
         if (String8("") != fileType && item.find(fileType) != -1) {
diff --git a/drm/common/IDrmIOService.cpp b/drm/common/IDrmIOService.cpp
index 7ce45e7..e44ca55 100644
--- a/drm/common/IDrmIOService.cpp
+++ b/drm/common/IDrmIOService.cpp
@@ -14,10 +14,6 @@
  * 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>
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 4fc828a..c28527c 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "IDrmManagerService(Native)"
 #include <utils/Log.h>
 
@@ -36,6 +36,23 @@
 
 using namespace android;
 
+int BpDrmManagerService::addUniqueId(int uniqueId) {
+    LOGV("add uniqueid");
+    Parcel data, reply;
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    remote()->transact(ADD_UNIQUEID, data, &reply);
+    return reply.readInt32();
+}
+
+void BpDrmManagerService::removeUniqueId(int uniqueId) {
+    LOGV("remove uniqueid");
+    Parcel data, reply;
+    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
+    data.writeInt32(uniqueId);
+    remote()->transact(REMOVE_UNIQUEID, data, &reply);
+}
+
 status_t BpDrmManagerService::loadPlugIns(int uniqueId) {
     LOGV("load plugins");
     Parcel data, reply;
@@ -237,7 +254,7 @@
     return drmInfo;
 }
 
-void BpDrmManagerService::saveRights(
+status_t BpDrmManagerService::saveRights(
             int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     LOGV("Save Rights");
@@ -264,6 +281,7 @@
     data.writeString8((contentPath == String8("")) ? String8("NULL") : contentPath);
 
     remote()->transact(SAVE_RIGHTS, data, &reply);
+    return reply.readInt32();
 }
 
 String8 BpDrmManagerService::getOriginalMimeType(int uniqueId, const String8& path) {
@@ -307,10 +325,10 @@
     return reply.readInt32();
 }
 
-void BpDrmManagerService::consumeRights(
+status_t BpDrmManagerService::consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
     LOGV("consumeRights");
-        Parcel data, reply;
+    Parcel data, reply;
 
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
     data.writeInt32(uniqueId);
@@ -330,9 +348,10 @@
     data.writeInt32(static_cast< int>(reserve));
 
     remote()->transact(CONSUME_RIGHTS, data, &reply);
+    return reply.readInt32();
 }
 
-void BpDrmManagerService::setPlaybackStatus(
+status_t BpDrmManagerService::setPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
     LOGV("setPlaybackStatus");
     Parcel data, reply;
@@ -355,6 +374,7 @@
     data.writeInt32(position);
 
     remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
+    return reply.readInt32();
 }
 
 bool BpDrmManagerService::validateAction(
@@ -375,7 +395,7 @@
     return static_cast<bool>(reply.readInt32());
 }
 
-void BpDrmManagerService::removeRights(int uniqueId, const String8& path) {
+status_t BpDrmManagerService::removeRights(int uniqueId, const String8& path) {
     LOGV("removeRights");
     Parcel data, reply;
 
@@ -384,9 +404,10 @@
     data.writeString8(path);
 
     remote()->transact(REMOVE_RIGHTS, data, &reply);
+    return reply.readInt32();
 }
 
-void BpDrmManagerService::removeAllRights(int uniqueId) {
+status_t BpDrmManagerService::removeAllRights(int uniqueId) {
     LOGV("removeAllRights");
     Parcel data, reply;
 
@@ -394,6 +415,7 @@
     data.writeInt32(uniqueId);
 
     remote()->transact(REMOVE_ALL_RIGHTS, data, &reply);
+    return reply.readInt32();
 }
 
 int BpDrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
@@ -517,15 +539,12 @@
     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;
@@ -546,7 +565,7 @@
     return handle;
 }
 
-void BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t BpDrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGV("closeDecryptSession");
     Parcel data, reply;
 
@@ -571,9 +590,10 @@
         delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
     }
     delete decryptHandle; decryptHandle = NULL;
+    return reply.readInt32();
 }
 
-void BpDrmManagerService::initializeDecryptUnit(
+status_t BpDrmManagerService::initializeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     LOGV("initializeDecryptUnit");
@@ -598,11 +618,12 @@
     data.write(headerInfo->data, headerInfo->length);
 
     remote()->transact(INITIALIZE_DECRYPT_UNIT, data, &reply);
+    return reply.readInt32();
 }
 
 status_t BpDrmManagerService::decrypt(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
-            const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     LOGV("decrypt");
     Parcel data, reply;
 
@@ -626,6 +647,11 @@
     data.writeInt32(encBuffer->length);
     data.write(encBuffer->data, encBuffer->length);
 
+    if (NULL != IV) {
+        data.writeInt32(IV->length);
+        data.write(IV->data, IV->length);
+    }
+
     remote()->transact(DECRYPT, data, &reply);
 
     const status_t status = reply.readInt32();
@@ -638,7 +664,7 @@
     return status;
 }
 
-void BpDrmManagerService::finalizeDecryptUnit(
+status_t BpDrmManagerService::finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
     LOGV("finalizeDecryptUnit");
     Parcel data, reply;
@@ -660,6 +686,7 @@
     data.writeInt32(decryptUnitId);
 
     remote()->transact(FINALIZE_DECRYPT_UNIT, data, &reply);
+    return reply.readInt32();
 }
 
 ssize_t BpDrmManagerService::pread(
@@ -702,6 +729,23 @@
     LOGV("Entering BnDrmManagerService::onTransact with code %d", code);
 
     switch (code) {
+    case ADD_UNIQUEID:
+    {
+        LOGV("BnDrmManagerService::onTransact :ADD_UNIQUEID");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+        int uniqueId = addUniqueId(data.readInt32());
+        reply->writeInt32(uniqueId);
+        return DRM_NO_ERROR;
+    }
+
+    case REMOVE_UNIQUEID:
+    {
+        LOGV("BnDrmManagerService::onTransact :REMOVE_UNIQUEID");
+        CHECK_INTERFACE(IDrmManagerService, data, reply);
+        removeUniqueId(data.readInt32());
+        return DRM_NO_ERROR;
+    }
+
     case LOAD_PLUGINS:
     {
         LOGV("BnDrmManagerService::onTransact :LOAD_PLUGINS");
@@ -711,7 +755,6 @@
 
         reply->writeInt32(status);
         return DRM_NO_ERROR;
-
     }
 
     case LOAD_PLUGINS_FROM_PATH:
@@ -745,7 +788,8 @@
         LOGV("BnDrmManagerService::onTransact :UNLOAD_PLUGINS");
         CHECK_INTERFACE(IDrmManagerService, data, reply);
 
-        status_t status = unloadPlugIns(data.readInt32());
+        const int uniqueId = data.readInt32();
+        status_t status = unloadPlugIns(uniqueId);
 
         reply->writeInt32(status);
         return DRM_NO_ERROR;
@@ -923,10 +967,11 @@
                             ((accountId == String8("NULL")) ? String8("") : accountId),
                             ((subscriptionId == String8("NULL")) ? String8("") : subscriptionId));
 
-        saveRights(uniqueId, drmRights,
+        const status_t status = saveRights(uniqueId, drmRights,
                             ((rightsPath == String8("NULL")) ? String8("") : rightsPath),
                             ((contentPath == String8("NULL")) ? String8("") : contentPath));
 
+        reply->writeInt32(status);
         return DRM_NO_ERROR;
     }
 
@@ -985,7 +1030,10 @@
             handle.decryptInfo->decryptBufferLength = bufferLength;
         }
 
-        consumeRights(uniqueId, &handle, data.readInt32(), static_cast<bool>(data.readInt32()));
+        const status_t status
+            = consumeRights(uniqueId, &handle, data.readInt32(),
+                static_cast<bool>(data.readInt32()));
+        reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
         return DRM_NO_ERROR;
@@ -1011,7 +1059,9 @@
             handle.decryptInfo->decryptBufferLength = bufferLength;
         }
 
-        setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+        const status_t status
+            = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+        reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
         return DRM_NO_ERROR;
@@ -1037,7 +1087,8 @@
         LOGV("BnDrmManagerService::onTransact :REMOVE_RIGHTS");
         CHECK_INTERFACE(IDrmManagerService, data, reply);
 
-        removeRights(data.readInt32(), data.readString8());
+        const status_t status = removeRights(data.readInt32(), data.readString8());
+        reply->writeInt32(status);
 
         return DRM_NO_ERROR;
     }
@@ -1047,7 +1098,8 @@
         LOGV("BnDrmManagerService::onTransact :REMOVE_ALL_RIGHTS");
         CHECK_INTERFACE(IDrmManagerService, data, reply);
 
-        removeAllRights(data.readInt32());
+        const status_t status = removeAllRights(data.readInt32());
+        reply->writeInt32(status);
 
         return DRM_NO_ERROR;
     }
@@ -1207,7 +1259,8 @@
             handle->decryptInfo->decryptBufferLength = bufferLength;
         }
 
-        closeDecryptSession(uniqueId, handle);
+        const status_t status = closeDecryptSession(uniqueId, handle);
+        reply->writeInt32(status);
         return DRM_NO_ERROR;
     }
 
@@ -1237,7 +1290,9 @@
         DrmBuffer* headerInfo = NULL;
         headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
 
-        initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
+        const status_t status
+            = initializeDecryptUnit(uniqueId, &handle, decryptUnitId, headerInfo);
+        reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
         delete headerInfo; headerInfo = NULL;
@@ -1274,7 +1329,14 @@
         buffer = new char[decBufferSize];
         DrmBuffer* decBuffer = new DrmBuffer(buffer, decBufferSize);
 
-        const status_t status = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer);
+        DrmBuffer* IV = NULL;
+        if (0 != data.dataAvail()) {
+            const int ivBufferlength = data.readInt32();
+            IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength);
+        }
+
+        const status_t status
+            = decrypt(uniqueId, &handle, decryptUnitId, encBuffer, &decBuffer, IV);
 
         reply->writeInt32(status);
 
@@ -1286,6 +1348,7 @@
         delete encBuffer; encBuffer = NULL;
         delete decBuffer; decBuffer = NULL;
         delete [] buffer; buffer = NULL;
+        delete IV; IV = NULL;
         return DRM_NO_ERROR;
     }
 
@@ -1309,7 +1372,8 @@
             handle.decryptInfo->decryptBufferLength = bufferLength;
         }
 
-        finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
+        const status_t status = finalizeDecryptUnit(uniqueId, &handle, data.readInt32());
+        reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
         return DRM_NO_ERROR;
diff --git a/drm/common/IDrmServiceListener.cpp b/drm/common/IDrmServiceListener.cpp
index 0a69115..6eeea40 100644
--- a/drm/common/IDrmServiceListener.cpp
+++ b/drm/common/IDrmServiceListener.cpp
@@ -14,10 +14,6 @@
  * 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>
diff --git a/drm/common/ReadWriteUtils.cpp b/drm/common/ReadWriteUtils.cpp
index 4319c1c..7ec4fa2 100644
--- a/drm/common/ReadWriteUtils.cpp
+++ b/drm/common/ReadWriteUtils.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ReadWriteUtils"
+#include <utils/Log.h>
+
 #include <ReadWriteUtils.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -22,7 +26,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <utils/FileMap.h>
 #include <utils/String8.h>
 
 using namespace android;
@@ -39,18 +42,39 @@
         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();
+            int length = sb.st_size;
+            char* bytes = new char[length];
+            if (length == read(fd, (void*) bytes, length)) {
+                string.append(bytes, length);
             }
+            delete bytes;
         }
         fclose(file);
     }
     return string;
 }
 
+int ReadWriteUtils::readBytes(const String8& filePath, char** buffer) {
+    FILE* file = NULL;
+    file = fopen(filePath.string(), "r");
+    int length = 0;
+
+    if (NULL != file) {
+        int fd = fileno(file);
+        struct stat sb;
+
+        if (fstat(fd, &sb) == 0 && sb.st_size > 0) {
+            length = sb.st_size;
+            *buffer = new char[length];
+            if (length != read(fd, (void*) *buffer, length)) {
+                length = FAILURE;
+            }
+        }
+        fclose(file);
+    }
+    return length;
+}
+
 void ReadWriteUtils::writeToFile(const String8& filePath, const String8& data) {
     FILE* file = NULL;
     file = fopen(filePath.string(), "w+");
@@ -60,12 +84,8 @@
 
         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();
+            if (size != write(fd, data.string(), size)) {
+                LOGE("Failed to write the data to: %s", filePath.string());
             }
         }
         fclose(file);
@@ -79,20 +99,9 @@
     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();
-                }
-            }
+        int size = data.size();
+        if (size != write(fd, data.string(), size)) {
+            LOGE("Failed to write the data to: %s", filePath.string());
         }
         fclose(file);
     }
diff --git a/drm/drmioserver/DrmIOService.cpp b/drm/drmioserver/DrmIOService.cpp
index 67cfd39..60e6e70 100644
--- a/drm/drmioserver/DrmIOService.cpp
+++ b/drm/drmioserver/DrmIOService.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "DrmIOService"
 #include <utils/Log.h>
 
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 44886f9..52527dc 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "DrmManager(Native)"
 #include "utils/Log.h"
 
@@ -36,6 +36,7 @@
 
 using namespace android;
 
+Vector<int> DrmManager::mUniqueIdVector;
 const String8 DrmManager::EMPTY_STRING("");
 
 DrmManager::DrmManager() :
@@ -48,6 +49,42 @@
 
 }
 
+int DrmManager::addUniqueId(int uniqueId) {
+    if (0 == uniqueId) {
+        int temp = 0;
+        bool foundUniqueId = false;
+        srand(time(NULL));
+
+        while (!foundUniqueId) {
+            const int size = mUniqueIdVector.size();
+            temp = rand() % 100;
+
+            int index = 0;
+            for (; index < size; ++index) {
+                if (mUniqueIdVector.itemAt(index) == temp) {
+                    foundUniqueId = false;
+                    break;
+                }
+            }
+            if (index == size) {
+                foundUniqueId = true;
+            }
+        }
+        uniqueId = temp;
+    }
+    mUniqueIdVector.push(uniqueId);
+    return uniqueId;
+}
+
+void DrmManager::removeUniqueId(int uniqueId) {
+    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
+        if (uniqueId == mUniqueIdVector.itemAt(i)) {
+            mUniqueIdVector.removeAt(i);
+            break;
+        }
+    }
+}
+
 status_t DrmManager::loadPlugIns(int uniqueId) {
     String8 pluginDirPath("/system/lib/drm/plugins/native");
     return loadPlugIns(uniqueId, pluginDirPath);
@@ -82,10 +119,12 @@
         rDrmEngine.terminate(uniqueId);
     }
 
-    mConvertSessionMap.clear();
-    mDecryptSessionMap.clear();
-    mSupportInfoToPlugInIdMap.clear();
-    mPlugInManager.unloadPlugIns();
+    if (0 >= mUniqueIdVector.size()) {
+        mConvertSessionMap.clear();
+        mDecryptSessionMap.clear();
+        mSupportInfoToPlugInIdMap.clear();
+        mPlugInManager.unloadPlugIns();
+    }
     return DRM_NO_ERROR;
 }
 
@@ -159,13 +198,15 @@
     return NULL;
 }
 
-void DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
+status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
+    status_t result = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != plugInId) {
         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
-        rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
+        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
     }
+    return result;
 }
 
 String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
@@ -195,21 +236,24 @@
     return RightsStatus::RIGHTS_INVALID;
 }
 
-void DrmManager::consumeRights(
+status_t DrmManager::consumeRights(
     int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
-        drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
+        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
     }
+    return result;
 }
 
-void DrmManager::setPlaybackStatus(
+status_t DrmManager::setPlaybackStatus(
     int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
-
+    status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
-        drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
     }
+    return result;
 }
 
 bool DrmManager::validateAction(
@@ -222,21 +266,27 @@
     return false;
 }
 
-void DrmManager::removeRights(int uniqueId, const String8& path) {
+status_t DrmManager::removeRights(int uniqueId, const String8& path) {
     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
+    status_t result = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != plugInId) {
         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
-        rDrmEngine.removeRights(uniqueId, path);
+        result = rDrmEngine.removeRights(uniqueId, path);
     }
+    return result;
 }
 
-void DrmManager::removeAllRights(int uniqueId) {
+status_t DrmManager::removeAllRights(int uniqueId) {
     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
-
+    status_t result = DRM_ERROR_UNKNOWN;
     for (unsigned int index = 0; index < plugInIdList.size(); index++) {
         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
-        rDrmEngine.removeAllRights(uniqueId);
+        result = rDrmEngine.removeAllRights(uniqueId);
+        if (DRM_NO_ERROR != result) {
+            break;
+        }
     }
+    return result;
 }
 
 int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
@@ -246,12 +296,12 @@
     if (EMPTY_STRING != plugInId) {
         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
 
-        Mutex::Autolock _l(mConvertLock);
-        ++mConvertId;
-        convertId = mConvertId;
-        mConvertSessionMap.add(mConvertId, &rDrmEngine);
-
-        rDrmEngine.openConvertSession(uniqueId, mConvertId);
+        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
+            Mutex::Autolock _l(mConvertLock);
+            ++mConvertId;
+            convertId = mConvertId;
+            mConvertSessionMap.add(convertId, &rDrmEngine);
+        }
     }
     return convertId;
 }
@@ -310,7 +360,6 @@
 }
 
 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();
 
@@ -324,18 +373,15 @@
             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) {
+    if (DRM_NO_ERROR != result) {
         delete handle; handle = NULL;
         LOGE("DrmManager::openDecryptSession: no capable plug-in found");
     }
@@ -343,39 +389,47 @@
     return handle;
 }
 
-void DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+    status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
-        drmEngine->closeDecryptSession(uniqueId, decryptHandle);
-
-        mDecryptSessionMap.removeItem(decryptHandle->decryptId);
+        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
+        if (DRM_NO_ERROR == result) {
+            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
+        }
     }
+    return result;
 }
 
-void DrmManager::initializeDecryptUnit(
+status_t DrmManager::initializeDecryptUnit(
     int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+    status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
-        drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
+        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
     }
+    return result;
 }
 
-status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
-    status_t status = DRM_ERROR_UNKNOWN;
+status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+    status_t result = 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);
+        result = drmEngine->decrypt(
+                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
     }
-    return status;
+    return result;
 }
 
-void DrmManager::finalizeDecryptUnit(
+status_t DrmManager::finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    status_t result = DRM_ERROR_UNKNOWN;
     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
-        drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
     }
+    return result;
 }
 
 ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 9d000e9..843dddb 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "DrmManagerService(Native)"
 #include <utils/Log.h>
 
@@ -29,20 +29,23 @@
 
 #define SUCCESS 0
 #define DRM_DIRECTORY_PERMISSION 0700
+#define DRM_PLUGINS_ROOT "/data/drm/plugins"
+#define DRM_PLUGINS_NATIVE "/data/drm/plugins/native"
+#define DRM_PLUGINS_NATIVE_DATABASES "/data/drm/plugins/native/databases"
 
 void DrmManagerService::instantiate() {
     LOGV("instantiate");
 
-    int res = mkdir("/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());

-            }

-        }

+    int res = mkdir(DRM_PLUGINS_ROOT, DRM_DIRECTORY_PERMISSION);
+    if (SUCCESS == res || EEXIST == errno) {
+        res = mkdir(DRM_PLUGINS_NATIVE, DRM_DIRECTORY_PERMISSION);
+        if (SUCCESS == res || EEXIST == errno) {
+            res = mkdir(DRM_PLUGINS_NATIVE_DATABASES, DRM_DIRECTORY_PERMISSION);
+            if (SUCCESS == res || EEXIST == errno) {
+                defaultServiceManager()
+                    ->addService(String16("drm.drmManager"), new DrmManagerService());
+            }
+        }
     }
 }
 
@@ -57,6 +60,14 @@
     delete mDrmManager; mDrmManager = NULL;
 }
 
+int DrmManagerService::addUniqueId(int uniqueId) {
+    return mDrmManager->addUniqueId(uniqueId);
+}
+
+void DrmManagerService::removeUniqueId(int uniqueId) {
+    mDrmManager->removeUniqueId(uniqueId);
+}
+
 status_t DrmManagerService::loadPlugIns(int uniqueId) {
     LOGV("Entering load plugins");
     return mDrmManager->loadPlugIns(uniqueId);
@@ -105,7 +116,7 @@
     return mDrmManager->acquireDrmInfo(uniqueId, drmInfoRequest);
 }
 
-void DrmManagerService::saveRights(
+status_t DrmManagerService::saveRights(
             int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     LOGV("Entering saveRights");
@@ -129,16 +140,16 @@
     return mDrmManager->checkRightsStatus(uniqueId, path, action);
 }
 
-void DrmManagerService::consumeRights(
+status_t DrmManagerService::consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
     LOGV("Entering consumeRights");
-    mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
+    return mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
 }
 
-void DrmManagerService::setPlaybackStatus(
+status_t DrmManagerService::setPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
     LOGV("Entering setPlaybackStatus");
-    mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
+    return mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
 }
 
 bool DrmManagerService::validateAction(
@@ -148,14 +159,14 @@
     return mDrmManager->validateAction(uniqueId, path, action, description);
 }
 
-void DrmManagerService::removeRights(int uniqueId, const String8& path) {
+status_t DrmManagerService::removeRights(int uniqueId, const String8& path) {
     LOGV("Entering removeRights");
-    mDrmManager->removeRights(uniqueId, path);
+    return mDrmManager->removeRights(uniqueId, path);
 }
 
-void DrmManagerService::removeAllRights(int uniqueId) {
+status_t DrmManagerService::removeAllRights(int uniqueId) {
     LOGV("Entering removeAllRights");
-    mDrmManager->removeAllRights(uniqueId);
+    return mDrmManager->removeAllRights(uniqueId);
 }
 
 int DrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
@@ -186,28 +197,28 @@
     return mDrmManager->openDecryptSession(uniqueId, fd, offset, length);
 }
 
-void DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGV("Entering closeDecryptSession");
-    mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
+    return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
 }
 
-void DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     LOGV("Entering initializeDecryptUnit");
-    mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
+    return mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
 }
 
 status_t DrmManagerService::decrypt(
-            int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     LOGV("Entering decrypt");
-    return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+    return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
-void DrmManagerService::finalizeDecryptUnit(
+status_t DrmManagerService::finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
     LOGV("Entering finalizeDecryptUnit");
-    mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/drmserver/StringTokenizer.cpp b/drm/drmserver/StringTokenizer.cpp
index 367c9bd..2130a00 100644
--- a/drm/drmserver/StringTokenizer.cpp
+++ b/drm/drmserver/StringTokenizer.cpp
@@ -45,12 +45,10 @@
 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;
diff --git a/drm/java/android/drm/DrmErrorEvent.java b/drm/java/android/drm/DrmErrorEvent.java
new file mode 100644
index 0000000..8e71634
--- /dev/null
+++ b/drm/java/android/drm/DrmErrorEvent.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+package android.drm;
+
+/**
+ * This is an entity class which would be passed to caller in
+ * {@link DrmManagerClient.OnErrorListener#onError(DrmManagerClient, DrmErrorEvent)}
+ *
+ */
+public class DrmErrorEvent extends DrmEvent {
+    /**
+     * TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights.
+     */
+    public static final int TYPE_RIGHTS_NOT_INSTALLED = 2001;
+    /**
+     * TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights.
+     */
+    public static final int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 2002;
+    /**
+     * TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent.
+     */
+    public static final int TYPE_NOT_SUPPORTED = 2003;
+    /**
+     * TYPE_OUT_OF_MEMORY, when memory allocation fail during renewal.
+     * Can in the future perhaps be used to trigger garbage collector.
+     */
+    public static final int TYPE_OUT_OF_MEMORY = 2004;
+    /**
+     * TYPE_NO_INTERNET_CONNECTION, when the Internet connection is missing and no attempt
+     * can be made to renew rights.
+     */
+    public static final int TYPE_NO_INTERNET_CONNECTION = 2005;
+    /**
+     * TYPE_REGISTRATION_FAILED, when failed to register with the service.
+     */
+    public static final int TYPE_REGISTRATION_FAILED = 2006;
+    /**
+     * TYPE_UNREGISTRATION_FAILED, when failed to unregister with the service.
+     */
+    public static final int TYPE_UNREGISTRATION_FAILED = 2007;
+    /**
+     * TYPE_RIGHTS_ACQUISITION_FAILED, when failed to acquire the rights information required.
+     */
+    public static final int TYPE_RIGHTS_ACQUISITION_FAILED = 2008;
+    /**
+     * TYPE_INITIALIZE_FAILED, when failed to load and initialize the available plugins.
+     */
+    public static final int TYPE_INITIALIZE_FAILED = 2009;
+    /**
+     * TYPE_FINALIZE_FAILED, when failed to unload and finalize the loaded plugins.
+     */
+    public static final int TYPE_FINALIZE_FAILED = 2010;
+    /**
+     * TYPE_REMOVE_ALL_RIGHTS_FAILED, when failed to remove all the rights objects
+     * associated with all DRM schemes.
+     */
+    public static final int TYPE_REMOVE_ALL_RIGHTS_FAILED = 2011;
+    /**
+     * TYPE_DRM_INFO_ACQUISITION_FAILED, when failed to get the required information to
+     * communicate with the service.
+     */
+    public static final int TYPE_DRM_INFO_ACQUISITION_FAILED = 2012;
+
+    /**
+     * constructor to create DrmErrorEvent object with given parameters
+     *
+     * @param uniqueId Unique session identifier
+     * @param type Type of information
+     * @param message Message description
+     */
+    public DrmErrorEvent(int uniqueId, int type, String message) {
+        super(uniqueId, type, message);
+    }
+}
+
diff --git a/drm/java/android/drm/DrmEvent.java b/drm/java/android/drm/DrmEvent.java
index 44c4b43..d6e0c3a 100644
--- a/drm/java/android/drm/DrmEvent.java
+++ b/drm/java/android/drm/DrmEvent.java
@@ -22,6 +22,40 @@
  *
  */
 public class DrmEvent {
+    /**
+     * Constant field signifies that unload and finalize the loaded plugins successfully
+     */
+    public static final int TYPE_FINALIZED = 1001;
+    /**
+     * Constant field signifies that register with the service successfully
+     */
+    public static final int TYPE_REGISTERED = 1002;
+    /**
+     * Constant field signifies that load and initialized the available plugins successfully
+     */
+    public static final int TYPE_INITIALIZED = 1003;
+    /**
+     * Constant field signifies that unregister with the service successfully
+     */
+    public static final int TYPE_UNREGISTERED = 1004;
+    /**
+     * Constant field signifies that rights information is acquired successfully
+     */
+    public static final int TYPE_RIGHTS_ACQUIRED = 1005;
+    /**
+     * Constant field signifies that all the rights information associated with
+     * all DRM schemes are removed successfully
+     */
+    public static final int TYPE_ALL_RIGHTS_REMOVED = 1006;
+    /**
+     * Constant field signifies that the required information to communicate with
+     * the service is acquired sucessfully
+     */
+    public static final int TYPE_DRM_INFO_ACQUIRED = 1007;
+
+    public static final String DRM_INFO_STATUS_OBJECT = "drm_info_status_object";
+    public static final String DRM_INFO_OBJECT = "drm_info_object";
+
     private final int mUniqueId;
     private final int mType;
     private String mMessage = "";
diff --git a/drm/java/android/drm/DrmInfoEvent.java b/drm/java/android/drm/DrmInfoEvent.java
index be1b009..a778e06 100644
--- a/drm/java/android/drm/DrmInfoEvent.java
+++ b/drm/java/android/drm/DrmInfoEvent.java
@@ -26,42 +26,25 @@
      * TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT, when registration has been already done
      * by another account ID.
      */
-    public static final int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 0x0000001;
+    public static final int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 1;
     /**
      * TYPE_REMOVE_RIGHTS, when the rights needs to be removed completely.
      */
-    public static final int TYPE_REMOVE_RIGHTS = 0x0000002;
+    public static final int TYPE_REMOVE_RIGHTS = 2;
     /**
      * TYPE_RIGHTS_INSTALLED, when the rights are downloaded and installed ok.
      */
-    public static final int TYPE_RIGHTS_INSTALLED = 0x0000003;
-    /**
-     * TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights.
-     */
-    public static final int TYPE_RIGHTS_NOT_INSTALLED = 0x0000004;
-    /**
-     * TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights.
-     */
-    public static final int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 0x0000005;
-    /**
-     * TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent.
-     */
-    public static final int TYPE_NOT_SUPPORTED = 0x0000006;
+    public static final int TYPE_RIGHTS_INSTALLED = 3;
     /**
      * TYPE_WAIT_FOR_RIGHTS, rights object is on it's way to phone,
      * wait before calling checkRights again.
      */
-    public static final int TYPE_WAIT_FOR_RIGHTS = 0x0000007;
+    public static final int TYPE_WAIT_FOR_RIGHTS = 4;
     /**
-     * TYPE_OUT_OF_MEMORY, when memory allocation fail during renewal.
-     * Can in the future perhaps be used to trigger garbage collector.
+     * TYPE_ACCOUNT_ALREADY_REGISTERED, when registration has been
+     * already done for the given account.
      */
-    public static final 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.
-     */
-    public static final int TYPE_NO_INTERNET_CONNECTION = 0x0000009;
+    public static final int TYPE_ACCOUNT_ALREADY_REGISTERED = 5;
 
     /**
      * constructor to create DrmInfoEvent object with given parameters
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 7ec70da..147c530 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -18,14 +18,19 @@
 
 import android.content.ContentValues;
 import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+import android.provider.MediaStore;
 import android.util.Log;
 
 import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * Interface of DRM Framework.
@@ -34,7 +39,16 @@
  *
  */
 public class DrmManagerClient {
-    private static final String TAG = "DrmManager";
+    /**
+     * Constant field signifies the success or no error occurred
+     */
+    public static final int ERROR_NONE = 0;
+    /**
+     * Constant field signifies that error occurred and the reason is not known
+     */
+    public static final int ERROR_UNKNOWN = -2000;
+
+    private static final String TAG = "DrmManagerClient";
 
     static {
         // Load the respective library
@@ -55,55 +69,189 @@
         public void onInfo(DrmManagerClient client, DrmInfoEvent event);
     }
 
-    private static final int STATE_UNINITIALIZED = 0x00000000;
-    private static final int STATE_INITIALIZED = 0x00000001;
+    /**
+     * Interface definition of a callback to be invoked to communicate
+     * the result of time consuming APIs asynchronously
+     */
+    public interface OnEventListener {
+        /**
+         * Called to indicate the result of asynchronous APIs.
+         *
+         * @param client DrmManagerClient instance
+         * @param event instance which wraps type and message
+         * @param attributes resultant values in key and value pair.
+         */
+        public void onEvent(DrmManagerClient client, DrmEvent event,
+                HashMap<String, Object> attributes);
+    }
+
+    /**
+     * Interface definition of a callback to be invoked to communicate
+     * the error occurred
+     */
+    public interface OnErrorListener {
+        /**
+         * Called to indicate the error occurred.
+         *
+         * @param client DrmManagerClient instance
+         * @param event instance which wraps error type and message
+         */
+        public void onError(DrmManagerClient client, DrmErrorEvent event);
+    }
+
+    private static final int STATE_UNINITIALIZED = 0;
+    private static final int STATE_INITIALIZED = 1;
+
+    private static final int ACTION_INITIALIZE = 1000;
+    private static final int ACTION_FINALIZE = 1001;
+    private static final int ACTION_REMOVE_ALL_RIGHTS = 1002;
+    private static final int ACTION_ACQUIRE_DRM_INFO = 1003;
+    private static final int ACTION_PROCESS_DRM_INFO = 1004;
 
     private int mUniqueId;
     private int mNativeContext;
+    private Context mContext;
+    private InfoHandler mInfoHandler;
     private EventHandler mEventHandler;
     private OnInfoListener mOnInfoListener;
+    private OnEventListener mOnEventListener;
+    private OnErrorListener mOnErrorListener;
     private int mCurrentState = STATE_UNINITIALIZED;
 
-    /**
-     * {@hide}
-     */
-    public static void notify(Object thisReference, int uniqueId, int infoType, String message) {
-        DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get();
-
-        if (null != instance && null != instance.mEventHandler) {
-            Message m = instance.mEventHandler.obtainMessage(
-                EventHandler.INFO_EVENT_TYPE, uniqueId, infoType, message);
-            instance.mEventHandler.sendMessage(m);
-        }
-    }
-
     private class EventHandler extends Handler {
-        public static final int INFO_EVENT_TYPE = 1;
 
         public EventHandler(Looper looper) {
             super(looper);
         }
 
         public void handleMessage(Message msg) {
+            DrmEvent event = null;
+            DrmErrorEvent error = null;
+            HashMap<String, Object> attributes = new HashMap<String, Object>();
+
+            switch(msg.what) {
+            case ACTION_INITIALIZE: {
+                if (ERROR_NONE == _loadPlugIns(mUniqueId, msg.obj)) {
+                    mCurrentState = STATE_INITIALIZED;
+                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_INITIALIZED, null);
+                } else {
+                    error = new DrmErrorEvent(mUniqueId,
+                            DrmErrorEvent.TYPE_INITIALIZE_FAILED, null);
+                }
+                break;
+            }
+            case ACTION_ACQUIRE_DRM_INFO: {
+                final DrmInfoRequest request = (DrmInfoRequest) msg.obj;
+                DrmInfo drmInfo = _acquireDrmInfo(mUniqueId, request);
+                if (null != drmInfo) {
+                    attributes.put(DrmEvent.DRM_INFO_OBJECT, drmInfo);
+                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_DRM_INFO_ACQUIRED, null);
+                } else {
+                    error = new DrmErrorEvent(mUniqueId,
+                            DrmErrorEvent.TYPE_DRM_INFO_ACQUISITION_FAILED, null);
+                }
+                break;
+            }
+            case ACTION_PROCESS_DRM_INFO: {
+                final DrmInfo drmInfo = (DrmInfo) msg.obj;
+                DrmInfoStatus status = _processDrmInfo(mUniqueId, drmInfo);
+                if (null != status && DrmInfoStatus.STATUS_OK == status.statusCode) {
+                    attributes.put(DrmEvent.DRM_INFO_STATUS_OBJECT, status);
+                    event = new DrmEvent(mUniqueId, getEventType(drmInfo.getInfoType()), null);
+                } else {
+                    error = new DrmErrorEvent(mUniqueId,
+                            getErrorType(drmInfo.getInfoType()), null);
+                }
+                break;
+            }
+            case ACTION_REMOVE_ALL_RIGHTS: {
+                if (ERROR_NONE == _removeAllRights(mUniqueId)) {
+                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_ALL_RIGHTS_REMOVED, null);
+                } else {
+                    error = new DrmErrorEvent(mUniqueId,
+                            DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED, null);
+                }
+                break;
+            }
+            case ACTION_FINALIZE: {
+                if (ERROR_NONE == _unloadPlugIns(mUniqueId)) {
+                    mCurrentState = STATE_UNINITIALIZED;
+                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_FINALIZED, null);
+                } else {
+                    error = new DrmErrorEvent(mUniqueId,
+                            DrmErrorEvent.TYPE_FINALIZE_FAILED, null);
+                }
+                break;
+            }
+            default:
+                Log.e(TAG, "Unknown message type " + msg.what);
+                return;
+            }
+            if (null != mOnEventListener && null != event) {
+                mOnEventListener.onEvent(DrmManagerClient.this, event, attributes);
+            }
+            if (null != mOnErrorListener && null != error) {
+                mOnErrorListener.onError(DrmManagerClient.this, error);
+            }
+        }
+    }
+
+    /**
+     * {@hide}
+     */
+    public static void notify(
+            Object thisReference, int uniqueId, int infoType, String message) {
+        DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get();
+
+        if (null != instance && null != instance.mInfoHandler) {
+            Message m = instance.mInfoHandler.obtainMessage(
+                InfoHandler.INFO_EVENT_TYPE, uniqueId, infoType, message);
+            instance.mInfoHandler.sendMessage(m);
+        }
+    }
+
+    private class InfoHandler extends Handler {
+        public static final int INFO_EVENT_TYPE = 1;
+
+        public InfoHandler(Looper looper) {
+            super(looper);
+        }
+
+        public void handleMessage(Message msg) {
+            DrmInfoEvent event = null;
+            DrmErrorEvent error = null;
 
             switch (msg.what) {
-            case EventHandler.INFO_EVENT_TYPE:
+            case InfoHandler.INFO_EVENT_TYPE:
                 int uniqueId = msg.arg1;
                 int infoType = msg.arg2;
                 String message = msg.obj.toString();
 
-                if (infoType == DrmInfoEvent.TYPE_REMOVE_RIGHTS) {
+                switch (infoType) {
+                case DrmInfoEvent.TYPE_REMOVE_RIGHTS: {
                     try {
                         DrmUtils.removeFile(message);
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
+                    event = new DrmInfoEvent(uniqueId, infoType, message);
+                    break;
+                }
+                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT: {
+                    event = new DrmInfoEvent(uniqueId, infoType, message);
+                    break;
+                }
+                default:
+                    error = new DrmErrorEvent(uniqueId, infoType, message);
+                    break;
                 }
 
-                if (null != mOnInfoListener) {
-                    DrmInfoEvent event = new DrmInfoEvent(uniqueId, infoType, message);
+                if (null != mOnInfoListener && null != event) {
                     mOnInfoListener.onInfo(DrmManagerClient.this, event);
                 }
+                if (null != mOnErrorListener && null != error) {
+                    mOnErrorListener.onError(DrmManagerClient.this, error);
+                }
                 return;
             default:
                 Log.e(TAG, "Unknown message type " + msg.what);
@@ -118,31 +266,58 @@
      * @param context context of the caller
      */
     public DrmManagerClient(Context context) {
+        mContext = context;
         Looper looper;
 
         if (null != (looper = Looper.myLooper())) {
-            mEventHandler = new EventHandler(looper);
+            mInfoHandler = new InfoHandler(looper);
         } else if (null != (looper = Looper.getMainLooper())) {
-            mEventHandler = new EventHandler(looper);
+            mInfoHandler = new InfoHandler(looper);
         } else {
-            mEventHandler = null;
+            mInfoHandler = null;
         }
 
+        HandlerThread thread = new HandlerThread("DrmManagerClient.EventHandler");
+        thread.start();
+        mEventHandler = new EventHandler(thread.getLooper());
+
         // save the unique id
         mUniqueId = hashCode();
     }
 
     /**
      * Register a callback to be invoked when the caller required to receive
-     * necessary information
+     * supplementary information.
      *
      * @param infoListener
      */
-    public void setOnInfoListener(OnInfoListener infoListener) {
-        synchronized(this) {
-            if (null != infoListener) {
-                mOnInfoListener = infoListener;
-            }
+    public synchronized void setOnInfoListener(OnInfoListener infoListener) {
+        if (null != infoListener) {
+            mOnInfoListener = infoListener;
+        }
+    }
+
+    /**
+     * Register a callback to be invoked when the caller required to receive
+     * the result of asynchronous APIs.
+     *
+     * @param eventListener
+     */
+    public synchronized void setOnEventListener(OnEventListener eventListener) {
+        if (null != eventListener) {
+            mOnEventListener = eventListener;
+        }
+    }
+
+    /**
+     * Register a callback to be invoked when the caller required to receive
+     * error result of asynchronous APIs.
+     *
+     * @param errorListener
+     */
+    public synchronized void setOnErrorListener(OnErrorListener errorListener) {
+        if (null != errorListener) {
+            mOnErrorListener = errorListener;
         }
     }
 
@@ -150,25 +325,43 @@
      * Initializes DrmFramework, which loads all available plug-ins
      * in the default plug-in directory path
      *
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public void loadPlugIns() {
-        if (getState() == STATE_UNINITIALIZED) {
-            _loadPlugIns(mUniqueId, new WeakReference<DrmManagerClient>(this));
-
-            mCurrentState = STATE_INITIALIZED;
+    public int loadPlugIns() {
+        int result = ERROR_UNKNOWN;
+        if (STATE_UNINITIALIZED == getState()) {
+            if (null != mEventHandler) {
+                Message msg = mEventHandler.obtainMessage(
+                        ACTION_INITIALIZE, new WeakReference<DrmManagerClient>(this));
+                result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
+            }
+        } else {
+            result = ERROR_NONE;
         }
+        return result;
     }
 
     /**
      * Finalize DrmFramework, which release resources associated with each plug-in
      * and unload all plug-ins.
+     *
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public void unloadPlugIns() {
-        if (getState() == STATE_INITIALIZED) {
-            _unloadPlugIns(mUniqueId);
-
-            mCurrentState = STATE_UNINITIALIZED;
+    public int unloadPlugIns() {
+        int result = ERROR_UNKNOWN;
+        if (STATE_INITIALIZED == getState()) {
+            if (null != mEventHandler) {
+                Message msg = mEventHandler.obtainMessage(ACTION_FINALIZE);
+                result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
+            }
+        } else {
+            result = ERROR_NONE;
         }
+        return result;
     }
 
     /**
@@ -177,7 +370,7 @@
      * @return Array of DrmEngine plug-in strings
      */
     public String[] getAvailableDrmEngines() {
-        if (getState() == STATE_UNINITIALIZED) {
+        if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
 
@@ -203,13 +396,25 @@
     public ContentValues getConstraints(String path, int action) {
         if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
             throw new IllegalArgumentException("Given usage or path is invalid/null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _getConstraints(mUniqueId, path, action);
     }
 
     /**
+     * Get constraints information evaluated from DRM content
+     *
+     * @param uri The Content URI of the data
+     * @param action Actions defined in {@link DrmStore.Action}
+     * @return ContentValues instance in which constraints key-value pairs are embedded
+     *         or null in case of failure
+     */
+    public ContentValues getConstraints(Uri uri, int action) {
+        return getConstraints(convertUriToPath(uri), action);
+    }
+
+    /**
      * Save DRM rights to specified rights path
      * and make association with content path.
      *
@@ -218,20 +423,22 @@
      * @param drmRights DrmRights to be saved
      * @param rightsPath File path where rights to be saved
      * @param contentPath File path where content was saved
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      * @throws IOException if failed to save rights information in the given path
      */
-    public void saveRights(
+    public int saveRights(
             DrmRights drmRights, String rightsPath, String contentPath) throws IOException {
-        if (null == drmRights || !drmRights.isValid()
-            || null == contentPath || contentPath.equals("")) {
+        if (null == drmRights || !drmRights.isValid()) {
             throw new IllegalArgumentException("Given drmRights or contentPath is not valid");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         if (null != rightsPath && !rightsPath.equals("")) {
             DrmUtils.writeToFile(rightsPath, drmRights.getData());
         }
-        _saveRights(mUniqueId, drmRights, rightsPath, contentPath);
+        return _saveRights(mUniqueId, drmRights, rightsPath, contentPath);
     }
 
     /**
@@ -244,7 +451,7 @@
         if (null == engineFilePath || engineFilePath.equals("")) {
             throw new IllegalArgumentException(
                 "Given engineFilePath: "+ engineFilePath + "is not valid");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         _installDrmEngine(mUniqueId, engineFilePath);
@@ -256,47 +463,78 @@
      * @param path Path of the content to be handled
      * @param mimeType Mimetype of the object to be handled
      * @return
-     *        true - if the given mimeType or path can be handled.
-     *        false - cannot be handled.  false will be returned in case
+     *        true - if the given mimeType or path can be handled
+     *        false - cannot be handled. false will be return in case
      *        the state is uninitialized
      */
     public boolean canHandle(String path, String mimeType) {
         if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
             throw new IllegalArgumentException("Path or the mimetype should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _canHandle(mUniqueId, path, mimeType);
     }
 
     /**
+     * Check whether the given mimetype or uri can be handled.
+     *
+     * @param uri The content URI of the data
+     * @param mimeType Mimetype of the object to be handled
+     * @return
+     *        true - if the given mimeType or path can be handled
+     *        false - cannot be handled. false will be return in case
+     *        the state is uninitialized
+     */
+    public boolean canHandle(Uri uri, String mimeType) {
+        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
+            throw new IllegalArgumentException("Uri or the mimetype should be non null");
+        }
+        return canHandle(convertUriToPath(uri), mimeType);
+    }
+
+    /**
      * Executes given drm information based on its type
      *
      * @param drmInfo Information needs to be processed
-     * @return DrmInfoStatus Instance as a result of processing given input
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public DrmInfoStatus processDrmInfo(DrmInfo drmInfo) {
+    public int processDrmInfo(DrmInfo drmInfo) {
         if (null == drmInfo || !drmInfo.isValid()) {
             throw new IllegalArgumentException("Given drmInfo is invalid/null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
-        return _processDrmInfo(mUniqueId, drmInfo);
+        int result = ERROR_UNKNOWN;
+        if (null != mEventHandler) {
+            Message msg = mEventHandler.obtainMessage(ACTION_PROCESS_DRM_INFO, drmInfo);
+            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
+        }
+        return result;
     }
 
     /**
      * Retrieves necessary information for register, unregister or rights acquisition.
      *
      * @param drmInfoRequest Request information to retrieve drmInfo
-     * @return DrmInfo Instance as a result of processing given input
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public DrmInfo acquireDrmInfo(DrmInfoRequest drmInfoRequest) {
+    public int acquireDrmInfo(DrmInfoRequest drmInfoRequest) {
         if (null == drmInfoRequest || !drmInfoRequest.isValid()) {
             throw new IllegalArgumentException("Given drmInfoRequest is invalid/null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
-        return _acquireDrmInfo(mUniqueId, drmInfoRequest);
+        int result = ERROR_UNKNOWN;
+        if (null != mEventHandler) {
+            Message msg = mEventHandler.obtainMessage(ACTION_ACQUIRE_DRM_INFO, drmInfoRequest);
+            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
+        }
+        return result;
     }
 
     /**
@@ -312,13 +550,37 @@
     public int getDrmObjectType(String path, String mimeType) {
         if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
             throw new IllegalArgumentException("Path or the mimetype should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _getDrmObjectType(mUniqueId, path, mimeType);
     }
 
     /**
+     * Retrieves the type of the protected object (content, rights, etc..)
+     * using specified uri or mimetype. At least one parameter should be non null
+     * to retrieve DRM object type
+     *
+     * @param uri The content URI of the data
+     * @param mimeType Mimetype of the content or null.
+     * @return Type of the DRM content.
+     * @see DrmStore.DrmObjectType
+     */
+    public int getDrmObjectType(Uri uri, String mimeType) {
+        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
+            throw new IllegalArgumentException("Uri or the mimetype should be non null");
+        }
+        String path = "";
+        try {
+            path = convertUriToPath(uri);
+        } catch (Exception e) {
+            // Even uri is invalid the mimetype shall be valid, so allow to proceed further.
+            Log.w(TAG, "Given Uri could not be found in media store");
+        }
+        return getDrmObjectType(path, mimeType);
+    }
+
+    /**
      * Retrieves the mime type embedded inside the original content
      *
      * @param path Path of the protected content
@@ -327,13 +589,26 @@
     public String getOriginalMimeType(String path) {
         if (null == path || path.equals("")) {
             throw new IllegalArgumentException("Given path should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _getOriginalMimeType(mUniqueId, path);
     }
 
     /**
+     * Retrieves the mime type embedded inside the original content
+     *
+     * @param uri The content URI of the data
+     * @return Mimetype of the original content, such as "video/mpeg"
+     */
+    public String getOriginalMimeType(Uri uri) {
+        if (null == uri || Uri.EMPTY == uri) {
+            throw new IllegalArgumentException("Given uri is not valid");
+        }
+        return getOriginalMimeType(convertUriToPath(uri));
+    }
+
+    /**
      * Check whether the given content has valid rights or not
      *
      * @param path Path of the protected content
@@ -345,6 +620,20 @@
     }
 
     /**
+     * Check whether the given content has valid rights or not
+     *
+     * @param uri The content URI of the data
+     * @return Status of the rights for the protected content
+     * @see DrmStore.RightsStatus
+     */
+    public int checkRightsStatus(Uri uri) {
+        if (null == uri || Uri.EMPTY == uri) {
+            throw new IllegalArgumentException("Given uri is not valid");
+        }
+        return checkRightsStatus(convertUriToPath(uri));
+    }
+
+    /**
      * Check whether the given content has valid rights or not for specified action.
      *
      * @param path Path of the protected content
@@ -355,35 +644,77 @@
     public int checkRightsStatus(String path, int action) {
         if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
             throw new IllegalArgumentException("Given path or action is not valid");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _checkRightsStatus(mUniqueId, path, action);
     }
 
     /**
+     * Check whether the given content has valid rights or not for specified action.
+     *
+     * @param uri The content URI of the data
+     * @param action Action to perform
+     * @return Status of the rights for the protected content
+     * @see DrmStore.RightsStatus
+     */
+    public int checkRightsStatus(Uri uri, int action) {
+        if (null == uri || Uri.EMPTY == uri) {
+            throw new IllegalArgumentException("Given uri is not valid");
+        }
+        return checkRightsStatus(convertUriToPath(uri), action);
+    }
+
+    /**
      * Removes the rights associated with the given protected content
      *
      * @param path Path of the protected content
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public void removeRights(String path) {
+    public int removeRights(String path) {
         if (null == path || path.equals("")) {
             throw new IllegalArgumentException("Given path should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
-        _removeRights(mUniqueId, path);
+        return _removeRights(mUniqueId, path);
+    }
+
+    /**
+     * Removes the rights associated with the given protected content
+     *
+     * @param uri The content URI of the data
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
+     */
+    public int removeRights(Uri uri) {
+        if (null == uri || Uri.EMPTY == uri) {
+            throw new IllegalArgumentException("Given uri is not valid");
+        }
+        return removeRights(convertUriToPath(uri));
     }
 
     /**
      * Removes all the rights information of every plug-in associated with
      * DRM framework. Will be used in master reset
+     *
+     * @return
+     *     ERROR_NONE for success
+     *     ERROR_UNKNOWN for failure
      */
-    public void removeAllRights() {
-        if (getState() == STATE_UNINITIALIZED) {
+    public int removeAllRights() {
+        if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
-        _removeAllRights(mUniqueId);
+        int result = ERROR_UNKNOWN;
+        if (null != mEventHandler) {
+            Message msg = mEventHandler.obtainMessage(ACTION_REMOVE_ALL_RIGHTS);
+            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
+        }
+        return result;
     }
 
     /**
@@ -398,7 +729,7 @@
     public int openConvertSession(String mimeType) {
         if (null == mimeType || mimeType.equals("")) {
             throw new IllegalArgumentException("Path or the mimeType should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _openConvertSession(mUniqueId, mimeType);
@@ -419,7 +750,7 @@
     public DrmConvertedStatus convertData(int convertId, byte[] inputData) {
         if (null == inputData || 0 >= inputData.length) {
             throw new IllegalArgumentException("Given inputData should be non null");
-        } else if (getState() == STATE_UNINITIALIZED) {
+        } else if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _convertData(mUniqueId, convertId, inputData);
@@ -438,7 +769,7 @@
      *     the application on which offset these signature data should be appended.
      */
     public DrmConvertedStatus closeConvertSession(int convertId) {
-        if (getState() == STATE_UNINITIALIZED) {
+        if (STATE_UNINITIALIZED == getState()) {
             throw new IllegalStateException("Not Initialized yet");
         }
         return _closeConvertSession(mUniqueId, convertId);
@@ -448,10 +779,68 @@
         return mCurrentState;
     }
 
-    // private native interfaces
-    private native void _loadPlugIns(int uniqueId, Object weak_this);
+    private int getEventType(int infoType) {
+        int eventType = -1;
 
-    private native void _unloadPlugIns(int uniqueId);
+        switch (infoType) {
+        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
+            eventType = DrmEvent.TYPE_REGISTERED;
+            break;
+        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
+            eventType = DrmEvent.TYPE_UNREGISTERED;
+            break;
+        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
+            eventType = DrmEvent.TYPE_RIGHTS_ACQUIRED;
+            break;
+        }
+        return eventType;
+    }
+
+    private int getErrorType(int infoType) {
+        int error = -1;
+
+        switch (infoType) {
+        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
+            error = DrmErrorEvent.TYPE_REGISTRATION_FAILED;
+            break;
+        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
+            error = DrmErrorEvent.TYPE_UNREGISTRATION_FAILED;
+            break;
+        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
+            error = DrmErrorEvent.TYPE_RIGHTS_ACQUISITION_FAILED;
+            break;
+        }
+        return error;
+    }
+
+    /**
+     * This method expects uri in the following format
+     *     content://media/<table_name>/<row_index> (or)
+     *     file://sdcard/test.mp4
+     *
+     * Here <table_name> shall be "video" or "audio" or "images"
+     * <row_index> the index of the content in given table
+     */
+    private String convertUriToPath(Uri uri) {
+        String scheme = uri.getScheme();
+        if (null == scheme || scheme.equals("file")) {
+            return uri.getPath();
+        }
+        String[] projection = new String[] {MediaStore.MediaColumns.DATA};
+        Cursor cursor = mContext.getContentResolver().query(uri, projection, null, null, null);
+        if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
+            throw new IllegalArgumentException("Given Uri could not be found in media store");
+        }
+        int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
+        String path = cursor.getString(pathIndex);
+        cursor.close();
+        return path;
+    }
+
+    // private native interfaces
+    private native int _loadPlugIns(int uniqueId, Object weak_this);
+
+    private native int _unloadPlugIns(int uniqueId);
 
     private native void _installDrmEngine(int uniqueId, String engineFilepath);
 
@@ -463,7 +852,7 @@
 
     private native DrmInfo _acquireDrmInfo(int uniqueId, DrmInfoRequest drmInfoRequest);
 
-    private native void _saveRights(
+    private native int _saveRights(
             int uniqueId, DrmRights drmRights, String rightsPath, String contentPath);
 
     private native int _getDrmObjectType(int uniqueId, String path, String mimeType);
@@ -472,13 +861,14 @@
 
     private native int _checkRightsStatus(int uniqueId, String path, int action);
 
-    private native void _removeRights(int uniqueId, String path);
+    private native int _removeRights(int uniqueId, String path);
 
-    private native void _removeAllRights(int uniqueId);
+    private native int _removeAllRights(int uniqueId);
 
     private native int _openConvertSession(int uniqueId, String mimeType);
 
-    private native DrmConvertedStatus _convertData(int uniqueId, int convertId, byte[] inputData);
+    private native DrmConvertedStatus _convertData(
+            int uniqueId, int convertId, byte[] inputData);
 
     private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId);
 
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
index bc5a7bf..6158b66 100644
--- a/drm/jni/android_drm_DrmManagerClient.cpp
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "DrmManager-JNI"
 #include <utils/Log.h>
 
@@ -76,7 +76,7 @@
             env->ReleaseStringUTFChars(valueString, bytes);
             delete [] data; data = NULL;
         } else {
-            LOGD("Failed to retrieve the data from the field %s", fieldName);
+            LOGV("Failed to retrieve the data from the field %s", fieldName);
         }
     }
     return dataString;
@@ -223,7 +223,7 @@
     return sp<DrmManagerClientImpl>(client);
 }
 
-static void android_drm_DrmManagerClient_loadPlugIns(
+static jint android_drm_DrmManagerClient_loadPlugIns(
         JNIEnv* env, jobject thiz, jint uniqueId, jobject weak_thiz) {
     LOGV("load plugins - Enter");
 
@@ -235,23 +235,26 @@
 
     setDrmManagerClientImpl(env, thiz, drmManager);
 
-    getDrmManagerClientImpl(env, thiz)->loadPlugIns(uniqueId);
     LOGV("load plugins - Exit");
+    return getDrmManagerClientImpl(env, thiz)->loadPlugIns(uniqueId);
 }
 
-static void android_drm_DrmManagerClient_unloadPlugIns(JNIEnv* env, jobject thiz, jint uniqueId) {
+static jint android_drm_DrmManagerClient_unloadPlugIns(JNIEnv* env, jobject thiz, jint uniqueId) {
     LOGV("unload plugins - Enter");
     sp<DrmManagerClientImpl> client = getDrmManagerClientImpl(env, thiz);
-    client->unloadPlugIns(uniqueId);
-    client->setOnInfoListener(uniqueId, NULL);
+
     DrmManagerClientImpl::remove(uniqueId);
+    int result = client->unloadPlugIns(uniqueId);
+    if (DRM_NO_ERROR == result) {
+        client->setOnInfoListener(uniqueId, NULL);
 
-    sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
-    if (oldClient != NULL) {
-        oldClient->setOnInfoListener(uniqueId, NULL);
+        sp<DrmManagerClientImpl> oldClient = setDrmManagerClientImpl(env, thiz, NULL);
+        if (oldClient != NULL) {
+            oldClient->setOnInfoListener(uniqueId, NULL);
+        }
     }
-
     LOGV("unload plugins - Exit");
+    return result;
 }
 
 static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
@@ -356,10 +359,11 @@
     LOGV("installDrmEngine - Exit");
 }
 
-static void android_drm_DrmManagerClient_saveRights(
+static jint android_drm_DrmManagerClient_saveRights(
             JNIEnv* env, jobject thiz, jint uniqueId,
             jobject drmRights, jstring rightsPath, jstring contentPath) {
     LOGV("saveRights - Enter");
+    int result = DRM_ERROR_UNKNOWN;
     int dataLength = 0;
     char* mData =  Utility::getByteArrayValue(env, drmRights, "mData", &dataLength);
 
@@ -368,13 +372,14 @@
                 Utility::getStringValue(env, drmRights, "mMimeType"),
                 Utility::getStringValue(env, drmRights, "mAccountId"),
                 Utility::getStringValue(env, drmRights, "mSubscriptionId"));
-        getDrmManagerClientImpl(env, thiz)
+        result = getDrmManagerClientImpl(env, thiz)
             ->saveRights(uniqueId, rights, Utility::getStringValue(env, rightsPath),
                                 Utility::getStringValue(env, contentPath));
     }
 
     delete mData; mData = NULL;
     LOGV("saveRights - Exit");
+    return result;
 }
 
 static jboolean android_drm_DrmManagerClient_canHandle(
@@ -423,7 +428,7 @@
 
         String8 keyString = Utility::getStringValue(env, key);
         String8 valueString = Utility::getStringValue(env, valString);
-        LOGD("Key: %s | Value: %s", keyString.string(), valueString.string());
+        LOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
 
         drmInfo.put(keyString, valueString);
     }
@@ -495,7 +500,7 @@
 
         String8 keyString = Utility::getStringValue(env, key);
         String8 valueString = Utility::getStringValue(env, value);
-        LOGD("Key: %s | Value: %s", keyString.string(), valueString.string());
+        LOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
 
         drmInfoReq.put(keyString, valueString);
     }
@@ -570,18 +575,17 @@
     return rightsStatus;
 }
 
-static void android_drm_DrmManagerClient_removeRights(
+static jint android_drm_DrmManagerClient_removeRights(
             JNIEnv* env, jobject thiz, jint uniqueId, jstring path) {
-    LOGV("removeRights Enter");
-    getDrmManagerClientImpl(env, thiz)->removeRights(uniqueId, Utility::getStringValue(env, path));
-    LOGV("removeRights Exit");
+    LOGV("removeRights");
+    return getDrmManagerClientImpl(env, thiz)
+               ->removeRights(uniqueId, Utility::getStringValue(env, path));
 }
 
-static void android_drm_DrmManagerClient_removeAllRights(
+static jint android_drm_DrmManagerClient_removeAllRights(
             JNIEnv* env, jobject thiz, jint uniqueId) {
-    LOGV("removeAllRights Enter");
-    getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
-    LOGV("removeAllRights Exit");
+    LOGV("removeAllRights");
+    return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId);
 }
 
 static jint android_drm_DrmManagerClient_openConvertSession(
@@ -674,10 +678,10 @@
 
 static JNINativeMethod nativeMethods[] = {
 
-    {"_loadPlugIns", "(ILjava/lang/Object;)V",
+    {"_loadPlugIns", "(ILjava/lang/Object;)I",
                                     (void*)android_drm_DrmManagerClient_loadPlugIns},
 
-    {"_unloadPlugIns", "(I)V",
+    {"_unloadPlugIns", "(I)I",
                                     (void*)android_drm_DrmManagerClient_unloadPlugIns},
 
     {"_getConstraints", "(ILjava/lang/String;I)Landroid/content/ContentValues;",
@@ -698,7 +702,7 @@
     {"_acquireDrmInfo", "(ILandroid/drm/DrmInfoRequest;)Landroid/drm/DrmInfo;",
                                     (void*)android_drm_DrmManagerClient_acquireDrmInfo},
 
-    {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)V",
+    {"_saveRights", "(ILandroid/drm/DrmRights;Ljava/lang/String;Ljava/lang/String;)I",
                                     (void*)android_drm_DrmManagerClient_saveRights},
 
     {"_getDrmObjectType", "(ILjava/lang/String;Ljava/lang/String;)I",
@@ -710,10 +714,10 @@
     {"_checkRightsStatus", "(ILjava/lang/String;I)I",
                                     (void*)android_drm_DrmManagerClient_checkRightsStatus},
 
-    {"_removeRights", "(ILjava/lang/String;)V",
+    {"_removeRights", "(ILjava/lang/String;)I",
                                     (void*)android_drm_DrmManagerClient_removeRights},
 
-    {"_removeAllRights", "(I)V",
+    {"_removeAllRights", "(I)I",
                                     (void*)android_drm_DrmManagerClient_removeAllRights},
 
     {"_openConvertSession", "(ILjava/lang/String;)I",
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index 06c7c50..c996994 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -14,10 +14,6 @@
  * 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>
@@ -37,8 +33,8 @@
 }
 
 DrmManagerClient::~DrmManagerClient() {
-    unloadPlugIns();
     DrmManagerClientImpl::remove(mUniqueId);
+    unloadPlugIns();
 
     delete mDrmManagerClientImpl; mDrmManagerClientImpl = NULL;
 }
@@ -72,7 +68,7 @@
     return mDrmManagerClientImpl->acquireDrmInfo(mUniqueId, drmInfoRequest);
 }
 
-void DrmManagerClient::saveRights(
+status_t DrmManagerClient::saveRights(
         const DrmRights& drmRights, const String8& rightsPath, const String8& contentPath) {
     return mDrmManagerClientImpl->saveRights(mUniqueId, drmRights, rightsPath, contentPath);
 }
@@ -89,13 +85,14 @@
     return mDrmManagerClientImpl->checkRightsStatus(mUniqueId, path, action);
 }
 
-void DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
-    mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
+status_t DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+    return mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
 }
 
-void DrmManagerClient::setPlaybackStatus(
+status_t DrmManagerClient::setPlaybackStatus(
             DecryptHandle* decryptHandle, int playbackStatus, int position) {
-    mDrmManagerClientImpl->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
+    return mDrmManagerClientImpl
+            ->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
 }
 
 bool DrmManagerClient::validateAction(
@@ -103,12 +100,12 @@
     return mDrmManagerClientImpl->validateAction(mUniqueId, path, action, description);
 }
 
-void DrmManagerClient::removeRights(const String8& path) {
-    mDrmManagerClientImpl->removeRights(mUniqueId, path);
+status_t DrmManagerClient::removeRights(const String8& path) {
+    return mDrmManagerClientImpl->removeRights(mUniqueId, path);
 }
 
-void DrmManagerClient::removeAllRights() {
-    mDrmManagerClientImpl->removeAllRights(mUniqueId);
+status_t DrmManagerClient::removeAllRights() {
+    return mDrmManagerClientImpl->removeAllRights(mUniqueId);
 }
 
 int DrmManagerClient::openConvertSession(const String8& mimeType) {
@@ -131,25 +128,25 @@
     return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
 }
 
-void DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
-    mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
+status_t DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
+    return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
 }
 
-void DrmManagerClient::initializeDecryptUnit(
+status_t DrmManagerClient::initializeDecryptUnit(
             DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
-    mDrmManagerClientImpl->initializeDecryptUnit(
-        mUniqueId, decryptHandle, decryptUnitId, headerInfo);
+    return mDrmManagerClientImpl->initializeDecryptUnit(
+            mUniqueId, decryptHandle, decryptUnitId, headerInfo);
 }
 
 status_t DrmManagerClient::decrypt(
     DecryptHandle* decryptHandle, int decryptUnitId,
-    const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+    const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     return mDrmManagerClientImpl->decrypt(
-            mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+            mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
-void DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
-    mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
+status_t DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
+    return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmManagerClient::pread(
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index 7274b49..272adcd 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
 #define LOG_TAG "DrmManagerClientImpl(Native)"
 #include <utils/Log.h>
 
@@ -29,44 +29,21 @@
 #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;
-            }
-        }
+        int uniqueId = getDrmManagerService()->addUniqueId(*pUniqueId);
         *pUniqueId = uniqueId;
+    } else {
+        getDrmManagerService()->addUniqueId(*pUniqueId);
     }
-    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;
-        }
-    }
+    getDrmManagerService()->removeUniqueId(uniqueId);
 }
 
 DrmManagerClientImpl::DrmManagerClientImpl() {
@@ -164,11 +141,13 @@
     return drmInfo;
 }
 
-void DrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
+status_t DrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
+    status_t status = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != contentPath) {
-        getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
+        status = getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
     }
+    return status;
 }
 
 String8 DrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path) {
@@ -197,19 +176,23 @@
     return rightsStatus;
 }
 
-void DrmManagerClientImpl::consumeRights(
+status_t DrmManagerClientImpl::consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+    status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle) {
-        getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
+        status = getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
     }
+    return status;
 }
 
-void DrmManagerClientImpl::setPlaybackStatus(
+status_t DrmManagerClientImpl::setPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) {
+    status_t status = DRM_ERROR_UNKNOWN;
     if (NULL != decryptHandle) {
-        getDrmManagerService()->setPlaybackStatus(
+        status = getDrmManagerService()->setPlaybackStatus(
                 uniqueId, decryptHandle, playbackStatus, position);
     }
+    return status;
 }
 
 bool DrmManagerClientImpl::validateAction(
@@ -221,14 +204,16 @@
     return retCode;
 }
 
-void DrmManagerClientImpl::removeRights(int uniqueId, const String8& path) {
+status_t DrmManagerClientImpl::removeRights(int uniqueId, const String8& path) {
+    status_t status = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != path) {
-        getDrmManagerService()->removeRights(uniqueId, path);
+        status = getDrmManagerService()->removeRights(uniqueId, path);
     }
+    return status;
 }
 
-void DrmManagerClientImpl::removeAllRights(int uniqueId) {
-    getDrmManagerService()->removeAllRights(uniqueId);
+status_t DrmManagerClientImpl::removeAllRights(int uniqueId) {
+    return getDrmManagerService()->removeAllRights(uniqueId);
 }
 
 int DrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
@@ -263,40 +248,46 @@
 
 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 DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if ((NULL != decryptHandle) && (NULL != encBuffer)
-        && (NULL != decBuffer) && (NULL != *decBuffer)) {
-        status = getDrmManagerService()->decrypt(
-                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer);
+    if (NULL != decryptHandle) {
+        status = getDrmManagerService()->closeDecryptSession( uniqueId, decryptHandle);
     }
     return status;
 }
 
-void DrmManagerClientImpl::finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
-    if (NULL != decryptHandle) {
-        getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+status_t DrmManagerClientImpl::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if ((NULL != decryptHandle) && (NULL != headerInfo)) {
+        status = getDrmManagerService()->initializeDecryptUnit(
+                uniqueId, decryptHandle, decryptUnitId, headerInfo);
     }
+    return status;
+}
+
+status_t DrmManagerClientImpl::decrypt(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if ((NULL != decryptHandle) && (NULL != encBuffer)
+        && (NULL != decBuffer) && (NULL != *decBuffer)) {
+        status = getDrmManagerService()->decrypt(
+                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
+    }
+    return status;
+}
+
+status_t DrmManagerClientImpl::finalizeDecryptUnit(
+            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+    status_t status = DRM_ERROR_UNKNOWN;
+    if (NULL != decryptHandle) {
+        status
+            = getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    }
+    return status;
 }
 
 ssize_t DrmManagerClientImpl::pread(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index 2ba9e99..dc3e460 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -53,6 +53,9 @@
     virtual ~DrmManager();
 
 public:
+    int addUniqueId(int uniqueId);
+
+    void removeUniqueId(int uniqueId);
 
     status_t loadPlugIns(int uniqueId);
 
@@ -73,7 +76,7 @@
 
     DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
 
-    void saveRights(int uniqueId, const DrmRights& drmRights,
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     String8 getOriginalMimeType(int uniqueId, const String8& path);
@@ -82,17 +85,17 @@
 
     int checkRightsStatus(int uniqueId, const String8& path, int action);
 
-    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
-    void setPlaybackStatus(
+    status_t 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);
+    status_t removeRights(int uniqueId, const String8& path);
 
-    void removeAllRights(int uniqueId);
+    status_t removeAllRights(int uniqueId);
 
     int openConvertSession(int uniqueId, const String8& mimeType);
 
@@ -104,15 +107,15 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
-    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
-    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer,DrmBuffer** decBuffer);
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off_t offset);
@@ -133,6 +136,7 @@
     void initializePlugIns(int uniqueId);
 
 private:
+    static Vector<int> mUniqueIdVector;
     static const String8 EMPTY_STRING;
 
     int mDecryptSessionId;
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index e70e6e1..492c7f5 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -132,8 +132,10 @@
      * @param[in] drmRights DrmRights to be saved
      * @param[in] rightsPath File path where rights to be saved
      * @param[in] contentPath File path where content was saved
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void saveRights(int uniqueId, const DrmRights& drmRights,
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     /**
@@ -179,8 +181,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
      * @param[in] reserve True if the rights should be reserved.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
     /**
      * Informs the DRM engine about the playback actions performed on the DRM files.
@@ -190,8 +194,10 @@
      * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
      * @param[in] position Position in the file (in milliseconds) where the start occurs.
      *     Only valid together with Playback::START.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void setPlaybackStatus(
+    status_t setPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position);
 
     /**
@@ -211,16 +217,20 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] path Path of the protected content
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void removeRights(int uniqueId, const String8& path);
+    status_t 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
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void removeAllRights(int uniqueId);
+    status_t removeAllRights(int uniqueId);
 
     /**
      * This API is for Forward Lock based DRM scheme.
@@ -295,8 +305,10 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -305,8 +317,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
     /**
@@ -319,14 +333,15 @@
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] encBuffer Encrypted data block
      * @param[out] decBuffer Decrypted data block
+     * @param[in] IV Optional buffer
      * @return status_t
      *     Returns the error code for this API
      *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
     /**
      * Finalize decryption for the given unit of the protected content
@@ -334,8 +349,10 @@
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -388,7 +405,6 @@
 
 private:
     static Mutex mMutex;
-    static Vector<int> mUniqueIdVector;
     static sp<IDrmManagerService> mDrmManagerService;
     static const sp<IDrmManagerService>& getDrmManagerService();
     static const String8 EMPTY_STRING;
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index fef121c..f455e15 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -46,6 +46,10 @@
     virtual ~DrmManagerService();
 
 public:
+    int addUniqueId(int uniqueId);
+
+    void removeUniqueId(int uniqueId);
+
     status_t loadPlugIns(int uniqueId);
 
     status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
@@ -65,7 +69,7 @@
 
     DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest);
 
-    void saveRights(int uniqueId, const DrmRights& drmRights,
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     String8 getOriginalMimeType(int uniqueId, const String8& path);
@@ -74,17 +78,17 @@
 
     int checkRightsStatus(int uniqueId, const String8& path,int action);
 
-    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
-    void setPlaybackStatus(
+    status_t 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);
+    status_t removeRights(int uniqueId, const String8& path);
 
-    void removeAllRights(int uniqueId);
+    status_t removeAllRights(int uniqueId);
 
     int openConvertSession(int uniqueId, const String8& mimeType);
 
@@ -96,15 +100,15 @@
 
     DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
-    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
-    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off_t offset);
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index a4d128a..5c668ed 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -44,7 +44,9 @@
 {
 public:
     enum {
-        LOAD_PLUGINS = IBinder::FIRST_CALL_TRANSACTION,
+        ADD_UNIQUEID = IBinder::FIRST_CALL_TRANSACTION,
+        REMOVE_UNIQUEID,
+        LOAD_PLUGINS,
         LOAD_PLUGINS_FROM_PATH,
         SET_DRM_SERVICE_LISTENER,
         UNLOAD_PLUGINS,
@@ -78,6 +80,10 @@
     DECLARE_META_INTERFACE(DrmManagerService);
 
 public:
+    virtual int addUniqueId(int uniqueId) = 0;
+
+    virtual void removeUniqueId(int uniqueId) = 0;
+
     virtual status_t loadPlugIns(int uniqueId) = 0;
 
     virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath) = 0;
@@ -98,7 +104,7 @@
 
     virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest) = 0;
 
-    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+    virtual status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) = 0;
 
     virtual String8 getOriginalMimeType(int uniqueId, const String8& path) = 0;
@@ -108,19 +114,19 @@
 
     virtual int checkRightsStatus(int uniqueId, const String8& path, int action) = 0;
 
-    virtual void consumeRights(
+    virtual status_t consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
 
-    virtual void setPlaybackStatus(
+    virtual status_t 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 status_t removeRights(int uniqueId, const String8& path) = 0;
 
-    virtual void removeAllRights(int uniqueId) = 0;
+    virtual status_t removeAllRights(int uniqueId) = 0;
 
     virtual int openConvertSession(int uniqueId, const String8& mimeType) = 0;
 
@@ -134,15 +140,15 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length) = 0;
 
-    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
 
-    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t 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 status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
-    virtual void finalizeDecryptUnit(
+    virtual status_t finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
 
     virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
@@ -158,6 +164,10 @@
     BpDrmManagerService(const sp<IBinder>& impl)
             : BpInterface<IDrmManagerService>(impl) {}
 
+    virtual int addUniqueId(int uniqueId);
+
+    virtual void removeUniqueId(int uniqueId);
+
     virtual status_t loadPlugIns(int uniqueId);
 
     virtual status_t loadPlugIns(int uniqueId, const String8& plugInDirPath);
@@ -177,7 +187,7 @@
 
     virtual DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest);
 
-    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+    virtual status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     virtual String8 getOriginalMimeType(int uniqueId, const String8& path);
@@ -186,18 +196,18 @@
 
     virtual int checkRightsStatus(int uniqueId, const String8& path, int action);
 
-    virtual void consumeRights(
+    virtual status_t consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
-    virtual void setPlaybackStatus(
+    virtual status_t 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 status_t removeRights(int uniqueId, const String8& path);
 
-    virtual void removeAllRights(int uniqueId);
+    virtual status_t removeAllRights(int uniqueId);
 
     virtual int openConvertSession(int uniqueId, const String8& mimeType);
 
@@ -211,15 +221,15 @@
 
     virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, int offset, int length);
 
-    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
-    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t 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 status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    virtual void finalizeDecryptUnit(
+    virtual status_t finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     virtual ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/drm/libdrmframework/include/ReadWriteUtils.h b/drm/libdrmframework/include/ReadWriteUtils.h
index 022149ee2..529b342 100644
--- a/drm/libdrmframework/include/ReadWriteUtils.h
+++ b/drm/libdrmframework/include/ReadWriteUtils.h
@@ -47,6 +47,14 @@
      */
     static String8 readBytes(const String8& filePath);
     /**
+     * Reads the data into the given buffer from the file path provided
+     *
+     * @param[in] filePath Path of the file
+     * @param[out] buffer Data read from the file
+     * @return Length of the data read from the file
+     */
+    static int readBytes(const String8& filePath, char** buffer);
+    /**
      * Writes the data into the file path provided
      *
      * @param[in] filePath Path of the file
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index 667958a..b355534 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -46,7 +46,7 @@
 
     DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
 
-    void saveRights(int uniqueId, const DrmRights& drmRights,
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
@@ -57,19 +57,19 @@
 
     int checkRightsStatus(int uniqueId, const String8& path, int action);
 
-    void consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
-    void setPlaybackStatus(
+    status_t 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);
+    status_t removeRights(int uniqueId, const String8& path);
 
-    void removeAllRights(int uniqueId);
+    status_t removeAllRights(int uniqueId);
 
-    void openConvertSession(int uniqueId, int convertId);
+    status_t openConvertSession(int uniqueId, int convertId);
 
     DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
 
@@ -80,15 +80,15 @@
     status_t openDecryptSession(
             int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
 
-    void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
-    void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-    void finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off_t offset);
@@ -172,8 +172,10 @@
      * @param[in] drmRights DrmRights to be saved
      * @param[in] rightsPath File path where rights to be saved
      * @param[in] contentPath File path where content was saved
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onSaveRights(int uniqueId, const DrmRights& drmRights,
+    virtual status_t onSaveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightspath, const String8& contentPath) = 0;
 
     /**
@@ -231,8 +233,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
      * @param[in] reserve True if the rights should be reserved.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
             int action, bool reserve) = 0;
 
     /**
@@ -243,8 +247,10 @@
      * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
      * @param[in] position Position in the file (in milliseconds) where the start occurs.
      *     Only valid together with Playback::START.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onSetPlaybackStatus(
+    virtual status_t onSetPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int position) = 0;
 
     /**
@@ -264,16 +270,20 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] path Path of the protected content
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onRemoveRights(int uniqueId, const String8& path) = 0;
+    virtual status_t onRemoveRights(int uniqueId, const String8& path) = 0;
 
     /**
      * Removes all the rights information of each plug-in associated with
      * DRM framework. Will be used in master reset
      *
      * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onRemoveAllRights(int uniqueId) = 0;
+    virtual status_t onRemoveAllRights(int uniqueId) = 0;
 
     /**
      * This API is for Forward Lock based DRM scheme.
@@ -283,8 +293,10 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] convertId Handle for the convert session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onOpenConvertSession(int uniqueId, int convertId) = 0;
+    virtual status_t onOpenConvertSession(int uniqueId, int convertId) = 0;
 
     /**
      * Accepts and converts the input data which is part of DRM file.
@@ -347,8 +359,10 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -357,8 +371,10 @@
      * @param[in] decryptId Handle for the decryption session
      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
      * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
 
     /**
@@ -371,14 +387,15 @@
      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
      * @param[in] encBuffer Encrypted data block
      * @param[out] decBuffer Decrypted data block
+     * @param[in] IV Optional buffer
      * @return status_t
      *     Returns the error code for this API
      *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0;
+    virtual status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
     /**
      * Finalize decryption for the given unit of the protected content
@@ -386,8 +403,10 @@
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID Specifies decryption unit, such as track ID
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void onFinalizeDecryptUnit(
+    virtual status_t onFinalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
 
     /**
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
index 0d52f66..b711500 100644
--- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -143,8 +143,10 @@
      * @param[in] drmRights DrmRights to be saved
      * @param[in] rightsPath File path where rights to be saved
      * @param[in] contentPath File path where content was saved
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void saveRights(int uniqueId, const DrmRights& drmRights,
+    virtual status_t saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) = 0;
 
     /**
@@ -191,8 +193,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
      * @param[in] reserve True if the rights should be reserved.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void consumeRights(
+    virtual status_t consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) = 0;
 
     /**
@@ -203,8 +207,10 @@
      * @param[in] playbackStatus Playback action (Playback::START, Playback::STOP, Playback::PAUSE)
      * @param[in] position Position in the file (in milliseconds) where the start occurs.
      *     Only valid together with Playback::START.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t setPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
             int playbackStatus, int position) = 0;
 
     /**
@@ -224,16 +230,20 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] path Path of the protected content
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void removeRights(int uniqueId, const String8& path) = 0;
+    virtual status_t removeRights(int uniqueId, const String8& path) = 0;
 
     /**
      * Removes all the rights information of each plug-in associated with
      * DRM framework. Will be used in master reset
      *
      * @param[in] uniqueId Unique identifier for a session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void removeAllRights(int uniqueId) = 0;
+    virtual status_t removeAllRights(int uniqueId) = 0;
 
     /**
      * This API is for Forward Lock based DRM scheme.
@@ -243,8 +253,10 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] convertId Handle for the convert session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void openConvertSession(int uniqueId, int convertId) = 0;
+    virtual status_t openConvertSession(int uniqueId, int convertId) = 0;
 
     /**
      * Accepts and converts the input data which is part of DRM file.
@@ -307,8 +319,10 @@
      *
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
+    virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0;
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -317,8 +331,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    virtual status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) = 0;
 
     /**
@@ -331,14 +347,15 @@
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] encBuffer Encrypted data block
      * @param[out] decBuffer Decrypted data block
+     * @param[in] IV Optional buffer
      * @return status_t
      *     Returns the error code for this API
      *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) = 0;
+    virtual status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) = 0;
 
     /**
      * Finalize decryption for the given unit of the protected content
@@ -346,8 +363,10 @@
      * @param[in] uniqueId Unique identifier for a session
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    virtual void finalizeDecryptUnit(
+    virtual status_t finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) = 0;
 
     /**
diff --git a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
index d2c7852..eed1628 100644
--- a/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
+++ b/drm/libdrmframework/plugins/passthru/include/DrmPassthruPlugIn.h
@@ -40,7 +40,7 @@
 
     DrmInfoStatus* onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo);
 
-    void onSaveRights(int uniqueId, const DrmRights& drmRights,
+    status_t onSaveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath);
 
     DrmInfo* onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
@@ -51,19 +51,19 @@
 
     int onCheckRightsStatus(int uniqueId, const String8& path, int action);
 
-    void onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t onConsumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
 
-    void onSetPlaybackStatus(
+    status_t 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);
+    status_t onRemoveRights(int uniqueId, const String8& path);
 
-    void onRemoveAllRights(int uniqueId);
+    status_t onRemoveAllRights(int uniqueId);
 
-    void onOpenConvertSession(int uniqueId, int convertId);
+    status_t onOpenConvertSession(int uniqueId, int convertId);
 
     DrmConvertedStatus* onConvertData(int uniqueId, int convertId, const DrmBuffer* inputData);
 
@@ -74,15 +74,15 @@
     status_t onOpenDecryptSession(
             int uniqueId, DecryptHandle* decryptHandle, int fd, int offset, int length);
 
-    void onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
 
-     void onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
-     status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+    status_t onDecrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
-     void onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t onFinalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
 
     ssize_t onPread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off_t offset);
diff --git a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
index 2655d0b..4c7714d 100644
--- a/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
+++ b/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp
@@ -129,9 +129,10 @@
     return drmSupportInfo;
 }
 
-void DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& drmRights,
+status_t DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     LOGD("DrmPassthruPlugIn::onSaveRights : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
 DrmInfo* DrmPassthruPlugIn::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
@@ -174,14 +175,16 @@
     return rightsStatus;
 }
 
-void DrmPassthruPlugIn::onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmPassthruPlugIn::onConsumeRights(int uniqueId, DecryptHandle* decryptHandle,
             int action, bool reserve) {
     LOGD("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
-void DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId, DecryptHandle* decryptHandle,
             int playbackStatus, int position) {
     LOGD("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
 bool DrmPassthruPlugIn::onValidateAction(int uniqueId, const String8& path,
@@ -190,16 +193,19 @@
     return true;
 }
 
-void DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) {
+status_t DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& path) {
     LOGD("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
-void DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) {
+status_t DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) {
     LOGD("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
-void DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) {
+status_t DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int convertId) {
     LOGD("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
 DrmConvertedStatus* DrmPassthruPlugIn::onConvertData(
@@ -237,7 +243,7 @@
     return DRM_ERROR_CANNOT_HANDLE;
 }
 
-void DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     LOGD("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
     if (NULL != decryptHandle) {
         if (NULL != decryptHandle->decryptInfo) {
@@ -245,15 +251,17 @@
         }
         delete decryptHandle; decryptHandle = NULL;
     }
+    return DRM_NO_ERROR;
 }
 
-void DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     LOGD("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
 status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer) {
+            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     LOGD("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
     /**
      * As a workaround implementation passthru would copy the given
@@ -267,9 +275,10 @@
     return DRM_NO_ERROR;
 }
 
-void DrmPassthruPlugIn::onFinalizeDecryptUnit(
+status_t DrmPassthruPlugIn::onFinalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
     LOGD("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
+    return DRM_NO_ERROR;
 }
 
 ssize_t DrmPassthruPlugIn::onPread(int uniqueId, DecryptHandle* decryptHandle,
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index 5e8817c..c722bd3 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -27,28 +27,40 @@
  */
 class DrmInfoEvent {
 public:
+    /**
+     * The following constant values should be in sync with DrmInfoEvent.java
+     */
     //! 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;
+    static const int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 1;
     //! TYPE_REMOVE_RIGHTS, when the rights needs to be removed completely.
-    static const int TYPE_REMOVE_RIGHTS = 0x0000002;
+    static const int TYPE_REMOVE_RIGHTS = 2;
     //! 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;
+    static const int TYPE_RIGHTS_INSTALLED = 3;
     //! 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;
+    static const int TYPE_WAIT_FOR_RIGHTS = 4;
+    //! TYPE_ACCOUNT_ALREADY_REGISTERED, when registration has been
+    //! already done for the given account.
+    static const int TYPE_ACCOUNT_ALREADY_REGISTERED = 5;
+
+    /**
+     * The following constant values should be in sync with DrmErrorEvent.java
+     */
+    //! TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights
+    static const int TYPE_RIGHTS_NOT_INSTALLED = 2001;
+    //! TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights
+    static const int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 2002;
+    //! TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent
+    static const int TYPE_NOT_SUPPORTED = 2003;
     //! 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;
+    static const int TYPE_OUT_OF_MEMORY = 2004;
     //! 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;
+    static const int TYPE_NO_INTERNET_CONNECTION = 2005;
+    //! TYPE_REGISTRATION_FAILED, when registration with server failed.
+    static const int TYPE_REGISTRATION_FAILED = 2006;
 
 public:
     /**
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index 7d14c44..c2ad084 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -70,8 +70,10 @@
      * Close the decrypt session for the given handle
      *
      * @param[in] decryptHandle Handle for the decryption session
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void closeDecryptSession(DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(DecryptHandle* decryptHandle);
 
     /**
      * Consumes the rights for a content.
@@ -81,8 +83,11 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] action Action to perform. (Action::DEFAULT, Action::PLAY, etc)
      * @param[in] reserve True if the rights should be reserved.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure.
+     *     In case license has been expired, DRM_ERROR_LICENSE_EXPIRED will be returned.
      */
-    void consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
 
     /**
      * Informs the DRM engine about the playback actions performed on the DRM files.
@@ -90,9 +95,11 @@
      * @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.
+     *                     Only valid together with Playback::START.
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int position);
+    status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int position);
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -100,8 +107,10 @@
      * @param[in] decryptHandle Handle for the decryption session
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] headerInfo Information for initializing decryption of this decrypUnit
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void initializeDecryptUnit(
+    status_t initializeDecryptUnit(
             DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
 
     /**
@@ -113,6 +122,7 @@
      * @param[in] decryptUnitId ID which specifies decryption unit, such as track ID
      * @param[in] encBuffer Encrypted data block
      * @param[out] decBuffer Decrypted data block
+     * @param[in] IV Optional buffer
      * @return status_t
      *     Returns the error code for this API
      *     DRM_NO_ERROR for success, and one of DRM_ERROR_UNKNOWN, DRM_ERROR_LICENSE_EXPIRED
@@ -121,15 +131,17 @@
      */
     status_t decrypt(
             DecryptHandle* decryptHandle, int decryptUnitId,
-            const DrmBuffer* encBuffer, DrmBuffer** decBuffer);
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV = NULL);
 
     /**
      * 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
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -217,8 +229,10 @@
      * @param[in] drmRights DrmRights to be saved
      * @param[in] rightsPath File path where rights to be saved
      * @param[in] contentPath File path where content was saved
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void saveRights(
+    status_t saveRights(
         const DrmRights& drmRights, const String8& rightsPath, const String8& contentPath);
 
     /**
@@ -256,15 +270,19 @@
      * Removes the rights associated with the given protected content
      *
      * @param[in] path Path of the protected content
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void removeRights(const String8& path);
+    status_t removeRights(const String8& path);
 
     /**
      * Removes all the rights information of each plug-in associated with
      * DRM framework. Will be used in master reset
      *
+     * @return status_t
+     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    void removeAllRights();
+    status_t removeAllRights();
 
     /**
      * This API is for Forward Lock DRM.
diff --git a/include/drm/DrmRights.h b/include/drm/DrmRights.h
index e04a066..11f8f78 100644
--- a/include/drm/DrmRights.h
+++ b/include/drm/DrmRights.h
@@ -61,7 +61,7 @@
     /**
      * Destructor for DrmRights
      */
-    virtual ~DrmRights() {}
+    virtual ~DrmRights();
 
 public:
     /**
@@ -97,6 +97,7 @@
     String8 mMimeType;
     String8 mAccountId;
     String8 mSubscriptionId;
+    char* mRightsFromFile;
 };
 
 };
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 8b8a9f5..c5765a9 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -254,13 +254,13 @@
      *      (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
+     *         DecryptApiType::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
+     *         DecryptApiType::CONTAINER_BASED
      *             POSIX based Decryption API set for container based DRM
      *                 pread()
      */
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 804af9c..f5a8119 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9252,6 +9252,9 @@
             sb.append("Subject: ").append(subject).append("\n");
         }
         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+        if (Debug.isDebuggerConnected()) {
+            sb.append("Debugger: Connected\n");
+        }
         sb.append("\n");
 
         // Do the rest in a worker thread to avoid blocking the caller on I/O
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index 8e7cadc..397a84a 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -67,6 +67,7 @@
     jint healthDead;
     jint healthOverVoltage;
     jint healthUnspecifiedFailure;
+    jint healthCold;
 };
 static BatteryManagerConstants gConstants;
 
@@ -104,6 +105,7 @@
 static jint getBatteryHealth(const char* status)
 {
     switch (status[0]) {
+        case 'C': return gConstants.healthCold;         // Cold
         case 'D': return gConstants.healthDead;         // Dead
         case 'G': return gConstants.healthGood;         // Good
         case 'O': {
@@ -390,6 +392,9 @@
     gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz, 
             env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
     
+    gConstants.healthCold = env->GetStaticIntField(clazz,
+            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
+
     return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
 }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
old mode 100644
new mode 100755
index 2cad6cc..d2a4bd8
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -552,32 +552,53 @@
     }
 
     @Override
-    protected void powerOffRadioSafely(){
-        // clean data connection
+    protected void powerOffRadioSafely() {
         DataConnectionTracker dcTracker = phone.mDataConnection;
 
         Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
-        msg.arg1 = 1; // tearDown is true
         msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
-        dcTracker.sendMessage(msg);
 
-        synchronized(this) {
-            if (!mPendingRadioPowerOffAfterDataOff) {
-                DataConnectionTracker.State currentState = dcTracker.getState();
-                if (currentState != DataConnectionTracker.State.CONNECTED
-                        && currentState != DataConnectionTracker.State.DISCONNECTING
-                        && currentState != DataConnectionTracker.State.INITING) {
-                    if (DBG) log("Data disconnected, turn off radio right away.");
-                    hangupAndPowerOff();
-                }
-                else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
-                    if (DBG) {
-                        log("Wait up to 30 sec for data to disconnect, then turn off radio.");
+        synchronized (this) {
+            if (networkType == ServiceState.RADIO_TECHNOLOGY_1xRTT) {
+                /*
+                 * In 1x CDMA , during radio power off modem will disconnect the
+                 * data call and sends the power down registration message along
+                 * with the data call release message to the network
+                 */
+
+                msg.arg1 = 0; // tearDown is false since modem does it anyway for 1X
+                dcTracker.sendMessage(msg);
+
+                Log.w(LOG_TAG, "Turn off the radio right away");
+                hangupAndPowerOff();
+            } else {
+                if (!mPendingRadioPowerOffAfterDataOff) {
+                    DataConnectionTracker.State currentState = dcTracker.getState();
+                    if (currentState != DataConnectionTracker.State.CONNECTED
+                            && currentState != DataConnectionTracker.State.DISCONNECTING
+                            && currentState != DataConnectionTracker.State.INITING) {
+
+                        msg.arg1 = 0; // tearDown is false as it is not needed.
+                        dcTracker.sendMessage(msg);
+
+                        if (DBG)
+                            log("Data disconnected, turn off radio right away.");
+                        hangupAndPowerOff();
+                    } else {
+                        // clean data connection
+                        msg.arg1 = 1; // tearDown is true
+                        dcTracker.sendMessage(msg);
+
+                        if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
+                            if (DBG) {
+                                log("Wait upto 30s for data to disconnect, then turn off radio.");
+                            }
+                            mPendingRadioPowerOffAfterDataOff = true;
+                        } else {
+                            Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
+                            hangupAndPowerOff();
+                        }
                     }
-                    mPendingRadioPowerOffAfterDataOff = true;
-                } else {
-                    Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
-                    hangupAndPowerOff();
                 }
             }
         }
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
old mode 100755
new mode 100644
index b50502c..f869dbd
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -29,6 +29,7 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.cdma.sms.BearerData;
 import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
+import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.util.HexDump;
@@ -138,6 +139,7 @@
         SmsMessage msg = new SmsMessage();
         SmsEnvelope env = new SmsEnvelope();
         CdmaSmsAddress addr = new CdmaSmsAddress();
+        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
         byte[] data;
         byte count;
         int countInt;
@@ -180,15 +182,24 @@
 
         addr.origBytes = data;
 
-        // ignore subaddress
-        p.readInt(); //p_cur->sSubAddress.subaddressType
-        p.readInt(); //p_cur->sSubAddress.odd
-        count = p.readByte(); //p_cur->sSubAddress.number_of_digits
-        //p_cur->sSubAddress.digits[digitCount] :
-        for (int index=0; index < count; index++) {
-            p.readByte();
+        subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType
+        subaddr.odd = p.readByte();     // p_cur->sSubAddress.odd
+        count = p.readByte();           // p_cur->sSubAddress.number_of_digits
+
+        if (count < 0) {
+            count = 0;
         }
 
+        // p_cur->sSubAddress.digits[digitCount] :
+
+        data = new byte[count];
+
+        for (int index = 0; index < count; ++index) {
+            data[index] = p.readByte();
+        }
+
+        subaddr.origBytes = data;
+
         /* currently not supported by the modem-lib:
             env.bearerReply
             env.replySeqNo
@@ -210,6 +221,7 @@
 
         // link the the filled objects to the SMS
         env.origAddress = addr;
+        env.origSubaddress = subaddr;
         msg.originatingAddress = addr;
         msg.mEnvelope = env;
 
@@ -818,6 +830,8 @@
         output.write(mEnvelope.teleService);
         output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length);
         output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length);
+        output.write(mEnvelope.origSubaddress.origBytes, 0,
+                mEnvelope.origSubaddress.origBytes.length);
 
         return output.toByteArray();
     }
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
new file mode 100644
index 0000000..f9cebf5
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project. All rights reserved.
+ * Copyright (C) 2010 Code Aurora Forum. All rights reserved.
+ *
+ * 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.
+ */
+
+package com.android.internal.telephony.cdma.sms;
+
+public class CdmaSmsSubaddress {
+    public int type;
+
+    public byte odd;
+
+    public byte[] origBytes;
+}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
index 0dcacc1..4f00163 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -17,6 +17,8 @@
 package com.android.internal.telephony.cdma.sms;
 
 
+import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
+
 public final class SmsEnvelope{
     /**
      * Message Types
@@ -74,17 +76,23 @@
 
     /**
      * The origination address identifies the originator of the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
      */
     public CdmaSmsAddress origAddress;
 
     /**
      * The destination address identifies the target of the SMS message.
-     * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+     * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
      */
     public CdmaSmsAddress destAddress;
 
     /**
+     * The origination subaddress identifies the originator of the SMS message.
+     * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+     */
+    public CdmaSmsSubaddress origSubaddress;
+
+    /**
      * The 6-bit bearer reply parameter is used to request the return of a
      * SMS Acknowledge Message.
      * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 6665632..49de5f9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -1227,7 +1227,8 @@
                 // Check if this is a different SIM than the previous one. If so unset the
                 // voice mail number.
                 String imsi = getVmSimImsi();
-                if (imsi != null && !getSubscriberId().equals(imsi)) {
+                String imsiFromSIM = getSubscriberId();
+                if (imsi != null && imsiFromSIM != null && !imsiFromSIM.equals(imsi)) {
                     storeVoiceMailNumber(null);
                     setVmSimImsi(null);
                 }