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

Commit c895ed30 authored by Edwin Wong's avatar Edwin Wong
Browse files

Add support for KEY_TYPE_RELEASE for clearkey plugin.

Test: android.media.cts.MediaDrmClearkeyTest#testReleaseOfflineLicense
Test: android.media.cts.MediaDrmClearkeyTest

bug: 117617857
Change-Id: I74b7db2824ca91f1301bba6404e4e900dde290d2
parent c76077c1
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ bool DeviceFiles::StoreLicense(
            break;
        case kLicenseStateReleasing:
            license->set_state(License_LicenseState_RELEASING);
            license->set_license(licenseResponse);
            break;
        default:
            ALOGW("StoreLicense: Unknown license state: %u", state);
@@ -106,8 +107,8 @@ bool DeviceFiles::StoreFileRaw(const std::string& fileName, const std::string& s

bool DeviceFiles::RetrieveLicense(
    const std::string& keySetId, LicenseState* state, std::string* offlineLicense) {
    OfflineFile file;

    OfflineFile file;
    if (!RetrieveHashedFile(keySetId + kLicenseFileNameExt, &file)) {
        return false;
    }
@@ -128,7 +129,6 @@ bool DeviceFiles::RetrieveLicense(
    }

    License license = file.license();

    switch (license.state()) {
        case License_LicenseState_ACTIVE:
            *state = kLicenseStateActive;
@@ -142,11 +142,14 @@ bool DeviceFiles::RetrieveLicense(
            *state = kLicenseStateUnknown;
            break;
    }

    *offlineLicense = license.license();
    return true;
}

bool DeviceFiles::DeleteLicense(const std::string& keySetId) {
    return mFileHandle.RemoveFile(keySetId + kLicenseFileNameExt);
}

bool DeviceFiles::DeleteAllLicenses() {
    return mFileHandle.RemoveAllFiles();
}
+51 −32
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
    mPlayPolicy.clear();
    initProperties();
    mSecureStops.clear();
    mReleaseKeysMap.clear();
    std::srand(std::time(nullptr));
}

@@ -155,7 +156,7 @@ Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
    // GetKeyRequestOfflineKeyTypeNotSupported() in vts 1.0 and 1.1 expects
    // KeyType::OFFLINE to return ERROR_DRM_CANNOT_HANDLE in clearkey plugin.
    // Those tests pass in an empty initData, we use the empty initData to
    // signal the specific use case.
    // signal such specific use case.
    if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
        return Status::ERROR_DRM_CANNOT_HANDLE;
    }
@@ -196,6 +197,14 @@ Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
                ALOGE("Problem releasing offline license");
                return Status::ERROR_DRM_UNKNOWN;
            }
            if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
                sp<Session> session = mSessionLibrary->createSession();
                mReleaseKeysMap[keySetIdString] = session->sessionId();
            } else {
                ALOGI("key is in use, ignore release request");
            }
        } else {
            ALOGE("Offline license not found, nothing to release");
        }
        *keyRequestType = KeyRequestType::RELEASE;
    }
@@ -305,25 +314,35 @@ Return<void> DrmPlugin::provideKeyResponse(
    bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
    if (isRelease) {
        keySetId.assign(scopeId.begin(), scopeId.end());

        auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
        if (iter != mReleaseKeysMap.end()) {
            sessionId.assign(iter->second.begin(), iter->second.end());
        }
    } else {
        sessionId.assign(scopeId.begin(), scopeId.end());
        // non offline license returns empty keySetId
        keySetId.clear();
    }

    sp<Session> session = mSessionLibrary->findSession(sessionId);
    if (!session.get()) {
        _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
        return Void();
    }

    setPlayPolicy();
        // non offline license returns empty keySetId
        keySetId.clear();

    status = session->provideKeyResponse(response);
    if (status == Status::OK) {
        if (isOfflineLicense) {
            if (isRelease) {
                mFileHandle.DeleteLicense(keySetId);
            } else {
                if (!makeKeySetId(&keySetId)) {
                    _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
                    return Void();
                }

                bool ok = mFileHandle.StoreLicense(
                        keySetId,
                        DeviceFiles::kLicenseStateActive,
@@ -332,6 +351,7 @@ Return<void> DrmPlugin::provideKeyResponse(
                    ALOGE("Failed to store offline license");
                }
            }
        }

        // Test calling AMediaDrm listeners.
        sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
@@ -355,9 +375,8 @@ Return<void> DrmPlugin::provideKeyResponse(

        installSecureStop(sessionId);
    } else {
            ALOGE("Failed to add key, error=%d", status);
        ALOGE("provideKeyResponse returns error=%d", status);
    }
    } // keyType::STREAMING || keyType::OFFLINE

    std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
    _hidl_cb(status, toHidlVec(keySetIdVec));
@@ -371,10 +390,10 @@ Return<Status> DrmPlugin::restoreKeys(
        }

        DeviceFiles::LicenseState licenseState;
        std::string keySetIdString(keySetId.begin(), keySetId.end());
        std::string offlineLicense;
        Status status = Status::OK;
        if (!mFileHandle.RetrieveLicense(keySetIdString, &licenseState, &offlineLicense)) {
        if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
                &licenseState, &offlineLicense)) {
            ALOGE("Failed to restore offline license");
            return Status::ERROR_DRM_NO_LICENSE;
        }
+2 −1
Original line number Diff line number Diff line
@@ -156,7 +156,8 @@ std::string InitDataParser::generateRequest(V1_0::KeyType keyType,
    }
    if (keyType == V1_0::KeyType::STREAMING) {
        request.append(kTemporarySession);
    } else if (keyType == V1_0::KeyType::OFFLINE) {
    } else if (keyType == V1_0::KeyType::OFFLINE ||
                   keyType == V1_0::KeyType::RELEASE) {
            request.append(kPersistentSession);
    }

+4 −1
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
// License Agreement.

#include <utils/Log.h>

#include <string>

#include "MemoryFileSystem.h"
@@ -54,6 +53,10 @@ size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) {

size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) {
    std::string key = GetFileName(path);
    auto result = mMemoryFileSystem.find(key);
    if (result != mMemoryFileSystem.end()) {
        mMemoryFileSystem.erase(key);
    }
    mMemoryFileSystem.insert(std::pair<std::string, MemoryFile>(key, memoryFile));
    return memoryFile.getFileSize();
}
+4 −2
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ sp<Session> SessionLibrary::createSession() {

    mSessions.insert(std::pair<std::vector<uint8_t>,
            sp<Session> >(sessionId, new Session(sessionId)));
    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
            mSessions.find(sessionId);
    if (itr != mSessions.end()) {
        return itr->second;
    } else {
@@ -70,7 +71,8 @@ sp<Session> SessionLibrary::createSession() {
sp<Session> SessionLibrary::findSession(
        const std::vector<uint8_t>& sessionId) {
    Mutex::Autolock lock(mSessionsLock);
    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
    std::map<std::vector<uint8_t>, sp<Session> >::iterator itr =
            mSessions.find(sessionId);
    if (itr != mSessions.end()) {
        return itr->second;
    } else {
Loading