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

Commit d4164c3a authored by Ronghua Wu's avatar Ronghua Wu Committed by Android (Google) Code Review
Browse files

Merge "drm: use DrmSessionManager for session resource managing."

parents 64c4e026 5c3da20d
Loading
Loading
Loading
Loading
+72 −2
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@

#include "Drm.h"

#include "DrmSessionClientInterface.h"
#include "DrmSessionManager.h"
#include <media/drm/DrmAPI.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
@@ -33,6 +35,10 @@

namespace android {

static inline int getCallingPid() {
    return IPCThreadState::self()->getCallingPid();
}

static bool checkPermission(const char* permissionString) {
#ifndef HAVE_ANDROID_OS
    return true;
@@ -57,14 +63,41 @@ static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
    return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
}

struct DrmSessionClient : public DrmSessionClientInterface {
    DrmSessionClient(Drm* drm) : mDrm(drm) {}

    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
        sp<Drm> drm = mDrm.promote();
        if (drm == NULL) {
            return true;
        }
        status_t err = drm->closeSession(sessionId);
        if (err != OK) {
            return false;
        }
        drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
        return true;
    }

protected:
    virtual ~DrmSessionClient() {}

private:
    wp<Drm> mDrm;

    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
};

Drm::Drm()
    : mInitCheck(NO_INIT),
      mDrmSessionClient(new DrmSessionClient(this)),
      mListener(NULL),
      mFactory(NULL),
      mPlugin(NULL) {
}

Drm::~Drm() {
    DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
    delete mPlugin;
    mPlugin = NULL;
    closeFactory();
@@ -289,7 +322,18 @@ status_t Drm::openSession(Vector<uint8_t> &sessionId) {
        return -EINVAL;
    }

    return mPlugin->openSession(sessionId);
    status_t err = mPlugin->openSession(sessionId);
    if (err == ERROR_DRM_RESOURCE_BUSY) {
        bool retry = false;
        retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
        if (retry) {
            err = mPlugin->openSession(sessionId);
        }
    }
    if (err == OK) {
        DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
    }
    return err;
}

status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
@@ -303,7 +347,11 @@ status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
        return -EINVAL;
    }

    return mPlugin->closeSession(sessionId);
    status_t err = mPlugin->closeSession(sessionId);
    if (err == OK) {
        DrmSessionManager::Instance()->removeSession(sessionId);
    }
    return err;
}

status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
@@ -321,6 +369,8 @@ status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
                                  optionalParameters, request, defaultUrl);
}
@@ -338,6 +388,8 @@ status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->provideKeyResponse(sessionId, response, keySetId);
}

@@ -367,6 +419,8 @@ status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->restoreKeys(sessionId, keySetId);
}

@@ -382,6 +436,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->queryKeyStatus(sessionId, infoMap);
}

@@ -561,6 +617,8 @@ status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->setCipherAlgorithm(sessionId, algorithm);
}

@@ -576,6 +634,8 @@ status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->setMacAlgorithm(sessionId, algorithm);
}

@@ -594,6 +654,8 @@ status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->encrypt(sessionId, keyId, input, iv, output);
}

@@ -612,6 +674,8 @@ status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->decrypt(sessionId, keyId, input, iv, output);
}

@@ -629,6 +693,8 @@ status_t Drm::sign(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->sign(sessionId, keyId, message, signature);
}

@@ -647,6 +713,8 @@ status_t Drm::verify(Vector<uint8_t> const &sessionId,
        return -EINVAL;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->verify(sessionId, keyId, message, signature, match);
}

@@ -669,6 +737,8 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
        return -EPERM;
    }

    DrmSessionManager::Instance()->useSession(sessionId);

    return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
}

+3 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ namespace android {

struct DrmFactory;
struct DrmPlugin;
struct DrmSessionClientInterface;

struct Drm : public BnDrm,
             public IBinder::DeathRecipient,
@@ -138,6 +139,8 @@ private:

    status_t mInitCheck;

    sp<DrmSessionClientInterface> mDrmSessionClient;

    sp<IDrmClient> mListener;
    mutable Mutex mEventLock;
    mutable Mutex mNotifyLock;
+43 −13
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include "DrmSessionClientInterface.h"
#include "ProcessInfoInterface.h"
#include <binder/IPCThreadState.h>
#include <binder/IProcessInfoService.h>
#include <binder/IServiceManager.h>
#include <unistd.h>
#include <utils/String8.h>

@@ -39,12 +41,25 @@ static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
struct ProcessInfo : public ProcessInfoInterface {
    ProcessInfo() {}

    virtual int getPriority(int pid) {
        // TODO: implement
        // Get process state to determine priority.
        // According to the define of PROCESS_STATE_***, higher the value lower
        // the priority. So we will do a converting from state to priority here.
        return -1;
    virtual bool getPriority(int pid, int* priority) {
        sp<IBinder> binder = defaultServiceManager()->getService(String16("processinfo"));
        sp<IProcessInfoService> service = interface_cast<IProcessInfoService>(binder);

        size_t length = 1;
        int32_t states;
        status_t err = service->getProcessStatesFromPids(length, &pid, &states);
        if (err != OK) {
            ALOGE("getProcessStatesFromPids failed");
            return false;
        }
        ALOGV("pid %d states %d", pid, states);
        if (states < 0) {
            return false;
        }

        // Use process state as the priority. Lower the value, higher the priority.
        *priority = states;
        return true;
    }

protected:
@@ -66,6 +81,11 @@ bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &
    return true;
}

sp<DrmSessionManager> DrmSessionManager::Instance() {
    static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
    return drmSessionManager;
}

DrmSessionManager::DrmSessionManager()
    : mProcessInfo(new ProcessInfo()),
      mTime(0) {}
@@ -155,15 +175,18 @@ bool DrmSessionManager::reclaimSession(int callingPid) {

    sp<DrmSessionClientInterface> drm;
    Vector<uint8_t> sessionId;
    {
        Mutex::Autolock lock(mLock);
        int callingPriority = mProcessInfo->getPriority(callingPid);
    int lowestPriorityPid;
    int lowestPriority;
    {
        Mutex::Autolock lock(mLock);
        int callingPriority;
        if (!mProcessInfo->getPriority(callingPid, &callingPriority)) {
            return false;
        }
        if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) {
            return false;
        }
        if (lowestPriority >= callingPriority) {
        if (lowestPriority <= callingPriority) {
            return false;
        }

@@ -176,6 +199,9 @@ bool DrmSessionManager::reclaimSession(int callingPid) {
        return false;
    }

    ALOGV("reclaim session(%s) opened by pid %d",
            GetSessionIdString(sessionId).string(), lowestPriorityPid);

    return drm->reclaimSession(sessionId);
}

@@ -185,19 +211,23 @@ int64_t DrmSessionManager::getTime_l() {

bool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) {
    int pid = -1;
    int priority = INT_MAX;
    int priority = -1;
    for (size_t i = 0; i < mSessionMap.size(); ++i) {
        if (mSessionMap.valueAt(i).size() == 0) {
            // no opened session by this process.
            continue;
        }
        int tempPid = mSessionMap.keyAt(i);
        int tempPriority = mProcessInfo->getPriority(tempPid);
        int tempPriority;
        if (!mProcessInfo->getPriority(tempPid, &tempPriority)) {
            // shouldn't happen.
            return false;
        }
        if (pid == -1) {
            pid = tempPid;
            priority = tempPriority;
        } else {
            if (tempPriority < priority) {
            if (tempPriority > priority) {
                pid = tempPid;
                priority = tempPriority;
            }
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ typedef Vector<SessionInfo > SessionInfos;
typedef KeyedVector<int, SessionInfos > PidSessionInfosMap;

struct DrmSessionManager : public RefBase {
    static sp<DrmSessionManager> Instance();

    DrmSessionManager();
    DrmSessionManager(sp<ProcessInfoInterface> processInfo);

+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
namespace android {

struct ProcessInfoInterface : public RefBase {
    virtual int getPriority(int pid) = 0;
    virtual bool getPriority(int pid, int* priority) = 0;

protected:
    virtual ~ProcessInfoInterface() {}
Loading