Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcd5d085 authored by Robert Shih's avatar Robert Shih Committed by Gerrit Code Review
Browse files

Merge "Updated metrics logging IDrm implementation"

parents 8c2ebfed 2ae39ca9
Loading
Loading
Loading
Loading
+95 −49
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#define LOG_TAG "DrmMetricsLogger"

#include <media/MediaMetrics.h>
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/base64.h>
#include <mediadrm/DrmHal.h>
#include <mediadrm/DrmMetricsLogger.h>
#include <mediadrm/DrmUtils.h>
@@ -34,7 +36,7 @@ std::vector<uint8_t> toStdVec(Vector<uint8_t> const& sessionId) {
}  // namespace

DrmMetricsLogger::DrmMetricsLogger(IDrmFrontend frontend)
    : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonceMsb(0), mObjNonceLsb(0), mFrontend(frontend) {}
    : mImpl(sp<DrmHal>::make()), mUuid(), mObjNonce(), mFrontend(frontend) {}

DrmMetricsLogger::~DrmMetricsLogger() {}

@@ -57,9 +59,15 @@ DrmStatus DrmMetricsLogger::isCryptoSchemeSupported(const uint8_t uuid[16], cons
}

DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8& appPackageName) {
    std::memcpy(mUuid, uuid, sizeof(mUuid));
    if (checkGetRandom(&mObjNonceMsb, __func__) == OK &&
        checkGetRandom(&mObjNonceLsb, __func__) == OK) {
    std::memcpy(mUuid.data(), uuid, mUuid.size());
    if (kUuidSchemeMap.count(mUuid)) {
        mScheme = kUuidSchemeMap.at(mUuid);
    } else {
        mScheme = "Other";
    }
    if (generateNonce(&mObjNonce, kNonceSize, __func__) != OK) {
        return ERROR_DRM_RESOURCE_BUSY;
    }
    DrmStatus status = mImpl->createPlugin(uuid, appPackageName);
    if (status == OK) {
        reportMediaDrmCreated();
@@ -68,8 +76,6 @@ DrmStatus DrmMetricsLogger::createPlugin(const uint8_t uuid[16], const String8&
    }
    return status;
}
    return ERROR_DRM_RESOURCE_BUSY;
}

DrmStatus DrmMetricsLogger::destroyPlugin() {
    DrmStatus status = mImpl->destroyPlugin();
@@ -82,8 +88,9 @@ DrmStatus DrmMetricsLogger::destroyPlugin() {
DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
                                        Vector<uint8_t>& sessionId) {
    SessionContext ctx{};
    if (checkGetRandom(&ctx.mNonceMsb, __func__) == OK &&
        checkGetRandom(&ctx.mNonceLsb, __func__) == OK) {
    if (generateNonce(&ctx.mNonce, kNonceSize, __func__) != OK) {
        return ERROR_DRM_RESOURCE_BUSY;
    }
    DrmStatus status = mImpl->openSession(securityLevel, sessionId);
    if (status == OK) {
        std::vector<uint8_t> sessionKey = toStdVec(sessionId);
@@ -101,8 +108,6 @@ DrmStatus DrmMetricsLogger::openSession(DrmPlugin::SecurityLevel securityLevel,
    }
    return status;
}
    return ERROR_DRM_RESOURCE_BUSY;
}

DrmStatus DrmMetricsLogger::closeSession(Vector<uint8_t> const& sessionId) {
    std::vector<uint8_t> sid = toStdVec(sessionId);
@@ -419,7 +424,7 @@ DrmStatus DrmMetricsLogger::requiresSecureDecoder(const char* mime,
                                                  bool* required) const {
    DrmStatus status = mImpl->requiresSecureDecoder(mime, securityLevel, required);
    if (status != OK) {
        reportMediaDrmErrored(status, __func__);
        reportMediaDrmErrored(status, "requiresSecureDecoderLevel");
    }
    return status;
}
@@ -451,26 +456,29 @@ DrmStatus DrmMetricsLogger::getSupportedSchemes(std::vector<uint8_t>& schemes) c

void DrmMetricsLogger::reportMediaDrmCreated() const {
    mediametrics_handle_t handle(mediametrics_create("mediadrm.created"));
    mediametrics_setCString(handle, "scheme", mScheme.c_str());
    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
    mediametrics_setInt32(handle, "frontend", mFrontend);
    mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
    mediametrics_selfRecord(handle);
    mediametrics_delete(handle);
}

void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& sessionId) const {
    mediametrics_handle_t handle(mediametrics_create("mediadrm.session_opened"));
    mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
    mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
    mediametrics_setCString(handle, "scheme", mScheme.c_str());
    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
    mediametrics_setInt32(handle, "frontend", mFrontend);
    mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
    const std::lock_guard<std::mutex> lock(mSessionMapMutex);
    auto it = mSessionMap.find(sessionId);
    if (it != mSessionMap.end()) {
        mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
        mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
        mediametrics_setInt64(handle, "target_seucrity_level", it->second.mTargetSecurityLevel);
        mediametrics_setInt64(handle, "actual_seucrity_level", it->second.mActualSecurityLevel);
        mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
        mediametrics_setInt64(handle, "requested_seucrity_level", it->second.mTargetSecurityLevel);
        mediametrics_setInt64(handle, "opened_seucrity_level", it->second.mActualSecurityLevel);
    }
    mediametrics_setInt32(handle, "frontend", mFrontend);
    mediametrics_selfRecord(handle);
    mediametrics_delete(handle);
}
@@ -478,36 +486,74 @@ void DrmMetricsLogger::reportMediaDrmSessionOpened(const std::vector<uint8_t>& s
void DrmMetricsLogger::reportMediaDrmErrored(const DrmStatus& error_code, const char* api,
                                             const std::vector<uint8_t>& sessionId) const {
    mediametrics_handle_t handle(mediametrics_create("mediadrm.errored"));
    mediametrics_setInt64(handle, "obj_nonce_msb", mObjNonceMsb);
    mediametrics_setInt64(handle, "obj_nonce_lsb", mObjNonceLsb);
    mediametrics_setCString(handle, "scheme", mScheme.c_str());
    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
    mediametrics_setInt32(handle, "frontend", mFrontend);
    mediametrics_setCString(handle, "object_nonce", mObjNonce.c_str());
    if (!sessionId.empty()) {
        const std::lock_guard<std::mutex> lock(mSessionMapMutex);
        auto it = mSessionMap.find(sessionId);
        if (it != mSessionMap.end()) {
            mediametrics_setInt64(handle, "session_nonce_msb", it->second.mNonceMsb);
            mediametrics_setInt64(handle, "session_nonce_lsb", it->second.mNonceLsb);
            mediametrics_setCString(handle, "session_nonce", it->second.mNonce.c_str());
            mediametrics_setInt64(handle, "seucrity_level", it->second.mActualSecurityLevel);
        }
    }
    mediametrics_setInt64(handle, "uuid_msb", be64toh(mUuid[0]));
    mediametrics_setInt64(handle, "uuid_lsb", be64toh(mUuid[1]));
    mediametrics_setCString(handle, "api", api);
    mediametrics_setInt32(handle, "error_code", error_code);
    mediametrics_setInt32(handle, "cdm_err", error_code.getCdmErr());
    mediametrics_setInt32(handle, "oem_err", error_code.getOemErr());
    mediametrics_setInt32(handle, "error_context", error_code.getContext());
    mediametrics_setCString(handle, "api", api);
    mediametrics_setInt32(handle, "frontend", mFrontend);
    mediametrics_selfRecord(handle);
    mediametrics_delete(handle);
}

DrmStatus DrmMetricsLogger::checkGetRandom(int64_t* nonce, const char* api) {
    ssize_t bytes = getrandom(nonce, sizeof(int64_t), GRND_NONBLOCK);
    if (bytes < sizeof(int64_t)) {
DrmStatus DrmMetricsLogger::generateNonce(std::string* out, size_t size, const char* api) {
    std::vector<uint8_t> buf(size);
    ssize_t bytes = getrandom(buf.data(), size, GRND_NONBLOCK);
    if (bytes < size) {
        ALOGE("getrandom failed: %d", errno);
        reportMediaDrmErrored(ERROR_DRM_RESOURCE_BUSY, api);
        return ERROR_DRM_RESOURCE_BUSY;
    }
    android::AString tmp;
    encodeBase64(buf.data(), size, &tmp);
    out->assign(tmp.c_str());
    return OK;
}

const std::map<std::array<int64_t, 2>, std::string> DrmMetricsLogger::kUuidSchemeMap {
        {{(int64_t)0x6DD8B3C345F44A68, (int64_t)0xBF3A64168D01A4A6}, "ABV DRM (MoDRM)"},
        {{(int64_t)0xF239E769EFA34850, (int64_t)0x9C16A903C6932EFB},
         "Adobe Primetime DRM version 4"},
        {{(int64_t)0x616C746963617374, (int64_t)0x2D50726F74656374}, "Alticast"},
        {{(int64_t)0x94CE86FB07FF4F43, (int64_t)0xADB893D2FA968CA2}, "Apple FairPlay"},
        {{(int64_t)0x279FE473512C48FE, (int64_t)0xADE8D176FEE6B40F}, "Arris Titanium"},
        {{(int64_t)0x3D5E6D359B9A41E8, (int64_t)0xB843DD3C6E72C42C}, "ChinaDRM"},
        {{(int64_t)0x3EA8778F77424BF9, (int64_t)0xB18BE834B2ACBD47}, "Clear Key AES-128"},
        {{(int64_t)0xBE58615B19C44684, (int64_t)0x88B3C8C57E99E957}, "Clear Key SAMPLE-AES"},
        {{(int64_t)0xE2719D58A985B3C9, (int64_t)0x781AB030AF78D30E}, "Clear Key DASH-IF"},
        {{(int64_t)0x644FE7B5260F4FAD, (int64_t)0x949A0762FFB054B4}, "CMLA (OMA DRM)"},
        {{(int64_t)0x37C332587B994C7E, (int64_t)0xB15D19AF74482154}, "Commscope Titanium V3"},
        {{(int64_t)0x45D481CB8FE049C0, (int64_t)0xADA9AB2D2455B2F2}, "CoreCrypt"},
        {{(int64_t)0xDCF4E3E362F15818, (int64_t)0x7BA60A6FE33FF3DD}, "DigiCAP SmartXess"},
        {{(int64_t)0x35BF197B530E42D7, (int64_t)0x8B651B4BF415070F}, "DivX DRM Series 5"},
        {{(int64_t)0x80A6BE7E14484C37, (int64_t)0x9E70D5AEBE04C8D2}, "Irdeto Content Protection"},
        {{(int64_t)0x5E629AF538DA4063, (int64_t)0x897797FFBD9902D4},
         "Marlin Adaptive Streaming Simple Profile V1.0"},
        {{(int64_t)0x9A04F07998404286, (int64_t)0xAB92E65BE0885F95}, "Microsoft PlayReady"},
        {{(int64_t)0x6A99532D869F5922, (int64_t)0x9A91113AB7B1E2F3}, "MobiTV DRM"},
        {{(int64_t)0xADB41C242DBF4A6D, (int64_t)0x958B4457C0D27B95}, "Nagra MediaAccess PRM 3.0"},
        {{(int64_t)0x1F83E1E86EE94F0D, (int64_t)0xBA2F5EC4E3ED1A66}, "SecureMedia"},
        {{(int64_t)0x992C46E6C4374899, (int64_t)0xB6A050FA91AD0E39}, "SecureMedia SteelKnot"},
        {{(int64_t)0xA68129D3575B4F1A, (int64_t)0x9CBA3223846CF7C3},
         "Synamedia/Cisco/NDS VideoGuard DRM"},
        {{(int64_t)0xAA11967FCC014A4A, (int64_t)0x8E99C5D3DDDFEA2D}, "Unitend DRM (UDRM)"},
        {{(int64_t)0x9A27DD82FDE24725, (int64_t)0x8CBC4234AA06EC09}, "Verimatrix VCAS"},
        {{(int64_t)0xB4413586C58CFFB0, (int64_t)0x94A5D4896C1AF6C3}, "Viaccess-Orca DRM (VODRM)"},
        {{(int64_t)0x793B79569F944946, (int64_t)0xA94223E7EF7E44B4}, "VisionCrypt"},
        {{(int64_t)0x1077EFECC0B24D02, (int64_t)0xACE33C1E52E2FB4B}, "W3C Common PSSH box"},
        {{(int64_t)0xEDEF8BA979D64ACE, (int64_t)0xA3C827DCD51D21ED}, "Widevine Content Protection"},
};

}  // namespace android
 No newline at end of file
+7 −5
Original line number Diff line number Diff line
@@ -26,8 +26,7 @@
namespace android {

struct SessionContext {
    int64_t mNonceMsb;
    int64_t mNonceLsb;
    std::string mNonce;
    int64_t mTargetSecurityLevel;
    DrmPlugin::SecurityLevel mActualSecurityLevel;
};
@@ -150,12 +149,15 @@ class DrmMetricsLogger : public IDrm {
            const DrmStatus& error_code, const char* api,
            const std::vector<uint8_t>& sessionId = std::vector<uint8_t>()) const;

    DrmStatus checkGetRandom(int64_t* nonce, const char* api);
    DrmStatus generateNonce(std::string* out, size_t size, const char* api);

  private:
    static const size_t kNonceSize = 16;
    static const std::map<std::array<int64_t, 2>, std::string> kUuidSchemeMap;
    sp<IDrm> mImpl;
    int64_t mUuid[2] = {};
    int64_t mObjNonceMsb, mObjNonceLsb;
    std::array<int64_t, 2> mUuid;
    std::string mObjNonce;
    std::string mScheme;
    std::map<std::vector<uint8_t>, SessionContext> mSessionMap;
    mutable std::mutex mSessionMapMutex;
    IDrmFrontend mFrontend;