Implement new MediaDrm methods

Methods for querying HDCP, security levels and
number of sessions

bug:64001680
bug:33657579

Test: cts: MediaDrmMockTest, ClearKeySystemTest
gts: GtsMediaTestCases

Change-Id: I7c84df02ec33d305b6bd5ac7479922f87aa64863
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index bc37557..02f74a8 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -37,17 +37,15 @@
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaErrors.h>
 
-using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::IDrmFactory;
-using ::android::hardware::drm::V1_0::IDrmPlugin;
-using ::android::hardware::drm::V1_0::KeyedVector;
-using ::android::hardware::drm::V1_0::KeyRequestType;
-using ::android::hardware::drm::V1_0::KeyStatus;
-using ::android::hardware::drm::V1_0::KeyStatusType;
-using ::android::hardware::drm::V1_0::KeyType;
-using ::android::hardware::drm::V1_0::KeyValue;
-using ::android::hardware::drm::V1_0::SecureStop;
-using ::android::hardware::drm::V1_0::Status;
+using drm::V1_0::KeyedVector;
+using drm::V1_0::KeyRequestType;
+using drm::V1_0::KeyStatusType;
+using drm::V1_0::KeyType;
+using drm::V1_0::KeyValue;
+using drm::V1_1::HdcpLevel;;
+using drm::V1_0::SecureStop;
+using drm::V1_1::SecurityLevel;
+using drm::V1_0::Status;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -58,6 +56,8 @@
 
 namespace android {
 
+#define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
+
 static inline int getCallingPid() {
     return IPCThreadState::self()->getCallingPid();
 }
@@ -89,6 +89,42 @@
     return hidl_string(string.string());
 }
 
+static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
+    switch(level) {
+    case SecurityLevel::SW_SECURE_CRYPTO:
+        return DrmPlugin::kSecurityLevelSwSecureCrypto;
+    case SecurityLevel::SW_SECURE_DECODE:
+        return DrmPlugin::kSecurityLevelSwSecureDecode;
+    case SecurityLevel::HW_SECURE_CRYPTO:
+        return DrmPlugin::kSecurityLevelHwSecureCrypto;
+    case SecurityLevel::HW_SECURE_DECODE:
+        return DrmPlugin::kSecurityLevelHwSecureDecode;
+    case SecurityLevel::HW_SECURE_ALL:
+        return DrmPlugin::kSecurityLevelHwSecureAll;
+    default:
+        return DrmPlugin::kSecurityLevelUnknown;
+    }
+}
+
+static DrmPlugin::HdcpLevel toHdcpLevel(HdcpLevel level) {
+    switch(level) {
+    case HdcpLevel::HDCP_NONE:
+        return DrmPlugin::kHdcpNone;
+    case HdcpLevel::HDCP_V1:
+        return DrmPlugin::kHdcpV1;
+    case HdcpLevel::HDCP_V2:
+        return DrmPlugin::kHdcpV2;
+    case HdcpLevel::HDCP_V2_1:
+        return DrmPlugin::kHdcpV2_1;
+    case HdcpLevel::HDCP_V2_2:
+        return DrmPlugin::kHdcpV2_2;
+    case HdcpLevel::HDCP_NO_OUTPUT:
+        return DrmPlugin::kHdcpNoOutput;
+    default:
+        return DrmPlugin::kHdcpLevelUnknown;
+    }
+}
+
 
 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
         keyedVector) {
@@ -407,6 +443,7 @@
     for (size_t i = 0; i < mFactories.size(); i++) {
         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
             mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
+            mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
         }
     }
 
@@ -425,9 +462,7 @@
 
 status_t DrmHal::destroyPlugin() {
     Mutex::Autolock autoLock(mLock);
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     closeOpenSessions();
     reportMetrics();
@@ -445,10 +480,7 @@
 
 status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t  err = UNKNOWN_ERROR;
 
@@ -491,10 +523,7 @@
 
 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     Return<Status> status = mPlugin->closeSession(toHidlVec(sessionId));
     if (status.isOk()) {
@@ -519,10 +548,7 @@
         String8> const &optionalParameters, Vector<uint8_t> &request,
         String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -574,10 +600,7 @@
 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
         Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -598,10 +621,7 @@
 
 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
 }
@@ -609,10 +629,7 @@
 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
         Vector<uint8_t> const &keySetId) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -623,10 +640,7 @@
 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
         KeyedVector<String8, String8> &infoMap) const {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -650,10 +664,7 @@
         String8 const &certAuthority, Vector<uint8_t> &request,
         String8 &defaultUrl) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -675,10 +686,7 @@
 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
         Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -698,10 +706,7 @@
 
 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -720,10 +725,7 @@
 
 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -741,24 +743,141 @@
 
 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
 }
 
 status_t DrmHal::releaseAllSecureStops() {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     return toStatusT(mPlugin->releaseAllSecureStops());
 }
 
+status_t DrmHal::getHdcpLevels(DrmPlugin::HdcpLevel *connected,
+            DrmPlugin::HdcpLevel *max) const {
+    Mutex::Autolock autoLock(mLock);
+    INIT_CHECK();
+
+    if (connected == NULL || max == NULL) {
+        return BAD_VALUE;
+    }
+    status_t err = UNKNOWN_ERROR;
+
+    if (mPluginV1_1 == NULL) {
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
+
+    *connected = DrmPlugin::kHdcpLevelUnknown;
+    *max = DrmPlugin::kHdcpLevelUnknown;
+
+    Return<void> hResult = mPluginV1_1->getHdcpLevels(
+            [&](Status status, const HdcpLevel& hConnected, const HdcpLevel& hMax) {
+                if (status == Status::OK) {
+                    *connected = toHdcpLevel(hConnected);
+                    *max = toHdcpLevel(hMax);
+                }
+                err = toStatusT(status);
+            }
+    );
+
+    return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
+status_t DrmHal::getNumberOfSessions(uint32_t *open, uint32_t *max) const {
+    Mutex::Autolock autoLock(mLock);
+    INIT_CHECK();
+
+    if (open == NULL || max == NULL) {
+        return BAD_VALUE;
+    }
+    status_t err = UNKNOWN_ERROR;
+
+    *open = 0;
+    *max = 0;
+
+    if (mPluginV1_1 == NULL) {
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
+
+    Return<void> hResult = mPluginV1_1->getNumberOfSessions(
+            [&](Status status, uint32_t hOpen, uint32_t hMax) {
+                if (status == Status::OK) {
+                    *open = hOpen;
+                    *max = hMax;
+                }
+                err = toStatusT(status);
+            }
+    );
+
+    return hResult.isOk() ? err : DEAD_OBJECT;
+}
+
+status_t DrmHal::getSecurityLevel(Vector<uint8_t> const &sessionId,
+        DrmPlugin::SecurityLevel *level) const {
+    Mutex::Autolock autoLock(mLock);
+    INIT_CHECK();
+
+    if (level == NULL) {
+        return BAD_VALUE;
+    }
+    status_t err = UNKNOWN_ERROR;
+
+    if (mPluginV1_1 == NULL) {
+        return ERROR_DRM_CANNOT_HANDLE;
+    }
+
+    *level = DrmPlugin::kSecurityLevelUnknown;
+
+    Return<void> hResult = mPluginV1_1->getSecurityLevel(toHidlVec(sessionId),
+            [&](Status status, SecurityLevel hLevel) {
+                if (status == Status::OK) {
+                    *level = toSecurityLevel(hLevel);
+                }
+                err = toStatusT(status);
+            }
+    );
+
+    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);
@@ -767,10 +886,7 @@
 status_t DrmHal::getPropertyStringInternal(String8 const &name, String8 &value) const {
     // This function is internal to the class and should only be called while
     // mLock is already held.
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -794,10 +910,7 @@
 status_t DrmHal::getPropertyByteArrayInternal(String8 const &name, Vector<uint8_t> &value ) const {
     // This function is internal to the class and should only be called while
     // mLock is already held.
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     status_t err = UNKNOWN_ERROR;
 
@@ -815,12 +928,9 @@
 
 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
     Mutex::Autolock autoLock(mLock);
+    INIT_CHECK();
 
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
-
-    Status status =  mPlugin->setPropertyString(toHidlString(name),
+    Status status = mPlugin->setPropertyString(toHidlString(name),
             toHidlString(value));
     return toStatusT(status);
 }
@@ -828,10 +938,7 @@
 status_t DrmHal::setPropertyByteArray(String8 const &name,
                                    Vector<uint8_t> const &value ) const {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     Status status = mPlugin->setPropertyByteArray(toHidlString(name),
             toHidlVec(value));
@@ -842,10 +949,7 @@
 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                  String8 const &algorithm) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -857,10 +961,7 @@
 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
                               String8 const &algorithm) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -873,10 +974,7 @@
         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;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -899,10 +997,7 @@
         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;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -925,10 +1020,7 @@
         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
         Vector<uint8_t> &signature) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -951,10 +1043,7 @@
         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;
-    }
+    INIT_CHECK();
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
@@ -979,10 +1068,7 @@
         String8 const &algorithm, Vector<uint8_t> const &message,
         Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
     Mutex::Autolock autoLock(mLock);
-
-    if (mInitCheck != OK) {
-        return mInitCheck;
-    }
+    INIT_CHECK();
 
     if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
         return -EPERM;