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

Commit 0f6f28be authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "bring-rm-uptodate"

* changes:
  drm: refactor resourcemanager death handling
  resourcemanager: refactor death notification
  media: update on concurrent codec usage
  resourcemanagerservice: make a copy of client config
  implementing concurrent codec metrics
parents 7681f87c 323711ff
Loading
Loading
Loading
Loading
+93 −25
Original line number Original line Diff line number Diff line
@@ -36,13 +36,6 @@ namespace android {
using aidl::android::media::MediaResourceParcel;
using aidl::android::media::MediaResourceParcel;
using aidl::android::media::ClientInfoParcel;
using aidl::android::media::ClientInfoParcel;


namespace {
void ResourceManagerServiceDied(void* cookie) {
    auto thiz = static_cast<DrmSessionManager*>(cookie);
    thiz->binderDied();
}
}

using ::ndk::ScopedAStatus;
using ::ndk::ScopedAStatus;


static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
@@ -60,6 +53,12 @@ static std::vector<Byte> toStdVec(const Vector<uint8_t> &vector) {
    return vec;
    return vec;
}
}


static Vector<uint8_t> toAndroidVec(const std::vector<uint8_t>& array) {
    Vector<uint8_t> vec;
    vec.appendArray(array.data(), array.size());
    return vec;
}

static std::vector<MediaResourceParcel> toResourceVec(
static std::vector<MediaResourceParcel> toResourceVec(
        const Vector<uint8_t> &sessionId, int64_t value) {
        const Vector<uint8_t> &sessionId, int64_t value) {
    using Type = aidl::android::media::MediaResourceType;
    using Type = aidl::android::media::MediaResourceType;
@@ -72,11 +71,6 @@ static std::vector<MediaResourceParcel> toResourceVec(
    return resources;
    return resources;
}
}


static std::shared_ptr<IResourceManagerService> getResourceManagerService() {
    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
    return IResourceManagerService::fromBinder(binder);
}

bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
    if (sessionId1.size() != sessionId2.size()) {
    if (sessionId1.size() != sessionId2.size()) {
        return false;
        return false;
@@ -96,16 +90,15 @@ sp<DrmSessionManager> DrmSessionManager::Instance() {
}
}


DrmSessionManager::DrmSessionManager()
DrmSessionManager::DrmSessionManager()
    : DrmSessionManager(getResourceManagerService()) {
    : DrmSessionManager(nullptr) {
}
}


DrmSessionManager::DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service)
DrmSessionManager::DrmSessionManager(const std::shared_ptr<IResourceManagerService> &service)
    : mService(service),
    : mService(service),
      mInitialized(false),
      mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
      mDeathRecipient(AIBinder_DeathRecipient_new(ResourceManagerServiceDied)) {
          AIBinder_DeathRecipient_new(ResourceManagerServiceDied))) {
    if (mService == NULL) {
    // Setting callback notification when DeathRecipient gets deleted.
        ALOGE("Failed to init ResourceManagerService");
    AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), BinderUnlinkedCallback);
    }
}
}


DrmSessionManager::~DrmSessionManager() {
DrmSessionManager::~DrmSessionManager() {
@@ -114,14 +107,64 @@ DrmSessionManager::~DrmSessionManager() {
    }
    }
}
}


void DrmSessionManager::init() {
status_t DrmSessionManager::init() {
    Mutex::Autolock lock(mLock);
    Mutex::Autolock lock(mLock);
    if (mInitialized) {
    getResourceManagerService_l();
    if (mService == nullptr) {
        ALOGE("Failed to init ResourceManagerService");
        return DEAD_OBJECT;
    }

    return OK;
}

void DrmSessionManager::getResourceManagerService_l() {
    if (mService != nullptr) {
        return;
        return;
    }
    }
    mInitialized = true;

    if (mService != NULL) {
    // Get binder interface to resource manager.
        AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
    ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.resource_manager"));
    mService = IResourceManagerService::fromBinder(binder);
    if (mService == nullptr) {
        ALOGE("Failed to get ResourceManagerService");
        return;
    }

    // Create the context that is passed as cookie to the binder death notification.
    // The context gets deleted at BinderUnlinkedCallback.
    BinderDiedContext* context = new BinderDiedContext{
        .mDrmSessionManager = wp<DrmSessionManager>::fromExisting(this)};
    // Register for the callbacks by linking to death notification.
    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), context);

    // If the RM was restarted, re-register all the resources.
    if (mBinderDied) {
        reRegisterAllResources_l();
        mBinderDied = false;
    }
}

void DrmSessionManager::reRegisterAllResources_l() {
    if (mSessionMap.empty()) {
        // Nothing to register.
        ALOGV("No resources to add");
        return;
    }

    if (mService == nullptr) {
        ALOGW("Service isn't available");
        return;
    }

    // Go through the session map and re-register all the resources for those sessions.
    for (SessionInfoMap::const_iterator iter = mSessionMap.begin();
         iter != mSessionMap.end(); ++iter) {
        ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(iter->second.pid),
                                    .uid = static_cast<int32_t>(iter->second.uid),
                                    .id = iter->second.clientId};
        mService->addResource(clientInfo, iter->second.drm,
                              toResourceVec(toAndroidVec(iter->first), iter->second.resourceValue));
    }
    }
}
}


@@ -137,7 +180,7 @@ void DrmSessionManager::addSession(int pid,
    }
    }


    static int64_t clientId = 0;
    static int64_t clientId = 0;
    mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId};
    mSessionMap[toStdVec(sessionId)] = (SessionInfo){pid, uid, clientId, drm, INT64_MAX};
    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(pid),
                                .uid = static_cast<int32_t>(uid),
                                .uid = static_cast<int32_t>(uid),
                                .id = clientId++};
                                .id = clientId++};
@@ -154,6 +197,7 @@ void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
    }
    }


    auto info = it->second;
    auto info = it->second;
    info.resourceValue = -1;
    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(info.pid),
    ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(info.pid),
                                .uid = static_cast<int32_t>(info.uid),
                                .uid = static_cast<int32_t>(info.uid),
                                .id = info.clientId};
                                .id = info.clientId};
@@ -215,7 +259,31 @@ bool DrmSessionManager::containsSession(const Vector<uint8_t>& sessionId) const
void DrmSessionManager::binderDied() {
void DrmSessionManager::binderDied() {
    ALOGW("ResourceManagerService died.");
    ALOGW("ResourceManagerService died.");
    Mutex::Autolock lock(mLock);
    Mutex::Autolock lock(mLock);
    mService.reset();
    mService = nullptr;
    mBinderDied = true;
    // start an async operation that will reconnect with the RM and
    // re-registers all the resources.
    mGetServiceFuture = std::async(std::launch::async, [this] { getResourceManagerService(); });
}

void DrmSessionManager::ResourceManagerServiceDied(void* cookie) {
    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);

    // Validate the context and check if the DrmSessionManager object is still in scope.
    if (context != nullptr) {
        sp<DrmSessionManager> thiz = context->mDrmSessionManager.promote();
        if (thiz != nullptr) {
            thiz->binderDied();
        } else {
            ALOGI("DrmSessionManager is out of scope already");
        }
    }
}

void DrmSessionManager::BinderUnlinkedCallback(void* cookie) {
    BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
    // Since we don't need the context anymore, we are deleting it now.
    delete context;
}
}


}  // namespace android
}  // namespace android
+44 −6
Original line number Original line Diff line number Diff line
@@ -27,8 +27,10 @@
#include <utils/threads.h>
#include <utils/threads.h>
#include <utils/Vector.h>
#include <utils/Vector.h>


#include <future>
#include <map>
#include <map>
#include <memory>
#include <memory>
#include <set>
#include <utility>
#include <utility>
#include <vector>
#include <vector>


@@ -38,6 +40,7 @@ class DrmSessionManagerTest;


using aidl::android::media::IResourceManagerClient;
using aidl::android::media::IResourceManagerClient;
using aidl::android::media::IResourceManagerService;
using aidl::android::media::IResourceManagerService;
using aidl::android::media::MediaResourceParcel;


bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);


@@ -45,6 +48,9 @@ struct SessionInfo {
    pid_t pid;
    pid_t pid;
    uid_t uid;
    uid_t uid;
    int64_t clientId;
    int64_t clientId;
    std::shared_ptr<IResourceManagerClient> drm;
    int64_t resourceValue;

};
};


typedef std::map<std::vector<uint8_t>, SessionInfo> SessionInfoMap;
typedef std::map<std::vector<uint8_t>, SessionInfo> SessionInfoMap;
@@ -66,20 +72,52 @@ struct DrmSessionManager : public RefBase {
    size_t getSessionCount() const;
    size_t getSessionCount() const;
    bool containsSession(const Vector<uint8_t>& sessionId) const;
    bool containsSession(const Vector<uint8_t>& sessionId) const;


    // implements DeathRecipient
    void binderDied();

protected:
protected:
    virtual ~DrmSessionManager();
    virtual ~DrmSessionManager();


private:
private:
    void init();
    status_t init();

    // To set up the binder interface with the resource manager service.
    void getResourceManagerService() {
        Mutex::Autolock lock(mLock);
        getResourceManagerService_l();
    }
    void getResourceManagerService_l();

    // To add/register all the resources currently added/registered with
    // the ResourceManagerService.
    // This function will be called right after the death of the Resource
    // Manager to make sure that the newly started ResourceManagerService
    // knows about the current resource usage.
    void reRegisterAllResources_l();

    // For binder death handling
    static void ResourceManagerServiceDied(void* cookie);
    static void BinderUnlinkedCallback(void* cookie);
    void binderDied();


    std::shared_ptr<IResourceManagerService> mService;
    // BinderDiedContext defines the cookie that is passed as DeathRecipient.
    // Since this can maintain more context than a raw pointer, we can
    // validate the scope of DrmSessionManager,
    // before deferencing it upon the binder death.
    struct BinderDiedContext {
        wp<DrmSessionManager> mDrmSessionManager;
    };

    std::shared_ptr<IResourceManagerService> mService = nullptr;
    mutable Mutex mLock;
    mutable Mutex mLock;
    SessionInfoMap mSessionMap;
    SessionInfoMap mSessionMap;
    bool mInitialized;
    bool mBinderDied = false;
    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
    /**
     * Reconnecting with the ResourceManagerService, after its binder interface dies,
     * is done asynchronously. It will also make sure that, all the resources
     * asssociated with this DrmSessionManager are added with the new instance
     * of the ResourceManagerService to persist the state of resources.
     * We must store the reference of the furture to guarantee real asynchronous operation.
     */
    std::future<void> mGetServiceFuture;


    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
    DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
};
};
+1 −2
Original line number Original line Diff line number Diff line
@@ -24,9 +24,8 @@
#include <aidl/android/media/BnResourceManagerClient.h>
#include <aidl/android/media/BnResourceManagerClient.h>
#include <aidl/android/media/BnResourceManagerService.h>
#include <aidl/android/media/BnResourceManagerService.h>


#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/ProcessInfoInterface.h>
#include <mediadrm/DrmSessionManager.h>
#include <mediadrm/DrmSessionManager.h>
#include <mediautils/ProcessInfoInterface.h>


#include <algorithm>
#include <algorithm>
#include <iostream>
#include <iostream>
+331 −113

File changed.

Preview size limit exceeded, changes collapsed.

+7 −1
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ namespace aidl {
namespace android {
namespace android {
namespace media {
namespace media {
class MediaResourceParcel;
class MediaResourceParcel;
class ClientConfigParcel;
} // media
} // media
} // android
} // android
} // aidl
} // aidl
@@ -71,6 +72,7 @@ struct IDescrambler;


using hardware::cas::native::V1_0::IDescrambler;
using hardware::cas::native::V1_0::IDescrambler;
using aidl::android::media::MediaResourceParcel;
using aidl::android::media::MediaResourceParcel;
using aidl::android::media::ClientConfigParcel;


struct MediaCodec : public AHandler {
struct MediaCodec : public AHandler {
    enum Domain {
    enum Domain {
@@ -445,6 +447,8 @@ private:
    void updateTunnelPeek(const sp<AMessage> &msg);
    void updateTunnelPeek(const sp<AMessage> &msg);
    void updatePlaybackDuration(const sp<AMessage> &msg);
    void updatePlaybackDuration(const sp<AMessage> &msg);


    inline void initClientConfigParcel(ClientConfigParcel& clientConfig);

    sp<AMessage> mOutputFormat;
    sp<AMessage> mOutputFormat;
    sp<AMessage> mInputFormat;
    sp<AMessage> mInputFormat;
    sp<AMessage> mCallback;
    sp<AMessage> mCallback;
@@ -452,7 +456,7 @@ private:
    sp<AMessage> mAsyncReleaseCompleteNotification;
    sp<AMessage> mAsyncReleaseCompleteNotification;
    sp<AMessage> mOnFirstTunnelFrameReadyNotification;
    sp<AMessage> mOnFirstTunnelFrameReadyNotification;


    sp<ResourceManagerServiceProxy> mResourceManagerProxy;
    std::shared_ptr<ResourceManagerServiceProxy> mResourceManagerProxy;


    Domain mDomain;
    Domain mDomain;
    AString mLogSessionId;
    AString mLogSessionId;
@@ -691,6 +695,8 @@ private:
    };
    };


    Histogram mLatencyHist;
    Histogram mLatencyHist;
    // An unique ID for the codec - Used by the metrics.
    uint64_t mCodecId = 0;


    std::function<sp<CodecBase>(const AString &, const char *)> mGetCodecBase;
    std::function<sp<CodecBase>(const AString &, const char *)> mGetCodecBase;
    std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo;
    std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo;
Loading