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

Commit cf3bafbf authored by Brian Lindahl's avatar Brian Lindahl
Browse files

Allow MediaCodecs to be created on behalf of other client processes.

Requires the MEDIA_RESOURCE_PID_OVERRIDE permission.

Bug: 217746837
Test: atest MediaCodecResourceTest
Change-Id: Ib6214e42b74666e2959724bb5501ae71205cf11b
parent 0fe05c41
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -61,7 +61,11 @@ struct FakeProcessInfo : public ProcessInfoInterface {
        return true;
    }

    virtual bool isValidPid(int /* pid */) {
    virtual bool isPidTrusted(int /* pid */) {
        return true;
    }

    virtual bool isPidUidTrusted(int /* pid */, int /* uid */) {
        return true;
    }

+28 −15
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
            const std::shared_ptr<IResourceManagerClient> &client);
    virtual ~ResourceManagerServiceProxy();

    void init();
    status_t init();

    // implements DeathRecipient
    static void BinderDiedCallback(void* cookie);
@@ -276,6 +276,9 @@ MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
        pid_t pid, uid_t uid, const std::shared_ptr<IResourceManagerClient> &client)
        : mPid(pid), mUid(uid), mClient(client),
          mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
    if (mUid == MediaCodec::kNoUid) {
        mUid = AIBinder_getCallingUid();
    }
    if (mPid == MediaCodec::kNoPid) {
        mPid = AIBinder_getCallingPid();
    }
@@ -294,12 +297,26 @@ MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
    }
}

void MediaCodec::ResourceManagerServiceProxy::init() {
status_t MediaCodec::ResourceManagerServiceProxy::init() {
    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
    mService = IResourceManagerService::fromBinder(binder);
    if (mService == nullptr) {
        ALOGE("Failed to get ResourceManagerService");
        return;
        return UNKNOWN_ERROR;
    }

    int callerPid = AIBinder_getCallingPid();
    int callerUid = AIBinder_getCallingUid();
    if (mPid != callerPid || mUid != callerUid) {
        // Media processes don't need special permissions to act on behalf of other processes.
        if (callerUid != AID_MEDIA) {
            char const * permission = "android.permission.MEDIA_RESOURCE_OVERRIDE_PID";
            if (!checkCallingPermission(String16(permission))) {
                ALOGW("%s is required to override the caller's PID for media resource management.",
                        permission);
                return PERMISSION_DENIED;
            }
        }
    }

    // Kill clients pending removal.
@@ -310,6 +327,7 @@ void MediaCodec::ResourceManagerServiceProxy::init() {

    // after this, require mLock whenever using mService
    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
    return OK;
}

//static
@@ -773,12 +791,7 @@ MediaCodec::MediaCodec(
      mInputBufferCounter(0),
      mGetCodecBase(getCodecBase),
      mGetCodecInfo(getCodecInfo) {
    if (uid == kNoUid) {
        mUid = AIBinder_getCallingUid();
    } else {
        mUid = uid;
    }
    mResourceManagerProxy = new ResourceManagerServiceProxy(pid, mUid,
    mResourceManagerProxy = new ResourceManagerServiceProxy(pid, uid,
            ::ndk::SharedRefBase::make<ResourceManagerClient>(this));
    if (!mGetCodecBase) {
        mGetCodecBase = [](const AString &name, const char *owner) {
@@ -807,7 +820,6 @@ MediaCodec::MediaCodec(
            return NAME_NOT_FOUND;
        };
    }

    initMediametrics();
}

@@ -1363,7 +1375,11 @@ static const CodecListCache &GetCodecListCache() {
}

status_t MediaCodec::init(const AString &name) {
    mResourceManagerProxy->init();
    status_t err = mResourceManagerProxy->init();
    if (err != OK) {
        mCodec = NULL; // remove the codec
        return err;
    }

    // save init parameters for reset
    mInitName = name;
@@ -1378,7 +1394,7 @@ status_t MediaCodec::init(const AString &name) {
    bool secureCodec = false;
    const char *owner = "";
    if (!name.startsWith("android.filter.")) {
        status_t err = mGetCodecInfo(name, &mCodecInfo);
        err = mGetCodecInfo(name, &mCodecInfo);
        if (err != OK) {
            mCodec = NULL;  // remove the codec.
            return err;
@@ -1446,7 +1462,6 @@ status_t MediaCodec::init(const AString &name) {
        mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this));
    }

    status_t err;
    std::vector<MediaResourceParcel> resources;
    resources.push_back(MediaResource::CodecResource(secureCodec, mIsVideo));
    for (int i = 0; i <= kMaxRetry; ++i) {
@@ -4599,7 +4614,6 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
    mCSD.erase(mCSD.begin());
    std::shared_ptr<C2Buffer> c2Buffer;
    sp<hardware::HidlMemory> memory;
    size_t offset = 0;

    if (mFlags & kFlagUseBlockModel) {
        if (hasCryptoOrDescrambler()) {
@@ -4620,7 +4634,6 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
            memcpy(mem->unsecurePointer(), csd->data(), csd->size());
            ssize_t heapOffset;
            memory = hardware::fromHeap(mem->getMemory(&heapOffset, nullptr));
            offset += heapOffset;
        } else {
            std::shared_ptr<C2LinearBlock> block =
                FetchLinearBlock(csd->size(), {std::string{mComponentName.c_str()}});
+0 −1
Original line number Diff line number Diff line
@@ -401,7 +401,6 @@ private:
    struct ResourceManagerServiceProxy;

    State mState;
    uid_t mUid;
    bool mReleasedByResourceManager;
    sp<ALooper> mLooper;
    sp<ALooper> mCodecLooper;
+2 −1
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@ struct ProcessInfo : public ProcessInfoInterface {
    ProcessInfo();

    virtual bool getPriority(int pid, int* priority);
    virtual bool isValidPid(int pid);
    virtual bool isPidTrusted(int pid);
    virtual bool isPidUidTrusted(int pid, int uid);
    virtual bool overrideProcessInfo(int pid, int procState, int oomScore);
    virtual void removeProcessInfoOverride(int pid);

+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ namespace android {

struct ProcessInfoInterface : public RefBase {
    virtual bool getPriority(int pid, int* priority) = 0;
    virtual bool isValidPid(int pid) = 0;
    virtual bool isPidTrusted(int pid) = 0;
    virtual bool isPidUidTrusted(int pid, int uid) = 0;
    virtual bool overrideProcessInfo(int pid, int procState, int oomScore);
    virtual void removeProcessInfoOverride(int pid);

Loading