Fix MediaDrm security level APIs

Vendors implementing the newly added MediaDrm.setSecurityLevel
HAL found that it was difficult to implement properly. Also the
semantics are somewhat ambiguous from the Java platform API
level. This CL binds the security level assignment to openSession
which clarifies the API for apps as well as making it more
natural to implement in HAL modules.

bug:72831697
bug:64001680

test: VtsHalDrmV1_1TargetTest, GTS media tests
Change-Id: Iaa07727be86ec2bc92be907d5a48c92136dc2014
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 07cec01..3bbc34b 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -510,24 +510,62 @@
     return OK;
 }
 
-status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
+status_t DrmHal::openSession(DrmPlugin::SecurityLevel level,
+        Vector<uint8_t> &sessionId) {
     Mutex::Autolock autoLock(mLock);
     INIT_CHECK();
 
-    status_t  err = UNKNOWN_ERROR;
+    SecurityLevel hSecurityLevel;
+    bool setSecurityLevel = true;
 
+    switch(level) {
+    case DrmPlugin::kSecurityLevelSwSecureCrypto:
+        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
+        break;
+    case DrmPlugin::kSecurityLevelSwSecureDecode:
+        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
+        break;
+    case DrmPlugin::kSecurityLevelHwSecureCrypto:
+        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
+        break;
+    case DrmPlugin::kSecurityLevelHwSecureDecode:
+        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
+        break;
+    case DrmPlugin::kSecurityLevelHwSecureAll:
+        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
+        break;
+    case DrmPlugin::kSecurityLevelMax:
+        setSecurityLevel = false;
+        break;
+    default:
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
+
+    status_t  err = UNKNOWN_ERROR;
     bool retry = true;
     do {
         hidl_vec<uint8_t> hSessionId;
 
-        Return<void> hResult = mPlugin->openSession(
-                [&](Status status, const hidl_vec<uint8_t>& id) {
-                    if (status == Status::OK) {
-                        sessionId = toVector(id);
+        Return<void> hResult;
+        if (mPluginV1_1 == NULL || !setSecurityLevel) {
+            hResult = mPlugin->openSession(
+                    [&](Status status,const hidl_vec<uint8_t>& id) {
+                        if (status == Status::OK) {
+                            sessionId = toVector(id);
+                        }
+                        err = toStatusT(status);
                     }
-                    err = toStatusT(status);
-                }
-            );
+                );
+        } else {
+            hResult = mPluginV1_1->openSession_1_1(hSecurityLevel,
+                    [&](Status status, const hidl_vec<uint8_t>& id) {
+                        if (status == Status::OK) {
+                            sessionId = toVector(id);
+                        }
+                        err = toStatusT(status);
+                    }
+                );
+        }
 
         if (!hResult.isOk()) {
             err = DEAD_OBJECT;
@@ -979,42 +1017,6 @@
     return hResult.isOk() ? err : DEAD_OBJECT;
 }
 
-status_t DrmHal::setSecurityLevel(Vector<uint8_t> const &sessionId,
-        const DrmPlugin::SecurityLevel& level) {
-    Mutex::Autolock autoLock(mLock);
-    INIT_CHECK();
-
-    if (mPluginV1_1 == NULL) {
-        return ERROR_DRM_CANNOT_HANDLE;
-    }
-
-    SecurityLevel hSecurityLevel;
-
-    switch(level) {
-    case DrmPlugin::kSecurityLevelSwSecureCrypto:
-        hSecurityLevel = SecurityLevel::SW_SECURE_CRYPTO;
-        break;
-    case DrmPlugin::kSecurityLevelSwSecureDecode:
-        hSecurityLevel = SecurityLevel::SW_SECURE_DECODE;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureCrypto:
-        hSecurityLevel = SecurityLevel::HW_SECURE_CRYPTO;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureDecode:
-        hSecurityLevel = SecurityLevel::HW_SECURE_DECODE;
-        break;
-    case DrmPlugin::kSecurityLevelHwSecureAll:
-        hSecurityLevel = SecurityLevel::HW_SECURE_ALL;
-        break;
-    default:
-        return ERROR_DRM_CANNOT_HANDLE;
-    }
-
-    Status status = mPluginV1_1->setSecurityLevel(toHidlVec(sessionId),
-            hSecurityLevel);
-    return toStatusT(status);
-}
-
 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
     Mutex::Autolock autoLock(mLock);
     return getPropertyStringInternal(name, value);
diff --git a/drm/libmediadrm/IDrm.cpp b/drm/libmediadrm/IDrm.cpp
index 63a9562..9f54dba 100644
--- a/drm/libmediadrm/IDrm.cpp
+++ b/drm/libmediadrm/IDrm.cpp
@@ -60,7 +60,6 @@
     GET_HDCP_LEVELS,
     GET_NUMBER_OF_SESSIONS,
     GET_SECURITY_LEVEL,
-    SET_SECURITY_LEVEL,
     REMOVE_SECURE_STOP,
     GET_SECURE_STOP_IDS
 };
@@ -121,9 +120,11 @@
         return reply.readInt32();
     }
 
-    virtual status_t openSession(Vector<uint8_t> &sessionId) {
+    virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+            Vector<uint8_t> &sessionId) {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+        data.writeInt32(securityLevel);
 
         status_t status = remote()->transact(OPEN_SESSION, data, &reply);
         if (status != OK) {
@@ -448,23 +449,6 @@
         return reply.readInt32();
     }
 
-    virtual status_t setSecurityLevel(Vector<uint8_t> const &sessionId,
-            const DrmPlugin::SecurityLevel& level) {
-        Parcel data, reply;
-
-        data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
-
-        writeVector(data, sessionId);
-        data.writeInt32(static_cast<uint32_t>(level));
-
-        status_t status = remote()->transact(SET_SECURITY_LEVEL, data, &reply);
-        if (status != OK) {
-            return status;
-        }
-
-        return reply.readInt32();
-    }
-
     virtual status_t getPropertyByteArray(String8 const &name, Vector<uint8_t> &value) const {
         Parcel data, reply;
         data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
@@ -742,8 +726,10 @@
         case OPEN_SESSION:
         {
             CHECK_INTERFACE(IDrm, data, reply);
+            DrmPlugin::SecurityLevel level =
+                    static_cast<DrmPlugin::SecurityLevel>(data.readInt32());
             Vector<uint8_t> sessionId;
-            status_t result = openSession(sessionId);
+            status_t result = openSession(level, sessionId);
             writeVector(reply, sessionId);
             reply->writeInt32(result);
             return OK;
@@ -977,18 +963,6 @@
             return OK;
         }
 
-        case SET_SECURITY_LEVEL:
-        {
-            CHECK_INTERFACE(IDrm, data, reply);
-            Vector<uint8_t> sessionId;
-            readVector(data, sessionId);
-            DrmPlugin::SecurityLevel level =
-                    static_cast<DrmPlugin::SecurityLevel>(data.readInt32());
-            status_t result = setSecurityLevel(sessionId, level);
-            reply->writeInt32(result);
-            return OK;
-        }
-
         case GET_PROPERTY_STRING:
         {
             CHECK_INTERFACE(IDrm, data, reply);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index bf97db9..899431e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -73,12 +73,24 @@
     mByteArrayProperties[kMetricsKey] = valueVector;
 }
 
+
 Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
     sp<Session> session = mSessionLibrary->createSession();
     std::vector<uint8_t> sessionId = session->sessionId();
 
-    setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
-    _hidl_cb(Status::OK, toHidlVec(sessionId));
+    Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
+    _hidl_cb(status, toHidlVec(sessionId));
+    mOpenSessionOkCount++;
+    return Void();
+}
+
+Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
+        openSession_1_1_cb _hidl_cb) {
+    sp<Session> session = mSessionLibrary->createSession();
+    std::vector<uint8_t> sessionId = session->sessionId();
+
+    Status status = setSecurityLevel(sessionId, securityLevel);
+    _hidl_cb(status, toHidlVec(sessionId));
     mOpenSessionOkCount++;
     return Void();
 }
@@ -344,8 +356,8 @@
         return Status::BAD_VALUE;
     }
 
-    if (level > SecurityLevel::HW_SECURE_ALL) {
-        ALOGE("Cannot set invalid security level");
+    if (level > SecurityLevel::SW_SECURE_CRYPTO) {
+        ALOGE("Cannot set security level > max");
         return Status::BAD_VALUE;
     }
 
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index 64c8262..5d12598 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -53,6 +53,8 @@
     virtual ~DrmPlugin() {}
 
     Return<void> openSession(openSession_cb _hidl_cb) override;
+    Return<void> openSession_1_1(SecurityLevel securityLevel,
+            openSession_cb _hidl_cb) override;
 
     Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
 
@@ -162,9 +164,6 @@
     Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
             getSecurityLevel_cb _hidl_cb) override;
 
-    Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
-            SecurityLevel level) override;
-
     Return<void> getMetrics(getMetrics_cb _hidl_cb) override;
 
     Return<void> getPropertyString(
@@ -333,6 +332,9 @@
     void initProperties();
     void setPlayPolicy();
 
+    Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
+            SecurityLevel level);
+
     std::vector<KeyValue> mPlayPolicy;
     std::map<std::string, std::string> mStringProperties;
     std::map<std::string, std::vector<uint8_t> > mByteArrayProperties;
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index ec3a9b3..2e28dd5 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -63,7 +63,8 @@
 
     virtual status_t destroyPlugin();
 
-    virtual status_t openSession(Vector<uint8_t> &sessionId);
+    virtual status_t openSession(DrmPlugin::SecurityLevel level,
+            Vector<uint8_t> &sessionId);
 
     virtual status_t closeSession(Vector<uint8_t> const &sessionId);
 
@@ -110,8 +111,6 @@
             uint32_t *maxSessions) const;
     virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
             DrmPlugin::SecurityLevel *level) const;
-    virtual status_t setSecurityLevel(Vector<uint8_t> const &sessionId,
-            const DrmPlugin::SecurityLevel& level);
 
     virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
     virtual status_t getPropertyByteArray(String8 const &name,
diff --git a/media/libmedia/include/media/IDrm.h b/media/libmedia/include/media/IDrm.h
index 994cade..c3ae684 100644
--- a/media/libmedia/include/media/IDrm.h
+++ b/media/libmedia/include/media/IDrm.h
@@ -40,7 +40,8 @@
 
     virtual status_t destroyPlugin() = 0;
 
-    virtual status_t openSession(Vector<uint8_t> &sessionId) = 0;
+    virtual status_t openSession(DrmPlugin::SecurityLevel securityLevel,
+            Vector<uint8_t> &sessionId) = 0;
 
     virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
 
@@ -88,8 +89,6 @@
             uint32_t *maxSessions) const = 0;
     virtual status_t getSecurityLevel(Vector<uint8_t> const &sessionId,
             DrmPlugin::SecurityLevel *level) const = 0;
-    virtual status_t setSecurityLevel(Vector<uint8_t> const &sessionId,
-            const DrmPlugin::SecurityLevel& level) = 0;
 
     virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
     virtual status_t getPropertyByteArray(String8 const &name,
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index eecc858..fe08ab9 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -240,7 +240,7 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
     Vector<uint8_t> session;
-    status_t status = mObj->mDrm->openSession(session);
+    status_t status = mObj->mDrm->openSession(DrmPlugin::kSecurityLevelMax, session);
     if (status == OK) {
         mObj->mIds.push_front(session);
         List<idvec_t>::iterator iter = mObj->mIds.begin();