Merge "AudioPolicyManager: add support for Bluetooth LE audio codec selection" into main
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 62cf827..1cf63b0 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -9,7 +9,8 @@
[Builtin Hooks Options]
# Only turn on clang-format check for the following subfolders.
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
- media/libmediatranscoding/
- services/mediatranscoding/
media/libaudioclient/tests/
media/libaudiohal/tests/
+ media/libmediatranscoding/
+ services/camera/virtualcamera/
+ services/mediatranscoding/
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 5386e69..f320d34 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -35,3 +35,9 @@
bug: "307409002"
}
+flag {
+ namespace: "camera_platform"
+ name: "session_hal_buf_manager"
+ description: "Enable or disable HAL buffer manager as requested by the camera HAL"
+ bug: "311263114"
+}
\ No newline at end of file
diff --git a/media/audio/aconfig/audioserver.aconfig b/media/audio/aconfig/audioserver.aconfig
index e487b58..21ea1a2 100644
--- a/media/audio/aconfig/audioserver.aconfig
+++ b/media/audio/aconfig/audioserver.aconfig
@@ -5,13 +5,12 @@
package: "com.android.media.audioserver"
flag {
- name: "mutex_priority_inheritance"
+ name: "direct_track_reprioritization"
namespace: "media_audio"
description:
- "Enable mutex priority inheritance in audioserver (std::mutex does not normally transfer "
- "priority from the blocked thread to the blocking thread). "
- "This feature helps reduce audio glitching caused by low priority blocking threads."
- bug: "209491695"
+ "Modify opening a direct output on a mixport to disrupt existing clients instead "
+ "of failing to open when resource limit is reached"
+ bug: "294525897"
}
flag {
@@ -20,3 +19,13 @@
description: "Improve fdtostring implementation to properly handle timing out."
bug: "306283018"
}
+
+flag {
+ name: "mutex_priority_inheritance"
+ namespace: "media_audio"
+ description:
+ "Enable mutex priority inheritance in audioserver (std::mutex does not normally transfer "
+ "priority from the blocked thread to the blocking thread). "
+ "This feature helps reduce audio glitching caused by low priority blocking threads."
+ bug: "209491695"
+}
diff --git a/media/codec2/hal/aidl/Component.cpp b/media/codec2/hal/aidl/Component.cpp
index 4f5b899..4605af3 100644
--- a/media/codec2/hal/aidl/Component.cpp
+++ b/media/codec2/hal/aidl/Component.cpp
@@ -294,46 +294,49 @@
static constexpr IComponent::BlockPoolAllocator::Tag IGBA =
IComponent::BlockPoolAllocator::allocator;
c2_status_t status = C2_OK;
+ ::android::C2PlatformAllocatorDesc allocatorParam;
switch (allocator.getTag()) {
- case ALLOCATOR_ID:
-#ifdef __ANDROID_APEX__
- status = ::android::CreateCodec2BlockPool(
- static_cast<::android::C2PlatformAllocatorStore::id_t>(
- allocator.get<ALLOCATOR_ID>()),
- mComponent,
- &c2BlockPool);
-#else
- status = ComponentStore::GetFilterWrapper()->createBlockPool(
- static_cast<::android::C2PlatformAllocatorStore::id_t>(
- allocator.get<ALLOCATOR_ID>()),
- mComponent,
- &c2BlockPool);
-#endif
- if (status != C2_OK) {
- blockPool = nullptr;
- }
- break;
- case IGBA:
- // FIXME
- break;
+ case ALLOCATOR_ID: {
+ allocatorParam.allocatorId =
+ allocator.get<IComponent::BlockPoolAllocator::allocatorId>();
+ }
+ break;
+ case IGBA: {
+ allocatorParam.allocatorId = ::android::C2PlatformAllocatorStore::IGBA;
+ allocatorParam.igba =
+ allocator.get<IComponent::BlockPoolAllocator::allocator>().igba;
+ allocatorParam.waitableFd.reset(
+ allocator.get<IComponent::BlockPoolAllocator::allocator>()
+ .waitableFd.dup().release());
+ }
+ break;
default:
- break;
+ return ScopedAStatus::fromServiceSpecificError(C2_CORRUPTED);
}
- if (blockPool) {
+#ifdef __ANDROID_APEX__
+ status = ::android::CreateCodec2BlockPool(
+ allocatorParam,
+ mComponent,
+ &c2BlockPool);
+#else
+ status = ComponentStore::GetFilterWrapper()->createBlockPool(
+ allocatorParam,
+ mComponent,
+ &c2BlockPool);
+#endif
+ if (status != C2_OK) {
+ return ScopedAStatus::fromServiceSpecificError(status);
+ }
+ {
mBlockPoolsMutex.lock();
mBlockPools.emplace(c2BlockPool->getLocalId(), c2BlockPool);
mBlockPoolsMutex.unlock();
- } else if (status == C2_OK) {
- status = C2_CORRUPTED;
}
blockPool->blockPoolId = c2BlockPool ? c2BlockPool->getLocalId() : 0;
blockPool->configurable = SharedRefBase::make<CachedConfigurable>(
std::make_unique<BlockPoolIntf>(c2BlockPool));
- if (status == C2_OK) {
- return ScopedAStatus::ok();
- }
- return ScopedAStatus::fromServiceSpecificError(status);
+ return ScopedAStatus::ok();
}
ScopedAStatus Component::destroyBlockPool(int64_t blockPoolId) {
diff --git a/media/codec2/hal/client/client.cpp b/media/codec2/hal/client/client.cpp
index e8e7cb2..2d19ecc 100644
--- a/media/codec2/hal/client/client.cpp
+++ b/media/codec2/hal/client/client.cpp
@@ -19,6 +19,8 @@
#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <android-base/logging.h>
#include <utils/Trace.h>
+
+#include <codec2/aidl/GraphicBufferAllocator.h>
#include <codec2/hidl/client.h>
#include <C2Debug.h>
#include <C2BufferPriv.h>
@@ -74,6 +76,7 @@
#include <limits>
#include <map>
#include <mutex>
+#include <optional>
#include <sstream>
#include <thread>
#include <type_traits>
@@ -96,6 +99,9 @@
V2_0::utils::H2BGraphicBufferProducer;
using ::android::hardware::media::c2::V1_2::SurfaceSyncObj;
+using AidlGraphicBufferAllocator = ::aidl::android::hardware::media::c2::
+ implementation::GraphicBufferAllocator;
+
namespace bufferpool2_aidl = ::aidl::android::hardware::media::bufferpool2;
namespace bufferpool_hidl = ::android::hardware::media::bufferpool::V2_0;
namespace c2_aidl = ::aidl::android::hardware::media::c2;
@@ -1041,6 +1047,85 @@
}
};
+// The class holds GraphicBufferAllocator and the associated id of
+// HAL side BlockPool.
+// This is tightly coupled with BlockPool creation and destruction.
+// The life cycle inside class will be as follows.
+//
+// On createBlockPool client request.
+// 1. this::create() creates a GraphicBufferAllocator and set it as
+// the current.
+// 2. C2AIDL_HAL::createBlockPool() creates a C2BlockPool using
+// the GraphicBufferAllocator created in #1.
+// 3. this::setCurrentId() associates the id returned in #2 to the current
+//
+// On destroyBlockPool cliet request
+// 1. C2AIDL_HAL::destroyBlockPool() destroys the block pool
+// from HAL process.
+// 2. this::remove() destroys GraphicBufferAllocator which is associatted
+// with the C2BlockPool in #1.
+//
+struct Codec2Client::Component::GraphicBufferAllocators {
+private:
+ std::optional<C2BlockPool::local_id_t> mCurrentId;
+ std::shared_ptr<AidlGraphicBufferAllocator> mCurrent;
+
+ // A new BlockPool is created before the old BlockPool is destroyed.
+ // This holds the reference of the old BlockPool when a new BlockPool is
+ // created until the old BlockPool is explicitly requested for destruction.
+ std::map<C2BlockPool::local_id_t, std::shared_ptr<AidlGraphicBufferAllocator>> mOlds;
+ std::mutex mMutex;
+
+public:
+ // Creates a GraphicBufferAllocator which will be passed to HAL
+ // for creating C2BlockPool. And the created GraphicBufferAllocator
+ // will be used afterwards by current().
+ std::shared_ptr<AidlGraphicBufferAllocator> create() {
+ std::unique_lock<std::mutex> l(mMutex);
+ if (mCurrent) {
+ // If this is not stopped.
+ mCurrent->reset();
+ if (mCurrentId.has_value()) {
+ mOlds.emplace(mCurrentId.value(), mCurrent);
+ }
+ mCurrentId.reset();
+ mCurrent.reset();
+ }
+ // TODO: integrate initial value with CCodec/CCodecBufferChannel
+ mCurrent =
+ AidlGraphicBufferAllocator::CreateGraphicBufferAllocator(3 /* maxDequeueCount */);
+ ALOGD("GraphicBufferAllocator created");
+ return mCurrent;
+ }
+
+ // Associates the blockpool Id returned from HAL to the
+ // current GraphicBufferAllocator.
+ void setCurrentId(C2BlockPool::local_id_t id) {
+ std::unique_lock<std::mutex> l(mMutex);
+ CHECK(!mCurrentId.has_value());
+ mCurrentId = id;
+ }
+
+ // Returns the current GraphicBufferAllocator.
+ std::shared_ptr<AidlGraphicBufferAllocator> current() {
+ std::unique_lock<std::mutex> l(mMutex);
+ return mCurrent;
+ }
+
+ // Removes the GraphicBufferAllocator associated with given \p id.
+ void remove(C2BlockPool::local_id_t id) {
+ std::unique_lock<std::mutex> l(mMutex);
+ mOlds.erase(id);
+ if (mCurrentId == id) {
+ if (mCurrent) {
+ mCurrent->reset();
+ mCurrent.reset();
+ }
+ mCurrentId.reset();
+ }
+ }
+};
+
// Codec2Client
Codec2Client::Codec2Client(sp<HidlBase> const& base,
sp<c2_hidl::IConfigurable> const& configurable,
@@ -1125,6 +1210,7 @@
<< status << ".";
}
(*component)->mAidlBufferPoolSender->setReceiver(mAidlHostPoolManager);
+ aidlListener->component = *component;
return status;
}
@@ -1951,7 +2037,7 @@
},
mAidlBase{base},
mAidlBufferPoolSender{std::make_unique<AidlBufferPoolSender>()},
- mOutputBufferQueue{std::make_unique<OutputBufferQueue>()} {
+ mGraphicBufferAllocators{std::make_unique<GraphicBufferAllocators>()} {
}
Codec2Client::Component::~Component() {
@@ -1966,11 +2052,42 @@
std::shared_ptr<Codec2Client::Configurable>* configurable) {
if (mAidlBase) {
c2_aidl::IComponent::BlockPool aidlBlockPool;
- ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(static_cast<int32_t>(id),
- &aidlBlockPool);
- c2_status_t status = GetC2Status(transStatus, "createBlockPool");
- if (status != C2_OK) {
- return status;
+ c2_status_t status = C2_OK;
+
+ // TODO: Temporary mapping for the current CCodecBufferChannel.
+ // Handle this properly and remove this temporary allocator mapping.
+ id = id == C2PlatformAllocatorStore::BUFFERQUEUE ?
+ C2PlatformAllocatorStore::IGBA : id;
+
+ if (id == C2PlatformAllocatorStore::IGBA) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->create();
+ ::ndk::ScopedFileDescriptor waitableFd;
+ ::ndk::ScopedAStatus ret = gba->getWaitableFd(&waitableFd);
+ status = GetC2Status(ret, "Gba::getWaitableFd");
+ if (status != C2_OK) {
+ return status;
+ }
+ c2_aidl::IComponent::BlockPoolAllocator allocator;
+ allocator.set<c2_aidl::IComponent::BlockPoolAllocator::allocator>();
+ allocator.get<c2_aidl::IComponent::BlockPoolAllocator::allocator>().igba =
+ c2_aidl::IGraphicBufferAllocator::fromBinder(gba->asBinder());
+ allocator.get<c2_aidl::IComponent::BlockPoolAllocator::allocator>().waitableFd =
+ std::move(waitableFd);
+ ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(
+ allocator, &aidlBlockPool);
+ status = GetC2Status(transStatus, "createBlockPool");
+ if (status != C2_OK) {
+ return status;
+ }
+ mGraphicBufferAllocators->setCurrentId(aidlBlockPool.blockPoolId);
+ } else {
+ ::ndk::ScopedAStatus transStatus = mAidlBase->createBlockPool(
+ static_cast<int32_t>(id), &aidlBlockPool);
+ status = GetC2Status(transStatus, "createBlockPool");
+ if (status != C2_OK) {
+ return status;
+ }
}
*blockPoolId = aidlBlockPool.blockPoolId;
*configurable = std::make_shared<Configurable>(aidlBlockPool.configurable);
@@ -2003,6 +2120,7 @@
c2_status_t Codec2Client::Component::destroyBlockPool(
C2BlockPool::local_id_t localId) {
if (mAidlBase) {
+ mGraphicBufferAllocators->remove(localId);
::ndk::ScopedAStatus transStatus = mAidlBase->destroyBlockPool(localId);
return GetC2Status(transStatus, "destroyBlockPool");
}
@@ -2017,8 +2135,12 @@
void Codec2Client::Component::handleOnWorkDone(
const std::list<std::unique_ptr<C2Work>> &workItems) {
- // Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue->holdBufferQueueBlocks(workItems);
+ if (mAidlBase) {
+ holdIgbaBlocks(workItems);
+ } else {
+ // Output bufferqueue-based blocks' lifetime management
+ mOutputBufferQueue->holdBufferQueueBlocks(workItems);
+ }
}
c2_status_t Codec2Client::Component::queue(
@@ -2102,8 +2224,12 @@
}
}
- // Output bufferqueue-based blocks' lifetime management
- mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
+ if (mAidlBase) {
+ holdIgbaBlocks(*flushedWork);
+ } else {
+ // Output bufferqueue-based blocks' lifetime management
+ mOutputBufferQueue->holdBufferQueueBlocks(*flushedWork);
+ }
return status;
}
@@ -2242,6 +2368,17 @@
const sp<IGraphicBufferProducer>& surface,
uint32_t generation,
int maxDequeueCount) {
+ if (mAidlBase) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (!gba) {
+ LOG(ERROR) << "setOutputSurface for AIDL -- "
+ "GraphicBufferAllocator was not created.";
+ return C2_CORRUPTED;
+ }
+ bool ret = gba->configure(surface, generation, maxDequeueCount);
+ return ret ? C2_OK : C2_CORRUPTED;
+ }
uint64_t bqId = 0;
sp<IGraphicBufferProducer> nullIgbp;
sp<HGraphicBufferProducer2> nullHgbp;
@@ -2303,10 +2440,6 @@
ALOGD("setOutputSurface -- generation=%u consumer usage=%#llx%s",
generation, (long long)consumerUsage, syncObj ? " sync" : "");
- if (mAidlBase) {
- // FIXME
- return C2_OMITTED;
- }
Return<c2_hidl::Status> transStatus = syncObj ?
mHidlBase1_2->setOutputSurfaceWithSyncObj(
static_cast<uint64_t>(blockPoolId),
@@ -2335,26 +2468,51 @@
const QueueBufferInput& input,
QueueBufferOutput* output) {
ScopedTrace trace(ATRACE_TAG,"Codec2Client::Component::queueToOutputSurface");
+ if (mAidlBase) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (gba) {
+ return gba->displayBuffer(block, input, output);
+ } else {
+ return C2_NOT_FOUND;
+ }
+ }
return mOutputBufferQueue->outputBuffer(block, input, output);
}
void Codec2Client::Component::pollForRenderedFrames(FrameEventHistoryDelta* delta) {
+ if (mAidlBase) {
+ // TODO b/311348680
+ return;
+ }
mOutputBufferQueue->pollForRenderedFrames(delta);
}
void Codec2Client::Component::setOutputSurfaceMaxDequeueCount(
int maxDequeueCount) {
+ if (mAidlBase) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (gba) {
+ gba->updateMaxDequeueBufferCount(maxDequeueCount);
+ }
+ return;
+ }
mOutputBufferQueue->updateMaxDequeueBufferCount(maxDequeueCount);
}
void Codec2Client::Component::stopUsingOutputSurface(
C2BlockPool::local_id_t blockPoolId) {
- std::scoped_lock lock(mOutputMutex);
- mOutputBufferQueue->stop();
if (mAidlBase) {
- // FIXME
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (gba) {
+ gba->reset();
+ }
return;
}
+ std::scoped_lock lock(mOutputMutex);
+ mOutputBufferQueue->stop();
Return<c2_hidl::Status> transStatus = mHidlBase1_0->setOutputSurface(
static_cast<uint64_t>(blockPoolId), nullptr);
if (!transStatus.isOk()) {
@@ -2372,9 +2530,50 @@
void Codec2Client::Component::onBufferReleasedFromOutputSurface(
uint32_t generation) {
+ if (mAidlBase) {
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (gba) {
+ gba->onBufferReleased(generation);
+ }
+ return;
+ }
mOutputBufferQueue->onBufferReleased(generation);
}
+void Codec2Client::Component::holdIgbaBlocks(
+ const std::list<std::unique_ptr<C2Work>>& workList) {
+ if (!mAidlBase) {
+ return;
+ }
+ std::shared_ptr<AidlGraphicBufferAllocator> gba =
+ mGraphicBufferAllocators->current();
+ if (!gba) {
+ return;
+ }
+ std::shared_ptr<c2_aidl::IGraphicBufferAllocator> igba =
+ c2_aidl::IGraphicBufferAllocator::fromBinder(gba->asBinder());
+ for (const std::unique_ptr<C2Work>& work : workList) {
+ if (!work) [[unlikely]] {
+ continue;
+ }
+ for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) {
+ if (!worklet) {
+ continue;
+ }
+ for (const std::shared_ptr<C2Buffer>& buffer : worklet->output.buffers) {
+ if (buffer) {
+ for (const C2ConstGraphicBlock& block : buffer->data().graphicBlocks()) {
+ std::shared_ptr<_C2BlockPoolData> poolData =
+ _C2BlockFactory::GetGraphicBlockPoolData(block);
+ _C2BlockFactory::RegisterIgba(poolData, igba);
+ }
+ }
+ }
+ }
+ }
+}
+
c2_status_t Codec2Client::Component::connectToInputSurface(
const std::shared_ptr<InputSurface>& inputSurface,
std::shared_ptr<InputSurfaceConnection>* connection) {
diff --git a/media/codec2/hal/client/include/codec2/hidl/client.h b/media/codec2/hal/client/include/codec2/hidl/client.h
index a8dd0bf..3b7f7a6 100644
--- a/media/codec2/hal/client/include/codec2/hidl/client.h
+++ b/media/codec2/hal/client/include/codec2/hidl/client.h
@@ -478,6 +478,14 @@
void onBufferReleasedFromOutputSurface(
uint32_t generation);
+ // When the client received \p workList and the blocks inside
+ // \p workList are IGBA based graphic blocks, specify the owner
+ // as the current IGBA for the future operations.
+ // Future operations could be rendering the blocks to the surface
+ // or deallocating blocks to the surface.
+ void holdIgbaBlocks(
+ const std::list<std::unique_ptr<C2Work>>& workList);
+
// Connect to a given InputSurface.
c2_status_t connectToInputSurface(
const std::shared_ptr<InputSurface>& inputSurface,
@@ -517,6 +525,9 @@
// In order to prevent the race condition mutex is added.
std::mutex mOutputMutex;
+ struct GraphicBufferAllocators;
+ std::unique_ptr<GraphicBufferAllocators> mGraphicBufferAllocators;
+
class AidlDeathManager;
static AidlDeathManager *GetAidlDeathManager();
std::optional<size_t> mAidlDeathSeq;
diff --git a/media/codec2/hal/plugin/FilterWrapper.cpp b/media/codec2/hal/plugin/FilterWrapper.cpp
index d5124fd..197d6e7 100644
--- a/media/codec2/hal/plugin/FilterWrapper.cpp
+++ b/media/codec2/hal/plugin/FilterWrapper.cpp
@@ -969,6 +969,15 @@
C2PlatformAllocatorStore::id_t allocatorId,
std::shared_ptr<const C2Component> component,
std::shared_ptr<C2BlockPool> *pool) {
+ C2PlatformAllocatorDesc allocatorParam;
+ allocatorParam.allocatorId = allocatorId;
+ return createBlockPool(allocatorParam, component, pool);
+}
+
+c2_status_t FilterWrapper::createBlockPool(
+ C2PlatformAllocatorDesc &allocatorParam,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
std::unique_lock lock(mWrappedComponentsMutex);
for (auto it = mWrappedComponents.begin(); it != mWrappedComponents.end(); ) {
std::shared_ptr<const C2Component> comp = it->front().lock();
@@ -983,13 +992,13 @@
[](const std::weak_ptr<const C2Component> &el) {
return el.lock();
});
- if (C2_OK == CreateCodec2BlockPool(allocatorId, components, pool)) {
+ if (C2_OK == CreateCodec2BlockPool(allocatorParam, components, pool)) {
return C2_OK;
}
}
++it;
}
- return CreateCodec2BlockPool(allocatorId, component, pool);
+ return CreateCodec2BlockPool(allocatorParam, component, pool);
}
c2_status_t FilterWrapper::queryParamsForPreviousComponent(
diff --git a/media/codec2/hal/plugin/FilterWrapperStub.cpp b/media/codec2/hal/plugin/FilterWrapperStub.cpp
index 01ca596..3fd5409 100644
--- a/media/codec2/hal/plugin/FilterWrapperStub.cpp
+++ b/media/codec2/hal/plugin/FilterWrapperStub.cpp
@@ -45,7 +45,16 @@
C2PlatformAllocatorStore::id_t allocatorId,
std::shared_ptr<const C2Component> component,
std::shared_ptr<C2BlockPool> *pool) {
- return CreateCodec2BlockPool(allocatorId, component, pool);
+ C2PlatformAllocatorDesc allocatorParam;
+ allocatorParam.allocatorId = allocatorId;
+ return createBlockPool(allocatorParam, component, pool);
+}
+
+c2_status_t FilterWrapper::createBlockPool(
+ C2PlatformAllocatorDesc &allocatorParam,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
+ return CreateCodec2BlockPool(allocatorParam, component, pool);
}
} // namespace android
diff --git a/media/codec2/hal/plugin/internal/FilterWrapper.h b/media/codec2/hal/plugin/internal/FilterWrapper.h
index cf2cc30..dcffb5c 100644
--- a/media/codec2/hal/plugin/internal/FilterWrapper.h
+++ b/media/codec2/hal/plugin/internal/FilterWrapper.h
@@ -90,6 +90,14 @@
std::shared_ptr<C2BlockPool> *pool);
/**
+ * Create a C2BlockPool object with |allocatorParam| for |component|.
+ */
+ c2_status_t createBlockPool(
+ C2PlatformAllocatorDesc &allocatorParam,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
+ /**
* Query parameters that |intf| wants from the previous component.
*/
c2_status_t queryParamsForPreviousComponent(
diff --git a/media/codec2/vndk/C2Fence.cpp b/media/codec2/vndk/C2Fence.cpp
index 4c385f1..52ebe25 100644
--- a/media/codec2/vndk/C2Fence.cpp
+++ b/media/codec2/vndk/C2Fence.cpp
@@ -26,6 +26,8 @@
#include <C2FenceFactory.h>
#include <C2SurfaceSyncObj.h>
+#include <utility>
+
#define MAX_FENCE_FDS 1
class C2Fence::Impl {
@@ -485,17 +487,26 @@
mValid = (mPipeFd.get() >= 0);
}
+ PipeFenceImpl(::android::base::unique_fd &&ufd) : mPipeFd{std::move(ufd)} {
+ mValid = (mPipeFd.get() >= 0);
+ }
+
private:
friend struct _C2FenceFactory;
static constexpr int kPipeFenceWaitLimitSecs = 5;
mutable std::atomic<bool> mValid;
- ::android::base::unique_fd mPipeFd;
+ const ::android::base::unique_fd mPipeFd;
};
C2Fence _C2FenceFactory::CreatePipeFence(int fd) {
+ ::android::base::unique_fd ufd{fd};
+ return CreatePipeFence(std::move(ufd));
+}
+
+C2Fence _C2FenceFactory::CreatePipeFence(::android::base::unique_fd &&ufd) {
std::shared_ptr<_C2FenceFactory::PipeFenceImpl> impl =
- std::make_shared<_C2FenceFactory::PipeFenceImpl>(fd);
+ std::make_shared<_C2FenceFactory::PipeFenceImpl>(std::move(ufd));
std::shared_ptr<C2Fence::Impl> p = std::static_pointer_cast<C2Fence::Impl>(impl);
if (!p) {
ALOGE("PipeFence creation failure");
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 76c378d..e7fd14f 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -26,12 +26,15 @@
#include <C2BqBufferPriv.h>
#include <C2Component.h>
#include <C2Config.h>
+#include <C2IgbaBufferPriv.h>
#include <C2PlatformStorePluginLoader.h>
#include <C2PlatformSupport.h>
#include <codec2/common/HalSelection.h>
#include <cutils/properties.h>
#include <util/C2InterfaceHelper.h>
+#include <aidl/android/hardware/media/c2/IGraphicBufferAllocator.h>
+
#include <dlfcn.h>
#include <unistd.h> // getpagesize
@@ -92,6 +95,9 @@
/// returns a shared-singleton bufferqueue supporting gralloc allocator
std::shared_ptr<C2Allocator> fetchBufferQueueAllocator();
+ /// returns a shared-singleton IGBA supporting AHardwareBuffer/gralloc allocator
+ std::shared_ptr<C2Allocator> fetchIgbaAllocator();
+
/// component store to use
std::mutex _mComponentStoreSetLock; // protects the entire updating _mComponentStore and its
// dependencies
@@ -158,6 +164,10 @@
*allocator = fetchBlobAllocator();
break;
+ case C2PlatformAllocatorStore::IGBA:
+ *allocator = fetchIgbaAllocator();
+ break;
+
default:
// Try to create allocator from platform store plugins.
c2_status_t res =
@@ -389,6 +399,18 @@
return allocator;
}
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIgbaAllocator() {
+ static std::mutex mutex;
+ static std::weak_ptr<C2Allocator> ahwbAllocator;
+ std::lock_guard<std::mutex> lock(mutex);
+ std::shared_ptr<C2Allocator> allocator = ahwbAllocator.lock();
+ if (allocator == nullptr) {
+ allocator = std::make_shared<C2AllocatorAhwb>(C2PlatformAllocatorStore::IGBA);
+ ahwbAllocator = allocator;
+ }
+ return allocator;
+}
+
namespace {
std::mutex gPreferredComponentStoreMutex;
std::shared_ptr<C2ComponentStore> gPreferredComponentStore;
@@ -460,12 +482,13 @@
private:
c2_status_t _createBlockPool(
- C2PlatformAllocatorStore::id_t allocatorId,
+ C2PlatformAllocatorDesc &allocatorParam,
std::vector<std::shared_ptr<const C2Component>> components,
C2BlockPool::local_id_t poolId,
std::shared_ptr<C2BlockPool> *pool) {
std::shared_ptr<C2AllocatorStore> allocatorStore =
GetCodec2PlatformAllocatorStore();
+ C2PlatformAllocatorStore::id_t allocatorId = allocatorParam.allocatorId;
std::shared_ptr<C2Allocator> allocator;
c2_status_t res = C2_NOT_FOUND;
@@ -532,6 +555,22 @@
components.begin(), components.end());
}
break;
+ case C2PlatformAllocatorStore::IGBA:
+ res = allocatorStore->fetchAllocator(
+ C2PlatformAllocatorStore::IGBA, &allocator);
+ if (res == C2_OK) {
+ std::shared_ptr<C2BlockPool> ptr(
+ new C2IgbaBlockPool(allocator,
+ allocatorParam.igba,
+ std::move(allocatorParam.waitableFd),
+ poolId), deleter);
+ *pool = ptr;
+ mBlockPools[poolId] = ptr;
+ mComponents[poolId].insert(
+ mComponents[poolId].end(),
+ components.begin(), components.end());
+ }
+ break;
default:
// Try to create block pool from platform store plugins.
std::shared_ptr<C2BlockPool> ptr;
@@ -554,10 +593,20 @@
C2PlatformAllocatorStore::id_t allocatorId,
std::vector<std::shared_ptr<const C2Component>> components,
std::shared_ptr<C2BlockPool> *pool) {
- std::unique_lock lock(mMutex);
- return _createBlockPool(allocatorId, components, mBlockPoolSeqId++, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return createBlockPool(allocator, components, pool);
}
+ c2_status_t createBlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ std::vector<std::shared_ptr<const C2Component>> components,
+ std::shared_ptr<C2BlockPool> *pool) {
+ std::unique_lock lock(mMutex);
+ return _createBlockPool(allocator, components, mBlockPoolSeqId++, pool);
+ }
+
+
c2_status_t getBlockPool(
C2BlockPool::local_id_t blockPoolId,
std::shared_ptr<const C2Component> component,
@@ -586,8 +635,10 @@
}
// TODO: remove this. this is temporary
if (blockPoolId == C2BlockPool::PLATFORM_START) {
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
return _createBlockPool(
- C2PlatformAllocatorStore::BUFFERQUEUE, {component}, blockPoolId, pool);
+ allocator, {component}, blockPoolId, pool);
}
return C2_NOT_FOUND;
}
@@ -644,7 +695,9 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- return sBlockPoolCache->createBlockPool(allocatorId, components, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return sBlockPoolCache->createBlockPool(allocator, components, pool);
}
c2_status_t CreateCodec2BlockPool(
@@ -653,7 +706,27 @@
std::shared_ptr<C2BlockPool> *pool) {
pool->reset();
- return sBlockPoolCache->createBlockPool(allocatorId, {component}, pool);
+ C2PlatformAllocatorDesc allocator;
+ allocator.allocatorId = allocatorId;
+ return sBlockPoolCache->createBlockPool(allocator, {component}, pool);
+}
+
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ const std::vector<std::shared_ptr<const C2Component>> &components,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+
+ return sBlockPoolCache->createBlockPool(allocator, components, pool);
+}
+
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+
+ return sBlockPoolCache->createBlockPool(allocator, {component}, pool);
}
class C2PlatformComponentStore : public C2ComponentStore {
diff --git a/media/codec2/vndk/include/C2FenceFactory.h b/media/codec2/vndk/include/C2FenceFactory.h
index 9b09980..4f974ca 100644
--- a/media/codec2/vndk/include/C2FenceFactory.h
+++ b/media/codec2/vndk/include/C2FenceFactory.h
@@ -20,6 +20,8 @@
#include <C2Buffer.h>
+#include <android-base/unique_fd.h>
+
/*
* Create a list of fds from fence
*
@@ -69,6 +71,7 @@
/*
* Create C2Fence from an fd created by pipe()/pipe2() syscall.
+ * The ownership of \p fd is transterred to the returned C2Fence.
*
* \param fd An fd representing the write end from a pair of
* file descriptors which are created by
@@ -76,6 +79,15 @@
*/
static C2Fence CreatePipeFence(int fd);
+ /*
+ * Create C2Fence from a unique_fd created by pipe()/pipe2() syscall.
+ *
+ * \param ufd A unique_fd representing the write end from a pair
+ * of file descriptors which are created by
+ * pipe()/pipe2() syscall.
+ */
+ static C2Fence CreatePipeFence(::android::base::unique_fd &&ufd);
+
/**
* Create a native handle from fence for marshalling
*
diff --git a/media/codec2/vndk/include/C2IgbaBufferPriv.h b/media/codec2/vndk/include/C2IgbaBufferPriv.h
index a5676b7..5879263 100644
--- a/media/codec2/vndk/include/C2IgbaBufferPriv.h
+++ b/media/codec2/vndk/include/C2IgbaBufferPriv.h
@@ -17,6 +17,8 @@
#include <C2Buffer.h>
+#include <android-base/unique_fd.h>
+
#include <memory>
namespace aidl::android::hardware::media::c2 {
@@ -32,8 +34,9 @@
public:
explicit C2IgbaBlockPool(
const std::shared_ptr<C2Allocator> &allocator,
- const std::shared_ptr<
- ::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba,
+ const std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator>
+ &igba,
+ ::android::base::unique_fd &&ufd,
const local_id_t localId);
virtual ~C2IgbaBlockPool() = default;
@@ -89,8 +92,7 @@
C2IgbaBlockPoolData(
const AHardwareBuffer *buffer,
- const std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator>
- &igba);
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
virtual ~C2IgbaBlockPoolData() override;
@@ -103,7 +105,10 @@
void disown();
+ void registerIgba(std::shared_ptr<
+ ::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
+
bool mOwned;
const AHardwareBuffer *mBuffer;
- const std::weak_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> mIgba;
+ std::weak_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> mIgba;
};
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
index 221a799..6fa155a 100644
--- a/media/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -22,6 +22,12 @@
#include <memory>
+#include <android-base/unique_fd.h>
+
+namespace aidl::android::hardware::media::c2 {
+class IGraphicBufferAllocator;
+}
+
namespace android {
/**
@@ -164,6 +170,53 @@
std::shared_ptr<C2BlockPool> *pool);
/**
+ * BlockPool creation parameters regarding allocator.
+ *
+ * igba, waitableFd are required only when allocatorId is
+ * C2PlatformAllocatorStore::IGBA.
+ */
+struct C2PlatformAllocatorDesc {
+ C2PlatformAllocatorStore::id_t allocatorId;
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> igba;
+ ::android::base::unique_fd waitableFd; // This will be passed and moved to C2Fence
+ // implementation.
+};
+
+/**
+ * Creates a block pool.
+ * \param allocator allocator ID and parameters which are used to allocate blocks
+ * \param component the component using the block pool (must be non-null)
+ * \param pool pointer to where the created block pool shall be store on success.
+ * nullptr will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the allocator does not exist
+ * \retval C2_NO_MEMORY not enough memory to create a block pool
+ */
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
+ * Creates a block pool.
+ * \param allocator allocator ID and parameters which are used to allocate blocks
+ * \param components the components using the block pool
+ * \param pool pointer to where the created block pool shall be store on success.
+ * nullptr will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the allocator does not exist
+ * \retval C2_NO_MEMORY not enough memory to create a block pool
+ */
+c2_status_t CreateCodec2BlockPool(
+ C2PlatformAllocatorDesc &allocator,
+ const std::vector<std::shared_ptr<const C2Component>> &components,
+ std::shared_ptr<C2BlockPool> *pool);
+
+/**
* Returns the platform component store.
* \retval nullptr if the platform component store could not be obtained
*/
diff --git a/media/codec2/vndk/internal/C2BlockInternal.h b/media/codec2/vndk/internal/C2BlockInternal.h
index 8198ee1..4baf2db 100644
--- a/media/codec2/vndk/internal/C2BlockInternal.h
+++ b/media/codec2/vndk/internal/C2BlockInternal.h
@@ -39,6 +39,12 @@
}
+namespace aidl::android::hardware::media::c2 {
+
+// IGraphicBufferAllocator for media.c2 aidl
+class IGraphicBufferAllocator;
+}
+
typedef struct AHardwareBuffer AHardwareBuffer;
using bufferpool_BufferPoolData = android::hardware::media::bufferpool::BufferPoolData;
@@ -472,6 +478,16 @@
*/
static void DisownIgbaBlock(
const std::shared_ptr<_C2BlockPoolData>& poolData);
+
+ /**
+ * When the client receives a block from HAL, the client needs to store
+ * IGraphicBufferAllocator from which the block was originally allocated.
+ * The stored \p igba will be used in the dtor to deallocate the buffer.
+ * (calling IGraphicBufferAllocator::deallocate to reclaim.)
+ */
+ static void RegisterIgba(
+ const std::shared_ptr<_C2BlockPoolData>& poolData,
+ std::shared_ptr<::aidl::android::hardware::media::c2::IGraphicBufferAllocator> &igba);
};
#endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
diff --git a/media/codec2/vndk/platform/C2IgbaBuffer.cpp b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
index 853d5a3..2051e8f 100644
--- a/media/codec2/vndk/platform/C2IgbaBuffer.cpp
+++ b/media/codec2/vndk/platform/C2IgbaBuffer.cpp
@@ -67,7 +67,8 @@
return err;
}
std::shared_ptr<C2IgbaBlockPoolData> poolData =
- std::make_shared<C2IgbaBlockPoolData>(ahwb, igba);
+ std::make_shared<C2IgbaBlockPoolData>(
+ ahwb, const_cast<std::shared_ptr<C2IGBA>&>(igba));
*block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
return C2_OK;
} else {
@@ -79,7 +80,7 @@
C2IgbaBlockPoolData::C2IgbaBlockPoolData(
const AHardwareBuffer *buffer,
- const std::shared_ptr<C2IGBA> &igba) : mOwned(true), mBuffer(buffer), mIgba(igba) {
+ std::shared_ptr<C2IGBA> &igba) : mOwned(true), mBuffer(buffer), mIgba(igba) {
CHECK(mBuffer);
AHardwareBuffer_acquire(const_cast<AHardwareBuffer *>(mBuffer));
}
@@ -115,6 +116,10 @@
mOwned = false;
}
+void C2IgbaBlockPoolData::registerIgba(std::shared_ptr<C2IGBA> &igba) {
+ mIgba = igba;
+}
+
std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(AHardwareBuffer *ahwb) {
// TODO: get proper allocator? and synchronization? or allocator-less?
static std::shared_ptr<C2AllocatorAhwb> sAllocator = std::make_shared<C2AllocatorAhwb>(0);
@@ -148,22 +153,30 @@
}
}
+void _C2BlockFactory::RegisterIgba(
+ const std::shared_ptr<_C2BlockPoolData>& data,
+ std::shared_ptr<C2IGBA> &igba) {
+ if (data && data->getType() == _C2BlockPoolData::TYPE_AHWBUFFER) {
+ const std::shared_ptr<C2IgbaBlockPoolData> poolData =
+ std::static_pointer_cast<C2IgbaBlockPoolData>(data);
+ poolData->registerIgba(igba);
+ }
+}
+
C2IgbaBlockPool::C2IgbaBlockPool(
const std::shared_ptr<C2Allocator> &allocator,
const std::shared_ptr<C2IGBA> &igba,
+ ::android::base::unique_fd &&ufd,
const local_id_t localId) : mAllocator(allocator), mIgba(igba), mLocalId(localId) {
if (!mIgba) {
mValid = false;
return;
}
- // TODO: Remove IPC (This is a nested IPC call during c2aidl creatBlockPool().
- ::ndk::ScopedFileDescriptor fd;
- ::ndk::ScopedAStatus status = mIgba->getWaitableFd(&fd);
- if (!status.isOk()) {
+ if (ufd.get() < 0) {
mValid = false;
return;
}
- mWaitFence = _C2FenceFactory::CreatePipeFence(fd.release());
+ mWaitFence = _C2FenceFactory::CreatePipeFence(std::move(ufd));
if (!mWaitFence.valid()) {
mValid = false;
return;
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 2870c4c..a7adfbd 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -366,14 +366,15 @@
return mStatus;
}
+ std::unique_lock ul(mLock, std::defer_lock);
if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
+ ul.lock();
if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) {
return NO_ERROR;
}
if (replySize == nullptr || *replySize != sizeof(status_t) || replyData == nullptr) {
return BAD_VALUE;
}
- mLock.lock();
}
std::vector<uint8_t> data;
@@ -398,7 +399,6 @@
if (status == NO_ERROR) {
mEnabled = (cmdCode == EFFECT_CMD_ENABLE);
}
- mLock.unlock();
}
return status;
diff --git a/media/libaudiohal/impl/Hal2AidlMapper.cpp b/media/libaudiohal/impl/Hal2AidlMapper.cpp
index f187057..47fcd27 100644
--- a/media/libaudiohal/impl/Hal2AidlMapper.cpp
+++ b/media/libaudiohal/impl/Hal2AidlMapper.cpp
@@ -82,6 +82,16 @@
}
}
+bool containHapticChannel(AudioChannelLayout channel) {
+ return channel.getTag() == AudioChannelLayout::Tag::layoutMask &&
+ ((channel.get<AudioChannelLayout::Tag::layoutMask>()
+ & AudioChannelLayout::CHANNEL_HAPTIC_A)
+ == AudioChannelLayout::CHANNEL_HAPTIC_A ||
+ (channel.get<AudioChannelLayout::Tag::layoutMask>()
+ & AudioChannelLayout::CHANNEL_HAPTIC_B)
+ == AudioChannelLayout::CHANNEL_HAPTIC_B);
+}
+
} // namespace
Hal2AidlMapper::Hal2AidlMapper(const std::string& instance, const std::shared_ptr<IModule>& module)
@@ -438,11 +448,20 @@
Hal2AidlMapper::Ports::iterator Hal2AidlMapper::findPort(
const AudioConfig& config, const AudioIoFlags& flags,
const std::set<int32_t>& destinationPortIds) {
- auto belongsToProfile = [&config](const AudioProfile& prof) {
+ auto channelMaskMatches = [](const std::vector<AudioChannelLayout>& channelMasks,
+ const AudioChannelLayout& channelMask) {
+ // Return true when 1) the channel mask is none and none of the channel mask from the
+ // collection contains haptic channel mask, or 2) the channel mask collection contains
+ // the queried channel mask.
+ return (channelMask.getTag() == AudioChannelLayout::none &&
+ std::none_of(channelMasks.begin(), channelMasks.end(),
+ containHapticChannel)) ||
+ std::find(channelMasks.begin(), channelMasks.end(), channelMask)
+ != channelMasks.end();
+ };
+ auto belongsToProfile = [&config, &channelMaskMatches](const AudioProfile& prof) {
return (isDefaultAudioFormat(config.base.format) || prof.format == config.base.format) &&
- (config.base.channelMask.getTag() == AudioChannelLayout::none ||
- std::find(prof.channelMasks.begin(), prof.channelMasks.end(),
- config.base.channelMask) != prof.channelMasks.end()) &&
+ channelMaskMatches(prof.channelMasks, config.base.channelMask) &&
(config.base.sampleRate == 0 ||
std::find(prof.sampleRates.begin(), prof.sampleRates.end(),
config.base.sampleRate) != prof.sampleRates.end());
diff --git a/media/libeffects/downmix/aidl/DownmixContext.cpp b/media/libeffects/downmix/aidl/DownmixContext.cpp
index ac893d8..0e76d1d 100644
--- a/media/libeffects/downmix/aidl/DownmixContext.cpp
+++ b/media/libeffects/downmix/aidl/DownmixContext.cpp
@@ -66,8 +66,8 @@
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " sample " << samples;
IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
- if (in == nullptr || out == nullptr || getInputFrameSize() != getOutputFrameSize() ||
- getInputFrameSize() == 0) {
+ if (in == nullptr || out == nullptr ||
+ getCommon().input.frameCount != getCommon().output.frameCount || getInputFrameSize() == 0) {
return status;
}
@@ -112,7 +112,7 @@
void DownmixContext::init_params(const Parameter::Common& common) {
// when configuring the effect, do not allow a blank or unsupported channel mask
AudioChannelLayout channelMask = common.input.base.channelMask;
- if (isChannelMaskValid(channelMask)) {
+ if (!isChannelMaskValid(channelMask)) {
LOG(ERROR) << "Downmix_Configure error: input channel mask " << channelMask.toString()
<< " not supported";
} else {
@@ -123,7 +123,7 @@
}
bool DownmixContext::isChannelMaskValid(AudioChannelLayout channelMask) {
- if (channelMask.getTag() == AudioChannelLayout::layoutMask) return false;
+ if (channelMask.getTag() != AudioChannelLayout::layoutMask) return false;
int chMask = channelMask.get<AudioChannelLayout::layoutMask>();
// check against unsupported channels (up to FCC_26)
constexpr uint32_t MAXIMUM_CHANNEL_MASK = AudioChannelLayout::LAYOUT_22POINT2 |
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index 30f6a91..6da8e31 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -148,8 +148,8 @@
class DrmSessionManagerTest : public ::testing::Test {
public:
DrmSessionManagerTest()
- : mService(::ndk::SharedRefBase::make<ResourceManagerService>
- (new FakeProcessInfo(), new FakeSystemCallback())),
+ : mService(ResourceManagerService::Create(
+ new FakeProcessInfo(), new FakeSystemCallback())),
mDrmSessionManager(new DrmSessionManager(mService)),
mTestDrm1(::ndk::SharedRefBase::make<FakeDrm>(
kTestSessionId1, mDrmSessionManager)),
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 97fd074..86741a6 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -2484,7 +2484,7 @@
{
audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
const char *mime;
- if (meta->findCString(kKeyMIMEType, &mime)
+ if (meta != nullptr && meta->findCString(kKeyMIMEType, &mime)
&& strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_OPUS) == 0) {
return false;
}
diff --git a/media/utils/include/mediautils/FixedString.h b/media/utils/include/mediautils/FixedString.h
index 047aa82..c316813 100644
--- a/media/utils/include/mediautils/FixedString.h
+++ b/media/utils/include/mediautils/FixedString.h
@@ -101,10 +101,15 @@
return strncmp(c_str(), s, capacity() + 1) == 0;
}
- bool operator==(std::string_view s) const {
+ bool operator==(const std::string_view s) const {
return size() == s.size() && memcmp(data(), s.data(), size()) == 0;
}
+ template <uint32_t N_>
+ bool operator==(const FixedString<N_>& s) const {
+ return operator==(s.asStringView());
+ }
+
// operator not-equals
template <typename T>
bool operator!=(const T& other) const {
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
index d1675fd..3fdc6eb 100644
--- a/media/utils/tests/Android.bp
+++ b/media/utils/tests/Android.bp
@@ -13,7 +13,6 @@
host_supported: true,
- cpp_std: "gnu++17",
cflags: [
"-Wall",
"-Werror",
diff --git a/services/audioflinger/afutils/NBAIO_Tee.h b/services/audioflinger/afutils/NBAIO_Tee.h
index 13335fe..a5c544e 100644
--- a/services/audioflinger/afutils/NBAIO_Tee.h
+++ b/services/audioflinger/afutils/NBAIO_Tee.h
@@ -24,6 +24,7 @@
#include <mutex>
#include <set>
+#include <audio_utils/clock.h>
#include <cutils/properties.h>
#include <media/nbaio/NBAIO.h>
diff --git a/services/audioflinger/datapath/SpdifStreamOut.h b/services/audioflinger/datapath/SpdifStreamOut.h
index 321b172..56d57f6 100644
--- a/services/audioflinger/datapath/SpdifStreamOut.h
+++ b/services/audioflinger/datapath/SpdifStreamOut.h
@@ -120,7 +120,6 @@
audio_config_base_t mApplicationConfig = AUDIO_CONFIG_BASE_INITIALIZER;
ssize_t writeDataBurst(const void* data, size_t bytes);
- ssize_t writeInternal(const void* buffer, size_t bytes);
#ifdef TEE_SINK
NBAIO_Tee mTee;
diff --git a/services/camera/virtualcamera/TEST_MAPPING b/services/camera/virtualcamera/TEST_MAPPING
index 10ba61a..66c5e52 100644
--- a/services/camera/virtualcamera/TEST_MAPPING
+++ b/services/camera/virtualcamera/TEST_MAPPING
@@ -1,8 +1,10 @@
{
- "postsubmit": [
+ "presubmit" : [
{
"name": "virtual_camera_tests"
- },
+ }
+ ],
+ "postsubmit": [
{
"name": "CtsVirtualDevicesCameraTestCases",
"options": [
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index e21afb7..f5fa16e 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -133,6 +133,8 @@
.setLensFacing(ANDROID_LENS_FACING_EXTERNAL)
.setSensorOrientation(0)
.setAvailableFaceDetectModes({ANDROID_STATISTICS_FACE_DETECT_MODE_OFF})
+ .setAvailableMaxDigitalZoom(1.0)
+ .setControlAvailableModes({ANDROID_CONTROL_MODE_AUTO})
.setControlAfAvailableModes({ANDROID_CONTROL_AF_MODE_OFF})
.setControlAeAvailableFpsRange(10, 30)
.setControlMaxRegions(0, 0, 0)
diff --git a/services/camera/virtualcamera/VirtualCameraSession.cc b/services/camera/virtualcamera/VirtualCameraSession.cc
index 34d9932..9e15871 100644
--- a/services/camera/virtualcamera/VirtualCameraSession.cc
+++ b/services/camera/virtualcamera/VirtualCameraSession.cc
@@ -260,11 +260,11 @@
switch (in_type) {
case RequestTemplate::PREVIEW:
case RequestTemplate::STILL_CAPTURE:
- case RequestTemplate::VIDEO_RECORD: {
+ case RequestTemplate::VIDEO_RECORD:
+ case RequestTemplate::VIDEO_SNAPSHOT: {
*_aidl_return = createDefaultRequestSettings(in_type);
return ndk::ScopedAStatus::ok();
}
- case RequestTemplate::VIDEO_SNAPSHOT:
case RequestTemplate::MANUAL:
case RequestTemplate::ZERO_SHUTTER_LAG:
// Don't support VIDEO_SNAPSHOT, MANUAL, ZSL templates
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.cc b/services/camera/virtualcamera/util/MetadataBuilder.cc
index fb06e31..b3b1a26 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.cc
+++ b/services/camera/virtualcamera/util/MetadataBuilder.cc
@@ -95,6 +95,14 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setControlAvailableModes(
+ const std::vector<camera_metadata_enum_android_control_mode_t>&
+ availableModes) {
+ mEntryMap[ANDROID_CONTROL_AVAILABLE_MODES] =
+ convertTo<uint8_t>(availableModes);
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setControlAfAvailableModes(
const std::vector<camera_metadata_enum_android_control_af_mode_t>&
availableModes) {
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.h b/services/camera/virtualcamera/util/MetadataBuilder.h
index 25c931c..2124398 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.h
+++ b/services/camera/virtualcamera/util/MetadataBuilder.h
@@ -99,6 +99,11 @@
MetadataBuilder& setAvailableOutputStreamConfigurations(
const std::vector<StreamConfiguration>& streamConfigurations);
+ // See ANDROID_CONTROL_AVAILABLE_MODES in CameraMetadataTag.aidl.
+ MetadataBuilder& setControlAvailableModes(
+ const std::vector<camera_metadata_enum_android_control_mode_t>&
+ availableModes);
+
// See ANDROID_CONTROL_AE_COMPENSATION_RANGE in CameraMetadataTag.aidl.
MetadataBuilder& setControlAeCompensationRange(int32_t min, int32_t max);
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 1643a83..1953237 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -24,169 +24,19 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <cutils/sched_policy.h>
-#include <dirent.h>
#include <media/MediaResourcePolicy.h>
#include <media/stagefright/foundation/ABase.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/ProcessInfo.h>
#include <mediautils/SchedulingPolicyService.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <unistd.h>
#include "IMediaResourceMonitor.h"
#include "ResourceManagerMetrics.h"
-#include "ResourceManagerService.h"
-#include "ResourceManagerServiceUtils.h"
#include "ResourceObserverService.h"
#include "ServiceLog.h"
namespace android {
-class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
-
- // 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 DeathNotifier, before deferencing it upon the binder death.
- struct BinderDiedContext {
- std::weak_ptr<DeathNotifier> mDeathNotifier;
- };
-public:
- static std::shared_ptr<DeathNotifier> Create(
- const std::shared_ptr<IResourceManagerClient>& client,
- const std::shared_ptr<ResourceManagerService>& service,
- const ClientInfoParcel& clientInfo,
- bool overrideProcessInfo = false);
-
- DeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
- const std::shared_ptr<ResourceManagerService>& service,
- const ClientInfoParcel& clientInfo);
-
- virtual ~DeathNotifier() {
- unlink();
- }
-
- // Implement death recipient
- static void BinderDiedCallback(void* cookie);
- static void BinderUnlinkedCallback(void* cookie);
- virtual void binderDied();
-
-private:
- void link() {
- // Create the context that is passed as cookie to the binder death notification.
- // The context gets deleted at BinderUnlinkedCallback.
- mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
- // Register for the callbacks by linking to death notification.
- AIBinder_linkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
- }
-
- void unlink() {
- if (mClient != nullptr) {
- // Unlink from the death notification.
- AIBinder_unlinkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
- mClient = nullptr;
- }
- }
-
-protected:
- std::shared_ptr<IResourceManagerClient> mClient;
- std::weak_ptr<ResourceManagerService> mService;
- const ClientInfoParcel mClientInfo;
- BinderDiedContext* mCookie;
- ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
-};
-
-DeathNotifier::DeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
- const std::shared_ptr<ResourceManagerService>& service,
- const ClientInfoParcel& clientInfo)
- : mClient(client), mService(service), mClientInfo(clientInfo),
- mCookie(nullptr),
- mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
- AIBinder_DeathRecipient_new(BinderDiedCallback))) {
- // Setting callback notification when DeathRecipient gets deleted.
- AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), BinderUnlinkedCallback);
-}
-
-//static
-void DeathNotifier::BinderUnlinkedCallback(void* cookie) {
- BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
- // Since we don't need the context anymore, we are deleting it now.
- delete context;
-}
-
-//static
-void DeathNotifier::BinderDiedCallback(void* cookie) {
- BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
-
- // Validate the context and check if the DeathNotifier object is still in scope.
- if (context != nullptr) {
- std::shared_ptr<DeathNotifier> thiz = context->mDeathNotifier.lock();
- if (thiz != nullptr) {
- thiz->binderDied();
- } else {
- ALOGI("DeathNotifier is out of scope already");
- }
- }
-}
-
-void DeathNotifier::binderDied() {
- // Don't check for pid validity since we know it's already dead.
- std::shared_ptr<ResourceManagerService> service = mService.lock();
- if (service == nullptr) {
- ALOGW("ResourceManagerService is dead as well.");
- return;
- }
-
- service->overridePid(mClientInfo.pid, -1);
- // thiz is freed in the call below, so it must be last call referring thiz
- service->removeResource(mClientInfo, false /*checkValid*/);
-}
-
-class OverrideProcessInfoDeathNotifier : public DeathNotifier {
-public:
- OverrideProcessInfoDeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
- const std::shared_ptr<ResourceManagerService>& service,
- const ClientInfoParcel& clientInfo)
- : DeathNotifier(client, service, clientInfo) {}
-
- virtual ~OverrideProcessInfoDeathNotifier() {}
-
- virtual void binderDied();
-};
-
-void OverrideProcessInfoDeathNotifier::binderDied() {
- // Don't check for pid validity since we know it's already dead.
- std::shared_ptr<ResourceManagerService> service = mService.lock();
- if (service == nullptr) {
- ALOGW("ResourceManagerService is dead as well.");
- return;
- }
-
- service->removeProcessInfoOverride(mClientInfo.pid);
-}
-
-std::shared_ptr<DeathNotifier> DeathNotifier::Create(
- const std::shared_ptr<IResourceManagerClient>& client,
- const std::shared_ptr<ResourceManagerService>& service,
- const ClientInfoParcel& clientInfo,
- bool overrideProcessInfo) {
- std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
- if (overrideProcessInfo) {
- deathNotifier = std::make_shared<OverrideProcessInfoDeathNotifier>(
- client, service, clientInfo);
- } else {
- deathNotifier = std::make_shared<DeathNotifier>(client, service, clientInfo);
- }
-
- if (deathNotifier) {
- deathNotifier->link();
- }
-
- return deathNotifier;
-}
-
static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel>& resources) {
static const char* const kServiceName = "media_resource_monitor";
sp<IBinder> binder = defaultServiceManager()->checkService(String16(kServiceName));
@@ -334,8 +184,7 @@
//static
void ResourceManagerService::instantiate() {
- std::shared_ptr<ResourceManagerService> service =
- ::ndk::SharedRefBase::make<ResourceManagerService>();
+ std::shared_ptr<ResourceManagerService> service = Create();
binder_status_t status =
AServiceManager_addServiceWithFlags(
service->asBinder().get(), getServiceName(),
@@ -356,6 +205,16 @@
//ABinderProcess_startThreadPool();
}
+std::shared_ptr<ResourceManagerService> ResourceManagerService::Create() {
+ return Create(new ProcessInfo(), new SystemCallbackImpl());
+}
+
+std::shared_ptr<ResourceManagerService> ResourceManagerService::Create(
+ const sp<ProcessInfoInterface>& processInfo,
+ const sp<SystemCallbackInterface>& systemResource) {
+ return ::ndk::SharedRefBase::make<ResourceManagerService>(processInfo, systemResource);
+}
+
ResourceManagerService::~ResourceManagerService() {}
void ResourceManagerService::setObserverService(
@@ -380,8 +239,7 @@
return Status::ok();
}
-void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource,
- const ResourceInfo& clientInfo) {
+void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource, uid_t uid) {
// first time added
if (resource.type == MediaResource::Type::kCpuBoost
&& resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
@@ -395,12 +253,11 @@
} else if (resource.type == MediaResource::Type::kBattery
&& (resource.subType == MediaResource::SubType::kHwVideoCodec
|| resource.subType == MediaResource::SubType::kSwVideoCodec)) {
- mSystemCB->noteStartVideo(clientInfo.uid);
+ mSystemCB->noteStartVideo(uid);
}
}
-void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource,
- const ResourceInfo& clientInfo) {
+void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource, uid_t uid) {
if (resource.type == MediaResource::Type::kCpuBoost
&& resource.subType == MediaResource::SubType::kUnspecifiedSubType
&& mCpuBoostCount > 0) {
@@ -410,24 +267,7 @@
} else if (resource.type == MediaResource::Type::kBattery
&& (resource.subType == MediaResource::SubType::kHwVideoCodec
|| resource.subType == MediaResource::SubType::kSwVideoCodec)) {
- mSystemCB->noteStopVideo(clientInfo.uid);
- }
-}
-
-void ResourceManagerService::mergeResources(MediaResourceParcel& r1,
- const MediaResourceParcel& r2) {
- // The resource entry on record is maintained to be in [0,INT64_MAX].
- // Clamp if merging in the new resource value causes it to go out of bound.
- // Note that the new resource value could be negative, eg.DrmSession, the
- // value goes lower when the session is used more often. During reclaim
- // the session with the highest value (lowest usage) would be closed.
- if (r2.value < INT64_MAX - r1.value) {
- r1.value += r2.value;
- if (r1.value < 0) {
- r1.value = 0;
- }
- } else {
- r1.value = INT64_MAX;
+ mSystemCB->noteStopVideo(uid);
}
}
@@ -469,7 +309,7 @@
ALOGW("Ignoring request to add new resource entry with value <= 0");
continue;
}
- onFirstAdded(res, info);
+ onFirstAdded(res, info.uid);
info.resources[resType] = res;
} else {
mergeResources(info.resources[resType], res);
@@ -540,7 +380,7 @@
if (resource.value > res.value) {
resource.value -= res.value;
} else {
- onLastRemoved(res, info);
+ onLastRemoved(res, info.uid);
actualRemoved.value = resource.value;
info.resources.erase(resType);
}
@@ -595,7 +435,7 @@
const ResourceInfo& info = foundClient->second;
for (auto it = info.resources.begin(); it != info.resources.end(); it++) {
- onLastRemoved(it->second, info);
+ onLastRemoved(it->second, info.uid);
}
// Since this client has been removed, update the metrics collector.
@@ -620,15 +460,13 @@
// Before looking into other processes, check if we have clients marked for
// pending removal in the same process.
- uid_t uid = 0;
- std::shared_ptr<IResourceManagerClient> client;
- if (getBiggestClientPendingRemoval_l(callingPid, res->type, res->subType, uid, &client)) {
- clientsInfo.emplace_back(callingPid, uid, client);
+ ClientInfo clientInfo;
+ if (getBiggestClientPendingRemoval_l(callingPid, res->type, res->subType, clientInfo)) {
+ clientsInfo.emplace_back(clientInfo);
return;
}
// Now find client(s) from a lowest priority process that has needed resources.
- ClientInfo clientInfo;
if (getLowestPriorityBiggestClient_l(resourceRequestInfo, clientInfo)) {
clientsInfo.push_back(clientInfo);
}
@@ -769,49 +607,75 @@
mResourceManagerMetrics->pushReclaimAtom(clientInfo, priorities, targetClients, reclaimed);
}
+std::shared_ptr<IResourceManagerClient> ResourceManagerService::getClient(
+ int pid, const int64_t& clientId) const {
+ std::map<int, ResourceInfos>::const_iterator found = mMap.find(pid);
+ if (found == mMap.end()) {
+ ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+ return nullptr;
+ }
+
+ const ResourceInfos& infos = found->second;
+ ResourceInfos::const_iterator foundClient = infos.find(clientId);
+ if (foundClient == infos.end()) {
+ ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+ return nullptr;
+ }
+
+ return foundClient->second.client;
+}
+
+bool ResourceManagerService::removeClient(int pid, const int64_t& clientId) {
+ std::map<int, ResourceInfos>::iterator found = mMap.find(pid);
+ if (found == mMap.end()) {
+ ALOGV("%s: didn't find pid %d for clientId %lld", __func__, pid, (long long) clientId);
+ return false;
+ }
+
+ ResourceInfos& infos = found->second;
+ ResourceInfos::iterator foundClient = infos.find(clientId);
+ if (foundClient == infos.end()) {
+ ALOGV("%s: didn't find clientId %lld", __func__, (long long) clientId);
+ return false;
+ }
+
+ infos.erase(foundClient);
+ return true;
+}
+
bool ResourceManagerService::reclaimUnconditionallyFrom(
const std::vector<ClientInfo>& targetClients) {
if (targetClients.size() == 0) {
return false;
}
- std::shared_ptr<IResourceManagerClient> failedClient;
+ int64_t failedClientId = -1;
+ int32_t failedClientPid = -1;
for (const ClientInfo& targetClient : targetClients) {
- if (targetClient.mClient == nullptr) {
+ std::shared_ptr<IResourceManagerClient> client = getClient(
+ targetClient.mPid, targetClient.mClientId);
+ if (client == nullptr) {
// skip already released clients.
continue;
}
- String8 log = String8::format("reclaimResource from client %p", targetClient.mClient.get());
+ String8 log = String8::format("reclaimResource from client %p", client.get());
mServiceLog->add(log);
bool success;
- Status status = targetClient.mClient->reclaimResource(&success);
+ Status status = client->reclaimResource(&success);
if (!status.isOk() || !success) {
- failedClient = targetClient.mClient;
+ failedClientId = targetClient.mClientId;
+ failedClientPid = targetClient.mPid;
break;
}
}
- if (failedClient == NULL) {
+ if (failedClientId == -1) {
return true;
}
- int failedClientPid = -1;
{
std::scoped_lock lock{mLock};
- bool found = false;
- for (auto& [pid, infos] : mMap) {
- for (const auto& [id, info] : infos) {
- if (info.client == failedClient) {
- infos.erase(id);
- found = true;
- break;
- }
- }
- if (found) {
- failedClientPid = pid;
- break;
- }
- }
+ bool found = removeClient(failedClientPid, failedClientId);
if (found) {
ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
} else {
@@ -968,21 +832,19 @@
MediaResource::SubType::kSwVideoCodec,
MediaResource::SubType::kHwImageCodec,
MediaResource::SubType::kSwImageCodec}) {
- std::shared_ptr<IResourceManagerClient> client;
- uid_t uid = 0;
- if (getBiggestClientPendingRemoval_l(pid, type, subType, uid, &client)) {
- targetClients.emplace_back(pid, uid, client);
+ ClientInfo clientInfo;
+ if (getBiggestClientPendingRemoval_l(pid, type, subType, clientInfo)) {
+ targetClients.emplace_back(clientInfo);
continue;
}
}
break;
// Non-codec resources are shared by audio, video and image codecs (no subtype).
default:
- std::shared_ptr<IResourceManagerClient> client;
- uid_t uid = 0;
+ ClientInfo clientInfo;
if (getBiggestClientPendingRemoval_l(pid, type,
- MediaResource::SubType::kUnspecifiedSubType, uid, &client)) {
- targetClients.emplace_back(pid, uid, client);
+ MediaResource::SubType::kUnspecifiedSubType, clientInfo)) {
+ targetClients.emplace_back(clientInfo);
}
break;
}
@@ -1024,7 +886,7 @@
clientsInfo.clear();
return false;
}
- clientsInfo.emplace_back(pid, info.uid, info.client);
+ clientsInfo.emplace_back(pid, info.uid, info.clientId);
}
}
}
@@ -1039,15 +901,13 @@
// - Find the bigegst client (with required resources) from that process.
bool ResourceManagerService::getLowestPriorityBiggestClient_l(
const ResourceRequestInfo& resourceRequestInfo,
- ClientInfo& clientsInfo) {
+ ClientInfo& clientInfo) {
int callingPid = resourceRequestInfo.mCallingPid;
MediaResource::Type type = resourceRequestInfo.mResource->type;
MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
int lowestPriorityPid;
int lowestPriority;
int callingPriority;
- uid_t uid = 0;
- std::shared_ptr<IResourceManagerClient> client;
if (!getPriority_l(callingPid, &callingPriority)) {
ALOGE("%s: can't get process priority for pid %d", __func__, callingPid);
@@ -1062,13 +922,10 @@
return false;
}
- if (!getBiggestClient_l(lowestPriorityPid, type, subType, uid, &client)) {
+ if (!getBiggestClient_l(lowestPriorityPid, type, subType, clientInfo)) {
return false;
}
- clientsInfo.mPid = lowestPriorityPid;
- clientsInfo.mUid = uid;
- clientsInfo.mClient = client;
ALOGI("%s: CallingProcess(%d:%d) will reclaim from the lowestPriorityProcess(%d:%d)",
__func__, callingPid, callingPriority, lowestPriorityPid, lowestPriority);
return true;
@@ -1121,15 +978,12 @@
}
bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, uid_t& uid,
- std::shared_ptr<IResourceManagerClient> *client) {
- return getBiggestClient_l(pid, type, subType, uid, client, true /* pendingRemovalOnly */);
+ MediaResource::SubType subType, ClientInfo& clientInfo) {
+ return getBiggestClient_l(pid, type, subType, clientInfo, true /* pendingRemovalOnly */);
}
bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, uid_t& uid,
- std::shared_ptr<IResourceManagerClient> *client,
- bool pendingRemovalOnly) {
+ MediaResource::SubType subType, ClientInfo& clientInfo, bool pendingRemovalOnly) {
PidResourceInfosMap::iterator found = mMap.find(pid);
if (found == mMap.end()) {
ALOGE_IF(!pendingRemovalOnly,
@@ -1137,7 +991,8 @@
return false;
}
- std::shared_ptr<IResourceManagerClient> clientTemp;
+ uid_t uid = -1;
+ int64_t clientId = -1;
uint64_t largestValue = 0;
const ResourceInfos& infos = found->second;
for (const auto& [id, info] : infos) {
@@ -1150,21 +1005,23 @@
if (hasResourceType(type, subType, resource)) {
if (resource.value > largestValue) {
largestValue = resource.value;
- clientTemp = info.client;
+ clientId = info.clientId;
uid = info.uid;
}
}
}
}
- if (clientTemp == NULL) {
+ if (clientId == -1) {
ALOGE_IF(!pendingRemovalOnly,
"getBiggestClient_l: can't find resource type %s and subtype %s for pid %d",
asString(type), asString(subType), pid);
return false;
}
- *client = clientTemp;
+ clientInfo.mPid = pid;
+ clientInfo.mUid = uid;
+ clientInfo.mClientId = clientId;
return true;
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 27ba004..e22a6b3 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -30,9 +30,10 @@
#include <utils/String8.h>
#include <utils/threads.h>
+#include "ResourceManagerServiceUtils.h"
+
namespace android {
-class DeathNotifier;
class ResourceObserverService;
class ServiceLog;
struct ProcessInfoInterface;
@@ -46,57 +47,6 @@
using ::aidl::android::media::ClientInfoParcel;
using ::aidl::android::media::ClientConfigParcel;
-typedef std::map<std::tuple<
- MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
- MediaResourceParcel> ResourceList;
-
-struct ResourceInfo {
- uid_t uid;
- int64_t clientId;
- std::string name;
- std::shared_ptr<IResourceManagerClient> client;
- std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
- ResourceList resources;
- bool pendingRemoval{false};
-};
-
-/*
- * Resource request info that encapsulates
- * - the calling/requesting process pid.
- * - the resource requesting (to be reclaimed from others)
- */
-struct ResourceRequestInfo {
- // uid of the calling/requesting process.
- int mCallingPid = -1;
- // resources requested.
- const ::aidl::android::media::MediaResourceParcel* mResource;
-};
-
-/*
- * Structure that defines the Client - a possible target to relcaim from.
- * This encapsulates pid, uid of the process and the client.
- * based on the reclaim policy.
- */
-struct ClientInfo {
- // pid of the process.
- pid_t mPid;
- // uid of the process.
- uid_t mUid;
- // Client to relcaim from.
- std::shared_ptr<::aidl::android::media::IResourceManagerClient> mClient;
- ClientInfo(
- pid_t pid = -1,
- uid_t uid = -1,
- const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client = nullptr)
- : mPid(pid),
- mUid(uid),
- mClient(client) {
- }
-};
-
-typedef std::map<int64_t, ResourceInfo> ResourceInfos;
-typedef std::map<int, ResourceInfos> PidResourceInfosMap;
-
class ResourceManagerService : public BnResourceManagerService {
public:
struct SystemCallbackInterface : public RefBase {
@@ -109,13 +59,20 @@
static char const *getServiceName() { return "media.resource_manager"; }
static void instantiate();
- virtual inline binder_status_t dump(
+ // Static creation methods.
+ static std::shared_ptr<ResourceManagerService> Create();
+ static std::shared_ptr<ResourceManagerService> Create(
+ const sp<ProcessInfoInterface>& processInfo,
+ const sp<SystemCallbackInterface>& systemResource);
+
+ virtual binder_status_t dump(
int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
ResourceManagerService();
explicit ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
const sp<SystemCallbackInterface> &systemResource);
virtual ~ResourceManagerService();
+
void setObserverService(const std::shared_ptr<ResourceObserverService>& observerService);
// IResourceManagerService interface
@@ -158,6 +115,7 @@
private:
friend class ResourceManagerServiceTest;
+ friend class ResourceManagerServiceTestBase;
friend class DeathNotifier;
friend class OverrideProcessInfoDeathNotifier;
@@ -183,12 +141,12 @@
// Returns false with no change to client if there are no clients holding resources of this
// type.
bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType,
- uid_t& uid, std::shared_ptr<IResourceManagerClient> *client,
+ ClientInfo& clientsInfo,
bool pendingRemovalOnly = false);
// Same method as above, but with pendingRemovalOnly as true.
bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
- MediaResource::SubType subType, uid_t& uid,
- std::shared_ptr<IResourceManagerClient>* client);
+ MediaResource::SubType subType,
+ ClientInfo& clientsInfo);
// A helper function that returns true if the callingPid has higher priority than pid.
// Returns false otherwise.
@@ -199,11 +157,8 @@
void getClientForResource_l(const ResourceRequestInfo& resourceRequestInfo,
std::vector<ClientInfo>& clientsInfo);
- void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
- void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
-
- // Merge r2 into r1
- void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
+ void onFirstAdded(const MediaResourceParcel& res, uid_t uid);
+ void onLastRemoved(const MediaResourceParcel& res, uid_t uid);
// Get priority from process's pid
bool getPriority_l(int pid, int* priority);
@@ -216,6 +171,12 @@
const std::vector<ClientInfo>& targetClients,
bool reclaimed);
+ // Get the client for given pid and the clientId from the map
+ std::shared_ptr<IResourceManagerClient> getClient(int pid, const int64_t& clientId) const;
+
+ // Remove the client for given pid and the clientId from the map
+ bool removeClient(int pid, const int64_t& clientId);
+
// The following utility functions are used only for testing by ResourceManagerServiceTest
// Gets lowest priority process that has the specified resource type.
// Returns false if failed. The output parameters will remain unchanged if failed.
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
index 892b1b3..de682f8 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
@@ -24,29 +24,32 @@
namespace android {
+// Bunch of utility functions that looks for a specific Resource.
+// Check whether a given resource (of type and subtype) is found in given resource parcel.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const MediaResourceParcel& resource) {
+ const MediaResourceParcel& resource) {
if (type != resource.type) {
return false;
}
switch (type) {
- // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so
- // compare the subtypes as well.
- case MediaResource::Type::kSecureCodec:
- case MediaResource::Type::kNonSecureCodec:
- if (resource.subType == subType) {
- return true;
- }
- break;
- // Non-codec resources are not segregated by the subtype (e.g. video vs. audio).
- default:
+ // Codec subtypes (e.g. video vs. audio and hw vs. sw) are each considered separate resources,
+ // so compare the subtypes as well.
+ case MediaResource::Type::kSecureCodec:
+ case MediaResource::Type::kNonSecureCodec:
+ if (resource.subType == subType) {
return true;
+ }
+ break;
+ // Non-codec resources are not segregated by the subtype (e.g. video vs. audio).
+ default:
+ return true;
}
return false;
}
+// Check whether a given resource (of type and subtype) is found in given resource list.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceList& resources) {
+ const ResourceList& resources) {
for (auto it = resources.begin(); it != resources.end(); it++) {
if (hasResourceType(type, subType, it->second)) {
return true;
@@ -55,8 +58,9 @@
return false;
}
+// Check whether a given resource (of type and subtype) is found in given resource info list.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceInfos& infos) {
+ const ResourceInfos& infos) {
for (const auto& [id, info] : infos) {
if (hasResourceType(type, subType, info.resources)) {
return true;
@@ -77,12 +81,17 @@
return found->second;
}
+// Return modifiable ResourceInfo for a given client (look up by client id)
+// from the map of ResourceInfos.
+// If the item is not in the map, create one and add it to the map.
ResourceInfo& getResourceInfoForEdit(const ClientInfoParcel& clientInfo,
- const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
+ const std::shared_ptr<IResourceManagerClient>& client,
+ ResourceInfos& infos) {
ResourceInfos::iterator found = infos.find(clientInfo.id);
if (found == infos.end()) {
- ResourceInfo info{.uid = static_cast<uid_t>(clientInfo.uid),
+ ResourceInfo info{.pid = clientInfo.pid,
+ .uid = static_cast<uid_t>(clientInfo.uid),
.clientId = clientInfo.id,
.name = clientInfo.name.empty()? "<unknown client>" : clientInfo.name,
.client = client,
@@ -95,4 +104,102 @@
return found->second;
}
+// Merge resources from r2 into r1.
+void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2) {
+ // The resource entry on record is maintained to be in [0,INT64_MAX].
+ // Clamp if merging in the new resource value causes it to go out of bound.
+ // Note that the new resource value could be negative, eg.DrmSession, the
+ // value goes lower when the session is used more often. During reclaim
+ // the session with the highest value (lowest usage) would be closed.
+ if (r2.value < INT64_MAX - r1.value) {
+ r1.value += r2.value;
+ if (r1.value < 0) {
+ r1.value = 0;
+ }
+ } else {
+ r1.value = INT64_MAX;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+////////////// Death Notifier implementation ////////////////////////
+///////////////////////////////////////////////////////////////////////
+
+DeathNotifier::DeathNotifier(const std::shared_ptr<IResourceManagerClient>& client,
+ const std::weak_ptr<ResourceManagerService>& service,
+ const ClientInfoParcel& clientInfo)
+ : mClient(client), mService(service), mClientInfo(clientInfo),
+ mCookie(nullptr),
+ mDeathRecipient(::ndk::ScopedAIBinder_DeathRecipient(
+ AIBinder_DeathRecipient_new(BinderDiedCallback))) {
+ // Setting callback notification when DeathRecipient gets deleted.
+ AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), BinderUnlinkedCallback);
+}
+
+//static
+void DeathNotifier::BinderUnlinkedCallback(void* cookie) {
+ BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+ // Since we don't need the context anymore, we are deleting it now.
+ delete context;
+}
+
+//static
+void DeathNotifier::BinderDiedCallback(void* cookie) {
+ BinderDiedContext* context = reinterpret_cast<BinderDiedContext*>(cookie);
+
+ // Validate the context and check if the DeathNotifier object is still in scope.
+ if (context != nullptr) {
+ std::shared_ptr<DeathNotifier> thiz = context->mDeathNotifier.lock();
+ if (thiz != nullptr) {
+ thiz->binderDied();
+ } else {
+ ALOGI("DeathNotifier is out of scope already");
+ }
+ }
+}
+
+void DeathNotifier::binderDied() {
+ // Don't check for pid validity since we know it's already dead.
+ std::shared_ptr<ResourceManagerService> service = mService.lock();
+ if (service == nullptr) {
+ ALOGW("ResourceManagerService is dead as well.");
+ return;
+ }
+
+ service->overridePid(mClientInfo.pid, -1);
+ // thiz is freed in the call below, so it must be last call referring thiz
+ service->removeResource(mClientInfo, false /*checkValid*/);
+}
+
+void OverrideProcessInfoDeathNotifier::binderDied() {
+ // Don't check for pid validity since we know it's already dead.
+ std::shared_ptr<ResourceManagerService> service = mService.lock();
+ if (service == nullptr) {
+ ALOGW("ResourceManagerService is dead as well.");
+ return;
+ }
+
+ service->removeProcessInfoOverride(mClientInfo.pid);
+}
+
+std::shared_ptr<DeathNotifier> DeathNotifier::Create(
+ const std::shared_ptr<IResourceManagerClient>& client,
+ const std::weak_ptr<ResourceManagerService>& service,
+ const ClientInfoParcel& clientInfo,
+ bool overrideProcessInfo) {
+ std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
+ if (overrideProcessInfo) {
+ deathNotifier = std::make_shared<OverrideProcessInfoDeathNotifier>(
+ client, service, clientInfo);
+ } else {
+ deathNotifier = std::make_shared<DeathNotifier>(client, service, clientInfo);
+ }
+
+ if (deathNotifier) {
+ deathNotifier->link();
+ }
+
+ return deathNotifier;
+}
+
} // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
index bbc26de..ac1e410 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -19,10 +19,143 @@
#define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
#include <vector>
+
+#include <aidl/android/media/BnResourceManagerService.h>
+#include <media/MediaResource.h>
#include <utils/String8.h>
namespace android {
+class ResourceManagerService;
+
+/*
+ * Death Notifier to track IResourceManagerClient's death.
+ */
+class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
+
+ // 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 DeathNotifier, before deferencing it upon the binder death.
+ struct BinderDiedContext {
+ std::weak_ptr<DeathNotifier> mDeathNotifier;
+ };
+public:
+ static std::shared_ptr<DeathNotifier> Create(
+ const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
+ const std::weak_ptr<ResourceManagerService>& service,
+ const ::aidl::android::media::ClientInfoParcel& clientInfo,
+ bool overrideProcessInfo = false);
+
+ DeathNotifier(const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
+ const std::weak_ptr<ResourceManagerService>& service,
+ const ::aidl::android::media::ClientInfoParcel& clientInfo);
+
+ virtual ~DeathNotifier() {
+ unlink();
+ }
+
+ // Implement death recipient
+ static void BinderDiedCallback(void* cookie);
+ static void BinderUnlinkedCallback(void* cookie);
+ virtual void binderDied();
+
+private:
+ void link() {
+ // Create the context that is passed as cookie to the binder death notification.
+ // The context gets deleted at BinderUnlinkedCallback.
+ mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
+ // Register for the callbacks by linking to death notification.
+ AIBinder_linkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
+ }
+
+ void unlink() {
+ if (mClient != nullptr) {
+ // Unlink from the death notification.
+ AIBinder_unlinkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
+ mClient = nullptr;
+ }
+ }
+
+protected:
+ std::shared_ptr<::aidl::android::media::IResourceManagerClient> mClient;
+ std::weak_ptr<ResourceManagerService> mService;
+ const ::aidl::android::media::ClientInfoParcel mClientInfo;
+ BinderDiedContext* mCookie;
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+
+class OverrideProcessInfoDeathNotifier : public DeathNotifier {
+public:
+ OverrideProcessInfoDeathNotifier(
+ const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
+ const std::weak_ptr<ResourceManagerService>& service,
+ const ::aidl::android::media::ClientInfoParcel& clientInfo)
+ : DeathNotifier(client, service, clientInfo) {}
+
+ virtual ~OverrideProcessInfoDeathNotifier() {}
+
+ virtual void binderDied();
+};
+
+// A map of tuple(type, sub-type, id) and the resource parcel.
+typedef std::map<std::tuple<
+ MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
+ ::aidl::android::media::MediaResourceParcel> ResourceList;
+
+// Encapsulation for Resource Info, that contains
+// - pid of the app
+// - uid of the app
+// - client id
+// - name of the client (specifically for the codec)
+// - the client associted with it
+// - death notifier for the (above) client
+// - list of resources associated with it
+// - A flag that marks whether this resource is pending to be removed.
+struct ResourceInfo {
+ pid_t pid;
+ uid_t uid;
+ int64_t clientId;
+ std::string name;
+ std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
+ std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
+ ResourceList resources;
+ bool pendingRemoval{false};
+};
+
+/*
+ * Resource request info that encapsulates
+ * - the calling/requesting process pid.
+ * - the resource requesting (to be reclaimed from others)
+ */
+struct ResourceRequestInfo {
+ // pid of the calling/requesting process.
+ int mCallingPid = -1;
+ // resources requested.
+ const ::aidl::android::media::MediaResourceParcel* mResource;
+};
+
+/*
+ * Structure that defines the Client - a possible target to relcaim from.
+ * This encapsulates pid, uid of the process and the client id
+ * based on the reclaim policy.
+ */
+struct ClientInfo {
+ // pid of the process.
+ pid_t mPid = -1;
+ // uid of the process.
+ uid_t mUid = -1;
+ // Client Id.
+ int64_t mClientId = -1;
+ ClientInfo(pid_t pid = -1, uid_t uid = -1, const int64_t& clientId = -1)
+ : mPid(pid), mUid(uid), mClientId(clientId) {}
+};
+
+// Map of Resource information index through the client id.
+typedef std::map<int64_t, ResourceInfo> ResourceInfos;
+
+// Map of Resource information indexed through the process id.
+typedef std::map<int, ResourceInfos> PidResourceInfosMap;
+
// templated function to stringify the given vector of items.
template <typename T>
String8 getString(const std::vector<T>& items) {
@@ -37,15 +170,15 @@
//Check whether a given resource (of type and subtype) is found in given resource parcel.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const MediaResourceParcel& resource);
+ const MediaResourceParcel& resource);
//Check whether a given resource (of type and subtype) is found in given resource list.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceList& resources);
+ const ResourceList& resources);
//Check whether a given resource (of type and subtype) is found in given resource info list.
bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceInfos& infos);
+ const ResourceInfos& infos);
// Return modifiable list of ResourceInfo for a given process (look up by pid)
// from the map of ResourceInfos.
@@ -54,8 +187,13 @@
// Return modifiable ResourceInfo for a given process (look up by pid)
// from the map of ResourceInfos.
// If the item is not in the map, create one and add it to the map.
-ResourceInfo& getResourceInfoForEdit(const ClientInfoParcel& clientInfo,
- const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos);
+ResourceInfo& getResourceInfoForEdit(
+ const aidl::android::media::ClientInfoParcel& clientInfo,
+ const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
+ ResourceInfos& infos);
+
+// Merge resources from r2 into r1.
+void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
} // namespace android
diff --git a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
index 6fa9831..643a4e5 100644
--- a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
+++ b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
@@ -208,9 +208,9 @@
return nullptr;
}
- shared_ptr<ResourceManagerService> mService =
- ::ndk::SharedRefBase::make<ResourceManagerService>(new TestProcessInfo(),
- new TestSystemCallback());
+ shared_ptr<ResourceManagerService> mService = ResourceManagerService::Create(
+ new TestProcessInfo(),
+ new TestSystemCallback());
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
};
diff --git a/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
index ca10d20..6253df7 100644
--- a/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
+++ b/services/mediaresourcemanager/fuzzer/resourcemanager_service_fuzzer.cpp
@@ -26,7 +26,7 @@
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- auto service = SharedRefBase::make<ResourceManagerService>();
+ std::shared_ptr<ResourceManagerService> service = ResourceManagerService::Create();
fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
return 0;
}
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 474ff0f..52d82b8 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -207,8 +207,7 @@
// silently ignored.
ABinderProcess_startThreadPool();
mSystemCB = new TestSystemCallback();
- mService = ::ndk::SharedRefBase::make<ResourceManagerService>(
- new TestProcessInfo, mSystemCB);
+ mService = ResourceManagerService::Create(new TestProcessInfo, mSystemCB);
mTestClient1 = ::ndk::SharedRefBase::make<TestClient>(kTestPid1, kTestUid1, mService);
mTestClient2 = ::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService);
mTestClient3 = ::ndk::SharedRefBase::make<TestClient>(kTestPid2, kTestUid2, mService);
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 7452275..8f05b13 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -495,8 +495,8 @@
EXPECT_EQ(2u, targetClients.size());
// (OK to require ordering in clients[], as the pid map is sorted)
- EXPECT_EQ(mTestClient3, targetClients[0].mClient);
- EXPECT_EQ(mTestClient1, targetClients[1].mClient);
+ EXPECT_EQ(getId(mTestClient3), targetClients[0].mClientId);
+ EXPECT_EQ(getId(mTestClient1), targetClients[1].mClientId);
}
void testReclaimResourceSecure() {
@@ -775,7 +775,7 @@
// kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
// mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
- EXPECT_EQ(mTestClient1, clientInfo.mClient);
+ EXPECT_EQ(getId(mTestClient1), clientInfo.mClientId);
}
void testGetLowestPriorityPid() {