Merge "Revert "audio AIDL: Consider `BUS` devices as attached"" into main
diff --git a/media/codec2/components/aom/C2SoftAomEnc.cpp b/media/codec2/components/aom/C2SoftAomEnc.cpp
index e08bf43..71909e5 100644
--- a/media/codec2/components/aom/C2SoftAomEnc.cpp
+++ b/media/codec2/components/aom/C2SoftAomEnc.cpp
@@ -107,7 +107,7 @@
addParameter(DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
.withDefault(new C2StreamProfileLevelInfo::output(0u, PROFILE_AV1_0,
- LEVEL_AV1_4_1))
+ LEVEL_AV1_2))
.withFields({
C2F(mProfileLevel, profile).equalTo(PROFILE_AV1_0),
C2F(mProfileLevel, level)
@@ -116,7 +116,7 @@
LEVEL_AV1_3_2, LEVEL_AV1_3_3, LEVEL_AV1_4,
LEVEL_AV1_4_1}),
})
- .withSetter(ProfileLevelSetter)
+ .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
.build());
std::vector<uint32_t> pixelFormats = {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
@@ -201,12 +201,69 @@
}
C2R C2SoftAomEnc::IntfImpl::ProfileLevelSetter(bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output>& me) {
+ C2P<C2StreamProfileLevelInfo::output>& me,
+ const C2P<C2StreamPictureSizeInfo::input>& size,
+ const C2P<C2StreamFrameRateInfo::output>& frameRate,
+ const C2P<C2StreamBitrateInfo::output>& bitrate) {
(void)mayBlock;
if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
me.set().profile = PROFILE_AV1_0;
}
+ struct LevelLimits {
+ C2Config::level_t level;
+ float samplesPerSec;
+ uint64_t samples;
+ uint32_t bitrate;
+ size_t maxHSize;
+ size_t maxVSize;
+ };
+ constexpr LevelLimits kLimits[] = {
+ {LEVEL_AV1_2, 4423680, 147456, 1500000, 2048, 1152},
+ {LEVEL_AV1_2_1, 8363520, 278784, 3000000, 2816, 1584},
+ {LEVEL_AV1_3, 19975680, 665856, 6000000, 4352, 2448},
+ {LEVEL_AV1_3_1, 37950720, 1065024, 10000000, 5504, 3096},
+ {LEVEL_AV1_4, 70778880, 2359296, 12000000, 6144, 3456},
+ {LEVEL_AV1_4_1, 141557760, 2359296, 20000000, 6144, 3456},
+ };
+
+ uint64_t samples = size.v.width * size.v.height;
+ float samplesPerSec = float(samples) * frameRate.v.value;
+
+ // Check if the supplied level meets the samples / bitrate requirements.
+ // If not, update the level with the lowest level meeting the requirements.
+ bool found = false;
+
+ // By default needsUpdate = false in case the supplied level does meet
+ // the requirements.
+ bool needsUpdate = false;
if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ needsUpdate = true;
+ }
+ for (const LevelLimits& limit : kLimits) {
+ if (samples <= limit.samples && samplesPerSec <= limit.samplesPerSec &&
+ bitrate.v.value <= limit.bitrate && size.v.width <= limit.maxHSize &&
+ size.v.height <= limit.maxVSize) {
+ // This is the lowest level that meets the requirements, and if
+ // we haven't seen the supplied level yet, that means we don't
+ // need the update.
+ if (needsUpdate) {
+ ALOGD("Given level %x does not cover current configuration: "
+ "adjusting to %x",
+ me.v.level, limit.level);
+ me.set().level = limit.level;
+ }
+ found = true;
+ break;
+ }
+ if (me.v.level == limit.level) {
+ // We break out of the loop when the lowest feasible level is
+ // found. The fact that we're here means that our level doesn't
+ // meet the requirement and needs to be updated.
+ needsUpdate = true;
+ }
+ }
+ if (!found) {
+ // We set to the highest supported level.
me.set().level = LEVEL_AV1_4_1;
}
return C2R::Ok();
@@ -248,6 +305,10 @@
return C2R::Ok();
}
+uint32_t C2SoftAomEnc::IntfImpl::getLevel_l() const {
+ return mProfileLevel->level - LEVEL_AV1_2;
+}
+
C2SoftAomEnc::C2SoftAomEnc(const char* name, c2_node_id_t id,
const std::shared_ptr<IntfImpl>& intfImpl)
: SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
@@ -324,6 +385,9 @@
aom_codec_err_t C2SoftAomEnc::setupCodecParameters() {
aom_codec_err_t codec_return = AOM_CODEC_OK;
+ codec_return = aom_codec_control(mCodecContext, AV1E_SET_TARGET_SEQ_LEVEL_IDX, mAV1EncLevel);
+ if (codec_return != AOM_CODEC_OK) goto BailOut;
+
codec_return = aom_codec_control(mCodecContext, AOME_SET_CPUUSED,
MapC2ComplexityToAOMSpeed(mComplexity->value));
if (codec_return != AOM_CODEC_OK) goto BailOut;
@@ -478,6 +542,7 @@
mColorAspects = mIntf->getCodedColorAspects_l();
mQuality = mIntf->getQuality_l();
mComplexity = mIntf->getComplexity_l();
+ mAV1EncLevel = mIntf->getLevel_l();
}
diff --git a/media/codec2/components/aom/C2SoftAomEnc.h b/media/codec2/components/aom/C2SoftAomEnc.h
index 3067735..7e5ea63 100644
--- a/media/codec2/components/aom/C2SoftAomEnc.h
+++ b/media/codec2/components/aom/C2SoftAomEnc.h
@@ -98,6 +98,8 @@
bool mIs10Bit;
+ uint32_t mAV1EncLevel;
+
std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
@@ -120,7 +122,10 @@
static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input>& oldMe,
C2P<C2StreamPictureSizeInfo::input>& me);
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output>& me);
+ static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output>& me,
+ const C2P<C2StreamPictureSizeInfo::input>& size,
+ const C2P<C2StreamFrameRateInfo::output>& frameRate,
+ const C2P<C2StreamBitrateInfo::output>& bitrate);
// unsafe getters
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
@@ -149,6 +154,7 @@
static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input>& me);
static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
const C2P<C2StreamColorAspectsInfo::input>& coded);
+ uint32_t getLevel_l() const;
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index fa4808b..870ebdf 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -785,6 +785,7 @@
kWhatOutputBuffersChanged = 'outC',
kWhatFirstTunnelFrameReady = 'ftfR',
kWhatPollForRenderedBuffers = 'plrb',
+ kWhatMetricsUpdated = 'mtru',
};
class CryptoAsyncCallback : public CryptoAsync::CryptoAsyncCallback {
@@ -882,6 +883,7 @@
virtual void onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) override;
virtual void onOutputBuffersChanged() override;
virtual void onFirstTunnelFrameReady() override;
+ virtual void onMetricsUpdated(const sp<AMessage> &updatedMetrics) override;
private:
const sp<AMessage> mNotify;
};
@@ -1008,6 +1010,13 @@
notify->post();
}
+void CodecCallback::onMetricsUpdated(const sp<AMessage> &updatedMetrics) {
+ sp<AMessage> notify(mNotify->dup());
+ notify->setInt32("what", kWhatMetricsUpdated);
+ notify->setMessage("updated-metrics", updatedMetrics);
+ notify->post();
+}
+
static MediaResourceSubType toMediaResourceSubType(MediaCodec::Domain domain) {
switch (domain) {
case MediaCodec::DOMAIN_VIDEO: return MediaResourceSubType::kVideoCodec;
@@ -4381,6 +4390,49 @@
break;
}
+ case kWhatMetricsUpdated:
+ {
+ sp<AMessage> updatedMetrics;
+ CHECK(msg->findMessage("updated-metrics", &updatedMetrics));
+
+ size_t numEntries = updatedMetrics->countEntries();
+ AMessage::Type type;
+ for (size_t i = 0; i < numEntries; ++i) {
+ const char *name = updatedMetrics->getEntryNameAt(i, &type);
+ AMessage::ItemData itemData = updatedMetrics->getEntryAt(i);
+ switch (type) {
+ case AMessage::kTypeInt32: {
+ int32_t metricValue;
+ itemData.find(&metricValue);
+ mediametrics_setInt32(mMetricsHandle, name, metricValue);
+ break;
+ }
+ case AMessage::kTypeInt64: {
+ int64_t metricValue;
+ itemData.find(&metricValue);
+ mediametrics_setInt64(mMetricsHandle, name, metricValue);
+ break;
+ }
+ case AMessage::kTypeDouble: {
+ double metricValue;
+ itemData.find(&metricValue);
+ mediametrics_setDouble(mMetricsHandle, name, metricValue);
+ break;
+ }
+ case AMessage::kTypeString: {
+ AString metricValue;
+ itemData.find(&metricValue);
+ mediametrics_setCString(mMetricsHandle, name, metricValue.c_str());
+ break;
+ }
+ // ToDo: add support for other types
+ default:
+ ALOGW("Updated metrics type not supported.");
+ }
+ }
+ break;
+ }
+
case kWhatEOS:
{
// We already notify the client of this by using the
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 916d41e..2a5989f 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -182,6 +182,12 @@
* Notify MediaCodec that the first tunnel frame is ready.
*/
virtual void onFirstTunnelFrameReady() = 0;
+ /**
+ * Notify MediaCodec that there are metrics to be updated.
+ *
+ * @param updatedMetrics metrics need to be updated.
+ */
+ virtual void onMetricsUpdated(const sp<AMessage> &updatedMetrics) = 0;
};
/**
diff --git a/media/module/extractors/mp4/MPEG4Extractor.cpp b/media/module/extractors/mp4/MPEG4Extractor.cpp
index ecd937d..a9ca078 100644
--- a/media/module/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/module/extractors/mp4/MPEG4Extractor.cpp
@@ -185,6 +185,8 @@
status_t parseSampleEncryption(off64_t offset, off64_t size);
// returns -1 for invalid layer ID
int32_t parseHEVCLayerId(const uint8_t *data, size_t size);
+ size_t getNALLengthSizeFromAvcCsd(const uint8_t *data, const size_t size) const;
+ size_t getNALLengthSizeFromHevcCsd(const uint8_t *data, const size_t size) const;
struct TrackFragmentHeaderInfo {
enum Flags {
@@ -5158,24 +5160,13 @@
size_t size;
CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 7);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
-
- // The number of bytes used to encode the length of a NAL unit.
- mNALLengthSize = 1 + (ptr[4] & 3);
+ mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
} else if (mIsHEVC) {
void *data;
size_t size;
CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size));
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 22);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
-
- mNALLengthSize = 1 + (ptr[14 + 7] & 3);
+ mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
} else if (mIsDolbyVision) {
ALOGV("%s DolbyVision stream detected", __FUNCTION__);
void *data;
@@ -5190,27 +5181,25 @@
CHECK(!((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1)));
const uint8_t profile = ptr[2] >> 1;
- // profile == (unknown,1,9) --> AVC; profile = (2,3,4,5,6,7,8) --> HEVC;
- // profile == (10) --> AV1
- if (profile > 1 && profile < 9) {
+ // profile == (4,5,6,7,8) --> HEVC; profile == (9) --> AVC; profile == (10) --> AV1
+ if (profile > 3 && profile < 9) {
CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size));
- const uint8_t *ptr = (const uint8_t *)data;
+ mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
+ } else if (9 == profile) {
+ CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
- CHECK(size >= 22);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
-
- mNALLengthSize = 1 + (ptr[14 + 7] & 3);
+ mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
} else if (10 == profile) {
/* AV1 profile nothing to do */
} else {
- CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
- const uint8_t *ptr = (const uint8_t *)data;
-
- CHECK(size >= 7);
- CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
- // The number of bytes used to encode the length of a NAL unit.
- mNALLengthSize = 1 + (ptr[4] & 3);
+ if (AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
+ mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
+ } else if (AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
+ mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
+ } else {
+ LOG_ALWAYS_FATAL("Invalid Dolby Vision profile = %d", profile);
+ }
}
}
@@ -6135,6 +6124,24 @@
return 0;
}
+size_t MPEG4Source::getNALLengthSizeFromAvcCsd(const uint8_t *data, const size_t size) const {
+ CHECK(data != nullptr);
+ CHECK(size >= 7);
+ CHECK_EQ((unsigned)data[0], 1u); // configurationVersion == 1
+
+ // The number of bytes used to encode the length of a NAL unit.
+ return 1 + (data[4] & 3);
+}
+
+size_t MPEG4Source::getNALLengthSizeFromHevcCsd(const uint8_t *data, const size_t size) const {
+ CHECK(data != nullptr);
+ CHECK(size >= 22);
+ CHECK_EQ((unsigned)data[0], 1u); // configurationVersion == 1
+
+ // The number of bytes used to encode the length of a NAL unit.
+ return 1 + (data[14 + 7] & 3);
+}
+
media_status_t MPEG4Source::read(
MediaBufferHelper **out, const ReadOptions *options) {
Mutex::Autolock autoLock(mLock);
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index a2bd5e1..73a96e9 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -77,6 +77,7 @@
"ResourceManagerMetrics.cpp",
"ResourceManagerService.cpp",
"ResourceObserverService.cpp",
+ "ResourceManagerServiceUtils.cpp",
"ServiceLog.cpp",
"UidObserver.cpp",
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 5d1ba2b..9552e25 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -39,6 +39,7 @@
#include "IMediaResourceMonitor.h"
#include "ResourceManagerMetrics.h"
#include "ResourceManagerService.h"
+#include "ResourceManagerServiceUtils.h"
#include "ResourceObserverService.h"
#include "ServiceLog.h"
@@ -160,87 +161,6 @@
service->removeProcessInfoOverride(mClientInfo.pid);
}
-template <typename T>
-static String8 getString(const std::vector<T>& items) {
- String8 itemsStr;
- for (size_t i = 0; i < items.size(); ++i) {
- itemsStr.appendFormat("%s ", toString(items[i]).c_str());
- }
- return itemsStr;
-}
-
-static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- 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:
- return true;
- }
- return false;
-}
-
-static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceList& resources) {
- for (auto it = resources.begin(); it != resources.end(); it++) {
- if (hasResourceType(type, subType, it->second)) {
- return true;
- }
- }
- return false;
-}
-
-static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
- const ResourceInfos& infos) {
- for (const auto& [id, info] : infos) {
- if (hasResourceType(type, subType, info.resources)) {
- return true;
- }
- }
- return false;
-}
-
-static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
- PidResourceInfosMap::iterator found = map.find(pid);
- if (found == map.end()) {
- // new pid
- ResourceInfos infosForPid;
- auto [it, inserted] = map.emplace(pid, infosForPid);
- found = it;
- }
-
- return found->second;
-}
-
-static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
- const std::string& name,
- const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
- ResourceInfos::iterator found = infos.find(clientId);
-
- if (found == infos.end()) {
- ResourceInfo info{.uid = uid,
- .clientId = clientId,
- .name = name.empty()? "<unknown client>" : name,
- .client = client,
- .deathNotifier = nullptr,
- .pendingRemoval = false};
- auto [it, inserted] = infos.emplace(clientId, info);
- found = it;
- }
-
- return found->second;
-}
-
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));
@@ -488,7 +408,6 @@
int32_t pid = clientInfo.pid;
int32_t uid = clientInfo.uid;
int64_t clientId = clientInfo.id;
- const std::string& name = clientInfo.name;
String8 log = String8::format("addResource(pid %d, uid %d clientId %lld, resources %s)",
pid, uid, (long long) clientId, getString(resources).c_str());
mServiceLog->add(log);
@@ -503,7 +422,7 @@
uid = callingUid;
}
ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
- ResourceInfo& info = getResourceInfoForEdit(uid, clientId, name, client, infos);
+ ResourceInfo& info = getResourceInfoForEdit(clientInfo, client, infos);
ResourceList resourceAdded;
for (size_t i = 0; i < resources.size(); ++i) {
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
new file mode 100644
index 0000000..892b1b3
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.cpp
@@ -0,0 +1,98 @@
+/*
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ResourceManagerServiceUtils"
+#include <utils/Log.h>
+
+#include "ResourceManagerService.h"
+#include "ResourceManagerServiceUtils.h"
+
+namespace android {
+
+bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ 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:
+ return true;
+ }
+ return false;
+}
+
+bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ const ResourceList& resources) {
+ for (auto it = resources.begin(); it != resources.end(); it++) {
+ if (hasResourceType(type, subType, it->second)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ const ResourceInfos& infos) {
+ for (const auto& [id, info] : infos) {
+ if (hasResourceType(type, subType, info.resources)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
+ PidResourceInfosMap::iterator found = map.find(pid);
+ if (found == map.end()) {
+ // new pid
+ ResourceInfos infosForPid;
+ auto [it, inserted] = map.emplace(pid, infosForPid);
+ found = it;
+ }
+
+ return found->second;
+}
+
+ResourceInfo& getResourceInfoForEdit(const ClientInfoParcel& clientInfo,
+ 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),
+ .clientId = clientInfo.id,
+ .name = clientInfo.name.empty()? "<unknown client>" : clientInfo.name,
+ .client = client,
+ .deathNotifier = nullptr,
+ .pendingRemoval = false};
+ auto [it, inserted] = infos.emplace(clientInfo.id, info);
+ found = it;
+ }
+
+ return found->second;
+}
+
+} // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
new file mode 100644
index 0000000..bbc26de
--- /dev/null
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -0,0 +1,62 @@
+/*
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
+#define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
+
+#include <vector>
+#include <utils/String8.h>
+
+namespace android {
+
+// templated function to stringify the given vector of items.
+template <typename T>
+String8 getString(const std::vector<T>& items) {
+ String8 itemsStr;
+ for (size_t i = 0; i < items.size(); ++i) {
+ itemsStr.appendFormat("%s ", toString(items[i]).c_str());
+ }
+ return itemsStr;
+}
+
+// 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);
+
+//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);
+
+//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);
+
+// Return modifiable list of ResourceInfo for a given process (look up by pid)
+// from the map of ResourceInfos.
+ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map);
+
+// 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);
+
+} // namespace android
+
+#endif //ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_