am 1ef63d1a: am a56e1506: Merge "MediaDrm API update" into jb-mr2-dev

* commit '1ef63d1a6a03d713954acbdb4e4641f53ade1d66':
  MediaDrm API update
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
index 91f5c9c..c34690b 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
@@ -21,6 +21,7 @@
 
 #include "drm/DrmAPI.h"
 #include "MockDrmCryptoPlugin.h"
+#include "media/stagefright/MediaErrors.h"
 
 using namespace android;
 
@@ -98,17 +99,17 @@
     }
 
 
-    status_t MockDrmPlugin::getLicenseRequest(Vector<uint8_t> const &sessionId,
-                                              Vector<uint8_t> const &initData,
-                                              String8 const &mimeType, LicenseType licenseType,
-                                              KeyedVector<String8, String8> const &optionalParameters,
-                                              Vector<uint8_t> &request, String8 &defaultUrl)
+    status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId,
+                                          Vector<uint8_t> const &initData,
+                                          String8 const &mimeType, KeyType keyType,
+                                          KeyedVector<String8, String8> const &optionalParameters,
+                                          Vector<uint8_t> &request, String8 &defaultUrl)
     {
         Mutex::Autolock lock(mLock);
-        ALOGD("MockDrmPlugin::getLicenseRequest(sessionId=%s, initData=%s, mimeType=%s"
-              ", licenseType=%d, optionalParameters=%s))",
+        ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s"
+              ", keyType=%d, optionalParameters=%s))",
               vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(),
-              licenseType, stringMapToString(optionalParameters).string());
+              keyType, stringMapToString(optionalParameters).string());
 
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -119,15 +120,15 @@
         // Properties used in mock test, set by mock plugin and verifed cts test app
         //   byte[] initData           -> mock-initdata
         //   string mimeType           -> mock-mimetype
-        //   string licenseType        -> mock-licensetype
+        //   string keyType            -> mock-keytype
         //   string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2}
 
         mByteArrayProperties.add(String8("mock-initdata"), initData);
         mStringProperties.add(String8("mock-mimetype"), mimeType);
 
-        String8 licenseTypeStr;
-        licenseTypeStr.appendFormat("%d", (int)licenseType);
-        mStringProperties.add(String8("mock-licensetype"), licenseTypeStr);
+        String8 keyTypeStr;
+        keyTypeStr.appendFormat("%d", (int)keyType);
+        mStringProperties.add(String8("mock-keytype"), keyTypeStr);
 
         String8 params;
         for (size_t i = 0; i < optionalParameters.size(); i++) {
@@ -159,11 +160,12 @@
         return OK;
     }
 
-    status_t MockDrmPlugin::provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                                   Vector<uint8_t> const &response)
+    status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                               Vector<uint8_t> const &response,
+                                               Vector<uint8_t> &keySetId)
     {
         Mutex::Autolock lock(mLock);
-        ALOGD("MockDrmPlugin::provideLicenseResponse(sessionId=%s, response=%s)",
+        ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)",
               vectorToString(sessionId).string(), vectorToString(response).string());
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
@@ -176,30 +178,61 @@
 
         // Properties used in mock test, set by mock plugin and verifed cts test app
         //   byte[] response            -> mock-response
-
         mByteArrayProperties.add(String8("mock-response"), response);
 
+        const size_t kKeySetIdSize = 8;
+
+        for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) {
+            long r = random();
+            keySetId.appendArray((uint8_t *)&r, sizeof(long));
+        }
+        mKeySets.add(keySetId);
+
         return OK;
     }
 
-    status_t MockDrmPlugin::removeLicense(Vector<uint8_t> const &sessionId)
+    status_t MockDrmPlugin::removeKeys(Vector<uint8_t> const &keySetId)
     {
         Mutex::Autolock lock(mLock);
-        ALOGD("MockDrmPlugin::removeLicense(sessionId=%s)",
-              vectorToString(sessionId).string());
+        ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)",
+              vectorToString(keySetId).string());
+
+        ssize_t index = findKeySet(keySetId);
+        if (index == kNotFound) {
+            ALOGD("Invalid keySetId");
+            return BAD_VALUE;
+        }
+        mKeySets.removeAt(index);
+
+        return OK;
+    }
+
+    status_t MockDrmPlugin::restoreKeys(Vector<uint8_t> const &sessionId,
+                                        Vector<uint8_t> const &keySetId)
+    {
+        Mutex::Autolock lock(mLock);
+        ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)",
+              vectorToString(sessionId).string(),
+              vectorToString(keySetId).string());
         ssize_t index = findSession(sessionId);
         if (index == kNotFound) {
             ALOGD("Invalid sessionId");
             return BAD_VALUE;
         }
 
+        index = findKeySet(keySetId);
+        if (index == kNotFound) {
+            ALOGD("Invalid keySetId");
+            return BAD_VALUE;
+        }
+
         return OK;
     }
 
-    status_t MockDrmPlugin::queryLicenseStatus(Vector<uint8_t> const &sessionId,
+    status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId,
                                                KeyedVector<String8, String8> &infoMap) const
     {
-        ALOGD("MockDrmPlugin::queryLicenseStatus(sessionId=%s)",
+        ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)",
               vectorToString(sessionId).string());
 
         ssize_t index = findSession(sessionId);
@@ -324,6 +357,198 @@
         return OK;
     }
 
+    status_t MockDrmPlugin::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                               String8 const &algorithm)
+    {
+        Mutex::Autolock lock(mLock);
+
+        ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)",
+              vectorToString(sessionId).string(), algorithm.string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        if (algorithm == "AES/CBC/NoPadding") {
+            return OK;
+        }
+        return BAD_VALUE;
+    }
+
+    status_t MockDrmPlugin::setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                                            String8 const &algorithm)
+    {
+        Mutex::Autolock lock(mLock);
+
+        ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)",
+              vectorToString(sessionId).string(), algorithm.string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        if (algorithm == "HmacSHA256") {
+            return OK;
+        }
+        return BAD_VALUE;
+    }
+
+    status_t MockDrmPlugin::encrypt(Vector<uint8_t> const &sessionId,
+                                    Vector<uint8_t> const &keyId,
+                                    Vector<uint8_t> const &input,
+                                    Vector<uint8_t> const &iv,
+                                    Vector<uint8_t> &output)
+    {
+        Mutex::Autolock lock(mLock);
+        ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
+              vectorToString(sessionId).string(),
+              vectorToString(keyId).string(),
+              vectorToString(input).string(),
+              vectorToString(iv).string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        // Properties used in mock test, set by mock plugin and verifed cts test app
+        //   byte[] keyId              -> mock-keyid
+        //   byte[] input              -> mock-input
+        //   byte[] iv                 -> mock-iv
+        mByteArrayProperties.add(String8("mock-keyid"), keyId);
+        mByteArrayProperties.add(String8("mock-input"), input);
+        mByteArrayProperties.add(String8("mock-iv"), iv);
+
+        // Properties used in mock test, set by cts test app returned from mock plugin
+        //   byte[] mock-output        -> output
+        index = mByteArrayProperties.indexOfKey(String8("mock-output"));
+        if (index < 0) {
+            ALOGD("Missing 'mock-request' parameter for mock");
+            return BAD_VALUE;
+        } else {
+            output = mByteArrayProperties.valueAt(index);
+        }
+        return OK;
+    }
+
+    status_t MockDrmPlugin::decrypt(Vector<uint8_t> const &sessionId,
+                                    Vector<uint8_t> const &keyId,
+                                    Vector<uint8_t> const &input,
+                                    Vector<uint8_t> const &iv,
+                                    Vector<uint8_t> &output)
+    {
+        Mutex::Autolock lock(mLock);
+        ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)",
+              vectorToString(sessionId).string(),
+              vectorToString(keyId).string(),
+              vectorToString(input).string(),
+              vectorToString(iv).string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        // Properties used in mock test, set by mock plugin and verifed cts test app
+        //   byte[] keyId              -> mock-keyid
+        //   byte[] input              -> mock-input
+        //   byte[] iv                 -> mock-iv
+        mByteArrayProperties.add(String8("mock-keyid"), keyId);
+        mByteArrayProperties.add(String8("mock-input"), input);
+        mByteArrayProperties.add(String8("mock-iv"), iv);
+
+        // Properties used in mock test, set by cts test app returned from mock plugin
+        //   byte[] mock-output        -> output
+        index = mByteArrayProperties.indexOfKey(String8("mock-output"));
+        if (index < 0) {
+            ALOGD("Missing 'mock-request' parameter for mock");
+            return BAD_VALUE;
+        } else {
+            output = mByteArrayProperties.valueAt(index);
+        }
+        return OK;
+    }
+
+    status_t MockDrmPlugin::sign(Vector<uint8_t> const &sessionId,
+                                 Vector<uint8_t> const &keyId,
+                                 Vector<uint8_t> const &message,
+                                 Vector<uint8_t> &signature)
+    {
+        Mutex::Autolock lock(mLock);
+        ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)",
+              vectorToString(sessionId).string(),
+              vectorToString(keyId).string(),
+              vectorToString(message).string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        // Properties used in mock test, set by mock plugin and verifed cts test app
+        //   byte[] keyId              -> mock-keyid
+        //   byte[] message            -> mock-message
+        mByteArrayProperties.add(String8("mock-keyid"), keyId);
+        mByteArrayProperties.add(String8("mock-message"), message);
+
+        // Properties used in mock test, set by cts test app returned from mock plugin
+        //   byte[] mock-signature        -> signature
+        index = mByteArrayProperties.indexOfKey(String8("mock-signature"));
+        if (index < 0) {
+            ALOGD("Missing 'mock-request' parameter for mock");
+            return BAD_VALUE;
+        } else {
+            signature = mByteArrayProperties.valueAt(index);
+        }
+        return OK;
+    }
+
+    status_t MockDrmPlugin::verify(Vector<uint8_t> const &sessionId,
+                                   Vector<uint8_t> const &keyId,
+                                   Vector<uint8_t> const &message,
+                                   Vector<uint8_t> const &signature,
+                                   bool &match)
+    {
+        Mutex::Autolock lock(mLock);
+        ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)",
+              vectorToString(sessionId).string(),
+              vectorToString(keyId).string(),
+              vectorToString(message).string(),
+              vectorToString(signature).string());
+
+        ssize_t index = findSession(sessionId);
+        if (index == kNotFound) {
+            ALOGD("Invalid sessionId");
+            return BAD_VALUE;
+        }
+
+        // Properties used in mock test, set by mock plugin and verifed cts test app
+        //   byte[] keyId              -> mock-keyid
+        //   byte[] message            -> mock-message
+        //   byte[] signature          -> mock-signature
+        mByteArrayProperties.add(String8("mock-keyid"), keyId);
+        mByteArrayProperties.add(String8("mock-message"), message);
+        mByteArrayProperties.add(String8("mock-signature"), signature);
+
+        // Properties used in mock test, set by cts test app returned from mock plugin
+        //   String mock-match "1" or "0"         -> match
+        index = mStringProperties.indexOfKey(String8("mock-match"));
+        if (index < 0) {
+            ALOGD("Missing 'mock-request' parameter for mock");
+            return BAD_VALUE;
+        } else {
+            match = atol(mStringProperties.valueAt(index).string());
+        }
+        return OK;
+    }
+
     ssize_t MockDrmPlugin::findSession(Vector<uint8_t> const &sessionId) const
     {
         ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size());
@@ -335,6 +560,18 @@
         return kNotFound;
     }
 
+    ssize_t MockDrmPlugin::findKeySet(Vector<uint8_t> const &keySetId) const
+    {
+        ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size());
+        for (size_t i = 0; i < mKeySets.size(); ++i) {
+            if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) {
+                return i;
+            }
+        }
+        return kNotFound;
+    }
+
+
     // Conversion utilities
     String8 MockDrmPlugin::vectorToString(Vector<uint8_t> const &vector) const
     {
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
index d46a127..ca9eac7 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
@@ -57,21 +57,23 @@
         status_t openSession(Vector<uint8_t> &sessionId);
         status_t closeSession(Vector<uint8_t> const &sessionId);
 
-        status_t
-            getLicenseRequest(Vector<uint8_t> const &sessionId,
-                              Vector<uint8_t> const &initData,
-                              String8 const &mimeType, LicenseType licenseType,
-                              KeyedVector<String8, String8> const &optionalParameters,
-                              Vector<uint8_t> &request, String8 &defaultUrl);
+        status_t getKeyRequest(Vector<uint8_t> const &sessionId,
+                               Vector<uint8_t> const &initData,
+                               String8 const &mimeType, KeyType keyType,
+                               KeyedVector<String8, String8> const &optionalParameters,
+                               Vector<uint8_t> &request, String8 &defaultUrl);
 
-        status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                                Vector<uint8_t> const &response);
+        status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                    Vector<uint8_t> const &response,
+                                    Vector<uint8_t> &keySetId);
 
-        status_t removeLicense(Vector<uint8_t> const &sessionId);
+        status_t removeKeys(Vector<uint8_t> const &keySetId);
 
-        status_t
-            queryLicenseStatus(Vector<uint8_t> const &sessionId,
-                               KeyedVector<String8, String8> &infoMap) const;
+        status_t restoreKeys(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keySetId);
+
+        status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+                                KeyedVector<String8, String8> &infoMap) const;
 
         status_t getProvisionRequest(Vector<uint8_t> &request,
                                              String8 &defaultUrl);
@@ -90,15 +92,46 @@
         status_t setPropertyByteArray(String8 const &name,
                                       Vector<uint8_t> const &value );
 
+        status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                    String8 const &algorithm);
+
+        status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                                 String8 const &algorithm);
+
+        status_t encrypt(Vector<uint8_t> const &sessionId,
+                         Vector<uint8_t> const &keyId,
+                         Vector<uint8_t> const &input,
+                         Vector<uint8_t> const &iv,
+                         Vector<uint8_t> &output);
+
+        status_t decrypt(Vector<uint8_t> const &sessionId,
+                         Vector<uint8_t> const &keyId,
+                         Vector<uint8_t> const &input,
+                         Vector<uint8_t> const &iv,
+                         Vector<uint8_t> &output);
+
+        status_t sign(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &keyId,
+                      Vector<uint8_t> const &message,
+                      Vector<uint8_t> &signature);
+
+        status_t verify(Vector<uint8_t> const &sessionId,
+                        Vector<uint8_t> const &keyId,
+                        Vector<uint8_t> const &message,
+                        Vector<uint8_t> const &signature,
+                        bool &match);
+
     private:
         String8 vectorToString(Vector<uint8_t> const &vector) const;
         String8 arrayToString(uint8_t const *array, size_t len) const;
         String8 stringMapToString(KeyedVector<String8, String8> map) const;
 
         SortedVector<Vector<uint8_t> > mSessions;
+        SortedVector<Vector<uint8_t> > mKeySets;
 
         static const ssize_t kNotFound = -1;
         ssize_t findSession(Vector<uint8_t> const &sessionId) const;
+        ssize_t findKeySet(Vector<uint8_t> const &keySetId) const;
 
         Mutex mLock;
         KeyedVector<String8, String8> mStringProperties;
diff --git a/include/media/IDrm.h b/include/media/IDrm.h
index 38e2378..15d0a75 100644
--- a/include/media/IDrm.h
+++ b/include/media/IDrm.h
@@ -42,19 +42,23 @@
     virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
 
     virtual status_t
-        getLicenseRequest(Vector<uint8_t> const &sessionId,
-                          Vector<uint8_t> const &initData,
-                          String8 const &mimeType, DrmPlugin::LicenseType licenseType,
-                          KeyedVector<String8, String8> const &optionalParameters,
-                          Vector<uint8_t> &request, String8 &defaultUrl) = 0;
+        getKeyRequest(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &initData,
+                      String8 const &mimeType, DrmPlugin::KeyType keyType,
+                      KeyedVector<String8, String8> const &optionalParameters,
+                      Vector<uint8_t> &request, String8 &defaultUrl) = 0;
 
-    virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                            Vector<uint8_t> const &response) = 0;
+    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                        Vector<uint8_t> const &response,
+                                        Vector<uint8_t> &keySetId) = 0;
 
-    virtual status_t removeLicense(Vector<uint8_t> const &sessionId) = 0;
+    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) = 0;
 
-    virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
-                                        KeyedVector<String8, String8> &infoMap) const = 0;
+    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+                                 Vector<uint8_t> const &keySetId) = 0;
+
+    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+                                    KeyedVector<String8, String8> &infoMap) const = 0;
 
     virtual status_t getProvisionRequest(Vector<uint8_t> &request,
                                          String8 &defaulUrl) = 0;
@@ -65,13 +69,42 @@
 
     virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
 
-    virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0;
+    virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
     virtual status_t getPropertyByteArray(String8 const &name,
-                                          Vector<uint8_t> &value ) const = 0;
+                                          Vector<uint8_t> &value) const = 0;
     virtual status_t setPropertyString(String8 const &name,
                                        String8 const &value ) const = 0;
     virtual status_t setPropertyByteArray(String8 const &name,
-                                          Vector<uint8_t> const &value ) const = 0;
+                                          Vector<uint8_t> const &value) const = 0;
+
+    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                        String8 const &algorithm) = 0;
+
+    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                                     String8 const &algorithm) = 0;
+
+    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output) = 0;
+
+    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output) = 0;
+
+    virtual status_t sign(Vector<uint8_t> const &sessionId,
+                          Vector<uint8_t> const &keyId,
+                          Vector<uint8_t> const &message,
+                          Vector<uint8_t> &signature) = 0;
+
+    virtual status_t verify(Vector<uint8_t> const &sessionId,
+                            Vector<uint8_t> const &keyId,
+                            Vector<uint8_t> const &message,
+                            Vector<uint8_t> const &signature,
+                            bool &match) = 0;
 
 private:
     DISALLOW_EVIL_CONSTRUCTORS(IDrm);
@@ -81,6 +114,9 @@
     virtual status_t onTransact(
             uint32_t code, const Parcel &data, Parcel *reply,
             uint32_t flags = 0);
+private:
+    void readVector(const Parcel &data, Vector<uint8_t> &vector) const;
+    void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;
 };
 
 }  // namespace android
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 3b13ec6..1641b56 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -33,10 +33,11 @@
     DESTROY_PLUGIN,
     OPEN_SESSION,
     CLOSE_SESSION,
-    GET_LICENSE_REQUEST,
-    PROVIDE_LICENSE_RESPONSE,
-    REMOVE_LICENSE,
-    QUERY_LICENSE_STATUS,
+    GET_KEY_REQUEST,
+    PROVIDE_KEY_RESPONSE,
+    REMOVE_KEYS,
+    RESTORE_KEYS,
+    QUERY_KEY_STATUS,
     GET_PROVISION_REQUEST,
     PROVIDE_PROVISION_RESPONSE,
     GET_SECURE_STOPS,
@@ -44,7 +45,13 @@
     GET_PROPERTY_STRING,
     GET_PROPERTY_BYTE_ARRAY,
     SET_PROPERTY_STRING,
-    SET_PROPERTY_BYTE_ARRAY
+    SET_PROPERTY_BYTE_ARRAY,
+    SET_CIPHER_ALGORITHM,
+    SET_MAC_ALGORITHM,
+    ENCRYPT,
+    DECRYPT,
+    SIGN,
+    VERIFY
 };
 
 struct BpDrm : public BpInterface<IDrm> {
@@ -92,9 +99,7 @@
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
         remote()->transact(OPEN_SESSION, data, &reply);
-        uint32_t size = reply.readInt32();
-        sessionId.insertAt((size_t)0, size);
-        reply.read(sessionId.editArray(), size);
+        readVector(reply, sessionId);
 
         return reply.readInt32();
     }
@@ -103,80 +108,81 @@
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(sessionId.size());
-        data.write(sessionId.array(), sessionId.size());
+        writeVector(data, sessionId);
         remote()->transact(CLOSE_SESSION, data, &reply);
 
         return reply.readInt32();
     }
 
     virtual status_t
-        getLicenseRequest(Vector<uint8_t> const &sessionId,
-                          Vector<uint8_t> const &initData,
-                          String8 const &mimeType, DrmPlugin::LicenseType licenseType,
-                          KeyedVector<String8, String8> const &optionalParameters,
-                          Vector<uint8_t> &request, String8 &defaultUrl) {
+        getKeyRequest(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &initData,
+                      String8 const &mimeType, DrmPlugin::KeyType keyType,
+                      KeyedVector<String8, String8> const &optionalParameters,
+                      Vector<uint8_t> &request, String8 &defaultUrl) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(sessionId.size());
-        data.write(sessionId.array(), sessionId.size());
-
-        data.writeInt32(initData.size());
-        data.write(initData.array(), initData.size());
-
+        writeVector(data, sessionId);
+        writeVector(data, initData);
         data.writeString8(mimeType);
-        data.writeInt32((uint32_t)licenseType);
+        data.writeInt32((uint32_t)keyType);
 
         data.writeInt32(optionalParameters.size());
         for (size_t i = 0; i < optionalParameters.size(); ++i) {
             data.writeString8(optionalParameters.keyAt(i));
             data.writeString8(optionalParameters.valueAt(i));
         }
-        remote()->transact(GET_LICENSE_REQUEST, data, &reply);
+        remote()->transact(GET_KEY_REQUEST, data, &reply);
 
-        uint32_t len = reply.readInt32();
-        request.insertAt((size_t)0, len);
-        reply.read(request.editArray(), len);
+        readVector(reply, request);
         defaultUrl = reply.readString8();
 
         return reply.readInt32();
     }
 
-    virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                            Vector<uint8_t> const &response) {
+    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                        Vector<uint8_t> const &response,
+                                        Vector<uint8_t> &keySetId) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
-
-        data.writeInt32(sessionId.size());
-        data.write(sessionId.array(), sessionId.size());
-        data.writeInt32(response.size());
-        data.write(response.array(), response.size());
-        remote()->transact(PROVIDE_LICENSE_RESPONSE, data, &reply);
+        writeVector(data, sessionId);
+        writeVector(data, response);
+        remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
+        readVector(reply, keySetId);
 
         return reply.readInt32();
     }
 
-    virtual status_t removeLicense(Vector<uint8_t> const &sessionId) {
+    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(sessionId.size());
-        data.write(sessionId.array(), sessionId.size());
-        remote()->transact(REMOVE_LICENSE, data, &reply);
+        writeVector(data, keySetId);
+        remote()->transact(REMOVE_KEYS, data, &reply);
 
         return reply.readInt32();
     }
 
-    virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
+    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+                                 Vector<uint8_t> const &keySetId) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        writeVector(data, keySetId);
+        remote()->transact(RESTORE_KEYS, data, &reply);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
                                         KeyedVector<String8, String8> &infoMap) const {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(sessionId.size());
-        data.write(sessionId.array(), sessionId.size());
-
-        remote()->transact(QUERY_LICENSE_STATUS, data, &reply);
+        writeVector(data, sessionId);
+        remote()->transact(QUERY_KEY_STATUS, data, &reply);
 
         infoMap.clear();
         size_t count = reply.readInt32();
@@ -195,9 +201,7 @@
 
         remote()->transact(GET_PROVISION_REQUEST, data, &reply);
 
-        uint32_t len = reply.readInt32();
-        request.insertAt((size_t)0, len);
-        reply.read(request.editArray(), len);
+        readVector(reply, request);
         defaultUrl = reply.readString8();
 
         return reply.readInt32();
@@ -207,8 +211,7 @@
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(response.size());
-        data.write(response.array(), response.size());
+        writeVector(data, response);
         remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
 
         return reply.readInt32();
@@ -224,9 +227,7 @@
         uint32_t count = reply.readInt32();
         for (size_t i = 0; i < count; i++) {
             Vector<uint8_t> secureStop;
-            uint32_t len = reply.readInt32();
-            secureStop.insertAt((size_t)0, len);
-            reply.read(secureStop.editArray(), len);
+            readVector(reply, secureStop);
             secureStops.push_back(secureStop);
         }
         return reply.readInt32();
@@ -236,8 +237,7 @@
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
-        data.writeInt32(ssRelease.size());
-        data.write(ssRelease.array(), ssRelease.size());
+        writeVector(data, ssRelease);
         remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
 
         return reply.readInt32();
@@ -261,10 +261,7 @@
         data.writeString8(name);
         remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
 
-        uint32_t len = reply.readInt32();
-        value.insertAt((size_t)0, len);
-        reply.read(value.editArray(), len);
-
+        readVector(reply, value);
         return reply.readInt32();
     }
 
@@ -285,15 +282,120 @@
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
 
         data.writeString8(name);
-        data.writeInt32(value.size());
-        data.write(value.array(), value.size());
+        writeVector(data, value);
         remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
 
         return reply.readInt32();
     }
 
 
+    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                        String8 const &algorithm) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        data.writeString8(algorithm);
+        remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                                     String8 const &algorithm) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        data.writeString8(algorithm);
+        remote()->transact(SET_MAC_ALGORITHM, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        writeVector(data, keyId);
+        writeVector(data, input);
+        writeVector(data, iv);
+
+        remote()->transact(ENCRYPT, data, &reply);
+        readVector(reply, output);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        writeVector(data, keyId);
+        writeVector(data, input);
+        writeVector(data, iv);
+
+        remote()->transact(DECRYPT, data, &reply);
+        readVector(reply, output);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t sign(Vector<uint8_t> const &sessionId,
+                          Vector<uint8_t> const &keyId,
+                          Vector<uint8_t> const &message,
+                          Vector<uint8_t> &signature) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        writeVector(data, keyId);
+        writeVector(data, message);
+
+        remote()->transact(SIGN, data, &reply);
+        readVector(reply, signature);
+
+        return reply.readInt32();
+    }
+
+    virtual status_t verify(Vector<uint8_t> const &sessionId,
+                            Vector<uint8_t> const &keyId,
+                            Vector<uint8_t> const &message,
+                            Vector<uint8_t> const &signature,
+                            bool &match) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+        writeVector(data, sessionId);
+        writeVector(data, keyId);
+        writeVector(data, message);
+        writeVector(data, signature);
+
+        remote()->transact(VERIFY, data, &reply);
+        match = (bool)reply.readInt32();
+        return reply.readInt32();
+    }
+
 private:
+    void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
+        uint32_t size = reply.readInt32();
+        vector.insertAt((size_t)0, size);
+        reply.read(vector.editArray(), size);
+    }
+
+    void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
+        data.writeInt32(vector.size());
+        data.write(vector.array(), vector.size());
+    }
+
     DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
 };
 
@@ -301,6 +403,17 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
+    uint32_t size = data.readInt32();
+    vector.insertAt((size_t)0, size);
+    data.read(vector.editArray(), size);
+}
+
+void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
+    reply->writeInt32(vector.size());
+    reply->write(vector.array(), vector.size());
+}
+
 status_t BnDrm::onTransact(
     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
     switch (code) {
@@ -341,8 +454,7 @@
             CHECK_INTERFACE(IDrm, data, reply);
             Vector<uint8_t> sessionId;
             status_t result = openSession(sessionId);
-            reply->writeInt32(sessionId.size());
-            reply->write(sessionId.array(), sessionId.size());
+            writeVector(reply, sessionId);
             reply->writeInt32(result);
             return OK;
         }
@@ -351,28 +463,20 @@
         {
             CHECK_INTERFACE(IDrm, data, reply);
             Vector<uint8_t> sessionId;
-            uint32_t size = data.readInt32();
-            sessionId.insertAt((size_t)0, size);
-            data.read(sessionId.editArray(), size);
+            readVector(data, sessionId);
             reply->writeInt32(closeSession(sessionId));
             return OK;
         }
 
-        case GET_LICENSE_REQUEST:
+        case GET_KEY_REQUEST:
         {
             CHECK_INTERFACE(IDrm, data, reply);
-            Vector<uint8_t> sessionId;
-            uint32_t size = data.readInt32();
-            sessionId.insertAt((size_t)0, size);
-            data.read(sessionId.editArray(), size);
+            Vector<uint8_t> sessionId, initData;
 
-            Vector<uint8_t> initData;
-            size = data.readInt32();
-            initData.insertAt((size_t)0, size);
-            data.read(initData.editArray(), size);
-
+            readVector(data, sessionId);
+            readVector(data, initData);
             String8 mimeType = data.readString8();
-            DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)data.readInt32();
+            DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
 
             KeyedVector<String8, String8> optionalParameters;
             uint32_t count = data.readInt32();
@@ -386,55 +490,54 @@
             Vector<uint8_t> request;
             String8 defaultUrl;
 
-            status_t result = getLicenseRequest(sessionId, initData,
-                                                mimeType, licenseType,
-                                                optionalParameters,
-                                                request, defaultUrl);
-            reply->writeInt32(request.size());
-            reply->write(request.array(), request.size());
+            status_t result = getKeyRequest(sessionId, initData,
+                                            mimeType, keyType,
+                                            optionalParameters,
+                                            request, defaultUrl);
+            writeVector(reply, request);
             reply->writeString8(defaultUrl);
             reply->writeInt32(result);
             return OK;
         }
 
-        case PROVIDE_LICENSE_RESPONSE:
+        case PROVIDE_KEY_RESPONSE:
         {
             CHECK_INTERFACE(IDrm, data, reply);
-            Vector<uint8_t> sessionId;
-            uint32_t size = data.readInt32();
-            sessionId.insertAt((size_t)0, size);
-            data.read(sessionId.editArray(), size);
-            Vector<uint8_t> response;
-            size = data.readInt32();
-            response.insertAt((size_t)0, size);
-            data.read(response.editArray(), size);
-
-            reply->writeInt32(provideLicenseResponse(sessionId, response));
+            Vector<uint8_t> sessionId, response, keySetId;
+            readVector(data, sessionId);
+            readVector(data, response);
+            uint32_t result = provideKeyResponse(sessionId, response, keySetId);
+            writeVector(reply, keySetId);
+            reply->writeInt32(result);
             return OK;
         }
 
-        case REMOVE_LICENSE:
+        case REMOVE_KEYS:
         {
             CHECK_INTERFACE(IDrm, data, reply);
-            Vector<uint8_t> sessionId;
-            uint32_t size = data.readInt32();
-            sessionId.insertAt((size_t)0, size);
-            data.read(sessionId.editArray(), size);
-            reply->writeInt32(removeLicense(sessionId));
+            Vector<uint8_t> keySetId;
+            readVector(data, keySetId);
+            reply->writeInt32(removeKeys(keySetId));
             return OK;
         }
 
-        case QUERY_LICENSE_STATUS:
+        case RESTORE_KEYS:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId, keySetId;
+            readVector(data, sessionId);
+            readVector(data, keySetId);
+            reply->writeInt32(restoreKeys(sessionId, keySetId));
+            return OK;
+        }
+
+        case QUERY_KEY_STATUS:
         {
             CHECK_INTERFACE(IDrm, data, reply);
             Vector<uint8_t> sessionId;
-            uint32_t size = data.readInt32();
-            sessionId.insertAt((size_t)0, size);
-            data.read(sessionId.editArray(), size);
+            readVector(data, sessionId);
             KeyedVector<String8, String8> infoMap;
-
-            status_t result = queryLicenseStatus(sessionId, infoMap);
-
+            status_t result = queryKeyStatus(sessionId, infoMap);
             size_t count = infoMap.size();
             reply->writeInt32(count);
             for (size_t i = 0; i < count; ++i) {
@@ -451,8 +554,7 @@
             Vector<uint8_t> request;
             String8 defaultUrl;
             status_t result = getProvisionRequest(request, defaultUrl);
-            reply->writeInt32(request.size());
-            reply->write(request.array(), request.size());
+            writeVector(reply, request);
             reply->writeString8(defaultUrl);
             reply->writeInt32(result);
             return OK;
@@ -462,11 +564,8 @@
         {
             CHECK_INTERFACE(IDrm, data, reply);
             Vector<uint8_t> response;
-            uint32_t size = data.readInt32();
-            response.insertAt((size_t)0, size);
-            data.read(response.editArray(), size);
+            readVector(data, response);
             reply->writeInt32(provideProvisionResponse(response));
-
             return OK;
         }
 
@@ -491,9 +590,7 @@
         {
             CHECK_INTERFACE(IDrm, data, reply);
             Vector<uint8_t> ssRelease;
-            uint32_t size = data.readInt32();
-            ssRelease.insertAt((size_t)0, size);
-            data.read(ssRelease.editArray(), size);
+            readVector(data, ssRelease);
             reply->writeInt32(releaseSecureStops(ssRelease));
             return OK;
         }
@@ -515,8 +612,7 @@
             String8 name = data.readString8();
             Vector<uint8_t> value;
             status_t result = getPropertyByteArray(name, value);
-            reply->writeInt32(value.size());
-            reply->write(value.array(), value.size());
+            writeVector(reply, value);
             reply->writeInt32(result);
             return OK;
         }
@@ -535,15 +631,89 @@
             CHECK_INTERFACE(IDrm, data, reply);
             String8 name = data.readString8();
             Vector<uint8_t> value;
-            size_t count = data.readInt32();
-            value.insertAt((size_t)0, count);
-            data.read(value.editArray(), count);
+            readVector(data, value);
             reply->writeInt32(setPropertyByteArray(name, value));
             return OK;
         }
 
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
+        case SET_CIPHER_ALGORITHM:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId;
+            readVector(data, sessionId);
+            String8 algorithm = data.readString8();
+            reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
+            return OK;
+        }
+
+        case SET_MAC_ALGORITHM:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId;
+            readVector(data, sessionId);
+            String8 algorithm = data.readString8();
+            reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
+            return OK;
+        }
+
+        case ENCRYPT:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId, keyId, input, iv, output;
+            readVector(data, sessionId);
+            readVector(data, keyId);
+            readVector(data, input);
+            readVector(data, iv);
+            uint32_t result = encrypt(sessionId, keyId, input, iv, output);
+            writeVector(reply, output);
+            reply->writeInt32(result);
+            return OK;
+        }
+
+        case DECRYPT:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId, keyId, input, iv, output;
+            readVector(data, sessionId);
+            readVector(data, keyId);
+            readVector(data, input);
+            readVector(data, iv);
+            uint32_t result = decrypt(sessionId, keyId, input, iv, output);
+            writeVector(reply, output);
+            reply->writeInt32(result);
+            return OK;
+        }
+
+        case SIGN:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId, keyId, message, signature;
+            readVector(data, sessionId);
+            readVector(data, keyId);
+            readVector(data, message);
+            uint32_t result = sign(sessionId, keyId, message, signature);
+            writeVector(reply, signature);
+            reply->writeInt32(result);
+            return OK;
+        }
+
+        case VERIFY:
+        {
+            CHECK_INTERFACE(IDrm, data, reply);
+            Vector<uint8_t> sessionId, keyId, message, signature;
+            readVector(data, sessionId);
+            readVector(data, keyId);
+            readVector(data, message);
+            readVector(data, signature);
+            bool match;
+            uint32_t result = verify(sessionId, keyId, message, signature, match);
+            reply->writeInt32(match);
+            reply->writeInt32(result);
+            return OK;
+        }
+
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
     }
 }
 
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index 6ac7530..5fdb9f4 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -243,11 +243,11 @@
     return mPlugin->closeSession(sessionId);
 }
 
-status_t Drm::getLicenseRequest(Vector<uint8_t> const &sessionId,
-                                Vector<uint8_t> const &initData,
-                                String8 const &mimeType, DrmPlugin::LicenseType licenseType,
-                                KeyedVector<String8, String8> const &optionalParameters,
-                                Vector<uint8_t> &request, String8 &defaultUrl) {
+status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
+                            Vector<uint8_t> const &initData,
+                            String8 const &mimeType, DrmPlugin::KeyType keyType,
+                            KeyedVector<String8, String8> const &optionalParameters,
+                            Vector<uint8_t> &request, String8 &defaultUrl) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
@@ -258,12 +258,13 @@
         return -EINVAL;
     }
 
-    return mPlugin->getLicenseRequest(sessionId, initData, mimeType, licenseType,
-                                      optionalParameters, request, defaultUrl);
+    return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
+                                  optionalParameters, request, defaultUrl);
 }
 
-status_t Drm::provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                     Vector<uint8_t> const &response) {
+status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                 Vector<uint8_t> const &response,
+                                 Vector<uint8_t> &keySetId) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
@@ -274,10 +275,10 @@
         return -EINVAL;
     }
 
-    return mPlugin->provideLicenseResponse(sessionId, response);
+    return mPlugin->provideKeyResponse(sessionId, response, keySetId);
 }
 
-status_t Drm::removeLicense(Vector<uint8_t> const &sessionId) {
+status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
@@ -288,11 +289,11 @@
         return -EINVAL;
     }
 
-    return mPlugin->removeLicense(sessionId);
+    return mPlugin->removeKeys(keySetId);
 }
 
-status_t Drm::queryLicenseStatus(Vector<uint8_t> const &sessionId,
-                                 KeyedVector<String8, String8> &infoMap) const {
+status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
+                          Vector<uint8_t> const &keySetId) {
     Mutex::Autolock autoLock(mLock);
 
     if (mInitCheck != OK) {
@@ -303,7 +304,22 @@
         return -EINVAL;
     }
 
-    return mPlugin->queryLicenseStatus(sessionId, infoMap);
+    return mPlugin->restoreKeys(sessionId, keySetId);
+}
+
+status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
+                             KeyedVector<String8, String8> &infoMap) const {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->queryKeyStatus(sessionId, infoMap);
 }
 
 status_t Drm::getProvisionRequest(Vector<uint8_t> &request, String8 &defaultUrl) {
@@ -420,4 +436,106 @@
     return mPlugin->setPropertyByteArray(name, value);
 }
 
+
+status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                 String8 const &algorithm) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->setCipherAlgorithm(sessionId, algorithm);
+}
+
+status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                              String8 const &algorithm) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->setMacAlgorithm(sessionId, algorithm);
+}
+
+status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &keyId,
+                      Vector<uint8_t> const &input,
+                      Vector<uint8_t> const &iv,
+                      Vector<uint8_t> &output) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->encrypt(sessionId, keyId, input, iv, output);
+}
+
+status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &keyId,
+                      Vector<uint8_t> const &input,
+                      Vector<uint8_t> const &iv,
+                      Vector<uint8_t> &output) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->decrypt(sessionId, keyId, input, iv, output);
+}
+
+status_t Drm::sign(Vector<uint8_t> const &sessionId,
+                   Vector<uint8_t> const &keyId,
+                   Vector<uint8_t> const &message,
+                   Vector<uint8_t> &signature) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->sign(sessionId, keyId, message, signature);
+}
+
+status_t Drm::verify(Vector<uint8_t> const &sessionId,
+                     Vector<uint8_t> const &keyId,
+                     Vector<uint8_t> const &message,
+                     Vector<uint8_t> const &signature,
+                     bool &match) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mInitCheck != OK) {
+        return mInitCheck;
+    }
+
+    if (mPlugin == NULL) {
+        return -EINVAL;
+    }
+
+    return mPlugin->verify(sessionId, keyId, message, signature, match);
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h
index 1b10958..f24921e 100644
--- a/media/libmediaplayerservice/Drm.h
+++ b/media/libmediaplayerservice/Drm.h
@@ -45,19 +45,23 @@
     virtual status_t closeSession(Vector<uint8_t> const &sessionId);
 
     virtual status_t
-        getLicenseRequest(Vector<uint8_t> const &sessionId,
-                          Vector<uint8_t> const &initData,
-                          String8 const &mimeType, DrmPlugin::LicenseType licenseType,
-                          KeyedVector<String8, String8> const &optionalParameters,
-                          Vector<uint8_t> &request, String8 &defaultUrl);
+        getKeyRequest(Vector<uint8_t> const &sessionId,
+                      Vector<uint8_t> const &initData,
+                      String8 const &mimeType, DrmPlugin::KeyType keyType,
+                      KeyedVector<String8, String8> const &optionalParameters,
+                      Vector<uint8_t> &request, String8 &defaultUrl);
 
-    virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
-                                            Vector<uint8_t> const &response);
+    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+                                        Vector<uint8_t> const &response,
+                                        Vector<uint8_t> &keySetId);
 
-    virtual status_t removeLicense(Vector<uint8_t> const &sessionId);
+    virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
 
-    virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
-                                        KeyedVector<String8, String8> &infoMap) const;
+    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+                                 Vector<uint8_t> const &keySetId);
+
+    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+                                    KeyedVector<String8, String8> &infoMap) const;
 
     virtual status_t getProvisionRequest(Vector<uint8_t> &request,
                                          String8 &defaulUrl);
@@ -75,6 +79,35 @@
     virtual status_t setPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> const &value ) const;
 
+    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+                                        String8 const &algorithm);
+
+    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+                                     String8 const &algorithm);
+
+    virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output);
+
+    virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+                             Vector<uint8_t> const &keyId,
+                             Vector<uint8_t> const &input,
+                             Vector<uint8_t> const &iv,
+                             Vector<uint8_t> &output);
+
+    virtual status_t sign(Vector<uint8_t> const &sessionId,
+                          Vector<uint8_t> const &keyId,
+                          Vector<uint8_t> const &message,
+                          Vector<uint8_t> &signature);
+
+    virtual status_t verify(Vector<uint8_t> const &sessionId,
+                            Vector<uint8_t> const &keyId,
+                            Vector<uint8_t> const &message,
+                            Vector<uint8_t> const &signature,
+                            bool &match);
+
 private:
     mutable Mutex mLock;