Merge "Effect AIDL: support output accumulate" into 24D1-dev
diff --git a/media/Android.mk b/media/Android.mk
deleted file mode 100644
index 220a358..0000000
--- a/media/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-$(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.conf))
-$(eval $(call declare-1p-copy-files,frameworks/av/media/libeffects,audio_effects.xml))
-$(eval $(call declare-1p-copy-files,frameworks/av/media/libstagefright,))
diff --git a/media/aconfig/Android.bp b/media/aconfig/Android.bp
index e0d1fa9..16beb28 100644
--- a/media/aconfig/Android.bp
+++ b/media/aconfig/Android.bp
@@ -43,6 +43,7 @@
name: "android.media.codec-aconfig-cc",
min_sdk_version: "30",
vendor_available: true,
+ double_loadable: true,
apex_available: [
"//apex_available:platform",
"com.android.media.swcodec",
diff --git a/media/audio/aconfig/audio.aconfig b/media/audio/aconfig/audio.aconfig
index 4d0df77..cdbadc2 100644
--- a/media/audio/aconfig/audio.aconfig
+++ b/media/audio/aconfig/audio.aconfig
@@ -13,6 +13,13 @@
}
flag {
+ name: "as_device_connection_failure"
+ namespace: "media_audio"
+ description: "AudioService handles device connection failures."
+ bug: "326597760"
+}
+
+flag {
name: "bluetooth_mac_address_anonymization"
namespace: "media_audio"
description:
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index 525dceb..cfdf1ab 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -71,6 +71,13 @@
}
flag {
+ name: "mute_background_audio"
+ namespace: "media_audio"
+ description: "mute audio playing in background"
+ bug: "296232417"
+}
+
+flag {
name: "sco_managed_by_audio"
namespace: "media_audio"
description: "\
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index c7a1bfd..55847f4 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -169,6 +169,11 @@
"%s: AudioSystem already has an AudioFlinger instance!", __func__);
const auto aps = sp<AudioPolicyService>::make();
ALOGD("%s: AudioPolicy created", __func__);
+ ALOGW_IF(AudioSystem::setLocalAudioPolicyService(aps) != OK,
+ "%s: AudioSystem already has an AudioPolicyService instance!", __func__);
+
+ // Start initialization of internally managed audio objects such as Device Effects.
+ aps->onAudioSystemReady();
// Add AudioFlinger and AudioPolicy to ServiceManager.
sp<IServiceManager> sm = defaultServiceManager();
diff --git a/media/codec2/hal/aidl/Component.cpp b/media/codec2/hal/aidl/Component.cpp
index ba5f8d4..eb64a4a 100644
--- a/media/codec2/hal/aidl/Component.cpp
+++ b/media/codec2/hal/aidl/Component.cpp
@@ -205,30 +205,7 @@
mDeathContext(nullptr) {
// Retrieve supported parameters from store
// TODO: We could cache this per component/interface type
- if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
- c2_status_t err = C2_OK;
- C2ComponentDomainSetting domain;
- std::vector<std::unique_ptr<C2Param>> heapParams;
- err = component->intf()->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
- if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
- std::vector<std::shared_ptr<C2ParamDescriptor>> params;
- bool isComponentSupportsLargeAudioFrame = false;
- component->intf()->querySupportedParams_nb(¶ms);
- for (const auto ¶mDesc : params) {
- if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
- isComponentSupportsLargeAudioFrame = true;
- LOG(VERBOSE) << "Underlying component supports large frame audio";
- break;
- }
- }
- if (!isComponentSupportsLargeAudioFrame) {
- mMultiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
- component->intf(),
- std::static_pointer_cast<C2ReflectorHelper>(
- ::android::GetCodec2PlatformComponentStore()->getParamReflector()));
- }
- }
- }
+ mMultiAccessUnitIntf = store->tryCreateMultiAccessUnitInterface(component->intf());
mInterface = SharedRefBase::make<ComponentInterface>(
component->intf(), mMultiAccessUnitIntf, store->getParameterCache());
mInit = mInterface->status();
diff --git a/media/codec2/hal/aidl/ComponentInterface.cpp b/media/codec2/hal/aidl/ComponentInterface.cpp
index 1f0534d..8ae9fa8 100644
--- a/media/codec2/hal/aidl/ComponentInterface.cpp
+++ b/media/codec2/hal/aidl/ComponentInterface.cpp
@@ -131,9 +131,35 @@
virtual c2_status_t querySupportedValues(
std::vector<C2FieldSupportedValuesQuery>& fields,
c2_blocking_t mayBlock) const override {
- c2_status_t err = mIntf->querySupportedValues_vb(fields, mayBlock);
- if (mMultiAccessUnitIntf != nullptr) {
- err = mMultiAccessUnitIntf->querySupportedValues(fields, mayBlock);
+ if (mMultiAccessUnitIntf == nullptr) {
+ return mIntf->querySupportedValues_vb(fields, mayBlock);
+ }
+ std::vector<C2FieldSupportedValuesQuery> dup = fields;
+ std::vector<C2FieldSupportedValuesQuery> queryArray[2];
+ std::map<C2ParamField, std::pair<uint32_t, size_t>> queryMap;
+ c2_status_t err = C2_OK;
+ for (int i = 0 ; i < fields.size(); i++) {
+ const C2ParamField &field = fields[i].field();
+ uint32_t queryArrayIdx = 1;
+ if (mMultiAccessUnitIntf->isValidField(fields[i].field())) {
+ queryArrayIdx = 0;
+ }
+ queryMap[field] = std::make_pair(
+ queryArrayIdx, queryArray[queryArrayIdx].size());
+ queryArray[queryArrayIdx].push_back(fields[i]);
+ }
+ if (queryArray[0].size() > 0) {
+ err = mMultiAccessUnitIntf->querySupportedValues(queryArray[0], mayBlock);
+ }
+ if (queryArray[1].size() > 0) {
+ err = mIntf->querySupportedValues_vb(queryArray[1], mayBlock);
+ }
+ for (int i = 0 ; i < dup.size(); i++) {
+ auto it = queryMap.find(dup[i].field());
+ if (it != queryMap.end()) {
+ std::pair<uint32_t, size_t> queryid = it->second;
+ fields[i] = queryArray[queryid.first][queryid.second];
+ }
}
return err;
}
diff --git a/media/codec2/hal/aidl/ComponentStore.cpp b/media/codec2/hal/aidl/ComponentStore.cpp
index ef49308..b95c09e 100644
--- a/media/codec2/hal/aidl/ComponentStore.cpp
+++ b/media/codec2/hal/aidl/ComponentStore.cpp
@@ -199,6 +199,36 @@
}
#endif
+std::shared_ptr<MultiAccessUnitInterface> ComponentStore::tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface) {
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf = nullptr;
+ if (c2interface == nullptr) {
+ return nullptr;
+ }
+ if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
+ c2_status_t err = C2_OK;
+ C2ComponentDomainSetting domain;
+ std::vector<std::unique_ptr<C2Param>> heapParams;
+ err = c2interface->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
+ if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
+ std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+ bool isComponentSupportsLargeAudioFrame = false;
+ c2interface->querySupportedParams_nb(¶ms);
+ for (const auto ¶mDesc : params) {
+ if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
+ isComponentSupportsLargeAudioFrame = true;
+ break;
+ }
+ }
+ if (!isComponentSupportsLargeAudioFrame) {
+ multiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
+ c2interface, std::static_pointer_cast<C2ReflectorHelper>(mParamReflector));
+ }
+ }
+ }
+ return multiAccessUnitIntf;
+}
+
// Methods from ::aidl::android::hardware::media::c2::IComponentStore
ScopedAStatus ComponentStore::createComponent(
const std::string& name,
@@ -258,7 +288,10 @@
c2interface = GetFilterWrapper()->maybeWrapInterface(c2interface);
#endif
onInterfaceLoaded(c2interface);
- *intf = SharedRefBase::make<ComponentInterface>(c2interface, mParameterCache);
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf =
+ tryCreateMultiAccessUnitInterface(c2interface);
+ *intf = SharedRefBase::make<ComponentInterface>(
+ c2interface, multiAccessUnitIntf, mParameterCache);
return ScopedAStatus::ok();
}
return ScopedAStatus::fromServiceSpecificError(res);
diff --git a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
index 0698b0f..746e1bf 100644
--- a/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
+++ b/media/codec2/hal/aidl/include/codec2/aidl/ComponentStore.h
@@ -75,6 +75,9 @@
static std::shared_ptr<::android::FilterWrapper> GetFilterWrapper();
+ std::shared_ptr<MultiAccessUnitInterface> tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface);
+
// Methods from ::aidl::android::hardware::media::c2::IComponentStore.
virtual ::ndk::ScopedAStatus createComponent(
const std::string& name,
diff --git a/media/codec2/hal/client/client.cpp b/media/codec2/hal/client/client.cpp
index 9ed9458..b3ae514 100644
--- a/media/codec2/hal/client/client.cpp
+++ b/media/codec2/hal/client/client.cpp
@@ -649,7 +649,7 @@
return C2_CORRUPTED;
}
size_t i = 0;
- size_t numUpdatedStackParams = 0;
+ size_t numQueried = 0;
for (auto it = paramPointers.begin(); it != paramPointers.end(); ) {
C2Param* paramPointer = *it;
if (numStackIndices > 0) {
@@ -678,7 +678,7 @@
continue;
}
if (stackParams[i++]->updateFrom(*paramPointer)) {
- ++numUpdatedStackParams;
+ ++numQueried;
} else {
LOG(WARNING) << "query -- param update failed: "
"index = "
@@ -695,14 +695,11 @@
"unexpected extra stack param.";
} else {
heapParams->emplace_back(C2Param::Copy(*paramPointer));
+ ++numQueried;
}
}
++it;
}
- size_t numQueried = numUpdatedStackParams;
- if (heapParams) {
- numQueried += heapParams->size();
- }
if (status == C2_OK && indices.size() != numQueried) {
status = C2_BAD_INDEX;
}
diff --git a/media/codec2/hal/common/MultiAccessUnitHelper.cpp b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
index 9221a24..3a71520 100644
--- a/media/codec2/hal/common/MultiAccessUnitHelper.cpp
+++ b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
@@ -73,12 +73,17 @@
for (std::shared_ptr<C2ParamDescriptor> &desc : supportedParams) {
mSupportedParamIndexSet.insert(desc->index());
}
+ mParamFields.emplace_back(mLargeFrameParams.get(), &(mLargeFrameParams.get()->maxSize));
+ mParamFields.emplace_back(mLargeFrameParams.get(), &(mLargeFrameParams.get()->thresholdSize));
if (mC2ComponentIntf) {
c2_status_t err = mC2ComponentIntf->query_vb({&mKind}, {}, C2_MAY_BLOCK, nullptr);
}
}
+bool MultiAccessUnitInterface::isValidField(const C2ParamField &field) const {
+ return (std::find(mParamFields.begin(), mParamFields.end(), field) != mParamFields.end());
+}
bool MultiAccessUnitInterface::isParamSupported(C2Param::Index index) {
return (mSupportedParamIndexSet.count(index) != 0);
}
diff --git a/media/codec2/hal/common/include/codec2/common/MultiAccessUnitHelper.h b/media/codec2/hal/common/include/codec2/common/MultiAccessUnitHelper.h
index ef5cff9..a90ae56 100644
--- a/media/codec2/hal/common/include/codec2/common/MultiAccessUnitHelper.h
+++ b/media/codec2/hal/common/include/codec2/common/MultiAccessUnitHelper.h
@@ -41,6 +41,7 @@
bool isParamSupported(C2Param::Index index);
C2LargeFrame::output getLargeFrameParam() const;
C2Component::kind_t kind() const;
+ bool isValidField(const C2ParamField &field) const;
protected:
void getDecoderSampleRateAndChannelCount(
@@ -49,6 +50,7 @@
std::shared_ptr<C2LargeFrame::output> mLargeFrameParams;
C2ComponentKindSetting mKind;
std::set<C2Param::Index> mSupportedParamIndexSet;
+ std::vector<C2ParamField> mParamFields;
friend struct MultiAccessUnitHelper;
};
diff --git a/media/codec2/hal/hidl/1.0/utils/Component.cpp b/media/codec2/hal/hidl/1.0/utils/Component.cpp
index ebbaafc..e32e6ae 100644
--- a/media/codec2/hal/hidl/1.0/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.0/utils/Component.cpp
@@ -259,30 +259,7 @@
mBufferPoolSender{clientPoolManager} {
// Retrieve supported parameters from store
// TODO: We could cache this per component/interface type
- if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
- c2_status_t err = C2_OK;
- C2ComponentDomainSetting domain;
- std::vector<std::unique_ptr<C2Param>> heapParams;
- err = component->intf()->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
- if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
- std::vector<std::shared_ptr<C2ParamDescriptor>> params;
- bool isComponentSupportsLargeAudioFrame = false;
- component->intf()->querySupportedParams_nb(¶ms);
- for (const auto ¶mDesc : params) {
- if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
- isComponentSupportsLargeAudioFrame = true;
- LOG(VERBOSE) << "Underlying component supports large frame audio";
- break;
- }
- }
- if (!isComponentSupportsLargeAudioFrame) {
- mMultiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
- component->intf(),
- std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector()));
- }
- }
- }
+ mMultiAccessUnitIntf = store->tryCreateMultiAccessUnitInterface(component->intf());
mInterface = new ComponentInterface(
component->intf(), mMultiAccessUnitIntf, store->getParameterCache());
mInit = mInterface->status();
diff --git a/media/codec2/hal/hidl/1.0/utils/ComponentInterface.cpp b/media/codec2/hal/hidl/1.0/utils/ComponentInterface.cpp
index 5a5e780..41a8904 100644
--- a/media/codec2/hal/hidl/1.0/utils/ComponentInterface.cpp
+++ b/media/codec2/hal/hidl/1.0/utils/ComponentInterface.cpp
@@ -130,9 +130,35 @@
virtual c2_status_t querySupportedValues(
std::vector<C2FieldSupportedValuesQuery>& fields,
c2_blocking_t mayBlock) const override {
- c2_status_t err = mIntf->querySupportedValues_vb(fields, mayBlock);
- if (mMultiAccessUnitIntf != nullptr) {
- err = mMultiAccessUnitIntf->querySupportedValues(fields, mayBlock);
+ if (mMultiAccessUnitIntf == nullptr) {
+ return mIntf->querySupportedValues_vb(fields, mayBlock);
+ }
+ std::vector<C2FieldSupportedValuesQuery> dup = fields;
+ std::vector<C2FieldSupportedValuesQuery> queryArray[2];
+ std::map<C2ParamField, std::pair<uint32_t, size_t>> queryMap;
+ c2_status_t err = C2_OK;
+ for (int i = 0 ; i < fields.size(); i++) {
+ const C2ParamField &field = fields[i].field();
+ uint32_t queryArrayIdx = 1;
+ if (mMultiAccessUnitIntf->isValidField(field)) {
+ queryArrayIdx = 0;
+ }
+ queryMap[field] = std::make_pair(
+ queryArrayIdx, queryArray[queryArrayIdx].size());
+ queryArray[queryArrayIdx].push_back(fields[i]);
+ }
+ if (queryArray[0].size() > 0) {
+ err = mMultiAccessUnitIntf->querySupportedValues(queryArray[0], mayBlock);
+ }
+ if (queryArray[1].size() > 0) {
+ err = mIntf->querySupportedValues_vb(queryArray[1], mayBlock);
+ }
+ for (int i = 0 ; i < dup.size(); i++) {
+ auto it = queryMap.find(dup[i].field());
+ if (it != queryMap.end()) {
+ std::pair<uint32_t, size_t> queryid = it->second;
+ fields[i] = queryArray[queryid.first][queryid.second];
+ }
}
return err;
}
diff --git a/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp b/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp
index 1c0d5b0..988ab6f 100644
--- a/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp
+++ b/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp
@@ -194,6 +194,36 @@
}
#endif
+std::shared_ptr<MultiAccessUnitInterface> ComponentStore::tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface) {
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf = nullptr;
+ if (c2interface == nullptr) {
+ return nullptr;
+ }
+ if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
+ c2_status_t err = C2_OK;
+ C2ComponentDomainSetting domain;
+ std::vector<std::unique_ptr<C2Param>> heapParams;
+ err = c2interface->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
+ if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
+ std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+ bool isComponentSupportsLargeAudioFrame = false;
+ c2interface->querySupportedParams_nb(¶ms);
+ for (const auto ¶mDesc : params) {
+ if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
+ isComponentSupportsLargeAudioFrame = true;
+ break;
+ }
+ }
+ if (!isComponentSupportsLargeAudioFrame) {
+ multiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
+ c2interface, std::static_pointer_cast<C2ReflectorHelper>(mParamReflector));
+ }
+ }
+ }
+ return multiAccessUnitIntf;
+}
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
Return<void> ComponentStore::createComponent(
const hidl_string& name,
@@ -242,7 +272,9 @@
c2interface = GetFilterWrapper()->maybeWrapInterface(c2interface);
#endif
onInterfaceLoaded(c2interface);
- interface = new ComponentInterface(c2interface, mParameterCache);
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf =
+ tryCreateMultiAccessUnitInterface(c2interface);
+ interface = new ComponentInterface(c2interface, multiAccessUnitIntf, mParameterCache);
}
_hidl_cb(static_cast<Status>(res), interface);
return Void();
diff --git a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
index 27e2a05..b5d85da 100644
--- a/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/ComponentStore.h
@@ -78,6 +78,9 @@
static std::shared_ptr<FilterWrapper> GetFilterWrapper();
+ std::shared_ptr<MultiAccessUnitInterface> tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface);
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore.
virtual Return<void> createComponent(
const hidl_string& name,
diff --git a/media/codec2/hal/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hal/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
index 275a721..ab47b7c 100644
--- a/media/codec2/hal/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hal/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "codec2_hidl_hal_component_test"
#include <android-base/logging.h>
+#include <android/binder_process.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
@@ -382,5 +383,6 @@
}
::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
diff --git a/media/codec2/hal/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp b/media/codec2/hal/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
index 47ceed5..a34cef1 100644
--- a/media/codec2/hal/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
+++ b/media/codec2/hal/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "codec2_hidl_hal_master_test"
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -82,6 +83,20 @@
}
}
+TEST_P(Codec2MasterHalTest, MustUseAidlBeyond202404) {
+ static int sBoardFirstApiLevel = android::base::GetIntProperty("ro.board.first_api_level", 0);
+ static int sBoardApiLevel = android::base::GetIntProperty("ro.board.api_level", 0);
+ if (sBoardFirstApiLevel < 202404 && sBoardApiLevel < 202404) {
+ GTEST_SKIP() << "board first level less than 202404:"
+ << " ro.board.first_api_level = " << sBoardFirstApiLevel
+ << " ro.board.api_level = " << sBoardApiLevel;
+ }
+ ALOGV("HidlCodecAllowed Test");
+
+ EXPECT_NE(mClient->getAidlBase(), nullptr) << "android.hardware.media.c2 MUST use AIDL "
+ << "for chipsets launching at 202404 or above";
+}
+
} // anonymous namespace
INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2MasterHalTest,
diff --git a/media/codec2/hal/hidl/1.1/utils/Component.cpp b/media/codec2/hal/hidl/1.1/utils/Component.cpp
index 5073983..09e5709 100644
--- a/media/codec2/hal/hidl/1.1/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.1/utils/Component.cpp
@@ -263,30 +263,7 @@
mBufferPoolSender{clientPoolManager} {
// Retrieve supported parameters from store
// TODO: We could cache this per component/interface type
- if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
- c2_status_t err = C2_OK;
- C2ComponentDomainSetting domain;
- std::vector<std::unique_ptr<C2Param>> heapParams;
- err = component->intf()->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
- if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
- std::vector<std::shared_ptr<C2ParamDescriptor>> params;
- bool isComponentSupportsLargeAudioFrame = false;
- component->intf()->querySupportedParams_nb(¶ms);
- for (const auto ¶mDesc : params) {
- if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
- isComponentSupportsLargeAudioFrame = true;
- LOG(VERBOSE) << "Underlying component supports large frame audio";
- break;
- }
- }
- if (!isComponentSupportsLargeAudioFrame) {
- mMultiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
- component->intf(),
- std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector()));
- }
- }
- }
+ mMultiAccessUnitIntf = store->tryCreateMultiAccessUnitInterface(component->intf());
mInterface = new ComponentInterface(
component->intf(), mMultiAccessUnitIntf, store->getParameterCache());
mInit = mInterface->status();
diff --git a/media/codec2/hal/hidl/1.1/utils/ComponentStore.cpp b/media/codec2/hal/hidl/1.1/utils/ComponentStore.cpp
index d47abdd..46af809 100644
--- a/media/codec2/hal/hidl/1.1/utils/ComponentStore.cpp
+++ b/media/codec2/hal/hidl/1.1/utils/ComponentStore.cpp
@@ -194,6 +194,37 @@
}
#endif
+std::shared_ptr<MultiAccessUnitInterface> ComponentStore::tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface) {
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf = nullptr;
+ if (c2interface == nullptr) {
+ return nullptr;
+ }
+ if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
+ c2_status_t err = C2_OK;
+ C2ComponentDomainSetting domain;
+ std::vector<std::unique_ptr<C2Param>> heapParams;
+ err = c2interface->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
+ if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
+ std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+ bool isComponentSupportsLargeAudioFrame = false;
+ c2interface->querySupportedParams_nb(¶ms);
+ for (const auto ¶mDesc : params) {
+ if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
+ isComponentSupportsLargeAudioFrame = true;
+ break;
+ }
+ }
+
+ if (!isComponentSupportsLargeAudioFrame) {
+ multiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
+ c2interface, std::static_pointer_cast<C2ReflectorHelper>(mParamReflector));
+ }
+ }
+ }
+ return multiAccessUnitIntf;
+}
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
Return<void> ComponentStore::createComponent(
const hidl_string& name,
@@ -241,7 +272,10 @@
c2interface = GetFilterWrapper()->maybeWrapInterface(c2interface);
#endif
onInterfaceLoaded(c2interface);
- interface = new ComponentInterface(c2interface, mParameterCache);
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf =
+ tryCreateMultiAccessUnitInterface(c2interface);
+ interface = new ComponentInterface(
+ c2interface, multiAccessUnitIntf, mParameterCache);
}
_hidl_cb(static_cast<Status>(res), interface);
return Void();
diff --git a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
index f6daee7..85862a9 100644
--- a/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.1/utils/include/codec2/hidl/1.1/ComponentStore.h
@@ -79,6 +79,9 @@
static std::shared_ptr<FilterWrapper> GetFilterWrapper();
+ std::shared_ptr<MultiAccessUnitInterface> tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface);
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore.
virtual Return<void> createComponent(
const hidl_string& name,
diff --git a/media/codec2/hal/hidl/1.2/utils/Component.cpp b/media/codec2/hal/hidl/1.2/utils/Component.cpp
index bbdbef5..0fe16e3 100644
--- a/media/codec2/hal/hidl/1.2/utils/Component.cpp
+++ b/media/codec2/hal/hidl/1.2/utils/Component.cpp
@@ -261,30 +261,7 @@
mBufferPoolSender{clientPoolManager} {
// Retrieve supported parameters from store
// TODO: We could cache this per component/interface type
- if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
- c2_status_t err = C2_OK;
- C2ComponentDomainSetting domain;
- std::vector<std::unique_ptr<C2Param>> heapParams;
- err = component->intf()->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
- if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
- std::vector<std::shared_ptr<C2ParamDescriptor>> params;
- bool isComponentSupportsLargeAudioFrame = false;
- component->intf()->querySupportedParams_nb(¶ms);
- for (const auto ¶mDesc : params) {
- if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
- isComponentSupportsLargeAudioFrame = true;
- LOG(VERBOSE) << "Underlying component supports large frame audio";
- break;
- }
- }
- if (!isComponentSupportsLargeAudioFrame) {
- mMultiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
- component->intf(),
- std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector()));
- }
- }
- }
+ mMultiAccessUnitIntf = store->tryCreateMultiAccessUnitInterface(component->intf());
mInterface = new ComponentInterface(
component->intf(), mMultiAccessUnitIntf, store->getParameterCache());
mInit = mInterface->status();
diff --git a/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp b/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp
index 9fac5d5..f89c835 100644
--- a/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp
+++ b/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp
@@ -194,6 +194,36 @@
}
#endif
+std::shared_ptr<MultiAccessUnitInterface> ComponentStore::tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface) {
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf = nullptr;
+ if (c2interface == nullptr) {
+ return nullptr;
+ }
+ if (MultiAccessUnitHelper::isEnabledOnPlatform()) {
+ c2_status_t err = C2_OK;
+ C2ComponentDomainSetting domain;
+ std::vector<std::unique_ptr<C2Param>> heapParams;
+ err = c2interface->query_vb({&domain}, {}, C2_MAY_BLOCK, &heapParams);
+ if (err == C2_OK && (domain.value == C2Component::DOMAIN_AUDIO)) {
+ std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+ bool isComponentSupportsLargeAudioFrame = false;
+ c2interface->querySupportedParams_nb(¶ms);
+ for (const auto ¶mDesc : params) {
+ if (paramDesc->name().compare(C2_PARAMKEY_OUTPUT_LARGE_FRAME) == 0) {
+ isComponentSupportsLargeAudioFrame = true;
+ break;
+ }
+ }
+ if (!isComponentSupportsLargeAudioFrame) {
+ multiAccessUnitIntf = std::make_shared<MultiAccessUnitInterface>(
+ c2interface, std::static_pointer_cast<C2ReflectorHelper>(mParamReflector));
+ }
+ }
+ }
+ return multiAccessUnitIntf;
+}
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
Return<void> ComponentStore::createComponent(
const hidl_string& name,
@@ -241,7 +271,9 @@
c2interface = GetFilterWrapper()->maybeWrapInterface(c2interface);
#endif
onInterfaceLoaded(c2interface);
- interface = new ComponentInterface(c2interface, mParameterCache);
+ std::shared_ptr<MultiAccessUnitInterface> multiAccessUnitIntf =
+ tryCreateMultiAccessUnitInterface(c2interface);
+ interface = new ComponentInterface(c2interface, multiAccessUnitIntf, mParameterCache);
}
_hidl_cb(static_cast<Status>(res), interface);
return Void();
diff --git a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
index e95a651..c08fce4 100644
--- a/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
+++ b/media/codec2/hal/hidl/1.2/utils/include/codec2/hidl/1.2/ComponentStore.h
@@ -79,6 +79,9 @@
static std::shared_ptr<FilterWrapper> GetFilterWrapper();
+ std::shared_ptr<MultiAccessUnitInterface> tryCreateMultiAccessUnitInterface(
+ const std::shared_ptr<C2ComponentInterface> &c2interface);
+
// Methods from ::android::hardware::media::c2::V1_0::IComponentStore.
virtual Return<void> createComponent(
const hidl_string& name,
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index d867eb1..18c2468 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -45,6 +45,7 @@
static_libs: [
"libSurfaceFlingerProperties",
+ "android.media.codec-aconfig-cc",
],
shared_libs: [
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 453a0d2..8dce789 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -20,6 +20,8 @@
#include <strings.h>
+#include <android_media_codec.h>
+
#include <C2Component.h>
#include <C2Config.h>
#include <C2Debug.h>
@@ -752,6 +754,24 @@
}
addSupportedColorFormats(
intf, caps.get(), trait, mediaType, it->second);
+
+ if (android::media::codec::provider_->large_audio_frame_finish()) {
+ // Adding feature-multiple-frames when C2LargeFrame param is present
+ if (trait.domain == C2Component::DOMAIN_AUDIO) {
+ std::vector<std::shared_ptr<C2ParamDescriptor>> params;
+ c2_status_t err = intf->querySupportedParams(¶ms);
+ if (err == C2_OK) {
+ for (const auto ¶mDesc : params) {
+ if (C2LargeFrame::output::PARAM_TYPE == paramDesc->index()) {
+ std::string featureMultipleFrames =
+ std::string(KEY_FEATURE_) + FEATURE_MultipleFrames;
+ caps->addDetail(featureMultipleFrames.c_str(), 0);
+ break;
+ }
+ }
+ }
+ }
+ }
}
}
}
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 6cc5d63..90910a1 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -68,7 +68,6 @@
"libaudioclient_aidl_conversion",
"libaudioutils",
"libbinder",
- "libbinder_ndk",
"libcutils",
"liblog",
"libutils",
@@ -188,6 +187,7 @@
"-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
+ "-Wthread-safety",
],
sanitize: {
misc_undefined: [
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 348e25f..d1b1849 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -65,115 +65,184 @@
using media::audio::common::AudioUsage;
using media::audio::common::Int;
-// client singleton for AudioFlinger binder interface
-Mutex AudioSystem::gLock;
-Mutex AudioSystem::gLockErrorCallbacks;
-Mutex AudioSystem::gLockAPS;
-sp<IAudioFlinger> AudioSystem::gAudioFlinger;
-sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
-std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
+std::mutex AudioSystem::gMutex;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
record_config_callback AudioSystem::gRecordConfigCallback = NULL;
routing_callback AudioSystem::gRoutingCallback = NULL;
vol_range_init_req_callback AudioSystem::gVolRangeInitReqCallback = NULL;
-// Required to be held while calling into gSoundTriggerCaptureStateListener.
-class CaptureStateListenerImpl;
+std::mutex AudioSystem::gApsCallbackMutex;
+std::mutex AudioSystem::gErrorCallbacksMutex;
+std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
-Mutex gSoundTriggerCaptureStateListenerLock;
-sp<CaptureStateListenerImpl> gSoundTriggerCaptureStateListener = nullptr;
+std::mutex AudioSystem::gSoundTriggerMutex;
+sp<CaptureStateListenerImpl> AudioSystem::gSoundTriggerCaptureStateListener;
-// Binder for the AudioFlinger service that's passed to this client process from the system server.
+// Sets the Binder for the AudioFlinger service, passed to this client process
+// from the system server.
// This allows specific isolated processes to access the audio system. Currently used only for the
// HotwordDetectionService.
-static sp<IBinder> gAudioFlingerBinder = nullptr;
+template <typename ServiceInterface, typename Client, typename AidlInterface,
+ typename ServiceTraits>
+class ServiceHandler {
+public:
+ sp<ServiceInterface> getService(bool canStartThreadPool = true)
+ EXCLUDES(mMutex) NO_THREAD_SAFETY_ANALYSIS { // std::unique_ptr
+ sp<ServiceInterface> service;
+ sp<Client> client;
-void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) {
- if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) {
- ALOGE("setAudioFlingerBinder: received a binder of type %s",
- String8(audioFlinger->getInterfaceDescriptor()).c_str());
- return;
- }
- Mutex::Autolock _l(gLock);
- if (gAudioFlinger != nullptr) {
- ALOGW("setAudioFlingerBinder: ignoring; AudioFlinger connection already established.");
- return;
- }
- gAudioFlingerBinder = audioFlinger;
-}
-
-static sp<IAudioFlinger> gLocalAudioFlinger; // set if we are local.
-
-status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) {
- Mutex::Autolock _l(gLock);
- if (gAudioFlinger != nullptr) return INVALID_OPERATION;
- gLocalAudioFlinger = af;
- return OK;
-}
-
-// establish binder interface to AudioFlinger service
-const sp<IAudioFlinger> AudioSystem::getAudioFlingerImpl(bool canStartThreadPool = true) {
- sp<IAudioFlinger> af;
- sp<AudioFlingerClient> afc;
- bool reportNoError = false;
- {
- Mutex::Autolock _l(gLock);
- if (gAudioFlinger != nullptr) {
- return gAudioFlinger;
+ bool reportNoError = false;
+ {
+ std::lock_guard _l(mMutex);
+ if (mService != nullptr) {
+ return mService;
+ }
}
- if (gAudioFlingerClient == nullptr) {
- gAudioFlingerClient = sp<AudioFlingerClient>::make();
+ std::unique_lock ul_only1thread(mSingleGetter);
+ std::unique_lock ul(mMutex);
+ if (mService != nullptr) {
+ return mService;
+ }
+ if (mClient == nullptr) {
+ mClient = sp<Client>::make();
} else {
reportNoError = true;
}
+ while (true) {
+ mService = mLocalService;
+ if (mService != nullptr) break;
- if (gLocalAudioFlinger != nullptr) {
- gAudioFlinger = gLocalAudioFlinger;
- } else {
- sp<IBinder> binder;
- if (gAudioFlingerBinder != nullptr) {
- binder = gAudioFlingerBinder;
- } else {
- sp<IServiceManager> sm = defaultServiceManager();
- binder = sm->waitForService(String16(IAudioFlinger::DEFAULT_SERVICE_NAME));
+ sp<IBinder> binder = mBinder;
+ if (binder == nullptr) {
+ sp <IServiceManager> sm = defaultServiceManager();
+ binder = sm->checkService(String16(ServiceTraits::SERVICE_NAME));
if (binder == nullptr) {
- return nullptr;
+ ALOGD("%s: waiting for %s", __func__, ServiceTraits::SERVICE_NAME);
+
+ // if the condition variable is present, setLocalService() and
+ // setBinder() is allowed to use it to notify us.
+ if (mCvGetter == nullptr) {
+ mCvGetter = std::make_shared<std::condition_variable>();
+ }
+ mCvGetter->wait_for(ul, std::chrono::seconds(1));
+ continue;
}
}
- binder->linkToDeath(gAudioFlingerClient);
- const auto afs = interface_cast<media::IAudioFlingerService>(binder);
- LOG_ALWAYS_FATAL_IF(afs == nullptr);
- gAudioFlinger = sp<AudioFlingerClientAdapter>::make(afs);
+ binder->linkToDeath(mClient);
+ auto aidlInterface = interface_cast<AidlInterface>(binder);
+ LOG_ALWAYS_FATAL_IF(aidlInterface == nullptr);
+ if constexpr (std::is_same_v<ServiceInterface, AidlInterface>) {
+ mService = std::move(aidlInterface);
+ } else /* constexpr */ {
+ mService = ServiceTraits::createServiceAdapter(aidlInterface);
+ }
+ break;
}
- afc = gAudioFlingerClient;
- af = gAudioFlinger;
- // Make sure callbacks can be received by gAudioFlingerClient
- if(canStartThreadPool) {
+ if (mCvGetter) mCvGetter.reset(); // remove condition variable.
+ client = mClient;
+ service = mService;
+ // Make sure callbacks can be received by the client
+ if (canStartThreadPool) {
ProcessState::self()->startThreadPool();
}
+ ul.unlock();
+ ul_only1thread.unlock();
+ ServiceTraits::onServiceCreate(service, client);
+ if (reportNoError) AudioSystem::reportError(NO_ERROR);
+ return service;
}
- const int64_t token = IPCThreadState::self()->clearCallingIdentity();
- af->registerClient(afc);
- IPCThreadState::self()->restoreCallingIdentity(token);
- if (reportNoError) reportError(NO_ERROR);
- return af;
+
+ status_t setLocalService(const sp<ServiceInterface>& service) EXCLUDES(mMutex) {
+ std::lock_guard _l(mMutex);
+ // we allow clearing once set, but not a double non-null set.
+ if (mService != nullptr && service != nullptr) return INVALID_OPERATION;
+ mLocalService = service;
+ if (mCvGetter) mCvGetter->notify_one();
+ return OK;
+ }
+
+ sp<Client> getClient() EXCLUDES(mMutex) {
+ const auto service = getService();
+ if (service == nullptr) return nullptr;
+ std::lock_guard _l(mMutex);
+ return mClient;
+ }
+
+ void setBinder(const sp<IBinder>& binder) EXCLUDES(mMutex) {
+ std::lock_guard _l(mMutex);
+ if (mService != nullptr) {
+ ALOGW("%s: ignoring; %s connection already established.",
+ __func__, ServiceTraits::SERVICE_NAME);
+ return;
+ }
+ mBinder = binder;
+ if (mCvGetter) mCvGetter->notify_one();
+ }
+
+ void clearService() EXCLUDES(mMutex) {
+ std::lock_guard _l(mMutex);
+ mService.clear();
+ if (mClient) ServiceTraits::onClearService(mClient);
+ }
+
+private:
+ std::mutex mSingleGetter;
+ std::mutex mMutex;
+ std::shared_ptr<std::condition_variable> mCvGetter GUARDED_BY(mMutex);
+ sp<IBinder> mBinder GUARDED_BY(mMutex);
+ sp<ServiceInterface> mLocalService GUARDED_BY(mMutex);
+ sp<ServiceInterface> mService GUARDED_BY(mMutex);
+ sp<Client> mClient GUARDED_BY(mMutex);
+};
+
+struct AudioFlingerTraits {
+ static void onServiceCreate(
+ const sp<IAudioFlinger>& af, const sp<AudioSystem::AudioFlingerClient>& afc) {
+ const int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ af->registerClient(afc);
+ IPCThreadState::self()->restoreCallingIdentity(token);
+ }
+
+ static sp<IAudioFlinger> createServiceAdapter(
+ const sp<media::IAudioFlingerService>& aidlInterface) {
+ return sp<AudioFlingerClientAdapter>::make(aidlInterface);
+ }
+
+ static void onClearService(const sp<AudioSystem::AudioFlingerClient>& afc) {
+ afc->clearIoCache();
+ }
+
+ static constexpr const char* SERVICE_NAME = IAudioFlinger::DEFAULT_SERVICE_NAME;
+};
+
+[[clang::no_destroy]] static constinit ServiceHandler<IAudioFlinger,
+ AudioSystem::AudioFlingerClient, media::IAudioFlingerService,
+ AudioFlingerTraits> gAudioFlingerServiceHandler;
+
+sp<IAudioFlinger> AudioSystem::get_audio_flinger() {
+ return gAudioFlingerServiceHandler.getService();
}
-const sp<IAudioFlinger> AudioSystem:: get_audio_flinger() {
- return getAudioFlingerImpl();
+sp<IAudioFlinger> AudioSystem::get_audio_flinger_for_fuzzer() {
+ return gAudioFlingerServiceHandler.getService(false /* canStartThreadPool */);
}
-const sp<IAudioFlinger> AudioSystem:: get_audio_flinger_for_fuzzer() {
- return getAudioFlingerImpl(false);
+sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
+ return gAudioFlingerServiceHandler.getClient();
}
-const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
- // calling get_audio_flinger() will initialize gAudioFlingerClient if needed
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return 0;
- Mutex::Autolock _l(gLock);
- return gAudioFlingerClient;
+void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) {
+ if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) {
+ ALOGE("%s: received a binder of type %s",
+ __func__, String8(audioFlinger->getInterfaceDescriptor()).c_str());
+ return;
+ }
+ gAudioFlingerServiceHandler.setBinder(audioFlinger);
+}
+
+status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) {
+ return gAudioFlingerServiceHandler.setLocalService(af);
}
sp<AudioIoDescriptor> AudioSystem::getIoDescriptor(audio_io_handle_t ioHandle) {
@@ -195,41 +264,41 @@
// FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
status_t AudioSystem::muteMicrophone(bool state) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setMicMute(state);
}
status_t AudioSystem::isMicrophoneMuted(bool* state) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*state = af->getMicMute();
return NO_ERROR;
}
status_t AudioSystem::setMasterVolume(float value) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setMasterVolume(value);
return NO_ERROR;
}
status_t AudioSystem::setMasterMute(bool mute) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setMasterMute(mute);
return NO_ERROR;
}
status_t AudioSystem::getMasterVolume(float* volume) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*volume = af->masterVolume();
return NO_ERROR;
}
status_t AudioSystem::getMasterMute(bool* mute) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*mute = af->masterMute();
return NO_ERROR;
@@ -238,7 +307,7 @@
status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output) {
if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setStreamVolume(stream, value, output);
return NO_ERROR;
@@ -246,7 +315,7 @@
status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute) {
if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setStreamMute(stream, mute);
return NO_ERROR;
@@ -255,7 +324,7 @@
status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume,
audio_io_handle_t output) {
if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*volume = af->streamVolume(stream, output);
return NO_ERROR;
@@ -263,7 +332,7 @@
status_t AudioSystem::getStreamMute(audio_stream_type_t stream, bool* mute) {
if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
*mute = af->streamMute(stream);
return NO_ERROR;
@@ -271,25 +340,25 @@
status_t AudioSystem::setMode(audio_mode_t mode) {
if (uint32_t(mode) >= AUDIO_MODE_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setMode(mode);
}
status_t AudioSystem::setSimulateDeviceConnections(bool enabled) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setSimulateDeviceConnections(enabled);
}
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setParameters(ioHandle, keyValuePairs);
}
String8 AudioSystem::getParameters(audio_io_handle_t ioHandle, const String8& keys) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
String8 result = String8("");
if (af == 0) return result;
@@ -308,23 +377,23 @@
// convert volume steps to natural log scale
// change this value to change volume scaling
-static const float dBPerStep = 0.5f;
+constexpr float kdbPerStep = 0.5f;
// shouldn't need to touch these
-static const float dBConvert = -dBPerStep * 2.302585093f / 20.0f;
-static const float dBConvertInverse = 1.0f / dBConvert;
+constexpr float kdBConvert = -kdbPerStep * 2.302585093f / 20.0f;
+constexpr float kdBConvertInverse = 1.0f / kdBConvert;
float AudioSystem::linearToLog(int volume) {
- // float v = volume ? exp(float(100 - volume) * dBConvert) : 0;
+ // float v = volume ? exp(float(100 - volume) * kdBConvert) : 0;
// ALOGD("linearToLog(%d)=%f", volume, v);
// return v;
- return volume ? exp(float(100 - volume) * dBConvert) : 0;
+ return volume ? exp(float(100 - volume) * kdBConvert) : 0;
}
int AudioSystem::logToLinear(float volume) {
- // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
+ // int v = volume ? 100 - int(kdBConvertInverse * log(volume) + 0.5) : 0;
// ALOGD("logTolinear(%d)=%f", v, volume);
// return v;
- return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
+ return volume ? 100 - int(kdBConvertInverse * log(volume) + 0.5) : 0;
}
/* static */ size_t AudioSystem::calculateMinFrameCount(
@@ -369,7 +438,7 @@
status_t AudioSystem::getSamplingRate(audio_io_handle_t ioHandle,
uint32_t* samplingRate) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
if (desc == 0) {
@@ -404,7 +473,7 @@
status_t AudioSystem::getFrameCount(audio_io_handle_t ioHandle,
size_t* frameCount) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
if (desc == 0) {
@@ -439,7 +508,7 @@
status_t AudioSystem::getLatency(audio_io_handle_t output,
uint32_t* latency) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
sp<AudioIoDescriptor> outputDesc = getIoDescriptor(output);
if (outputDesc == 0) {
@@ -463,21 +532,21 @@
}
status_t AudioSystem::setVoiceVolume(float value) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setVoiceVolume(value);
}
status_t AudioSystem::getRenderPosition(audio_io_handle_t output, uint32_t* halFrames,
uint32_t* dspFrames) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->getRenderPosition(halFrames, dspFrames, output);
}
uint32_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
uint32_t result = 0;
if (af == 0) return result;
if (ioHandle == AUDIO_IO_HANDLE_NONE) return result;
@@ -488,46 +557,46 @@
audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use) {
// Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
return af->newAudioUniqueId(use);
}
void AudioSystem::acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af != 0) {
af->acquireAudioSessionId(audioSession, pid, uid);
}
}
void AudioSystem::releaseAudioSessionId(audio_session_t audioSession, pid_t pid) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af != 0) {
af->releaseAudioSessionId(audioSession, pid);
}
}
audio_hw_sync_t AudioSystem::getAudioHwSyncForSession(audio_session_t sessionId) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return AUDIO_HW_SYNC_INVALID;
return af->getAudioHwSyncForSession(sessionId);
}
status_t AudioSystem::systemReady() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return NO_INIT;
return af->systemReady();
}
status_t AudioSystem::audioPolicyReady() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return NO_INIT;
return af->audioPolicyReady();
}
status_t AudioSystem::getFrameCountHAL(audio_io_handle_t ioHandle,
size_t* frameCount) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
if (desc == 0) {
@@ -549,7 +618,7 @@
void AudioSystem::AudioFlingerClient::clearIoCache() {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
mIoDescriptors.clear();
mInBuffSize = 0;
mInSamplingRate = 0;
@@ -558,14 +627,7 @@
}
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) {
- {
- Mutex::Autolock _l(AudioSystem::gLock);
- AudioSystem::gAudioFlinger.clear();
- }
-
- // clear output handles and stream to output map caches
- clearIoCache();
-
+ gAudioFlingerServiceHandler.clearService();
reportError(DEAD_OBJECT);
ALOGW("AudioFlinger server died!");
@@ -587,7 +649,7 @@
audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
std::vector<sp<AudioDeviceCallback>> callbacksToCall;
{
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
auto callbacks = std::map<audio_port_handle_t, wp<AudioDeviceCallback>>();
switch (event) {
@@ -595,13 +657,10 @@
case AUDIO_OUTPUT_REGISTERED:
case AUDIO_INPUT_OPENED:
case AUDIO_INPUT_REGISTERED: {
- sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle());
- if (oldDesc == 0) {
- mIoDescriptors.add(ioDesc->getIoHandle(), ioDesc);
- } else {
+ if (sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->getIoHandle())) {
deviceId = oldDesc->getDeviceId();
- mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc);
}
+ mIoDescriptors[ioDesc->getIoHandle()] = ioDesc;
if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
deviceId = ioDesc->getDeviceId();
@@ -630,7 +689,7 @@
ALOGV("ioConfigChanged() %s %d closed",
event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->getIoHandle());
- mIoDescriptors.removeItem(ioDesc->getIoHandle());
+ mIoDescriptors.erase(ioDesc->getIoHandle());
mAudioDeviceCallbacks.erase(ioDesc->getIoHandle());
}
break;
@@ -646,7 +705,7 @@
}
deviceId = oldDesc->getDeviceId();
- mIoDescriptors.replaceValueFor(ioDesc->getIoHandle(), ioDesc);
+ mIoDescriptors[ioDesc->getIoHandle()] = ioDesc;
if (deviceId != ioDesc->getDeviceId()) {
deviceId = ioDesc->getDeviceId();
@@ -692,8 +751,8 @@
}
}
- // Callbacks must be called without mLock held. May lead to dead lock if calling for
- // example getRoutedDevice that updates the device and tries to acquire mLock.
+ // Callbacks must be called without mMutex held. May lead to dead lock if calling for
+ // example getRoutedDevice that updates the device and tries to acquire mMutex.
for (auto cb : callbacksToCall) {
// If callbacksToCall is not empty, it implies ioDesc->getIoHandle() and deviceId are valid
cb->onAudioDeviceUpdate(ioDesc->getIoHandle(), deviceId);
@@ -712,7 +771,7 @@
std::vector<sp<SupportedLatencyModesCallback>> callbacks;
{
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
for (auto callback : mSupportedLatencyModesCallbacks) {
if (auto ref = callback.promote(); ref != nullptr) {
callbacks.push_back(ref);
@@ -729,11 +788,11 @@
status_t AudioSystem::AudioFlingerClient::getInputBufferSize(
uint32_t sampleRate, audio_format_t format,
audio_channel_mask_t channelMask, size_t* buffSize) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) {
return PERMISSION_DENIED;
}
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
// Do we have a stale mInBuffSize or are we requesting the input buffer size for new values
if ((mInBuffSize == 0) || (sampleRate != mInSamplingRate) || (format != mInFormat)
|| (channelMask != mInChannelMask)) {
@@ -759,16 +818,15 @@
sp<AudioIoDescriptor>
AudioSystem::AudioFlingerClient::getIoDescriptor_l(audio_io_handle_t ioHandle) {
- sp<AudioIoDescriptor> desc;
- ssize_t index = mIoDescriptors.indexOfKey(ioHandle);
- if (index >= 0) {
- desc = mIoDescriptors.valueAt(index);
+ if (const auto it = mIoDescriptors.find(ioHandle);
+ it != mIoDescriptors.end()) {
+ return it->second;
}
- return desc;
+ return {};
}
sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
return getIoDescriptor_l(ioHandle);
}
@@ -776,7 +834,7 @@
const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
audio_port_handle_t portId) {
ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
auto& callbacks = mAudioDeviceCallbacks.emplace(
audioIo,
std::map<audio_port_handle_t, wp<AudioDeviceCallback>>()).first->second;
@@ -791,7 +849,7 @@
const wp<AudioDeviceCallback>& callback __unused, audio_io_handle_t audioIo,
audio_port_handle_t portId) {
ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
auto it = mAudioDeviceCallbacks.find(audioIo);
if (it == mAudioDeviceCallbacks.end()) {
return INVALID_OPERATION;
@@ -807,7 +865,7 @@
status_t AudioSystem::AudioFlingerClient::addSupportedLatencyModesCallback(
const sp<SupportedLatencyModesCallback>& callback) {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
if (std::find(mSupportedLatencyModesCallbacks.begin(),
mSupportedLatencyModesCallbacks.end(),
callback) != mSupportedLatencyModesCallbacks.end()) {
@@ -819,7 +877,7 @@
status_t AudioSystem::AudioFlingerClient::removeSupportedLatencyModesCallback(
const sp<SupportedLatencyModesCallback>& callback) {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mMutex);
auto it = std::find(mSupportedLatencyModesCallbacks.begin(),
mSupportedLatencyModesCallbacks.end(),
callback);
@@ -831,93 +889,78 @@
}
/* static */ uintptr_t AudioSystem::addErrorCallback(audio_error_callback cb) {
- Mutex::Autolock _l(gLockErrorCallbacks);
+ std::lock_guard _l(gErrorCallbacksMutex);
gAudioErrorCallbacks.insert(cb);
return reinterpret_cast<uintptr_t>(cb);
}
/* static */ void AudioSystem::removeErrorCallback(uintptr_t cb) {
- Mutex::Autolock _l(gLockErrorCallbacks);
+ std::lock_guard _l(gErrorCallbacksMutex);
gAudioErrorCallbacks.erase(reinterpret_cast<audio_error_callback>(cb));
}
/* static */ void AudioSystem::reportError(status_t err) {
- Mutex::Autolock _l(gLockErrorCallbacks);
+ std::lock_guard _l(gErrorCallbacksMutex);
for (auto callback : gAudioErrorCallbacks) {
callback(err);
}
}
/*static*/ void AudioSystem::setDynPolicyCallback(dynamic_policy_callback cb) {
- Mutex::Autolock _l(gLock);
+ std::lock_guard _l(gMutex);
gDynPolicyCallback = cb;
}
/*static*/ void AudioSystem::setRecordConfigCallback(record_config_callback cb) {
- Mutex::Autolock _l(gLock);
+ std::lock_guard _l(gMutex);
gRecordConfigCallback = cb;
}
/*static*/ void AudioSystem::setRoutingCallback(routing_callback cb) {
- Mutex::Autolock _l(gLock);
+ std::lock_guard _l(gMutex);
gRoutingCallback = cb;
}
/*static*/ void AudioSystem::setVolInitReqCallback(vol_range_init_req_callback cb) {
- Mutex::Autolock _l(gLock);
+ std::lock_guard _l(gMutex);
gVolRangeInitReqCallback = cb;
}
-// client singleton for AudioPolicyService binder interface
-// protected by gLockAPS
-sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
-sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;
-
-
-// establish binder interface to AudioPolicy service
-const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() {
- sp<IAudioPolicyService> ap;
- sp<AudioPolicyServiceClient> apc;
- {
- Mutex::Autolock _l(gLockAPS);
- if (gAudioPolicyService == 0) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->waitForService(String16("media.audio_policy"));
- if (binder == nullptr) {
- return nullptr;
- }
- if (gAudioPolicyServiceClient == NULL) {
- gAudioPolicyServiceClient = new AudioPolicyServiceClient();
- }
- binder->linkToDeath(gAudioPolicyServiceClient);
- gAudioPolicyService = interface_cast<IAudioPolicyService>(binder);
- LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0);
- apc = gAudioPolicyServiceClient;
- // Make sure callbacks can be received by gAudioPolicyServiceClient
- ProcessState::self()->startThreadPool();
- }
- ap = gAudioPolicyService;
- }
- if (apc != 0) {
- int64_t token = IPCThreadState::self()->clearCallingIdentity();
+struct AudioPolicyTraits {
+ static void onServiceCreate(const sp<IAudioPolicyService>& ap,
+ const sp<AudioSystem::AudioPolicyServiceClient>& apc) {
+ const int64_t token = IPCThreadState::self()->clearCallingIdentity();
ap->registerClient(apc);
ap->setAudioPortCallbacksEnabled(apc->isAudioPortCbEnabled());
ap->setAudioVolumeGroupCallbacksEnabled(apc->isAudioVolumeGroupCbEnabled());
IPCThreadState::self()->restoreCallingIdentity(token);
}
- return ap;
+ static void onClearService(const sp<AudioSystem::AudioPolicyServiceClient>&) {}
+
+ static constexpr const char *SERVICE_NAME = "media.audio_policy";
+};
+
+[[clang::no_destroy]] static constinit ServiceHandler<IAudioPolicyService,
+ AudioSystem::AudioPolicyServiceClient, IAudioPolicyService,
+ AudioPolicyTraits> gAudioPolicyServiceHandler;
+
+status_t AudioSystem::setLocalAudioPolicyService(const sp<IAudioPolicyService>& aps) {
+ return gAudioPolicyServiceHandler.setLocalService(aps);
+}
+
+sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() {
+ return gAudioPolicyServiceHandler.getService();
}
void AudioSystem::clearAudioPolicyService() {
- Mutex::Autolock _l(gLockAPS);
- gAudioPolicyService.clear();
+ gAudioPolicyServiceHandler.clearService();
}
// ---------------------------------------------------------------------------
void AudioSystem::onNewAudioModulesAvailable() {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return;
aps->onNewAudioModulesAvailable();
}
@@ -925,7 +968,7 @@
status_t AudioSystem::setDeviceConnectionState(audio_policy_dev_state_t state,
const android::media::audio::common::AudioPort& port,
audio_format_t encodedFormat) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -940,7 +983,7 @@
audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
const char* device_address) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
auto result = [&]() -> ConversionResult<audio_policy_dev_state_t> {
@@ -960,7 +1003,7 @@
const char* device_address,
const char* device_name,
audio_format_t encodedFormat) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
const char* address = "";
const char* name = "";
@@ -983,7 +1026,7 @@
status_t AudioSystem::setPhoneState(audio_mode_t state, uid_t uid) {
if (uint32_t(state) >= AUDIO_MODE_CNT) return BAD_VALUE;
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return statusTFromBinderStatus(aps->setPhoneState(
@@ -993,7 +1036,7 @@
status_t
AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return statusTFromBinderStatus(
@@ -1006,7 +1049,7 @@
}
audio_policy_forced_cfg_t AudioSystem::getForceUse(audio_policy_force_use_t usage) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return AUDIO_POLICY_FORCE_NONE;
auto result = [&]() -> ConversionResult<audio_policy_forced_cfg_t> {
@@ -1023,7 +1066,7 @@
audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return AUDIO_IO_HANDLE_NONE;
auto result = [&]() -> ConversionResult<audio_io_handle_t> {
@@ -1071,7 +1114,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return NO_INIT;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1120,7 +1163,7 @@
}
status_t AudioSystem::startOutput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
@@ -1128,7 +1171,7 @@
}
status_t AudioSystem::stopOutput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
@@ -1136,7 +1179,7 @@
}
void AudioSystem::releaseOutput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return;
auto status = [&]() -> status_t {
@@ -1176,7 +1219,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return NO_INIT;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1210,7 +1253,7 @@
}
status_t AudioSystem::startInput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
@@ -1218,7 +1261,7 @@
}
status_t AudioSystem::stopInput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
@@ -1226,7 +1269,7 @@
}
void AudioSystem::releaseInput(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return;
auto status = [&]() -> status_t {
@@ -1243,7 +1286,7 @@
status_t AudioSystem::initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1264,7 +1307,7 @@
status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,
int index,
audio_devices_t device) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1279,7 +1322,7 @@
status_t AudioSystem::getStreamVolumeIndex(audio_stream_type_t stream,
int* index,
audio_devices_t device) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1298,7 +1341,7 @@
status_t AudioSystem::setVolumeIndexForAttributes(const audio_attributes_t& attr,
int index,
audio_devices_t device) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1313,7 +1356,7 @@
status_t AudioSystem::getVolumeIndexForAttributes(const audio_attributes_t& attr,
int& index,
audio_devices_t device) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1328,7 +1371,7 @@
}
status_t AudioSystem::getMaxVolumeIndexForAttributes(const audio_attributes_t& attr, int& index) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1341,7 +1384,7 @@
}
status_t AudioSystem::getMinVolumeIndexForAttributes(const audio_attributes_t& attr, int& index) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
@@ -1354,7 +1397,7 @@
}
product_strategy_t AudioSystem::getStrategyForStream(audio_stream_type_t stream) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PRODUCT_STRATEGY_NONE;
auto result = [&]() -> ConversionResult<product_strategy_t> {
@@ -1374,7 +1417,7 @@
if (devices == nullptr) {
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
@@ -1390,7 +1433,7 @@
}
audio_io_handle_t AudioSystem::getOutputForEffect(const effect_descriptor_t* desc) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
// FIXME change return type to status_t, and return PERMISSION_DENIED here
if (aps == 0) return AUDIO_IO_HANDLE_NONE;
@@ -1411,7 +1454,7 @@
product_strategy_t strategy,
audio_session_t session,
int id) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::EffectDescriptor descAidl = VALUE_OR_RETURN_STATUS(
@@ -1425,7 +1468,7 @@
}
status_t AudioSystem::unregisterEffect(int id) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t idAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(id));
@@ -1434,7 +1477,7 @@
}
status_t AudioSystem::setEffectEnabled(int id, bool enabled) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t idAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(id));
@@ -1443,7 +1486,7 @@
}
status_t AudioSystem::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<int32_t> idsAidl = VALUE_OR_RETURN_STATUS(
@@ -1453,7 +1496,7 @@
}
status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
if (state == NULL) return BAD_VALUE;
@@ -1467,7 +1510,7 @@
status_t AudioSystem::isStreamActiveRemotely(audio_stream_type_t stream, bool* state,
uint32_t inPastMs) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
if (state == NULL) return BAD_VALUE;
@@ -1480,7 +1523,7 @@
}
status_t AudioSystem::isSourceActive(audio_source_t stream, bool* state) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
if (state == NULL) return BAD_VALUE;
@@ -1492,19 +1535,19 @@
}
uint32_t AudioSystem::getPrimaryOutputSamplingRate() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return 0;
return af->getPrimaryOutputSamplingRate();
}
size_t AudioSystem::getPrimaryOutputFrameCount() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return 0;
return af->getPrimaryOutputFrameCount();
}
status_t AudioSystem::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setLowRamDevice(isLowRamDevice, totalMemory);
}
@@ -1512,18 +1555,12 @@
void AudioSystem::clearAudioConfigCache() {
// called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances
ALOGV("clearAudioConfigCache()");
- {
- Mutex::Autolock _l(gLock);
- if (gAudioFlingerClient != 0) {
- gAudioFlingerClient->clearIoCache();
- }
- gAudioFlinger.clear();
- }
+ gAudioFlingerServiceHandler.clearService();
clearAudioPolicyService();
}
status_t AudioSystem::setSupportedSystemUsages(const std::vector<audio_usage_t>& systemUsages) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) return PERMISSION_DENIED;
std::vector<AudioUsage> systemUsagesAidl = VALUE_OR_RETURN_STATUS(
@@ -1533,7 +1570,7 @@
}
status_t AudioSystem::setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) return PERMISSION_DENIED;
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
@@ -1544,7 +1581,7 @@
audio_offload_mode_t AudioSystem::getOffloadSupport(const audio_offload_info_t& info) {
ALOGV("%s", __func__);
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return AUDIO_OFFLOAD_NOT_SUPPORTED;
auto result = [&]() -> ConversionResult<audio_offload_mode_t> {
@@ -1569,7 +1606,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortRole roleAidl = VALUE_OR_RETURN_STATUS(
@@ -1593,7 +1630,7 @@
status_t AudioSystem::listDeclaredDevicePorts(media::AudioPortRole role,
std::vector<media::AudioPortFw>* result) {
if (result == nullptr) return BAD_VALUE;
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aps->listDeclaredDevicePorts(role, result)));
return OK;
@@ -1603,7 +1640,7 @@
if (port == nullptr) {
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortFw portAidl;
@@ -1619,7 +1656,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
@@ -1632,7 +1669,7 @@
}
status_t AudioSystem::releaseAudioPatch(audio_patch_handle_t handle) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(handle));
@@ -1647,7 +1684,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -1670,7 +1707,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
@@ -1679,14 +1716,13 @@
}
status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callback) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ const auto apc = gAudioPolicyServiceHandler.getClient();
+ if (apc == nullptr) return NO_INIT;
- Mutex::Autolock _l(gLockAPS);
- if (gAudioPolicyServiceClient == 0) {
- return NO_INIT;
- }
- int ret = gAudioPolicyServiceClient->addAudioPortCallback(callback);
+ std::lock_guard _l(gApsCallbackMutex);
+ const int ret = apc->addAudioPortCallback(callback);
if (ret == 1) {
aps->setAudioPortCallbacksEnabled(true);
}
@@ -1695,14 +1731,13 @@
/*static*/
status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callback) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ const auto apc = gAudioPolicyServiceHandler.getClient();
+ if (apc == nullptr) return NO_INIT;
- Mutex::Autolock _l(gLockAPS);
- if (gAudioPolicyServiceClient == 0) {
- return NO_INIT;
- }
- int ret = gAudioPolicyServiceClient->removeAudioPortCallback(callback);
+ std::lock_guard _l(gApsCallbackMutex);
+ const int ret = apc->removeAudioPortCallback(callback);
if (ret == 0) {
aps->setAudioPortCallbacksEnabled(false);
}
@@ -1710,14 +1745,13 @@
}
status_t AudioSystem::addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ const auto apc = gAudioPolicyServiceHandler.getClient();
+ if (apc == nullptr) return NO_INIT;
- Mutex::Autolock _l(gLockAPS);
- if (gAudioPolicyServiceClient == 0) {
- return NO_INIT;
- }
- int ret = gAudioPolicyServiceClient->addAudioVolumeGroupCallback(callback);
+ std::lock_guard _l(gApsCallbackMutex);
+ const int ret = apc->addAudioVolumeGroupCallback(callback);
if (ret == 1) {
aps->setAudioVolumeGroupCallbacksEnabled(true);
}
@@ -1725,14 +1759,13 @@
}
status_t AudioSystem::removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ const auto apc = gAudioPolicyServiceHandler.getClient();
+ if (apc == nullptr) return NO_INIT;
- Mutex::Autolock _l(gLockAPS);
- if (gAudioPolicyServiceClient == 0) {
- return NO_INIT;
- }
- int ret = gAudioPolicyServiceClient->removeAudioVolumeGroupCallback(callback);
+ std::lock_guard _l(gApsCallbackMutex);
+ const int ret = apc->removeAudioVolumeGroupCallback(callback);
if (ret == 0) {
aps->setAudioVolumeGroupCallbacksEnabled(false);
}
@@ -1748,7 +1781,7 @@
}
status_t status = afc->addAudioDeviceCallback(callback, audioIo, portId);
if (status == NO_ERROR) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af != 0) {
af->registerClient(afc);
}
@@ -1785,7 +1818,7 @@
}
audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
const sp<AudioIoDescriptor> desc = getIoDescriptor(audioIo);
if (desc == 0) {
@@ -1800,7 +1833,7 @@
if (session == nullptr || ioHandle == nullptr || device == nullptr) {
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::SoundTriggerSession retAidl;
@@ -1814,7 +1847,7 @@
}
status_t AudioSystem::releaseSoundTriggerSession(audio_session_t session) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t sessionAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(session));
@@ -1822,7 +1855,7 @@
}
audio_mode_t AudioSystem::getPhoneState() {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return AUDIO_MODE_INVALID;
auto result = [&]() -> ConversionResult<audio_mode_t> {
@@ -1835,7 +1868,7 @@
}
status_t AudioSystem::registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
size_t mixesSize = std::min(mixes.size(), size_t{MAX_MIXES_PER_POLICY});
@@ -1868,7 +1901,7 @@
status_t AudioSystem::updatePolicyMixes(
const std::vector<std::pair<AudioMix, std::vector<AudioMixMatchCriterion>>>&
mixesWithUpdates) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<media::AudioMixUpdate> updatesAidl;
@@ -1887,7 +1920,7 @@
}
status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
@@ -1898,7 +1931,7 @@
}
status_t AudioSystem::removeUidDeviceAffinities(uid_t uid) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
@@ -1907,7 +1940,7 @@
status_t AudioSystem::setUserIdDeviceAffinities(int userId,
const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t userIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(userId));
@@ -1919,7 +1952,7 @@
}
status_t AudioSystem::removeUserIdDeviceAffinities(int userId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t userIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(userId));
return statusTFromBinderStatus(aps->removeUserIdDeviceAffinities(userIdAidl));
@@ -1931,7 +1964,7 @@
if (source == nullptr || attributes == nullptr || portId == nullptr) {
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
@@ -1946,7 +1979,7 @@
}
status_t AudioSystem::stopAudioSource(audio_port_handle_t portId) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
@@ -1954,7 +1987,7 @@
}
status_t AudioSystem::setMasterMono(bool mono) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return statusTFromBinderStatus(aps->setMasterMono(mono));
}
@@ -1963,26 +1996,26 @@
if (mono == nullptr) {
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return statusTFromBinderStatus(aps->getMasterMono(mono));
}
status_t AudioSystem::setMasterBalance(float balance) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setMasterBalance(balance);
}
status_t AudioSystem::getMasterBalance(float* balance) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->getMasterBalance(balance);
}
float
AudioSystem::getStreamVolumeDB(audio_stream_type_t stream, int index, audio_devices_t device) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return NAN;
auto result = [&]() -> ConversionResult<float> {
@@ -2000,13 +2033,13 @@
}
status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->getMicrophones(microphones);
}
status_t AudioSystem::setAudioHalPids(const std::vector<pid_t>& pids) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) return PERMISSION_DENIED;
return af->setAudioHalPids(pids);
}
@@ -2020,7 +2053,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
Int numSurroundFormatsAidl;
numSurroundFormatsAidl.value =
@@ -2047,7 +2080,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
Int numSurroundFormatsAidl;
numSurroundFormatsAidl.value =
@@ -2065,7 +2098,7 @@
}
status_t AudioSystem::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
AudioFormatDescription audioFormatAidl = VALUE_OR_RETURN_STATUS(
@@ -2075,7 +2108,7 @@
}
status_t AudioSystem::setAssistantServicesUids(const std::vector<uid_t>& uids) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<int32_t> uidsAidl = VALUE_OR_RETURN_STATUS(
@@ -2084,7 +2117,7 @@
}
status_t AudioSystem::setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<int32_t> activeUidsAidl = VALUE_OR_RETURN_STATUS(
@@ -2093,7 +2126,7 @@
}
status_t AudioSystem::setA11yServicesUids(const std::vector<uid_t>& uids) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<int32_t> uidsAidl = VALUE_OR_RETURN_STATUS(
@@ -2102,7 +2135,7 @@
}
status_t AudioSystem::setCurrentImeUid(uid_t uid) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
@@ -2110,7 +2143,7 @@
}
bool AudioSystem::isHapticPlaybackSupported() {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return false;
auto result = [&]() -> ConversionResult<bool> {
@@ -2123,7 +2156,7 @@
}
bool AudioSystem::isUltrasoundSupported() {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return false;
auto result = [&]() -> ConversionResult<bool> {
@@ -2141,7 +2174,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<AudioFormatDescription> formatsAidl;
@@ -2157,7 +2190,7 @@
}
status_t AudioSystem::listAudioProductStrategies(AudioProductStrategyVector& strategies) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<media::AudioProductStrategy> strategiesAidl;
@@ -2219,7 +2252,7 @@
status_t AudioSystem::getProductStrategyFromAudioAttributes(const audio_attributes_t& aa,
product_strategy_t& productStrategy,
bool fallbackOnDefault) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
@@ -2235,7 +2268,7 @@
}
status_t AudioSystem::listAudioVolumeGroups(AudioVolumeGroupVector& groups) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
std::vector<media::AudioVolumeGroup> groupsAidl;
@@ -2249,7 +2282,7 @@
status_t AudioSystem::getVolumeGroupFromAudioAttributes(const audio_attributes_t &aa,
volume_group_t& volumeGroup,
bool fallbackOnDefault) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
@@ -2262,13 +2295,13 @@
}
status_t AudioSystem::setRttEnabled(bool enabled) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return statusTFromBinderStatus(aps->setRttEnabled(enabled));
}
bool AudioSystem::isCallScreenModeSupported() {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) return false;
auto result = [&]() -> ConversionResult<bool> {
@@ -2283,7 +2316,7 @@
status_t AudioSystem::setDevicesRoleForStrategy(product_strategy_t strategy,
device_role_t role,
const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2300,7 +2333,7 @@
status_t AudioSystem::removeDevicesRoleForStrategy(product_strategy_t strategy,
device_role_t role,
const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2316,7 +2349,7 @@
status_t
AudioSystem::clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2329,7 +2362,7 @@
status_t AudioSystem::getDevicesForRoleAndStrategy(product_strategy_t strategy,
device_role_t role,
AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2347,7 +2380,7 @@
status_t AudioSystem::setDevicesRoleForCapturePreset(audio_source_t audioSource,
device_role_t role,
const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2365,7 +2398,7 @@
status_t AudioSystem::addDevicesRoleForCapturePreset(audio_source_t audioSource,
device_role_t role,
const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2381,7 +2414,7 @@
status_t AudioSystem::removeDevicesRoleForCapturePreset(
audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2397,7 +2430,7 @@
status_t AudioSystem::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
device_role_t role) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2411,7 +2444,7 @@
status_t AudioSystem::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
device_role_t role,
AudioDeviceTypeAddrVector& devices) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2429,7 +2462,7 @@
status_t AudioSystem::getSpatializer(const sp<media::INativeSpatializerCallback>& callback,
sp<media::ISpatializer>* spatializer) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (spatializer == nullptr) {
return BAD_VALUE;
}
@@ -2448,7 +2481,7 @@
const audio_config_t *config,
const AudioDeviceTypeAddrVector &devices,
bool *canBeSpatialized) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (canBeSpatialized == nullptr) {
return BAD_VALUE;
}
@@ -2472,7 +2505,7 @@
status_t AudioSystem::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2491,7 +2524,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2515,7 +2548,7 @@
return BAD_VALUE;
}
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
@@ -2534,7 +2567,7 @@
status_t AudioSystem::setRequestedLatencyMode(
audio_io_handle_t output, audio_latency_mode_t mode) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2543,7 +2576,7 @@
status_t AudioSystem::getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2551,7 +2584,7 @@
}
status_t AudioSystem::setBluetoothVariableLatencyEnabled(bool enabled) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2560,7 +2593,7 @@
status_t AudioSystem::isBluetoothVariableLatencyEnabled(
bool *enabled) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2569,7 +2602,7 @@
status_t AudioSystem::supportsBluetoothVariableLatency(
bool *support) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2577,7 +2610,7 @@
}
status_t AudioSystem::getAudioPolicyConfig(media::AudioPolicyConfig *config) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2605,15 +2638,15 @@
}
binder::Status setCaptureState(bool active) override {
- Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+ std::lock_guard _l(AudioSystem::gSoundTriggerMutex);
mListener->onStateChanged(active);
return binder::Status::ok();
}
void binderDied(const wp<IBinder>&) override {
- Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+ std::lock_guard _l(AudioSystem::gSoundTriggerMutex);
mListener->onServiceDied();
- gSoundTriggerCaptureStateListener = nullptr;
+ AudioSystem::gSoundTriggerCaptureStateListener = nullptr;
}
private:
@@ -2626,13 +2659,12 @@
const sp<CaptureStateListener>& listener) {
LOG_ALWAYS_FATAL_IF(listener == nullptr);
- const sp<IAudioPolicyService>& aps =
- AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == 0) {
return PERMISSION_DENIED;
}
- Mutex::Autolock _l(gSoundTriggerCaptureStateListenerLock);
+ std::lock_guard _l(AudioSystem::gSoundTriggerMutex);
gSoundTriggerCaptureStateListener = new CaptureStateListenerImpl(aps, listener);
gSoundTriggerCaptureStateListener->init();
@@ -2641,7 +2673,7 @@
status_t AudioSystem::setVibratorInfos(
const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2650,7 +2682,7 @@
status_t AudioSystem::getMmapPolicyInfo(
AudioMMapPolicyType policyType, std::vector<AudioMMapPolicyInfo> *policyInfos) {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2658,7 +2690,7 @@
}
int32_t AudioSystem::getAAudioMixerBurstCount() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2666,7 +2698,7 @@
}
int32_t AudioSystem::getAAudioHardwareBurstMinUsec() {
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ const sp<IAudioFlinger> af = get_audio_flinger();
if (af == nullptr) {
return PERMISSION_DENIED;
}
@@ -2675,7 +2707,7 @@
status_t AudioSystem::getSupportedMixerAttributes(
audio_port_handle_t portId, std::vector<audio_mixer_attributes_t> *mixerAttrs) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) {
return PERMISSION_DENIED;
}
@@ -2695,7 +2727,7 @@
audio_port_handle_t portId,
uid_t uid,
const audio_mixer_attributes_t *mixerAttr) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) {
return PERMISSION_DENIED;
}
@@ -2715,7 +2747,7 @@
const audio_attributes_t *attr,
audio_port_handle_t portId,
std::optional<audio_mixer_attributes_t> *mixerAttr) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) {
return PERMISSION_DENIED;
}
@@ -2738,7 +2770,7 @@
status_t AudioSystem::clearPreferredMixerAttributes(const audio_attributes_t *attr,
audio_port_handle_t portId,
uid_t uid) {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const sp<IAudioPolicyService> aps = get_audio_policy_service();
if (aps == nullptr) {
return PERMISSION_DENIED;
}
@@ -2755,45 +2787,28 @@
int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
const sp<AudioPortCallback>& callback) {
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
- if (mAudioPortCallbacks[i] == callback) {
- return -1;
- }
- }
- mAudioPortCallbacks.add(callback);
- return mAudioPortCallbacks.size();
+ std::lock_guard _l(mMutex);
+ return mAudioPortCallbacks.insert(callback).second ? mAudioPortCallbacks.size() : -1;
}
int AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
const sp<AudioPortCallback>& callback) {
- Mutex::Autolock _l(mLock);
- size_t i;
- for (i = 0; i < mAudioPortCallbacks.size(); i++) {
- if (mAudioPortCallbacks[i] == callback) {
- break;
- }
- }
- if (i == mAudioPortCallbacks.size()) {
- return -1;
- }
- mAudioPortCallbacks.removeAt(i);
- return mAudioPortCallbacks.size();
+ std::lock_guard _l(mMutex);
+ return mAudioPortCallbacks.erase(callback) > 0 ? mAudioPortCallbacks.size() : -1;
}
-
Status AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() {
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
- mAudioPortCallbacks[i]->onAudioPortListUpdate();
+ std::lock_guard _l(mMutex);
+ for (const auto& callback : mAudioPortCallbacks) {
+ callback->onAudioPortListUpdate();
}
return Status::ok();
}
Status AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() {
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
- mAudioPortCallbacks[i]->onAudioPatchListUpdate();
+ std::lock_guard _l(mMutex);
+ for (const auto& callback : mAudioPortCallbacks) {
+ callback->onAudioPatchListUpdate();
}
return Status::ok();
}
@@ -2801,30 +2816,16 @@
// ----------------------------------------------------------------------------
int AudioSystem::AudioPolicyServiceClient::addAudioVolumeGroupCallback(
const sp<AudioVolumeGroupCallback>& callback) {
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
- if (mAudioVolumeGroupCallback[i] == callback) {
- return -1;
- }
- }
- mAudioVolumeGroupCallback.add(callback);
- return mAudioVolumeGroupCallback.size();
+ std::lock_guard _l(mMutex);
+ return mAudioVolumeGroupCallbacks.insert(callback).second
+ ? mAudioVolumeGroupCallbacks.size() : -1;
}
int AudioSystem::AudioPolicyServiceClient::removeAudioVolumeGroupCallback(
const sp<AudioVolumeGroupCallback>& callback) {
- Mutex::Autolock _l(mLock);
- size_t i;
- for (i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
- if (mAudioVolumeGroupCallback[i] == callback) {
- break;
- }
- }
- if (i == mAudioVolumeGroupCallback.size()) {
- return -1;
- }
- mAudioVolumeGroupCallback.removeAt(i);
- return mAudioVolumeGroupCallback.size();
+ std::lock_guard _l(mMutex);
+ return mAudioVolumeGroupCallbacks.erase(callback) > 0
+ ? mAudioVolumeGroupCallbacks.size() : -1;
}
Status AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(int32_t group,
@@ -2833,9 +2834,9 @@
aidl2legacy_int32_t_volume_group_t(group));
int flagsLegacy = VALUE_OR_RETURN_BINDER_STATUS(convertReinterpret<int>(flags));
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
- mAudioVolumeGroupCallback[i]->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy);
+ std::lock_guard _l(mMutex);
+ for (const auto& callback : mAudioVolumeGroupCallbacks) {
+ callback->onAudioVolumeGroupChanged(groupLegacy, flagsLegacy);
}
return Status::ok();
}
@@ -2849,7 +2850,7 @@
int stateLegacy = VALUE_OR_RETURN_BINDER_STATUS(convertReinterpret<int>(state));
dynamic_policy_callback cb = NULL;
{
- Mutex::Autolock _l(AudioSystem::gLock);
+ std::lock_guard _l(AudioSystem::gMutex);
cb = gDynPolicyCallback;
}
@@ -2870,7 +2871,7 @@
AudioSource source) {
record_config_callback cb = NULL;
{
- Mutex::Autolock _l(AudioSystem::gLock);
+ std::lock_guard _l(AudioSystem::gMutex);
cb = gRecordConfigCallback;
}
@@ -2903,7 +2904,7 @@
Status AudioSystem::AudioPolicyServiceClient::onRoutingUpdated() {
routing_callback cb = NULL;
{
- Mutex::Autolock _l(AudioSystem::gLock);
+ std::lock_guard _l(AudioSystem::gMutex);
cb = gRoutingCallback;
}
@@ -2916,7 +2917,7 @@
Status AudioSystem::AudioPolicyServiceClient::onVolumeRangeInitRequest() {
vol_range_init_req_callback cb = NULL;
{
- Mutex::Autolock _l(AudioSystem::gLock);
+ std::lock_guard _l(AudioSystem::gMutex);
cb = gVolRangeInitReqCallback;
}
@@ -2928,12 +2929,12 @@
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) {
{
- Mutex::Autolock _l(mLock);
- for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
- mAudioPortCallbacks[i]->onServiceDied();
+ std::lock_guard _l(mMutex);
+ for (const auto& callback : mAudioPortCallbacks) {
+ callback->onServiceDied();
}
- for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
- mAudioVolumeGroupCallback[i]->onServiceDied();
+ for (const auto& callback : mAudioVolumeGroupCallbacks) {
+ callback->onServiceDied();
}
}
AudioSystem::clearAudioPolicyService();
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 565427b..98a1fde 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1699,29 +1699,42 @@
}
status_t AudioTrack::setOutputDevice(audio_port_handle_t deviceId) {
+ status_t result = NO_ERROR;
AutoMutex lock(mLock);
- ALOGV("%s(%d): deviceId=%d mSelectedDeviceId=%d mRoutedDeviceId %d",
- __func__, mPortId, deviceId, mSelectedDeviceId, mRoutedDeviceId);
+ ALOGV("%s(%d): deviceId=%d mSelectedDeviceId=%d",
+ __func__, mPortId, deviceId, mSelectedDeviceId);
if (mSelectedDeviceId != deviceId) {
mSelectedDeviceId = deviceId;
if (mStatus == NO_ERROR) {
- // allow track invalidation when track is not playing to propagate
- // the updated mSelectedDeviceId
- if (isPlaying_l()) {
- if (mSelectedDeviceId != mRoutedDeviceId) {
- android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
- mProxy->interrupt();
+ if (isOffloadedOrDirect_l()) {
+ if (mState == STATE_STOPPED || mState == STATE_FLUSHED) {
+ ALOGD("%s(%d): creating a new AudioTrack", __func__, mPortId);
+ result = restoreTrack_l("setOutputDevice", true /* forceRestore */);
+ } else {
+ ALOGW("%s(%d). Offloaded or Direct track is not STOPPED or FLUSHED. "
+ "State: %s.",
+ __func__, mPortId, stateToString(mState));
+ result = INVALID_OPERATION;
}
} else {
- // if the track is idle, try to restore now and
- // defer to next start if not possible
- if (restoreTrack_l("setOutputDevice") != OK) {
- android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+ // allow track invalidation when track is not playing to propagate
+ // the updated mSelectedDeviceId
+ if (isPlaying_l()) {
+ if (mSelectedDeviceId != mRoutedDeviceId) {
+ android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+ mProxy->interrupt();
+ }
+ } else {
+ // if the track is idle, try to restore now and
+ // defer to next start if not possible
+ if (restoreTrack_l("setOutputDevice") != OK) {
+ android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+ }
}
}
}
}
- return NO_ERROR;
+ return result;
}
audio_port_handle_t AudioTrack::getOutputDevice() {
@@ -2836,7 +2849,7 @@
return 0;
}
-status_t AudioTrack::restoreTrack_l(const char *from)
+status_t AudioTrack::restoreTrack_l(const char *from, bool forceRestore)
{
status_t result = NO_ERROR; // logged: make sure to set this before returning.
const int64_t beginNs = systemTime();
@@ -2857,7 +2870,8 @@
// output parameters and new IAudioFlinger in createTrack_l()
AudioSystem::clearAudioConfigCache();
- if (isOffloadedOrDirect_l() || mDoNotReconnect) {
+ if (!forceRestore &&
+ (isOffloadedOrDirect_l() || mDoNotReconnect)) {
// FIXME re-creation of offloaded and direct tracks is not yet implemented;
// Disabled since (1) timestamp correction is not implemented for non-PCM and
// (2) We pre-empt existing direct tracks on resource constraint, so these tracks
diff --git a/media/libaudioclient/PolicyAidlConversion.cpp b/media/libaudioclient/PolicyAidlConversion.cpp
index 60b08fa..a71bb18 100644
--- a/media/libaudioclient/PolicyAidlConversion.cpp
+++ b/media/libaudioclient/PolicyAidlConversion.cpp
@@ -242,6 +242,7 @@
legacy.mCbFlags = VALUE_OR_RETURN(aidl2legacy_AudioMixCallbackFlag_uint32_t_mask(aidl.cbFlags));
legacy.mAllowPrivilegedMediaPlaybackCapture = aidl.allowPrivilegedMediaPlaybackCapture;
legacy.mVoiceCommunicationCaptureAllowed = aidl.voiceCommunicationCaptureAllowed;
+ legacy.mToken = aidl.mToken;
return legacy;
}
@@ -265,6 +266,7 @@
aidl.cbFlags = VALUE_OR_RETURN(legacy2aidl_uint32_t_AudioMixCallbackFlag_mask(legacy.mCbFlags));
aidl.allowPrivilegedMediaPlaybackCapture = legacy.mAllowPrivilegedMediaPlaybackCapture;
aidl.voiceCommunicationCaptureAllowed = legacy.mVoiceCommunicationCaptureAllowed;
+ aidl.mToken = legacy.mToken;
return aidl;
}
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 9c4ccb8..e213f08 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -872,6 +872,18 @@
{ .duration = 0 , .waveFreq = { 0 }, 0, 0}},
.repeatCnt = 3,
.repeatSegment = 0 }, // TONE_NZ_CALL_WAITING
+ { .segments = { { .duration = 500, .waveFreq = { 425, 0 }, 0, 0 },
+ { .duration = 250, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+ .repeatCnt = ToneGenerator::TONEGEN_INF,
+ .repeatSegment = 0 }, // TONE_MY_CONGESTION
+ { .segments = { { .duration = 400, .waveFreq = { 425, 0 }, 0, 0 },
+ { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 400, .waveFreq = { 425, 0 }, 0, 0 },
+ { .duration = 2000, .waveFreq = { 0 }, 0, 0},
+ { .duration = 0, .waveFreq = { 0 }, 0, 0}},
+ .repeatCnt = ToneGenerator::TONEGEN_INF,
+ .repeatSegment = 0 } // TONE_MY_RINGTONE
};
// Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
@@ -976,6 +988,16 @@
TONE_SUP_ERROR, // TONE_SUP_ERROR
TONE_NZ_CALL_WAITING, // TONE_SUP_CALL_WAITING
TONE_GB_RINGTONE // TONE_SUP_RINGTONE
+ },
+ { // MALAYSIA
+ TONE_SUP_DIAL, // TONE_SUP_DIAL
+ TONE_SUP_BUSY, // TONE_SUP_BUSY
+ TONE_MY_CONGESTION, // TONE_SUP_CONGESTION
+ TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK
+ TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL
+ TONE_SUP_ERROR, // TONE_SUP_ERROR
+ TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
+ TONE_MY_RINGTONE // TONE_SUP_RINGTONE
}
};
@@ -1055,6 +1077,8 @@
mRegion = TAIWAN;
} else if (strstr(value, "nz") != NULL) {
mRegion = NZ;
+ } else if (strstr(value, "my") != NULL) {
+ mRegion = MY;
} else {
mRegion = CEPT;
}
diff --git a/media/libaudioclient/aidl/android/media/AudioMix.aidl b/media/libaudioclient/aidl/android/media/AudioMix.aidl
index 88b0450..f0c561c 100644
--- a/media/libaudioclient/aidl/android/media/AudioMix.aidl
+++ b/media/libaudioclient/aidl/android/media/AudioMix.aidl
@@ -39,4 +39,6 @@
boolean allowPrivilegedMediaPlaybackCapture;
/** Indicates if the caller can capture voice communication output */
boolean voiceCommunicationCaptureAllowed;
+ /** Identifies the owner of the AudioPolicy that this AudioMix belongs to */
+ IBinder mToken;
}
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index ec35e93..9e4ae54 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -18,6 +18,7 @@
#ifndef ANDROID_AUDIO_POLICY_H
#define ANDROID_AUDIO_POLICY_H
+#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <media/AudioDeviceTypeAddr.h>
#include <system/audio.h>
@@ -127,6 +128,7 @@
audio_devices_t mDeviceType;
String8 mDeviceAddress;
uint32_t mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
+ sp<IBinder> mToken;
/** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
bool mAllowPrivilegedMediaPlaybackCapture = false;
/** Indicates if the caller can capture voice communication output */
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index acbcf3f..338534d 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -19,6 +19,7 @@
#include <sys/types.h>
+#include <mutex>
#include <set>
#include <vector>
@@ -86,6 +87,7 @@
typedef void (*routing_callback)();
typedef void (*vol_range_init_req_callback)();
+class CaptureStateListenerImpl;
class IAudioFlinger;
class String8;
@@ -95,6 +97,13 @@
class AudioSystem
{
+ friend class AudioFlingerClient;
+ friend class AudioPolicyServiceClient;
+ friend class CaptureStateListenerImpl;
+ template <typename ServiceInterface, typename Client, typename AidlInterface,
+ typename ServiceTraits>
+ friend class ServiceHandler;
+
public:
// FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
@@ -177,8 +186,8 @@
static status_t setLocalAudioFlinger(const sp<IAudioFlinger>& af);
// helper function to obtain AudioFlinger service handle
- static const sp<IAudioFlinger> get_audio_flinger();
- static const sp<IAudioFlinger> get_audio_flinger_for_fuzzer();
+ static sp<IAudioFlinger> get_audio_flinger();
+ static sp<IAudioFlinger> get_audio_flinger_for_fuzzer();
static float linearToLog(int volume);
static int logToLinear(float volume);
@@ -402,7 +411,12 @@
// and output configuration cache (gOutputs)
static void clearAudioConfigCache();
- static const sp<media::IAudioPolicyService> get_audio_policy_service();
+ // Sets a local AudioPolicyService interface to be used by AudioSystem.
+ // This is used by audioserver main() to allow client object initialization
+ // before exposing any interfaces to ServiceManager.
+ static status_t setLocalAudioPolicyService(const sp<media::IAudioPolicyService>& aps);
+
+ static sp<media::IAudioPolicyService> get_audio_policy_service();
static void clearAudioPolicyService();
// helpers for android.media.AudioManager.getProperty(), see description there for meaning
@@ -776,23 +790,18 @@
static int32_t getAAudioHardwareBurstMinUsec();
-private:
-
class AudioFlingerClient: public IBinder::DeathRecipient, public media::BnAudioFlingerClient
{
public:
- AudioFlingerClient() :
- mInBuffSize(0), mInSamplingRate(0),
- mInFormat(AUDIO_FORMAT_DEFAULT), mInChannelMask(AUDIO_CHANNEL_NONE) {
- }
+ AudioFlingerClient() = default;
- void clearIoCache();
+ void clearIoCache() EXCLUDES(mMutex);
status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
- audio_channel_mask_t channelMask, size_t* buffSize);
- sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
+ audio_channel_mask_t channelMask, size_t* buffSize) EXCLUDES(mMutex);
+ sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle) EXCLUDES(mMutex);
// DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
+ void binderDied(const wp<IBinder>& who) final;
// IAudioFlingerClient
@@ -800,61 +809,71 @@
// values for output/input parameters up-to-date in client process
binder::Status ioConfigChanged(
media::AudioIoConfigEvent event,
- const media::AudioIoDescriptor& ioDesc) override;
+ const media::AudioIoDescriptor& ioDesc) final EXCLUDES(mMutex);
binder::Status onSupportedLatencyModesChanged(
int output,
- const std::vector<media::audio::common::AudioLatencyMode>& latencyModes) override;
+ const std::vector<media::audio::common::AudioLatencyMode>& latencyModes)
+ final EXCLUDES(mMutex);
status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
- audio_io_handle_t audioIo,
- audio_port_handle_t portId);
+ audio_io_handle_t audioIo, audio_port_handle_t portId) EXCLUDES(mMutex);
status_t removeAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
- audio_io_handle_t audioIo,
- audio_port_handle_t portId);
+ audio_io_handle_t audioIo, audio_port_handle_t portId) EXCLUDES(mMutex);
status_t addSupportedLatencyModesCallback(
- const sp<SupportedLatencyModesCallback>& callback);
+ const sp<SupportedLatencyModesCallback>& callback) EXCLUDES(mMutex);
status_t removeSupportedLatencyModesCallback(
- const sp<SupportedLatencyModesCallback>& callback);
+ const sp<SupportedLatencyModesCallback>& callback) EXCLUDES(mMutex);
- audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
+ audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo) EXCLUDES(mMutex);
private:
- Mutex mLock;
- DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> > mIoDescriptors;
+ mutable std::mutex mMutex;
+ std::map<audio_io_handle_t, sp<AudioIoDescriptor>> mIoDescriptors GUARDED_BY(mMutex);
std::map<audio_io_handle_t, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>>
- mAudioDeviceCallbacks;
+ mAudioDeviceCallbacks GUARDED_BY(mMutex);
std::vector<wp<SupportedLatencyModesCallback>>
- mSupportedLatencyModesCallbacks GUARDED_BY(mLock);
+ mSupportedLatencyModesCallbacks GUARDED_BY(mMutex);
// cached values for recording getInputBufferSize() queries
- size_t mInBuffSize; // zero indicates cache is invalid
- uint32_t mInSamplingRate;
- audio_format_t mInFormat;
- audio_channel_mask_t mInChannelMask;
- sp<AudioIoDescriptor> getIoDescriptor_l(audio_io_handle_t ioHandle);
+ size_t mInBuffSize GUARDED_BY(mMutex) = 0; // zero indicates cache is invalid
+ uint32_t mInSamplingRate GUARDED_BY(mMutex) = 0;
+ audio_format_t mInFormat GUARDED_BY(mMutex) = AUDIO_FORMAT_DEFAULT;
+ audio_channel_mask_t mInChannelMask GUARDED_BY(mMutex) = AUDIO_CHANNEL_NONE;
+
+ sp<AudioIoDescriptor> getIoDescriptor_l(audio_io_handle_t ioHandle) REQUIRES(mMutex);
};
class AudioPolicyServiceClient: public IBinder::DeathRecipient,
- public media::BnAudioPolicyServiceClient
- {
+ public media::BnAudioPolicyServiceClient {
public:
- AudioPolicyServiceClient() {
+ AudioPolicyServiceClient() = default;
+
+ int addAudioPortCallback(const sp<AudioPortCallback>& callback) EXCLUDES(mMutex);
+
+ int removeAudioPortCallback(const sp<AudioPortCallback>& callback) EXCLUDES(mMutex);
+
+ bool isAudioPortCbEnabled() const EXCLUDES(mMutex) {
+ std::lock_guard _l(mMutex);
+ return !mAudioPortCallbacks.empty();
}
- int addAudioPortCallback(const sp<AudioPortCallback>& callback);
- int removeAudioPortCallback(const sp<AudioPortCallback>& callback);
- bool isAudioPortCbEnabled() const { return (mAudioPortCallbacks.size() != 0); }
+ int addAudioVolumeGroupCallback(
+ const sp<AudioVolumeGroupCallback>& callback) EXCLUDES(mMutex);
- int addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
- int removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
- bool isAudioVolumeGroupCbEnabled() const { return (mAudioVolumeGroupCallback.size() != 0); }
+ int removeAudioVolumeGroupCallback(
+ const sp<AudioVolumeGroupCallback>& callback) EXCLUDES(mMutex);
+
+ bool isAudioVolumeGroupCbEnabled() const EXCLUDES(mMutex) {
+ std::lock_guard _l(mMutex);
+ return !mAudioVolumeGroupCallbacks.empty();
+ }
// DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
+ void binderDied(const wp<IBinder>& who) final;
// IAudioPolicyServiceClient
binder::Status onAudioVolumeGroupChanged(int32_t group, int32_t flags) override;
@@ -875,43 +894,36 @@
binder::Status onVolumeRangeInitRequest();
private:
- Mutex mLock;
- Vector <sp <AudioPortCallback> > mAudioPortCallbacks;
- Vector <sp <AudioVolumeGroupCallback> > mAudioVolumeGroupCallback;
+ mutable std::mutex mMutex;
+ std::set<sp<AudioPortCallback>> mAudioPortCallbacks GUARDED_BY(mMutex);
+ std::set<sp<AudioVolumeGroupCallback>> mAudioVolumeGroupCallbacks GUARDED_BY(mMutex);
};
+ private:
+
static audio_io_handle_t getOutput(audio_stream_type_t stream);
- static const sp<AudioFlingerClient> getAudioFlingerClient();
+ static sp<AudioFlingerClient> getAudioFlingerClient();
static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
- static const sp<IAudioFlinger> getAudioFlingerImpl(bool canStartThreadPool);
// Invokes all registered error callbacks with the given error code.
static void reportError(status_t err);
- static sp<AudioFlingerClient> gAudioFlingerClient;
- static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
- friend class AudioFlingerClient;
- friend class AudioPolicyServiceClient;
+ [[clang::no_destroy]] static std::mutex gMutex;
+ static dynamic_policy_callback gDynPolicyCallback GUARDED_BY(gMutex);
+ static record_config_callback gRecordConfigCallback GUARDED_BY(gMutex);
+ static routing_callback gRoutingCallback GUARDED_BY(gMutex);
+ static vol_range_init_req_callback gVolRangeInitReqCallback GUARDED_BY(gMutex);
- static Mutex gLock; // protects gAudioFlinger
- static Mutex gLockErrorCallbacks; // protects gAudioErrorCallbacks
- static Mutex gLockAPS; // protects gAudioPolicyService and gAudioPolicyServiceClient
- static sp<IAudioFlinger> gAudioFlinger;
- static std::set<audio_error_callback> gAudioErrorCallbacks;
- static dynamic_policy_callback gDynPolicyCallback;
- static record_config_callback gRecordConfigCallback;
- static routing_callback gRoutingCallback;
- static vol_range_init_req_callback gVolRangeInitReqCallback;
+ [[clang::no_destroy]] static std::mutex gApsCallbackMutex;
+ [[clang::no_destroy]] static std::mutex gErrorCallbacksMutex;
+ [[clang::no_destroy]] static std::set<audio_error_callback> gAudioErrorCallbacks
+ GUARDED_BY(gErrorCallbacksMutex);
- static size_t gInBuffSize;
- // previous parameters for recording buffer size queries
- static uint32_t gPrevInSamplingRate;
- static audio_format_t gPrevInFormat;
- static audio_channel_mask_t gPrevInChannelMask;
-
- static sp<media::IAudioPolicyService> gAudioPolicyService;
+ [[clang::no_destroy]] static std::mutex gSoundTriggerMutex;
+ [[clang::no_destroy]] static sp<CaptureStateListenerImpl> gSoundTriggerCaptureStateListener
+ GUARDED_BY(gSoundTriggerMutex);
};
-}; // namespace android
+} // namespace android
#endif /*ANDROID_AUDIOSYSTEM_H_*/
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 523383f..19780ae 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -1220,7 +1220,7 @@
void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
// FIXME enum is faster than strcmp() for parameter 'from'
- status_t restoreTrack_l(const char *from);
+ status_t restoreTrack_l(const char *from, bool forceRestore = false);
uint32_t getUnderrunCount_l() const;
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 46e9501..3e515fc 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -225,11 +225,14 @@
TONE_INDIA_CONGESTION, // Congestion tone: 400 Hz, 250ms ON, 250ms OFF...
TONE_INDIA_CALL_WAITING, // Call waiting tone: 400 Hz, tone repeated in a 0.2s on, 0.1s off, 0.2s on, 7.5s off pattern.
TONE_INDIA_RINGTONE, // Ring tone: 400 Hz tone modulated with 25Hz, 0.4 on 0.2 off 0.4 on 2..0 off
- // TAIWAN supervisory tones
+ // TAIWAN supervisory tones
TONE_TW_RINGTONE, // Ring Tone: 440 Hz + 480 Hz repeated with pattern 1s on, 3s off.
- // NEW ZEALAND supervisory tones
+ // NEW ZEALAND supervisory tones
TONE_NZ_CALL_WAITING, // Call waiting tone: 400 Hz, 0.2s ON, 3s OFF,
// 0.2s ON, 3s OFF, 0.2s ON, 3s OFF, 0.2s ON
+ // MALAYSIA supervisory tones
+ TONE_MY_CONGESTION, // Congestion tone: 425 Hz, 500ms ON, 250ms OFF...
+ TONE_MY_RINGTONE, // Ring tone: 425 Hz, 400ms ON 200ms OFF 400ms ON 2s OFF..
NUM_ALTERNATE_TONES
};
@@ -244,6 +247,7 @@
INDIA,
TAIWAN,
NZ,
+ MY,
CEPT,
NUM_REGIONS
};
diff --git a/media/libaudioclient/tests/audio_test_utils.cpp b/media/libaudioclient/tests/audio_test_utils.cpp
index ee5489b..9a202cc3 100644
--- a/media/libaudioclient/tests/audio_test_utils.cpp
+++ b/media/libaudioclient/tests/audio_test_utils.cpp
@@ -565,12 +565,14 @@
int attempts = 5;
status_t status;
unsigned int generation1, generation;
- unsigned int numPorts = 0;
+ unsigned int numPorts;
do {
if (attempts-- < 0) {
status = TIMED_OUT;
break;
}
+ // query for number of ports.
+ numPorts = 0;
status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
nullptr, &generation1);
if (status != NO_ERROR) {
@@ -622,12 +624,14 @@
int attempts = 5;
status_t status;
unsigned int generation1, generation;
- unsigned int numPatches = 0;
+ unsigned int numPatches;
do {
if (attempts-- < 0) {
status = TIMED_OUT;
break;
}
+ // query for number of patches.
+ numPatches = 0;
status = AudioSystem::listAudioPatches(&numPatches, nullptr, &generation1);
if (status != NO_ERROR) {
ALOGE("AudioSystem::listAudioPatches returned error %d", status);
diff --git a/media/libaudioclient/tests/audiorouting_tests.cpp b/media/libaudioclient/tests/audiorouting_tests.cpp
index 8f76f9b..3b2285e 100644
--- a/media/libaudioclient/tests/audiorouting_tests.cpp
+++ b/media/libaudioclient/tests/audiorouting_tests.cpp
@@ -17,6 +17,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "AudioRoutingTest"
+#include <string.h>
+
+#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
#include <gtest/gtest.h>
@@ -149,6 +152,7 @@
config.sample_rate = 48000;
AudioMix mix(criteria, mixType, config, mixFlag, String8{mAddress.c_str()}, 0);
mix.mDeviceType = deviceType;
+ mix.mToken = sp<BBinder>::make();
mMixes.push(mix);
if (OK == AudioSystem::registerPolicyMixes(mMixes, true)) {
mPolicyMixRegistered = true;
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.cpp b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
index a701852..33fe3ed 100644
--- a/media/libaudiohal/impl/EffectBufferHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.cpp
@@ -58,25 +58,14 @@
}
EffectBufferHalAidl::~EffectBufferHalAidl() {
+ if (mAudioBuffer.raw) free(mAudioBuffer.raw);
}
status_t EffectBufferHalAidl::init() {
- int fd = ashmem_create_region("audioEffectAidl", mBufferSize);
- if (fd < 0) {
- ALOGE("%s create ashmem failed %d", __func__, fd);
- return fd;
+ if (0 != posix_memalign(&mAudioBuffer.raw, 32, mBufferSize)) {
+ return NO_MEMORY;
}
- ScopedFileDescriptor tempFd(fd);
- mAudioBuffer.raw = mmap(nullptr /* address */, mBufferSize /* length */, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0 /* offset */);
- if (mAudioBuffer.raw == MAP_FAILED) {
- ALOGE("mmap failed for fd %d", fd);
- mAudioBuffer.raw = nullptr;
- return INVALID_OPERATION;
- }
-
- mMemory = {std::move(tempFd), static_cast<int64_t>(mBufferSize)};
return OK;
}
diff --git a/media/libaudiohal/impl/EffectBufferHalAidl.h b/media/libaudiohal/impl/EffectBufferHalAidl.h
index 035314b..cf6031f 100644
--- a/media/libaudiohal/impl/EffectBufferHalAidl.h
+++ b/media/libaudiohal/impl/EffectBufferHalAidl.h
@@ -50,7 +50,6 @@
const size_t mBufferSize;
bool mFrameCountChanged;
void* mExternalData;
- aidl::android::hardware::common::Ashmem mMemory;
audio_buffer_t mAudioBuffer;
// Can not be constructed directly by clients.
diff --git a/media/libaudiohal/impl/EffectHalAidl.cpp b/media/libaudiohal/impl/EffectHalAidl.cpp
index 54c1217..7262148 100644
--- a/media/libaudiohal/impl/EffectHalAidl.cpp
+++ b/media/libaudiohal/impl/EffectHalAidl.cpp
@@ -54,6 +54,7 @@
#include "effectsAidlConversion/AidlConversionVisualizer.h"
using ::aidl::android::aidl_utils::statusTFromBinderStatus;
+using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::IEffect;
using ::aidl::android::hardware::audio::effect::IFactory;
@@ -295,6 +296,7 @@
status_t EffectHalAidl::close() {
TIME_CHECK();
+ mEffect->command(CommandId::STOP);
return statusTFromBinderStatus(mEffect->close());
}
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 57b860d..f9ae2d4 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -441,10 +441,10 @@
track->prepareForAdjustChannels(mFrameCount);
}
} break;
- case HAPTIC_INTENSITY: {
- const os::HapticScale hapticIntensity = static_cast<os::HapticScale>(valueInt);
- if (track->mHapticIntensity != hapticIntensity) {
- track->mHapticIntensity = hapticIntensity;
+ case HAPTIC_SCALE: {
+ const os::HapticScale hapticScale = *reinterpret_cast<os::HapticScale*>(value);
+ if (track->mHapticScale != hapticScale) {
+ track->mHapticScale = hapticScale;
}
} break;
case HAPTIC_MAX_AMPLITUDE: {
@@ -585,7 +585,7 @@
t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
// haptic
t->mHapticPlaybackEnabled = false;
- t->mHapticIntensity = os::HapticScale::NONE;
+ t->mHapticScale = {/*level=*/os::HapticLevel::NONE };
t->mHapticMaxAmplitude = NAN;
t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
t->mMixerHapticChannelCount = 0;
@@ -636,7 +636,7 @@
switch (t->mMixerFormat) {
// Mixer format should be AUDIO_FORMAT_PCM_FLOAT.
case AUDIO_FORMAT_PCM_FLOAT: {
- os::scaleHapticData((float*) buffer, sampleCount, t->mHapticIntensity,
+ os::scaleHapticData((float*) buffer, sampleCount, t->mHapticScale,
t->mHapticMaxAmplitude);
} break;
default:
diff --git a/media/libaudioprocessing/include/media/AudioMixer.h b/media/libaudioprocessing/include/media/AudioMixer.h
index b39fb92..f558fd5 100644
--- a/media/libaudioprocessing/include/media/AudioMixer.h
+++ b/media/libaudioprocessing/include/media/AudioMixer.h
@@ -49,7 +49,7 @@
DOWNMIX_TYPE = 0x4004,
// for haptic
HAPTIC_ENABLED = 0x4007, // Set haptic data from this track should be played or not.
- HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
+ HAPTIC_SCALE = 0x4008, // Set the scale to play haptic data.
HAPTIC_MAX_AMPLITUDE = 0x4009, // Set the max amplitude allowed for haptic data.
// for target TIMESTRETCH
PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name;
@@ -141,7 +141,7 @@
// Haptic
bool mHapticPlaybackEnabled;
- os::HapticScale mHapticIntensity;
+ os::HapticScale mHapticScale;
float mHapticMaxAmplitude;
audio_channel_mask_t mHapticChannelMask;
uint32_t mHapticChannelCount;
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
index 042b063..311d60a 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -485,7 +485,7 @@
if (!stageInUse) {
LOG(WARNING) << __func__ << " not in use " << ::android::internal::ToString(channels);
- return RetCode::SUCCESS;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
}
RETURN_VALUE_IF(!stageInUse, RetCode::ERROR_ILLEGAL_PARAMETER, "stageNotInUse");
diff --git a/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp b/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
index a8892d8..5d9886c 100644
--- a/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
+++ b/media/libeffects/hapticgenerator/EffectHapticGenerator.cpp
@@ -145,7 +145,7 @@
memset(context->param.hapticChannelSource, 0, sizeof(context->param.hapticChannelSource));
context->param.hapticChannelCount = 0;
context->param.audioChannelCount = 0;
- context->param.maxHapticIntensity = os::HapticScale::MUTE;
+ context->param.maxHapticIntensity = os::HapticLevel::MUTE;
context->param.resonantFrequency = DEFAULT_RESONANT_FREQUENCY;
context->param.bpfQ = 1.0f;
@@ -316,9 +316,10 @@
return -EINVAL;
}
int id = *(int *) value;
- os::HapticScale hapticIntensity = static_cast<os::HapticScale>(*((int *) value + 1));
+ os::HapticLevel hapticIntensity =
+ static_cast<os::HapticLevel>(*((int *) value + 1));
ALOGD("Setting haptic intensity as %d", static_cast<int>(hapticIntensity));
- if (hapticIntensity == os::HapticScale::MUTE) {
+ if (hapticIntensity == os::HapticLevel::MUTE) {
context->param.id2Intensity.erase(id);
} else {
context->param.id2Intensity.emplace(id, hapticIntensity);
@@ -478,7 +479,7 @@
return -ENODATA;
}
- if (context->param.maxHapticIntensity == os::HapticScale::MUTE) {
+ if (context->param.maxHapticIntensity == os::HapticLevel::MUTE) {
// Haptic channels are muted, not need to generate haptic data.
return 0;
}
@@ -504,8 +505,9 @@
float* hapticOutBuffer = HapticGenerator_runProcessingChain(
context->processingChain, context->inputBuffer.data(),
context->outputBuffer.data(), inBuffer->frameCount);
- os::scaleHapticData(hapticOutBuffer, hapticSampleCount, context->param.maxHapticIntensity,
- context->param.maxHapticAmplitude);
+ os::scaleHapticData(hapticOutBuffer, hapticSampleCount,
+ { /*level=*/context->param.maxHapticIntensity},
+ context->param.maxHapticAmplitude);
// For haptic data, the haptic playback thread will copy the data from effect input buffer,
// which contains haptic data at the end of the buffer, directly to sink buffer.
diff --git a/media/libeffects/hapticgenerator/EffectHapticGenerator.h b/media/libeffects/hapticgenerator/EffectHapticGenerator.h
index 85e961f..f122c0a 100644
--- a/media/libeffects/hapticgenerator/EffectHapticGenerator.h
+++ b/media/libeffects/hapticgenerator/EffectHapticGenerator.h
@@ -49,8 +49,8 @@
uint32_t hapticChannelCount;
// A map from track id to haptic intensity.
- std::map<int, os::HapticScale> id2Intensity;
- os::HapticScale maxHapticIntensity; // max intensity will be used to scale haptic data.
+ std::map<int, os::HapticLevel> id2Intensity;
+ os::HapticLevel maxHapticIntensity; // max intensity will be used to scale haptic data.
float maxHapticAmplitude; // max amplitude will be used to limit haptic data absolute values.
float resonantFrequency;
diff --git a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
index e671543..5c38d17 100644
--- a/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
+++ b/media/libeffects/hapticgenerator/aidl/HapticGeneratorContext.cpp
@@ -174,7 +174,7 @@
runProcessingChain(mInputBuffer.data(), mOutputBuffer.data(), mFrameCount);
::android::os::scaleHapticData(
hapticOutBuffer, hapticSampleCount,
- static_cast<::android::os::HapticScale>(mParams.mMaxVibratorScale),
+ {/*level=*/static_cast<::android::os::HapticLevel>(mParams.mMaxVibratorScale) },
mParams.mVibratorInfo.qFactor);
// For haptic data, the haptic playback thread will copy the data from effect input
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
index a9d0cc2..aa18deb 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.cpp
@@ -284,15 +284,15 @@
// roundoff
int maxLevelRound = (int)(totalEnergyEstimation + 0.99);
- if (maxLevelRound + mVolume > 0) {
- gainCorrection = maxLevelRound + mVolume;
+ if (maxLevelRound + mVolumedB > 0) {
+ gainCorrection = maxLevelRound + mVolumedB;
}
- params.VC_EffectLevel = mVolume - gainCorrection;
+ params.VC_EffectLevel = mVolumedB - gainCorrection;
if (params.VC_EffectLevel < -96) {
params.VC_EffectLevel = -96;
}
- LOG(INFO) << "\tVol: " << mVolume << ", GainCorrection: " << gainCorrection
+ LOG(INFO) << "\tVol: " << mVolumedB << ", GainCorrection: " << gainCorrection
<< ", Actual vol: " << params.VC_EffectLevel;
/* Activate the initial settings */
@@ -576,25 +576,25 @@
RetCode BundleContext::setVolumeLevel(float level) {
if (mMuteEnabled) {
- mLevelSaved = level;
+ mLevelSaveddB = level;
} else {
- mVolume = level;
+ mVolumedB = level;
}
LOG(INFO) << __func__ << " success with level " << level;
return limitLevel();
}
float BundleContext::getVolumeLevel() const {
- return (mMuteEnabled ? mLevelSaved : mVolume);
+ return (mMuteEnabled ? mLevelSaveddB : mVolumedB);
}
RetCode BundleContext::setVolumeMute(bool mute) {
mMuteEnabled = mute;
if (mMuteEnabled) {
- mLevelSaved = mVolume;
- mVolume = -96;
+ mLevelSaveddB = mVolumedB;
+ mVolumedB = -96;
} else {
- mVolume = mLevelSaved;
+ mVolumedB = mLevelSaveddB;
}
return limitLevel();
}
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
index af46818..d823030 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleContext.h
@@ -124,8 +124,8 @@
bool mVirtualizerTempDisabled = false;
::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
// Volume
- float mLevelSaved = 0; /* for when mute is set, level must be saved */
- float mVolume = 0;
+ float mLevelSaveddB = 0; /* for when mute is set, level must be saved */
+ float mVolumedB = 0;
bool mMuteEnabled = false; /* Must store as mute = -96dB level */
RetCode initControlParameter(LVM_ControlParams_t& params) const;
diff --git a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
index 143329d..daabdb7 100644
--- a/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
+++ b/media/libeffects/lvm/wrapper/Aidl/BundleTypes.h
@@ -129,8 +129,7 @@
.implementor = "NXP Software Ltd."},
.capability = kVirtualizerCap};
-static const std::vector<Range::VolumeRange> kVolumeRanges = {
- MAKE_RANGE(Volume, levelDb, -9600, 0)};
+static const std::vector<Range::VolumeRange> kVolumeRanges = {MAKE_RANGE(Volume, levelDb, -96, 0)};
static const Capability kVolumeCap = {.range = kVolumeRanges};
static const std::string kVolumeEffectName = "Volume";
static const Descriptor kVolumeDesc = {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index d50c06b..a18dbfe 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1640,6 +1640,11 @@
ALOGV("buffer->range_length:%lld", (long long)buffer->range_length());
if (buffer->meta_data().findInt64(kKeySampleFileOffset, &offset)) {
ALOGV("offset:%lld, old_offset:%lld", (long long)offset, (long long)old_offset);
+ if (mMaxOffsetAppend > offset) {
+ // This has already been appended, skip updating mOffset value.
+ *bytesWritten = buffer->range_length();
+ return offset;
+ }
if (old_offset == offset) {
mOffset += buffer->range_length();
} else {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index f4c40e1..24ac2e8 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -697,6 +697,7 @@
inline constexpr char FEATURE_AdaptivePlayback[] = "adaptive-playback";
inline constexpr char FEATURE_EncodingStatistics[] = "encoding-statistics";
inline constexpr char FEATURE_IntraRefresh[] = "intra-refresh";
+inline constexpr char FEATURE_MultipleFrames[] = "multiple-frames";
inline constexpr char FEATURE_PartialFrame[] = "partial-frame";
inline constexpr char FEATURE_QpBounds[] = "qp-bounds";
inline constexpr char FEATURE_SecurePlayback[] = "secure-playback";
diff --git a/media/mediaserver/Android.bp b/media/mediaserver/Android.bp
index 19f9549..2341af1 100644
--- a/media/mediaserver/Android.bp
+++ b/media/mediaserver/Android.bp
@@ -1,4 +1,3 @@
-
package {
default_applicable_licenses: ["frameworks_av_media_mediaserver_license"],
}
@@ -86,7 +85,16 @@
"-Wall",
],
- vintf_fragments: ["manifest_media_c2_software.xml"],
+ // AIDL is only used when release_aidl_use_unfrozen is true
+ // because the swcodec mainline module is a prebuilt from an
+ // Android U branch in that case.
+ // TODO(b/327508501)
+ vintf_fragments: ["manifest_media_c2_software_hidl.xml"],
+ product_variables: {
+ release_aidl_use_unfrozen: {
+ vintf_fragments: ["manifest_media_c2_software_aidl.xml"],
+ },
+ },
soong_config_variables: {
TARGET_DYNAMIC_64_32_MEDIASERVER: {
diff --git a/media/mediaserver/manifest_media_c2_software_aidl.xml b/media/mediaserver/manifest_media_c2_software_aidl.xml
new file mode 100644
index 0000000..e6bcafa
--- /dev/null
+++ b/media/mediaserver/manifest_media_c2_software_aidl.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="framework">
+ <hal format="aidl">
+ <name>android.hardware.media.c2</name>
+ <version>1</version>
+ <fqname>IComponentStore/software</fqname>
+ </hal>
+</manifest>
diff --git a/media/mediaserver/manifest_media_c2_software.xml b/media/mediaserver/manifest_media_c2_software_hidl.xml
similarity index 68%
rename from media/mediaserver/manifest_media_c2_software.xml
rename to media/mediaserver/manifest_media_c2_software_hidl.xml
index 31dfafb..69a27be 100644
--- a/media/mediaserver/manifest_media_c2_software.xml
+++ b/media/mediaserver/manifest_media_c2_software_hidl.xml
@@ -8,9 +8,4 @@
<instance>software</instance>
</interface>
</hal>
- <hal format="aidl">
- <name>android.hardware.media.c2</name>
- <version>1</version>
- <fqname>IComponentStore/software</fqname>
- </hal>
</manifest>
diff --git a/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
index caf2524..4fbfab1 100644
--- a/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
+++ b/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
@@ -819,19 +819,21 @@
}
bool registered = false;
- if (platformVersion >= __ANDROID_API_V__) {
- if (!aidlStore) {
- aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(
- std::make_shared<H2C2ComponentStore>(nullptr));
- }
- const std::string serviceName =
- std::string(c2_aidl::IComponentStore::descriptor) + "/software";
- binder_exception_t ex = AServiceManager_addService(
- aidlStore->asBinder().get(), serviceName.c_str());
- if (ex == EX_NONE) {
- registered = true;
- } else {
- LOG(ERROR) << "Cannot register software Codec2 AIDL service.";
+ const std::string aidlServiceName =
+ std::string(c2_aidl::IComponentStore::descriptor) + "/software";
+ if (__builtin_available(android __ANDROID_API_S__, *)) {
+ if (AServiceManager_isDeclared(aidlServiceName.c_str())) {
+ if (!aidlStore) {
+ aidlStore = ::ndk::SharedRefBase::make<c2_aidl::utils::ComponentStore>(
+ std::make_shared<H2C2ComponentStore>(nullptr));
+ }
+ binder_exception_t ex = AServiceManager_addService(
+ aidlStore->asBinder().get(), aidlServiceName.c_str());
+ if (ex == EX_NONE) {
+ registered = true;
+ } else {
+ LOG(WARNING) << "Cannot register software Codec2 AIDL service. Exception: " << ex;
+ }
}
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 99fd533..725e5a6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2546,6 +2546,7 @@
bool mm;
if (OK == dev->getMasterMute(&mm)) {
mMasterMute = mm;
+ ALOGI_IF(mMasterMute, "%s: applying mute from HAL %s", __func__, name);
}
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index a02657e..b270813 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1536,7 +1536,7 @@
return IAfEffectModule::isSpatializer(&mDescriptor.type);
}
-status_t EffectModule::setHapticIntensity_l(int id, os::HapticScale intensity) {
+status_t EffectModule::setHapticScale_l(int id, os::HapticScale hapticScale) {
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1551,7 +1551,7 @@
param->vsize = sizeof(int32_t) * 2;
*(int32_t*)param->data = HG_PARAM_HAPTIC_INTENSITY;
*((int32_t*)param->data + 1) = id;
- *((int32_t*)param->data + 2) = static_cast<int32_t>(intensity);
+ *((int32_t*)param->data + 2) = static_cast<int32_t>(hapticScale.getLevel());
std::vector<uint8_t> response;
status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
if (status == NO_ERROR) {
@@ -2674,11 +2674,11 @@
return false;
}
-void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)
+void EffectChain::setHapticScale_l(int id, os::HapticScale hapticScale)
{
audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); ++i) {
- mEffects[i]->setHapticIntensity_l(id, intensity);
+ mEffects[i]->setHapticScale_l(id, hapticScale);
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 6e34e9b..46c44a6 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -233,7 +233,7 @@
bool isHapticGenerator() const final;
bool isSpatializer() const final;
- status_t setHapticIntensity_l(int id, os::HapticScale intensity) final
+ status_t setHapticScale_l(int id, os::HapticScale hapticScale) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
@@ -520,7 +520,7 @@
// Requires either IAfThreadBase::mutex() or EffectChain::mutex() held
bool containsHapticGeneratingEffect_l() final;
- void setHapticIntensity_l(int id, os::HapticScale intensity) final
+ void setHapticScale_l(int id, os::HapticScale hapticScale) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
sp<EffectCallbackInterface> effectCallback() const final { return mEffectCallback; }
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 82436a3..fd4dd62 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -180,7 +180,7 @@
static bool isSpatializer(const effect_uuid_t* type);
virtual bool isSpatializer() const = 0;
- virtual status_t setHapticIntensity_l(int id, os::HapticScale intensity)
+ virtual status_t setHapticScale_l(int id, os::HapticScale hapticScale)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
virtual status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
@@ -319,7 +319,7 @@
virtual bool containsHapticGeneratingEffect_l() = 0;
- virtual void setHapticIntensity_l(int id, os::HapticScale intensity)
+ virtual void setHapticScale_l(int id, os::HapticScale hapticScale)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual sp<EffectCallbackInterface> effectCallback() const = 0;
diff --git a/services/audioflinger/IAfTrack.h b/services/audioflinger/IAfTrack.h
index ac4ed36..8ed44c6 100644
--- a/services/audioflinger/IAfTrack.h
+++ b/services/audioflinger/IAfTrack.h
@@ -339,12 +339,12 @@
/** Set haptic playback of the track is enabled or not, should be
* set after query or get callback from vibrator service */
virtual void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) = 0;
- /** Return at what intensity to play haptics, used in mixer. */
- virtual os::HapticScale getHapticIntensity() const = 0;
+ /** Return the haptics scale, used in mixer. */
+ virtual os::HapticScale getHapticScale() const = 0;
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
virtual float getHapticMaxAmplitude() const = 0;
- /** Set intensity of haptic playback, should be set after querying vibrator service. */
- virtual void setHapticIntensity(os::HapticScale hapticIntensity) = 0;
+ /** Set scale for haptic playback, should be set after querying vibrator service. */
+ virtual void setHapticScale(os::HapticScale hapticScale) = 0;
/** Set maximum amplitude allowed for haptic data, should be set after querying
* vibrator service.
*/
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 826ba65..6c22e21 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -174,15 +174,15 @@
void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) final {
mHapticPlaybackEnabled = hapticPlaybackEnabled;
}
- /** Return at what intensity to play haptics, used in mixer. */
- os::HapticScale getHapticIntensity() const final { return mHapticIntensity; }
+ /** Return the haptics scale, used in mixer. */
+ os::HapticScale getHapticScale() const final { return mHapticScale; }
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
float getHapticMaxAmplitude() const final { return mHapticMaxAmplitude; }
/** Set intensity of haptic playback, should be set after querying vibrator service. */
- void setHapticIntensity(os::HapticScale hapticIntensity) final {
- if (os::isValidHapticScale(hapticIntensity)) {
- mHapticIntensity = hapticIntensity;
- setHapticPlaybackEnabled(mHapticIntensity != os::HapticScale::MUTE);
+ void setHapticScale(os::HapticScale hapticScale) final {
+ if (os::isValidHapticScale(hapticScale)) {
+ mHapticScale = hapticScale;
+ setHapticPlaybackEnabled(!mHapticScale.isScaleMute());
}
}
/** Set maximum amplitude allowed for haptic data, should be set after querying
@@ -329,8 +329,8 @@
sp<OpPlayAudioMonitor> mOpPlayAudioMonitor;
bool mHapticPlaybackEnabled = false; // indicates haptic playback enabled or not
- // intensity to play haptic data
- os::HapticScale mHapticIntensity = os::HapticScale::MUTE;
+ // scale to play haptic data
+ os::HapticScale mHapticScale = os::HapticScale::mute();
// max amplitude allowed for haptic data
float mHapticMaxAmplitude = NAN;
class AudioVibrationController : public os::BnExternalVibrationController {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9018dcc..d1a09a4 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2901,7 +2901,7 @@
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
mutex().unlock();
- const os::HapticScale intensity = afutils::onExternalVibrationStart(
+ const os::HapticScale hapticScale = afutils::onExternalVibrationStart(
track->getExternalVibration());
std::optional<media::AudioVibratorInfo> vibratorInfo;
{
@@ -2911,7 +2911,7 @@
vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
}
mutex().lock();
- track->setHapticIntensity(intensity);
+ track->setHapticScale(hapticScale);
if (vibratorInfo) {
track->setHapticMaxAmplitude(vibratorInfo->maxAmplitude);
}
@@ -2927,7 +2927,8 @@
// Set haptic intensity for effect
if (chain != nullptr) {
- chain->setHapticIntensity_l(track->id(), intensity);
+ // TODO(b/324559333): Add adaptive haptics scaling support for the HapticGenerator.
+ chain->setHapticScale_l(track->id(), hapticScale);
}
}
@@ -4810,7 +4811,7 @@
// When the track is stop, set the haptic intensity as MUTE
// for the HapticGenerator effect.
if (chain != nullptr) {
- chain->setHapticIntensity_l(track->id(), os::HapticScale::MUTE);
+ chain->setHapticScale_l(track->id(), os::HapticScale::mute());
}
}
@@ -5170,7 +5171,7 @@
// audio to FastMixer
fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer
fastTrack->mHapticPlaybackEnabled = mHapticChannelMask != AUDIO_CHANNEL_NONE;
- fastTrack->mHapticIntensity = os::HapticScale::NONE;
+ fastTrack->mHapticScale = {/*level=*/os::HapticLevel::NONE };
fastTrack->mHapticMaxAmplitude = NAN;
fastTrack->mGeneration++;
state->mFastTracksGen++;
@@ -5728,7 +5729,7 @@
fastTrack->mChannelMask = track->channelMask();
fastTrack->mFormat = track->format();
fastTrack->mHapticPlaybackEnabled = track->getHapticPlaybackEnabled();
- fastTrack->mHapticIntensity = track->getHapticIntensity();
+ fastTrack->mHapticScale = track->getHapticScale();
fastTrack->mHapticMaxAmplitude = track->getHapticMaxAmplitude();
fastTrack->mGeneration++;
state->mTrackMask |= 1 << j;
@@ -6089,10 +6090,11 @@
trackId,
AudioMixer::TRACK,
AudioMixer::HAPTIC_ENABLED, (void *)(uintptr_t)track->getHapticPlaybackEnabled());
+ const os::HapticScale hapticScale = track->getHapticScale();
mAudioMixer->setParameter(
- trackId,
- AudioMixer::TRACK,
- AudioMixer::HAPTIC_INTENSITY, (void *)(uintptr_t)track->getHapticIntensity());
+ trackId,
+ AudioMixer::TRACK,
+ AudioMixer::HAPTIC_SCALE, (void *)&hapticScale);
const float hapticMaxAmplitude = track->getHapticMaxAmplitude();
mAudioMixer->setParameter(
trackId,
@@ -10663,6 +10665,16 @@
}
}
+ // For mmap streams, once the routing has changed, they will be disconnected. It should be
+ // okay to notify the client earlier before the new patch creation.
+ if (mDeviceId != deviceId) {
+ if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
+ // The aaudioservice handle the routing changed event asynchronously. In that case,
+ // it is safe to hold the lock here.
+ callback->onRoutingChanged(deviceId);
+ }
+ }
+
if (mAudioHwDev->supportsAudioPatches()) {
status = mHalDevice->createAudioPatch(patch->num_sources, patch->sources, patch->num_sinks,
patch->sinks, handle);
@@ -10688,12 +10700,6 @@
sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
mInDeviceTypeAddr = sourceDeviceTypeAddr;
}
- sp<MmapStreamCallback> callback = mCallback.promote();
- if (mDeviceId != deviceId && callback != 0) {
- mutex().unlock();
- callback->onRoutingChanged(deviceId);
- mutex().lock();
- }
mPatch = *patch;
mDeviceId = deviceId;
}
@@ -10845,22 +10851,19 @@
void MmapThread::checkInvalidTracks_l()
{
- sp<MmapStreamCallback> callback;
for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (track->isInvalid()) {
- callback = mCallback.promote();
- if (callback == nullptr && mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
+ if (const sp<MmapStreamCallback> callback = mCallback.promote()) {
+ // The aaudioservice handle the routing changed event asynchronously. In that case,
+ // it is safe to hold the lock here.
+ callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
+ } else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
ALOGW("Could not notify MMAP stream tear down: no onRoutingChanged callback!");
mNoCallbackWarningCount++;
}
break;
}
}
- if (callback != 0) {
- mutex().unlock();
- callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
- mutex().lock();
- }
}
void MmapThread::dumpInternals_l(int fd, const Vector<String16>& /* args */)
@@ -11119,7 +11122,7 @@
char *endptr;
unsigned long ul = strtoul(value, &endptr, 0);
if (*endptr == '\0' && ul != 0) {
- ALOGD("Silence is golden");
+ ALOGW("%s: mute from ro.audio.silent. Silence is golden", __func__);
// The setprop command will not allow a property to be changed after
// the first time it is set, so we don't have to worry about un-muting.
setMasterMute_l(true);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 4e82173..4d07821 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1233,7 +1233,7 @@
&& (state == IDLE || state == STOPPED || state == FLUSHED)) {
mFrameMap.reset();
- if (!isFastTrack() && (isDirect() || isOffloaded())) {
+ if (!isFastTrack()) {
// Start point of track -> sink frame map. If the HAL returns a
// frame position smaller than the first written frame in
// updateTrackFrameInfo, the timestamp can be interpolated
@@ -1674,7 +1674,7 @@
if (result == OK) {
ALOGI("%s(%d): processed mute state for port ID %d from %d to %d", __func__, id(), mPortId,
- int(muteState), int(mMuteState));
+ static_cast<int>(mMuteState), static_cast<int>(muteState));
mMuteState = muteState;
} else {
ALOGW("%s(%d): cannot process mute state for port ID %d, status error %d", __func__, id(),
@@ -3554,6 +3554,8 @@
}
if (result == OK) {
+ ALOGI("%s(%d): processed mute state for port ID %d from %d to %d", __func__, id(), mPortId,
+ static_cast<int>(mMuteState), static_cast<int>(muteState));
mMuteState = muteState;
} else {
ALOGW("%s(%d): cannot process mute state for port ID %d, status error %d",
diff --git a/services/audioflinger/afutils/Vibrator.cpp b/services/audioflinger/afutils/Vibrator.cpp
index ab15a09..7c99ca9 100644
--- a/services/audioflinger/afutils/Vibrator.cpp
+++ b/services/audioflinger/afutils/Vibrator.cpp
@@ -20,6 +20,7 @@
#include "Vibrator.h"
+#include <android/os/ExternalVibrationScale.h>
#include <android/os/IExternalVibratorService.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
@@ -46,14 +47,15 @@
os::HapticScale onExternalVibrationStart(const sp<os::ExternalVibration>& externalVibration) {
if (externalVibration->getAudioAttributes().flags & AUDIO_FLAG_MUTE_HAPTIC) {
ALOGD("%s, mute haptic according to audio attributes flag", __func__);
- return os::HapticScale::MUTE;
+ return os::HapticScale::mute();
}
const sp<os::IExternalVibratorService> evs = getExternalVibratorService();
if (evs != nullptr) {
- int32_t ret;
+
+ os::ExternalVibrationScale ret;
binder::Status status = evs->onExternalVibrationStart(*externalVibration, &ret);
if (status.isOk()) {
- ALOGD("%s, start external vibration with intensity as %d", __func__, ret);
+ ALOGD("%s, start external vibration with intensity as %d", __func__, ret.scaleLevel);
return os::ExternalVibration::externalVibrationScaleToHapticScale(ret);
}
}
@@ -61,7 +63,7 @@
__func__,
evs == nullptr ? "external vibration service not found"
: "error when querying intensity");
- return os::HapticScale::MUTE;
+ return os::HapticScale::mute();
}
void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration) {
diff --git a/services/audioflinger/datapath/AudioStreamIn.cpp b/services/audioflinger/datapath/AudioStreamIn.cpp
index 24f3bb9..76618f4 100644
--- a/services/audioflinger/datapath/AudioStreamIn.cpp
+++ b/services/audioflinger/datapath/AudioStreamIn.cpp
@@ -56,15 +56,15 @@
return status;
}
- // Adjust for standby using HAL rate frames.
- // Only apply this correction if the HAL is getting PCM frames.
- if (mHalFormatHasProportionalFrames) {
+ if (mHalFormatHasProportionalFrames &&
+ (flags & AUDIO_INPUT_FLAG_DIRECT) == AUDIO_INPUT_FLAG_DIRECT) {
+ // For DirectRecord reset timestamp to 0 on standby.
const uint64_t adjustedPosition = (halPosition <= mFramesReadAtStandby) ?
0 : (halPosition - mFramesReadAtStandby);
// Scale from HAL sample rate to application rate.
*frames = adjustedPosition / mRateMultiplier;
} else {
- // For compressed formats.
+ // For compressed formats and linear PCM.
*frames = halPosition;
}
diff --git a/services/audioflinger/datapath/AudioStreamOut.cpp b/services/audioflinger/datapath/AudioStreamOut.cpp
index 1830d15..9851f3a 100644
--- a/services/audioflinger/datapath/AudioStreamOut.cpp
+++ b/services/audioflinger/datapath/AudioStreamOut.cpp
@@ -99,15 +99,15 @@
return status;
}
- // Adjust for standby using HAL rate frames.
- // Only apply this correction if the HAL is getting PCM frames.
- if (mHalFormatHasProportionalFrames) {
+ if (mHalFormatHasProportionalFrames &&
+ (flags & AUDIO_OUTPUT_FLAG_DIRECT) == AUDIO_OUTPUT_FLAG_DIRECT) {
+ // For DirectTrack reset timestamp to 0 on standby.
const uint64_t adjustedPosition = (halPosition <= mFramesWrittenAtStandby) ?
0 : (halPosition - mFramesWrittenAtStandby);
// Scale from HAL sample rate to application rate.
*frames = adjustedPosition / mRateMultiplier;
} else {
- // For offloaded MP3 and other compressed formats.
+ // For offloaded MP3 and other compressed formats, and linear PCM.
*frames = halPosition;
}
diff --git a/services/audioflinger/fastpath/FastMixer.cpp b/services/audioflinger/fastpath/FastMixer.cpp
index e0a15c1..1d41b3f 100644
--- a/services/audioflinger/fastpath/FastMixer.cpp
+++ b/services/audioflinger/fastpath/FastMixer.cpp
@@ -178,8 +178,8 @@
(void *)(uintptr_t)mSinkChannelMask);
mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_ENABLED,
(void *)(uintptr_t)fastTrack->mHapticPlaybackEnabled);
- mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_INTENSITY,
- (void *)(uintptr_t)fastTrack->mHapticIntensity);
+ mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_SCALE,
+ (void *)(&(fastTrack->mHapticScale)));
mMixer->setParameter(index, AudioMixer::TRACK, AudioMixer::HAPTIC_MAX_AMPLITUDE,
(void *)(&(fastTrack->mHapticMaxAmplitude)));
diff --git a/services/audioflinger/fastpath/FastMixerState.h b/services/audioflinger/fastpath/FastMixerState.h
index 8ab6d25..0a56f92 100644
--- a/services/audioflinger/fastpath/FastMixerState.h
+++ b/services/audioflinger/fastpath/FastMixerState.h
@@ -54,7 +54,7 @@
audio_format_t mFormat = AUDIO_FORMAT_INVALID; // track format
int mGeneration = 0; // increment when any field is assigned
bool mHapticPlaybackEnabled = false; // haptic playback is enabled or not
- os::HapticScale mHapticIntensity = os::HapticScale::MUTE; // intensity of haptic data
+ os::HapticScale mHapticScale = os::HapticScale::mute(); // scale of haptic data
float mHapticMaxAmplitude = NAN; // max amplitude allowed for haptic data
};
diff --git a/services/audioflinger/sounddose/SoundDoseManager.cpp b/services/audioflinger/sounddose/SoundDoseManager.cpp
index 8d40b63..3b764d1 100644
--- a/services/audioflinger/sounddose/SoundDoseManager.cpp
+++ b/services/audioflinger/sounddose/SoundDoseManager.cpp
@@ -231,10 +231,12 @@
ALOGI("%s: could not find port id for device %s", __func__, adt.toString().c_str());
return AUDIO_PORT_HANDLE_NONE;
}
- const auto btDeviceIt = mBluetoothDevicesWithCsd.find(std::make_pair(address, type));
- if (btDeviceIt != mBluetoothDevicesWithCsd.end()) {
- if (!btDeviceIt->second) {
- ALOGI("%s: bt device %s does not support sound dose", __func__, adt.toString().c_str());
+
+ if (audio_is_ble_out_device(type) || audio_is_a2dp_device(type)) {
+ const auto btDeviceIt = mBluetoothDevicesWithCsd.find(std::make_pair(address, type));
+ if (btDeviceIt == mBluetoothDevicesWithCsd.end() || !btDeviceIt->second) {
+ ALOGI("%s: bt device %s does not support sound dose", __func__,
+ adt.toString().c_str());
return AUDIO_PORT_HANDLE_NONE;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index 598d52d..e8b04ce 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -36,6 +36,7 @@
"src/TypeConverter.cpp",
],
shared_libs: [
+ "android.media.audiopolicy-aconfig-cc",
"audioclient-types-aidl-cpp",
"audiopolicy-types-aidl-cpp",
"libaudioclient_aidl_conversion",
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index dc0f466..d1819fd 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "APM_AudioPolicyMix"
-// #define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <algorithm>
#include <iterator>
@@ -28,6 +28,9 @@
#include "PolicyAudioPort.h"
#include "IOProfile.h"
#include <AudioOutputDescriptor.h>
+#include <android_media_audiopolicy.h>
+
+namespace audio_flags = android::media::audiopolicy;
namespace android {
namespace {
@@ -190,6 +193,12 @@
mix.mDeviceType, mix.mDeviceAddress.c_str());
return BAD_VALUE;
}
+ if (audio_flags::audio_mix_ownership()) {
+ if (mix.mToken == registeredMix->mToken) {
+ ALOGE("registerMix(): same mix already registered - skipping");
+ return BAD_VALUE;
+ }
+ }
}
if (!areMixCriteriaConsistent(mix.mCriteria)) {
ALOGE("registerMix(): Mix contains inconsistent criteria "
@@ -212,12 +221,21 @@
{
for (size_t i = 0; i < size(); i++) {
const sp<AudioPolicyMix>& registeredMix = itemAt(i);
- if (mix.mDeviceType == registeredMix->mDeviceType
+ if (audio_flags::audio_mix_ownership()) {
+ if (mix.mToken == registeredMix->mToken) {
+ ALOGD("unregisterMix(): removing mix for dev=0x%x addr=%s",
+ mix.mDeviceType, mix.mDeviceAddress.c_str());
+ removeAt(i);
+ return NO_ERROR;
+ }
+ } else {
+ if (mix.mDeviceType == registeredMix->mDeviceType
&& mix.mDeviceAddress.compare(registeredMix->mDeviceAddress) == 0) {
- ALOGD("unregisterMix(): removing mix for dev=0x%x addr=%s",
- mix.mDeviceType, mix.mDeviceAddress.c_str());
- removeAt(i);
- return NO_ERROR;
+ ALOGD("unregisterMix(): removing mix for dev=0x%x addr=%s",
+ mix.mDeviceType, mix.mDeviceAddress.c_str());
+ removeAt(i);
+ return NO_ERROR;
+ }
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 2761480..3bebb11 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3678,6 +3678,7 @@
status_t res = NO_ERROR;
bool checkOutputs = false;
sp<HwModule> rSubmixModule;
+ Vector<AudioMix> registeredMixes;
// examine each mix's route type
for (size_t i = 0; i < mixes.size(); i++) {
AudioMix mix = mixes[i];
@@ -3801,11 +3802,19 @@
break;
} else {
checkOutputs = true;
+ registeredMixes.add(mix);
}
}
}
if (res != NO_ERROR) {
- unregisterPolicyMixes(mixes);
+ if (audio_flags::audio_mix_ownership()) {
+ // Only unregister mixes that were actually registered to not accidentally unregister
+ // mixes that already existed previously.
+ unregisterPolicyMixes(registeredMixes);
+ registeredMixes.clear();
+ } else {
+ unregisterPolicyMixes(mixes);
+ }
} else if (checkOutputs) {
checkForDeviceAndOutputChanges();
updateCallAndOutputRouting();
@@ -3816,6 +3825,7 @@
status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
{
ALOGV("unregisterPolicyMixes() num mixes %zu", mixes.size());
+ status_t endResult = NO_ERROR;
status_t res = NO_ERROR;
bool checkOutputs = false;
sp<HwModule> rSubmixModule;
@@ -3828,6 +3838,7 @@
AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
if (rSubmixModule == 0) {
res = INVALID_OPERATION;
+ endResult = INVALID_OPERATION;
continue;
}
}
@@ -3836,6 +3847,7 @@
if (mPolicyMixes.unregisterMix(mix) != NO_ERROR) {
res = INVALID_OPERATION;
+ endResult = INVALID_OPERATION;
continue;
}
@@ -3848,6 +3860,7 @@
if (res != OK) {
ALOGE("Error making RemoteSubmix device unavailable for mix "
"with type %d, address %s", device, address.c_str());
+ endResult = INVALID_OPERATION;
}
}
}
@@ -3857,15 +3870,24 @@
} else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
if (mPolicyMixes.unregisterMix(mix) != NO_ERROR) {
res = INVALID_OPERATION;
+ endResult = INVALID_OPERATION;
continue;
} else {
checkOutputs = true;
}
}
}
- if (res == NO_ERROR && checkOutputs) {
- checkForDeviceAndOutputChanges();
- updateCallAndOutputRouting();
+ if (audio_flags::audio_mix_ownership()) {
+ res = endResult;
+ if (res == NO_ERROR && checkOutputs) {
+ checkForDeviceAndOutputChanges();
+ updateCallAndOutputRouting();
+ }
+ } else {
+ if (res == NO_ERROR && checkOutputs) {
+ checkForDeviceAndOutputChanges();
+ updateCallAndOutputRouting();
+ }
}
return res;
}
@@ -3882,6 +3904,7 @@
policyMix->mFormat, policyMix->mRouteFlags, policyMix->mDeviceAddress,
policyMix->mCbFlags);
_aidl_return.back().mDeviceType = policyMix->mDeviceType;
+ _aidl_return.back().mToken = policyMix->mToken;
}
ALOGVV("%s() returning %zu registered mixes", __func__, _aidl_return->size());
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 71edd57..d67ddb6 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -61,11 +61,6 @@
}
}
-void AudioPolicyEffects::setDefaultDeviceEffects() {
- mDefaultDeviceEffectFuture = std::async(
- std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
-}
-
status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
audio_source_t inputSource,
audio_session_t audioSession)
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index a9628c2..259b84a 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -116,10 +116,8 @@
// Remove the default stream effect from wherever it's attached.
status_t removeStreamDefaultEffect(audio_unique_id_t id) EXCLUDES_AudioPolicyEffects_Mutex;
- // Called by AudioPolicyService::onFirstRef() to load device effects
- // on a separate worker thread.
- // TODO(b/319515492) move this initialization after AudioPolicyService::onFirstRef().
- void setDefaultDeviceEffects();
+ // Initializes the Effects (AudioSystem must be ready as this creates audio client objects).
+ void initDefaultDeviceEffects() EXCLUDES(mDeviceEffectsMutex) EXCLUDES_EffectHandle_Mutex;
private:
@@ -201,11 +199,6 @@
};
- // Called on an async thread because it creates AudioEffects
- // which register with AudioFlinger and AudioPolicy.
- // We must therefore exclude the EffectHandle_Mutex.
- void initDefaultDeviceEffects() EXCLUDES(mDeviceEffectsMutex) EXCLUDES_EffectHandle_Mutex;
-
status_t loadAudioEffectConfig_ll(const sp<EffectsFactoryHalInterface>& effectsFactoryHal)
REQUIRES(mMutex, mDeviceEffectsMutex);
@@ -281,18 +274,6 @@
std::mutex mDeviceEffectsMutex;
std::map<std::string, std::unique_ptr<DeviceEffects>> mDeviceEffects
GUARDED_BY(mDeviceEffectsMutex);
-
- /**
- * Device Effect initialization must be asynchronous: the audio_policy service parses and init
- * effect on first reference. AudioFlinger will handle effect creation and register these
- * effect on audio_policy service.
- *
- * The future is associated with the std::async launched thread - no need to lock as
- * it is only set once on init. Due to the async nature, it is conceivable that
- * some device effects are not available immediately after AudioPolicyService::onFirstRef()
- * while the effects are being created.
- */
- std::future<void> mDefaultDeviceEffectFuture;
};
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index bc6498a..e95147e 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -313,9 +313,16 @@
}
}
AudioSystem::audioPolicyReady();
- // AudioFlinger will handle effect creation and register these effects on audio_policy
- // service. Hence, audio_policy service must be ready.
- audioPolicyEffects->setDefaultDeviceEffects();
+}
+
+void AudioPolicyService::onAudioSystemReady() {
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ audio_utils::lock_guard _l(mMutex);
+
+ audioPolicyEffects = mAudioPolicyEffects;
+ }
+ audioPolicyEffects->initDefaultDeviceEffects();
}
void AudioPolicyService::unloadAudioPolicyManager()
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index bd56366..7aa80cf 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -322,6 +322,9 @@
// RefBase
virtual void onFirstRef();
+ // Commence initialization when AudioSystem is ready.
+ void onAudioSystemReady();
+
//
// Helpers for the struct audio_policy_service_ops implementation.
// This is used by the audio policy manager for certain operations that
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index dbc48ae..16f3a9a 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -50,12 +50,12 @@
using aidl_utils::statusTFromBinderStatus;
using android::content::AttributionSourceState;
using binder::Status;
+using internal::ToString;
using media::HeadTrackingMode;
using media::Pose3f;
using media::SensorPoseProvider;
using media::audio::common::HeadTracking;
using media::audio::common::Spatialization;
-using ::android::internal::ToString;
using namespace std::chrono_literals;
@@ -349,7 +349,8 @@
bool activeLevelFound = false;
for (const auto spatializationLevel : spatializationLevels) {
if (!aidl_utils::isValidEnum(spatializationLevel)) {
- ALOGW("%s: ignoring spatializationLevel:%d", __func__, (int)spatializationLevel);
+ ALOGW("%s: ignoring spatializationLevel:%s", __func__,
+ ToString(spatializationLevel).c_str());
continue;
}
if (spatializationLevel == Spatialization::Level::NONE) {
@@ -376,7 +377,8 @@
for (const auto spatializationMode : spatializationModes) {
if (!aidl_utils::isValidEnum(spatializationMode)) {
- ALOGW("%s: ignoring spatializationMode:%d", __func__, (int)spatializationMode);
+ ALOGW("%s: ignoring spatializationMode:%s", __func__,
+ ToString(spatializationMode).c_str());
continue;
}
// we don't detect duplicates.
@@ -413,27 +415,26 @@
return BAD_VALUE;
}
- //TODO b/273373363: use AIDL enum when available
if (com::android::media::audio::dsa_over_bt_le_audio()
&& mSupportsHeadTracking) {
- mHeadtrackingConnectionMode = HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED;
- std::vector<uint8_t> headtrackingConnectionModes;
+ mHeadtrackingConnectionMode = HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED;
+ std::vector<HeadTracking::ConnectionMode> headtrackingConnectionModes;
status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_HEADTRACKING_CONNECTION,
&headtrackingConnectionModes);
if (status == NO_ERROR) {
for (const auto htConnectionMode : headtrackingConnectionModes) {
- if (htConnectionMode < HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED ||
- htConnectionMode > HEADTRACKING_CONNECTION_DIRECT_TO_SENSOR_TUNNEL) {
- ALOGW("%s: ignoring HT connection mode:%d", __func__, (int)htConnectionMode);
+ if (htConnectionMode < HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED ||
+ htConnectionMode > HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL) {
+ ALOGW("%s: ignoring HT connection mode:%s", __func__,
+ ToString(htConnectionMode).c_str());
continue;
}
- mSupportedHeadtrackingConnectionModes.insert(
- static_cast<headtracking_connection_t> (htConnectionMode));
+ mSupportedHeadtrackingConnectionModes.insert(htConnectionMode);
}
ALOGW_IF(mSupportedHeadtrackingConnectionModes.find(
- HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED)
- == mSupportedHeadtrackingConnectionModes.end(),
- "%s: HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED not reported", __func__);
+ HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED) ==
+ mSupportedHeadtrackingConnectionModes.end(),
+ "%s: Headtracking FRAMEWORK_PROCESSED not reported", __func__);
}
}
@@ -560,12 +561,12 @@
}
audio_utils::lock_guard lock(mMutex);
*level = mLevel;
- ALOGV("%s level %d", __func__, (int)*level);
+ ALOGV("%s level %s", __func__, ToString(*level).c_str());
return Status::ok();
}
Status Spatializer::isHeadTrackingSupported(bool *supports) {
- ALOGV("%s mSupportsHeadTracking %d", __func__, mSupportsHeadTracking);
+ ALOGV("%s mSupportsHeadTracking %s", __func__, ToString(mSupportsHeadTracking).c_str());
if (supports == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
@@ -860,7 +861,7 @@
}
void Spatializer::onActualModeChange(HeadTrackingMode mode) {
- std::string modeStr = media::toString(mode);
+ std::string modeStr = ToString(mode);
ALOGV("%s(%s)", __func__, modeStr.c_str());
sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
@@ -868,7 +869,7 @@
}
void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) {
- ALOGV("%s(%d)", __func__, (int) mode);
+ ALOGV("%s(%s)", __func__, ToString(mode).c_str());
sp<media::ISpatializerHeadTrackingCallback> callback;
HeadTracking::Mode spatializerMode;
{
@@ -887,7 +888,7 @@
spatializerMode = HeadTracking::Mode::RELATIVE_SCREEN;
break;
default:
- LOG_ALWAYS_FATAL("Unknown mode: %d", static_cast<int>(mode));
+ LOG_ALWAYS_FATAL("Unknown mode: %s", ToString(mode).c_str());
}
}
mActualHeadTrackingMode = spatializerMode;
@@ -901,7 +902,7 @@
}
}
callback = mHeadTrackingCallback;
- mLocalLog.log("%s: updating mode to %s", __func__, media::toString(mode).c_str());
+ mLocalLog.log("%s: updating mode to %s", __func__, ToString(mode).c_str());
}
if (callback != nullptr) {
callback->onHeadTrackingModeChanged(spatializerMode);
@@ -1059,24 +1060,23 @@
}
}
-//TODO b/273373363: use AIDL enum when available
audio_latency_mode_t Spatializer::selectHeadtrackingConnectionMode_l() {
if (!com::android::media::audio::dsa_over_bt_le_audio()) {
return AUDIO_LATENCY_MODE_LOW;
}
// mSupportedLatencyModes is ordered according to system preferences loaded in
// mOrderedLowLatencyModes
- mHeadtrackingConnectionMode = HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED;
+ mHeadtrackingConnectionMode = HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED;
audio_latency_mode_t requestedLatencyMode = mSupportedLatencyModes[0];
if (requestedLatencyMode == AUDIO_LATENCY_MODE_DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
if (mSupportedHeadtrackingConnectionModes.find(
- HEADTRACKING_CONNECTION_DIRECT_TO_SENSOR_TUNNEL)
+ HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL)
!= mSupportedHeadtrackingConnectionModes.end()) {
- mHeadtrackingConnectionMode = HEADTRACKING_CONNECTION_DIRECT_TO_SENSOR_TUNNEL;
+ mHeadtrackingConnectionMode = HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL;
} else if (mSupportedHeadtrackingConnectionModes.find(
- HEADTRACKING_CONNECTION_DIRECT_TO_SENSOR_SW)
+ HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_SW)
!= mSupportedHeadtrackingConnectionModes.end()) {
- mHeadtrackingConnectionMode = HEADTRACKING_CONNECTION_DIRECT_TO_SENSOR_SW;
+ mHeadtrackingConnectionMode = HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_SW;
} else {
// if the engine does not support direct reading of IMU data, do not allow
// DYNAMIC_SPATIAL_AUDIO_HARDWARE mode and fallback to next mode
@@ -1220,7 +1220,7 @@
base::StringAppendF(&ss, " %s", ToString(mode).c_str());
}
base::StringAppendF(&ss, "], Desired: %s, Actual %s\n",
- media::toString(mDesiredHeadTrackingMode).c_str(),
+ ToString(mDesiredHeadTrackingMode).c_str(),
ToString(mActualHeadTrackingMode).c_str());
base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str());
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 24788dc..355df18 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -486,11 +486,13 @@
bool mSupportsHeadTracking;
/** List of supported headtracking connection modes reported by the spatializer.
* If the list is empty, the spatializer does not support any optional connection
- * mode and mode HEADTRACKING_CONNECTION_FRAMEWORK_PROCESSED is assumed.
+ * mode and mode HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED is assumed.
*/
- std::unordered_set<headtracking_connection_t> mSupportedHeadtrackingConnectionModes;
+ std::unordered_set<media::audio::common::HeadTracking::ConnectionMode>
+ mSupportedHeadtrackingConnectionModes;
/** Selected HT connection mode when several modes are supported by the spatializer */
- headtracking_connection_t mHeadtrackingConnectionMode;
+ media::audio::common::HeadTracking::ConnectionMode mHeadtrackingConnectionMode =
+ media::audio::common::HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED;
// Looper thread for mEngine callbacks
class EngineCallbackHandler;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index e883e10..e02c93a 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -1330,6 +1330,10 @@
std::string mixAddress, const audio_config_t& audioConfig,
const std::vector<AudioMixMatchCriterion>& matchCriteria);
+ status_t addPolicyMix(const AudioMix& mix);
+
+ status_t removePolicyMixes(const Vector<AudioMix>& mixes);
+
std::vector<AudioMix> getRegisteredPolicyMixes();
void clearPolicyMix();
void addPolicyMixAndStartInputForLoopback(
@@ -1367,7 +1371,11 @@
myAudioMix.mDeviceType = deviceType;
// Clear mAudioMix before add new one to make sure we don't add already exist mixes.
mAudioMixes.clear();
- mAudioMixes.add(myAudioMix);
+ return addPolicyMix(myAudioMix);
+}
+
+status_t AudioPolicyManagerTestDynamicPolicy::addPolicyMix(const AudioMix& mix) {
+ mAudioMixes.add(mix);
// As the policy mixes registration may fail at some case,
// caller need to check the returned status.
@@ -1375,6 +1383,11 @@
return ret;
}
+status_t AudioPolicyManagerTestDynamicPolicy::removePolicyMixes(const Vector<AudioMix>& mixes) {
+ status_t ret = mManager->unregisterPolicyMixes(mixes);
+ return ret;
+}
+
std::vector<AudioMix> AudioPolicyManagerTestDynamicPolicy::getRegisteredPolicyMixes() {
std::vector<AudioMix> audioMixes;
if (mManager != nullptr) {
@@ -1539,6 +1552,98 @@
TEST_F_WITH_FLAGS(
AudioPolicyManagerTestDynamicPolicy,
+ RegisterInvalidMixesDoesNotImpactPriorMixes,
+ REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
+ ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
+) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
+ MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
+ validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+
+ mAudioMixes.clear();
+ mAudioMixes.add(validAudioMix);
+ status_t ret = mManager->registerPolicyMixes(mAudioMixes);
+
+ ASSERT_EQ(NO_ERROR, ret);
+
+ std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
+ ASSERT_EQ(1, registeredMixes.size());
+
+ std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUidCriterion(/*uid=*/1235, /*exclude=*/true),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+
+ AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
+ MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
+ validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+
+ mAudioMixes.add(invalidAudioMix);
+ ret = mManager->registerPolicyMixes(mAudioMixes);
+
+ ASSERT_EQ(INVALID_OPERATION, ret);
+
+ std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
+ ASSERT_EQ(registeredMixes.size(), remainingMixes.size());
+}
+
+TEST_F_WITH_FLAGS(
+ AudioPolicyManagerTestDynamicPolicy,
+ UnregisterInvalidMixesReturnsError,
+ REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api),
+ ACONFIG_FLAG(android::media::audiopolicy, audio_mix_ownership))
+) {
+ audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+
+ std::vector<AudioMixMatchCriterion> validMixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+ AudioMix validAudioMix(validMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
+ MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
+ validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+
+ mAudioMixes.clear();
+ mAudioMixes.add(validAudioMix);
+ status_t ret = mManager->registerPolicyMixes(mAudioMixes);
+
+ ASSERT_EQ(NO_ERROR, ret);
+
+ std::vector<AudioMix> registeredMixes = getRegisteredPolicyMixes();
+ ASSERT_EQ(1, registeredMixes.size());
+
+ std::vector<AudioMixMatchCriterion> invalidMixMatchCriteria = {
+ createUidCriterion(/*uid=*/42),
+ createUidCriterion(/*uid=*/1235, /*exclude=*/true),
+ createUsageCriterion(AUDIO_USAGE_MEDIA, /*exclude=*/true)};
+
+ AudioMix invalidAudioMix(invalidMixMatchCriteria, MIX_TYPE_PLAYERS, audioConfig,
+ MIX_ROUTE_FLAG_LOOP_BACK, String8(mMixAddress.c_str()), 0);
+ validAudioMix.mDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+
+ Vector<AudioMix> mixes;
+ mixes.add(invalidAudioMix);
+ mixes.add(validAudioMix);
+ ret = removePolicyMixes(mixes);
+
+ ASSERT_EQ(INVALID_OPERATION, ret);
+
+ std::vector<AudioMix> remainingMixes = getRegisteredPolicyMixes();
+ EXPECT_THAT(remainingMixes, IsEmpty());
+}
+
+TEST_F_WITH_FLAGS(
+ AudioPolicyManagerTestDynamicPolicy,
GetRegisteredPolicyMixes,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(android::media::audiopolicy, audio_mix_test_api))
) {
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 5b76bb0..b748888 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -186,6 +186,7 @@
"aidl/AidlCameraServiceListener.cpp",
"aidl/AidlUtils.cpp",
"aidl/DeathPipe.cpp",
+ "utils/AttributionAndPermissionUtils.cpp",
"utils/CameraServiceProxyWrapper.cpp",
"utils/CameraThreadState.cpp",
"utils/CameraTraces.cpp",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2d55f39..ebe771e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -38,7 +38,6 @@
#include <aidl/AidlCameraService.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
-#include <android/permission/PermissionChecker.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -129,20 +128,16 @@
// ----------------------------------------------------------------------------
-static const std::string sDumpPermission("android.permission.DUMP");
-static const std::string sManageCameraPermission("android.permission.MANAGE_CAMERA");
-static const std::string sCameraPermission("android.permission.CAMERA");
-static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
-static const std::string sCameraHeadlessSystemUserPermission(
- "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
-static const std::string sCameraPrivacyAllowlistPermission(
- "android.permission.CAMERA_PRIVACY_ALLOWLIST");
-static const std::string
- sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
-static const std::string sCameraOpenCloseListenerPermission(
- "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
-static const std::string
- sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
+// Permission strings (references to AttributionAndPermissionUtils for brevity)
+static const std::string &sDumpPermission =
+ AttributionAndPermissionUtils::sDumpPermission;
+static const std::string &sManageCameraPermission =
+ AttributionAndPermissionUtils::sManageCameraPermission;
+static const std::string &sCameraSendSystemEventsPermission =
+ AttributionAndPermissionUtils::sCameraSendSystemEventsPermission;
+static const std::string &sCameraInjectExternalCameraPermission =
+ AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission;
+
// Constant integer for FGS Logging, used to denote the API type for logger
static const int LOG_FGS_CAMERA_API = 1;
const char *sFileName = "lastOpenSessionDumpFile";
@@ -158,9 +153,13 @@
static std::set<std::string> sServiceErrorEventSet;
CameraService::CameraService(
- std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
+ std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils) :
mCameraServiceProxyWrapper(cameraServiceProxyWrapper == nullptr ?
std::make_shared<CameraServiceProxyWrapper>() : cameraServiceProxyWrapper),
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils == nullptr ?
+ std::make_shared<AttributionAndPermissionUtils>(this)\
+ : attributionAndPermissionUtils),
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
mNumberOfCamerasWithoutSystemCamera(0),
@@ -215,7 +214,7 @@
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
- mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this, mAttributionAndPermissionUtils);
mSensorPrivacyPolicy->registerSelf();
mInjectionStatusListener = new InjectionStatusListener(this);
@@ -708,34 +707,15 @@
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}
-static bool isAutomotiveDevice() {
- // Checks the property ro.hardware.type and returns true if it is
- // automotive.
- char value[PROPERTY_VALUE_MAX] = {0};
- property_get("ro.hardware.type", value, "");
- return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+bool CameraService::isAutomotiveDevice() const {
+ return mAttributionAndPermissionUtils->isAutomotiveDevice();
}
-static bool isHeadlessSystemUserMode() {
- // Checks if the device is running in headless system user mode
- // by checking the property ro.fw.mu.headless_system_user.
- char value[PROPERTY_VALUE_MAX] = {0};
- property_get("ro.fw.mu.headless_system_user", value, "");
- return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
+bool CameraService::isAutomotivePrivilegedClient(int32_t uid) const {
+ return mAttributionAndPermissionUtils->isAutomotivePrivilegedClient(uid);
}
-static bool isAutomotivePrivilegedClient(int32_t uid) {
- // Returns false if this is not an automotive device type.
- if (!isAutomotiveDevice())
- return false;
-
- // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
- // privileged client uid used for safety critical use cases such as
- // rear view and surround view.
- return uid == AID_AUTOMOTIVE_EVS;
-}
-
-bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const{
+bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const {
// Returns false if this is not an automotive device type.
if (!isAutomotiveDevice())
return false;
@@ -780,54 +760,47 @@
return true;
}
-bool CameraService::checkPermission(const std::string& cameraId, const std::string& permission,
- const AttributionSourceState& attributionSource, const std::string& message,
- int32_t attributedOpCode) const{
- if (isAutomotivePrivilegedClient(attributionSource.uid)) {
- // If cameraId is empty, then it means that this check is not used for the
- // purpose of accessing a specific camera, hence grant permission just
- // based on uid to the automotive privileged client.
- if (cameraId.empty())
- return true;
- // If this call is used for accessing a specific camera then cam_id must be provided.
- // In that case, only pre-grants the permission for accessing the exterior system only
- // camera.
- return isAutomotiveExteriorSystemCamera(cameraId);
- }
+static AttributionSourceState attributionSourceFromPidAndUid(int callingPid, int callingUid) {
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ return attributionSource;
+}
- permission::PermissionChecker permissionChecker;
- return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
- toString16(message), attributedOpCode)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+bool CameraService::hasPermissionsForCamera(int callingPid, int callingUid) const {
+ return hasPermissionsForCamera(std::string(), callingPid, callingUid);
+}
+
+bool CameraService::hasPermissionsForCamera(const std::string& cameraId, int callingPid,
+ int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
}
bool CameraService::hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid,
- int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = checkPermission(cameraId,
- sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- bool checkPermissionForCamera = checkPermission(cameraId,
- sCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- return checkPermissionForSystemCamera && checkPermissionForCamera;
+ int callingUid, bool checkCameraPermissions) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForSystemCamera(
+ cameraId, attributionSource, checkCameraPermissions);
}
bool CameraService::hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
- int callingPid, int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- return checkPermission(cameraId, sCameraHeadlessSystemUserPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+ int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCameraHeadlessSystemUser(
+ cameraId, attributionSource);
}
-bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- return checkPermission(std::string(), sCameraPrivacyAllowlistPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCameraPrivacyAllowlist(
+ attributionSource);
+}
+
+bool CameraService::hasPermissionsForOpenCloseListener(int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForOpenCloseListener(
+ attributionSource);
}
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
@@ -1272,13 +1245,9 @@
const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
auto callingPid = CameraThreadState::getCallingPid();
auto callingUid = CameraThreadState::getCallingUid();
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = checkPermission(std::to_string(cameraIdInt),
- sSystemCameraPermission, attributionSource, std::string(),
- AppOpsManager::OP_NONE);
- if (checkPermissionForSystemCamera || getpid() == callingPid) {
+ bool systemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraIdInt),
+ callingPid, callingUid, /* checkCameraPermissions= */ false);
+ if (systemCameraPermissions || getpid() == callingPid) {
deviceIds = &mNormalDeviceIds;
}
if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(deviceIds->size())) {
@@ -1351,11 +1320,7 @@
// If it's not calling from cameraserver, check the permission only if
// android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
// it would've already been checked in shouldRejectSystemCameraConnection.
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+ bool checkPermissionForCamera = hasPermissionsForCamera(cameraId, callingPid, callingUid);
if ((callingPid != getpid()) &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
!checkPermissionForCamera) {
@@ -1541,7 +1506,7 @@
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
- packageName, featureId, cameraId,
+ cameraService->mAttributionAndPermissionUtils, packageName, featureId, cameraId,
api1CameraId, facing, sensorOrientation,
clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
forceSlowJpegMode);
@@ -1551,7 +1516,8 @@
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
*client = new CameraDeviceClient(cameraService, tmp,
- cameraService->mCameraServiceProxyWrapper, packageName, systemNativeClient,
+ cameraService->mCameraServiceProxyWrapper,
+ cameraService->mAttributionAndPermissionUtils, packageName, systemNativeClient,
featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
overrideForPerfClass, overrideToPortrait, originalCameraId);
ALOGI("%s: Camera2 API, override to portrait %d", __FUNCTION__, overrideToPortrait);
@@ -1716,35 +1682,13 @@
}
// Can camera service trust the caller based on the calling UID?
-static bool isTrustedCallingUid(uid_t uid) {
- switch (uid) {
- case AID_MEDIA: // mediaserver
- case AID_CAMERASERVER: // cameraserver
- case AID_RADIO: // telephony
- return true;
- default:
- return false;
- }
+bool CameraService::isTrustedCallingUid(uid_t uid) const {
+ return mAttributionAndPermissionUtils->isTrustedCallingUid(uid);
}
-static status_t getUidForPackage(const std::string &packageName, int userId, /*inout*/uid_t& uid,
- int err) {
- PermissionController pc;
- uid = pc.getPackageUid(toString16(packageName), 0);
- if (uid <= 0) {
- ALOGE("Unknown package: '%s'", packageName.c_str());
- dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
- return BAD_VALUE;
- }
-
- if (userId < 0) {
- ALOGE("Invalid user: %d", userId);
- dprintf(err, "Invalid user: %d\n", userId);
- return BAD_VALUE;
- }
-
- uid = multiuser_get_uid(userId, uid);
- return NO_ERROR;
+status_t CameraService::getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err) const {
+ return mAttributionAndPermissionUtils->getUidForPackage(packageName, userId, uid, err);
}
Status CameraService::validateConnectLocked(const std::string& cameraId,
@@ -1798,8 +1742,6 @@
Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
const std::string& clientName, int& clientUid, int& clientPid,
/*out*/int& originalClientPid) const {
- AttributionSourceState attributionSource{};
-
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
@@ -1846,11 +1788,7 @@
// If it's not calling from cameraserver, check the permission if the
// device isn't a system only camera (shouldRejectSystemCameraConnection already checks for
// android.permission.SYSTEM_CAMERA for system only camera devices).
- attributionSource.pid = clientPid;
- attributionSource.uid = clientUid;
- attributionSource.packageName = clientName;
- bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+ bool checkPermissionForCamera = hasPermissionsForCamera(cameraId, clientPid, clientUid);
if (callingPid != getpid() &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
@@ -1906,8 +1844,9 @@
// If the System User tries to access the camera when the device is running in
// headless system user mode, ensure that client has the required permission
// CAMERA_HEADLESS_SYSTEM_USER.
- if (isHeadlessSystemUserMode() && (clientUserId == USER_SYSTEM) &&
- !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
+ if (mAttributionAndPermissionUtils->isHeadlessSystemUserMode()
+ && (clientUserId == USER_SYSTEM)
+ && !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" as Headless System \
@@ -2273,7 +2212,7 @@
}
// (1) Cameraserver trying to connect, accept.
- if (CameraThreadState::getCallingPid() == getpid()) {
+ if (mAttributionAndPermissionUtils->isCallerCameraServerNotDelegating()) {
return false;
}
// (2)
@@ -3323,22 +3262,6 @@
return Status::ok();
}
-bool CameraService::hasCameraPermissions() const {
- int callingPid = CameraThreadState::getCallingPid();
- int callingUid = CameraThreadState::getCallingUid();
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool res = checkPermission(std::string(), sCameraPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
-
- bool hasPermission = ((callingPid == getpid()) || res);
- if (!hasPermission) {
- ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
- }
- return hasPermission;
-}
-
Status CameraService::isConcurrentSessionConfigurationSupported(
const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations,
int targetSdkVersion, /*out*/bool* isSupported) {
@@ -3354,7 +3277,11 @@
}
// Check for camera permissions
- if (!hasCameraPermissions()) {
+ int callingPid = CameraThreadState::getCallingPid();
+ int callingUid = CameraThreadState::getCallingUid();
+ bool hasCameraPermission = ((callingPid == getpid()) ||
+ hasPermissionsForCamera(callingPid, callingUid));
+ if (!hasCameraPermission) {
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
"android.permission.CAMERA needed to call"
"isConcurrentSessionConfigurationSupported");
@@ -3398,15 +3325,9 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
}
- auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
- AttributionSourceState attributionSource{};
- attributionSource.uid = clientUid;
- attributionSource.pid = clientPid;
-
- bool openCloseCallbackAllowed = checkPermission(std::string(),
- sCameraOpenCloseListenerPermission, attributionSource, std::string(),
- AppOpsManager::OP_NONE);
+ auto clientUid = CameraThreadState::getCallingUid();
+ bool openCloseCallbackAllowed = hasPermissionsForOpenCloseListener(clientPid, clientUid);
Mutex::Autolock lock(mServiceLock);
@@ -4049,6 +3970,7 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName, bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraIdStr,
@@ -4057,6 +3979,7 @@
int servicePid, bool overrideToPortrait) :
CameraService::BasicClient(cameraService,
IInterface::asBinder(cameraClient),
+ attributionAndPermissionUtils,
clientPackageName, systemNativeClient, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation,
clientPid, clientUid,
@@ -4087,10 +4010,12 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName, bool nativeClient,
const std::optional<std::string>& clientFeatureId, const std::string& cameraIdStr,
int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid, bool overrideToPortrait):
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils),
mDestructionStarted(false),
mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation),
mClientPackageName(clientPackageName), mSystemNativeClient(nativeClient),
@@ -4123,7 +4048,7 @@
mAppOpsManager = std::make_unique<AppOpsManager>();
}
- mUidIsTrusted = isTrustedCallingUid(mClientUid);
+ mUidIsTrusted = mAttributionAndPermissionUtils->isTrustedCallingUid(mClientUid);
}
CameraService::BasicClient::~BasicClient() {
@@ -4862,7 +4787,7 @@
}
hasCameraPrivacyFeature(); // Called so the result is cached
mSpm.addSensorPrivacyListener(this);
- if (isAutomotiveDevice()) {
+ if (mAttributionAndPermissionUtils->isAutomotiveDevice()) {
mSpm.addToggleSensorPrivacyListener(this);
}
mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled();
@@ -4902,7 +4827,7 @@
void CameraService::SensorPrivacyPolicy::unregisterSelf() {
Mutex::Autolock _l(mSensorPrivacyLock);
mSpm.removeSensorPrivacyListener(this);
- if (isAutomotiveDevice()) {
+ if (mAttributionAndPermissionUtils->isAutomotiveDevice()) {
mSpm.removeToggleSensorPrivacyListener(this);
}
mSpm.unlinkToDeath(this);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8822cd3..11cf1a1 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -53,6 +53,7 @@
#include "utils/ClientManager.h"
#include "utils/IPCTransport.h"
#include "utils/CameraServiceProxyWrapper.h"
+#include "utils/AttributionAndPermissionUtils.h"
#include <set>
#include <string>
@@ -119,7 +120,9 @@
// Non-null arguments for cameraServiceProxyWrapper should be provided for
// testing purposes only.
CameraService(std::shared_ptr<CameraServiceProxyWrapper>
- cameraServiceProxyWrapper = nullptr);
+ cameraServiceProxyWrapper = nullptr,
+ std::shared_ptr<AttributionAndPermissionUtils>
+ attributionAndPermissionUtils = nullptr);
virtual ~CameraService();
/////////////////////////////////////////////////////////////////////
@@ -314,6 +317,21 @@
// Shared utilities
static binder::Status filterGetInfoErrorCode(status_t err);
+ bool isAutomotiveDevice() const;
+
+ /**
+ * Returns true if the client has uid AID_AUTOMOTIVE_EVS and the device is an automotive device.
+ */
+ bool isAutomotivePrivilegedClient(int32_t uid) const;
+
+ /**
+ * Returns true if the device is an automotive device and cameraId is system
+ * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
+ * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+ * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
+ */
+ bool isAutomotiveExteriorSystemCamera(const std::string& cameraId) const;
+
/////////////////////////////////////////////////////////////////////
// CameraClient functionality
@@ -428,6 +446,7 @@
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool nativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -441,6 +460,8 @@
virtual ~BasicClient();
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
+
// the instance is in the middle of destruction. When this is set,
// the instance should not be accessed from callback.
// CameraService's mClientLock should be acquired to access this.
@@ -541,6 +562,7 @@
// Interface used by CameraService
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -644,13 +666,6 @@
int32_t updateAudioRestrictionLocked();
private:
- /**
- * Returns true if the device is an automotive device and cameraId is system
- * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
- * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
- * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
- */
- bool isAutomotiveExteriorSystemCamera(const std::string& cameraId) const;
// TODO: b/263304156 update this to make use of a death callback for more
// robust/fault tolerant logging
@@ -666,29 +681,20 @@
return activityManager;
}
- /**
- * Pre-grants the permission if the attribution source uid is for an automotive
- * privileged client. Otherwise uses system service permission checker to check
- * for the appropriate permission. If this function is called for accessing a specific
- * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
- * privileged client so that permission is pre-granted only to access system camera device
- * which is located outside of the vehicle body frame because camera located inside the vehicle
- * cabin would need user permission.
- */
- bool checkPermission(const std::string& cameraId, const std::string& permission,
- const content::AttributionSourceState& attributionSource, const std::string& message,
- int32_t attributedOpCode) const;
+ bool hasPermissionsForCamera(int callingPid, int callingUid) const;
- bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid)
- const;
+ bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid) const;
+
+ bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid,
+ bool checkCameraPermissions = true) const;
bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
int callingUid) const;
- bool hasCameraPermissions() const;
-
bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const;
+ bool hasPermissionsForOpenCloseListener(int callingPid, int callingUid) const;
+
/**
* Typesafe version of device status, containing both the HAL-layer and the service interface-
* layer values.
@@ -875,8 +881,11 @@
public virtual IBinder::DeathRecipient,
public virtual IServiceManager::LocalRegistrationCallback {
public:
- explicit SensorPrivacyPolicy(wp<CameraService> service)
- : mService(service), mSensorPrivacyEnabled(false),
+ explicit SensorPrivacyPolicy(wp<CameraService> service,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
+ : mService(service),
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils),
+ mSensorPrivacyEnabled(false),
mCameraPrivacyState(SensorPrivacyManager::DISABLED), mRegistered(false) {}
void registerSelf();
@@ -900,6 +909,7 @@
private:
SensorPrivacyManager mSpm;
wp<CameraService> mService;
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
Mutex mSensorPrivacyLock;
bool mSensorPrivacyEnabled;
int mCameraPrivacyState;
@@ -914,6 +924,7 @@
sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
std::shared_ptr<CameraServiceProxyWrapper> mCameraServiceProxyWrapper;
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
// Delay-load the Camera HAL module
virtual void onFirstRef();
@@ -926,6 +937,11 @@
void addStates(const std::string& id);
void removeStates(const std::string& id);
+ bool isTrustedCallingUid(uid_t uid) const;
+
+ status_t getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err) const;
+
// Check if we can connect, before we acquire the service lock.
// The returned originalClientPid is the PID of the original process that wants to connect to
// camera.
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index f2d1414..14e5fad 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -17,12 +17,13 @@
#define LOG_TAG "AidlUtils"
#include <aidl/AidlUtils.h>
+#include <aidl/ExtensionMetadataTags.h>
#include <aidl/VndkVersionMetadataTags.h>
#include <aidlcommonsupport/NativeHandle.h>
+#include <camera/StringUtils.h>
#include <device3/Camera3StreamInterface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <mediautils/AImageReaderUtils.h>
-#include <camera/StringUtils.h>
namespace android::hardware::cameraservice::utils::conversion::aidl {
@@ -333,4 +334,47 @@
return OK;
}
+bool areExtensionKeysSupported(const CameraMetadata& metadata) {
+ auto requestKeys = metadata.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+ if (requestKeys.count == 0) {
+ ALOGE("%s: No ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS entries!", __FUNCTION__);
+ return false;
+ }
+
+ auto resultKeys = metadata.find(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
+ if (resultKeys.count == 0) {
+ ALOGE("%s: No ANDROID_REQUEST_AVAILABLE_RESULT_KEYS entries!", __FUNCTION__);
+ return false;
+ }
+
+ for (const auto& extensionKey : extension_metadata_keys) {
+ if (std::find(requestKeys.data.i32, requestKeys.data.i32 + requestKeys.count, extensionKey)
+ != requestKeys.data.i32 + requestKeys.count) {
+ return true;
+ }
+
+ if (std::find(resultKeys.data.i32, resultKeys.data.i32 + resultKeys.count, extensionKey)
+ != resultKeys.data.i32 + resultKeys.count) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+status_t filterExtensionKeys(CameraMetadata* metadata /*out*/) {
+ if (metadata == nullptr) {
+ return BAD_VALUE;
+ }
+
+ for (const auto& key : extension_metadata_keys) {
+ status_t res = metadata->erase(key);
+ if (res != OK) {
+ ALOGE("%s metadata key %d could not be erased", __FUNCTION__, key);
+ return res;
+ }
+ }
+ return OK;
+}
+
} // namespace android::hardware::cameraservice::utils::conversion::aidl
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.h b/services/camera/libcameraservice/aidl/AidlUtils.h
index c89d7ff..562aa70 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.h
+++ b/services/camera/libcameraservice/aidl/AidlUtils.h
@@ -122,6 +122,9 @@
status_t filterVndkKeys(int vndkVersion, CameraMetadata &metadata, bool isStatic = true);
+bool areExtensionKeysSupported(const CameraMetadata& metadata);
+
+status_t filterExtensionKeys(CameraMetadata* metadata /*out*/);
} // namespace android::hardware::cameraservice::utils::conversion::aidl
#endif // FRAMEWORKS_AV_SERVICES_CAMERA_LIBCAMERASERVICE_AIDL_AIDLUTILS_H_
diff --git a/services/camera/libcameraservice/aidl/ExtensionMetadataTags.h b/services/camera/libcameraservice/aidl/ExtensionMetadataTags.h
new file mode 100644
index 0000000..86af36c
--- /dev/null
+++ b/services/camera/libcameraservice/aidl/ExtensionMetadataTags.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#include <vector>
+#pragma once
+/**
+ * ! Do not edit this file directly !
+ *
+ * Generated automatically from extensions_camera_metadata_tags.mako. To be included in libcameraservice
+ * only by aidl/AidlUtils.cpp.
+ */
+
+/**
+ * API level to dynamic keys mapping. To be used for filtering out keys depending on vndk version
+ * used by vendor clients.
+ */
+std::vector<camera_metadata_tag> extension_metadata_keys{
+ ANDROID_EXTENSION_STRENGTH,
+ ANDROID_EXTENSION_CURRENT_TYPE,
+ ANDROID_EFV_PADDING_ZOOM_FACTOR,
+ ANDROID_EFV_AUTO_ZOOM,
+ ANDROID_EFV_MAX_PADDING_ZOOM_FACTOR,
+ ANDROID_EFV_STABILIZATION_MODE,
+ ANDROID_EFV_TRANSLATE_VIEWPORT,
+ ANDROID_EFV_ROTATE_VIEWPORT,
+ ANDROID_EFV_PADDING_REGION,
+ ANDROID_EFV_AUTO_ZOOM_PADDING_REGION,
+ ANDROID_EFV_TARGET_COORDINATES,
+};
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index caa6424..19e2999 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -56,6 +56,7 @@
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraDeviceId,
@@ -68,7 +69,8 @@
bool overrideForPerfClass,
bool overrideToPortrait,
bool forceSlowJpegMode):
- Camera2ClientBase(cameraService, cameraClient, cameraServiceProxyWrapper, clientPackageName,
+ Camera2ClientBase(cameraService, cameraClient, cameraServiceProxyWrapper,
+ attributionAndPermissionUtils, clientPackageName,
false/*systemNativeClient - since no ndk for api1*/, clientFeatureId,
cameraDeviceId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 2cb7af0..2654a25 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -103,6 +103,7 @@
Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraDeviceId,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 508d487..7c2f71c 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -61,6 +61,7 @@
CameraDeviceClientBase::CameraDeviceClientBase(
const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -74,6 +75,7 @@
bool overrideToPortrait) :
BasicClient(cameraService,
IInterface::asBinder(remoteCallback),
+ attributionAndPermissionUtils,
clientPackageName,
systemNativeClient,
clientFeatureId,
@@ -92,6 +94,7 @@
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -104,7 +107,8 @@
bool overrideForPerfClass,
bool overrideToPortrait,
const std::string& originalCameraId) :
- Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper, clientPackageName,
+ Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper,
+ attributionAndPermissionUtils, clientPackageName,
systemNativeClient, clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing,
sensorOrientation, clientPid, clientUid, servicePid, overrideForPerfClass,
overrideToPortrait),
@@ -1900,9 +1904,9 @@
sp<CameraOfflineSessionClient> offlineClient;
if (offlineSession.get() != nullptr) {
offlineClient = new CameraOfflineSessionClient(sCameraService,
- offlineSession, offlineCompositeStreamMap, cameraCb, mClientPackageName,
- mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation, mClientPid, mClientUid,
- mServicePid);
+ offlineSession, offlineCompositeStreamMap, cameraCb, mAttributionAndPermissionUtils,
+ mClientPackageName, mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation,
+ mClientPid, mClientUid, mServicePid);
ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index b2c9626..d93eaff 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,6 +50,7 @@
protected:
CameraDeviceClientBase(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -181,6 +182,7 @@
CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool clientPackageOverride,
const std::optional<std::string>& clientFeatureId,
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 804498f..c6f3e06 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -47,6 +47,7 @@
sp<CameraOfflineSessionBase> session,
const KeyedVector<sp<IBinder>, sp<CompositeStream>>& offlineCompositeStreamMap,
const sp<ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraIdStr, int cameraFacing, int sensorOrientation,
@@ -54,6 +55,7 @@
CameraService::BasicClient(
cameraService,
IInterface::asBinder(remoteCallback),
+ attributionAndPermissionUtils,
// (v)ndk doesn't have offline session support
clientPackageName, /*overridePackageName*/false, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation, clientPid, clientUid, servicePid,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index a126f61..3a78937 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -50,6 +50,7 @@
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -63,9 +64,9 @@
bool overrideForPerfClass,
bool overrideToPortrait,
bool legacyClient):
- TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
- clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
- clientUid, servicePid, overrideToPortrait),
+ TClientBase(cameraService, remoteCallback, attributionAndPermissionUtils, clientPackageName,
+ systemNativeClient, clientFeatureId, cameraId, api1CameraId, cameraFacing,
+ sensorOrientation, clientPid, clientUid, servicePid, overrideToPortrait),
mSharedCameraCallbacks(remoteCallback),
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mDeviceActive(false), mApi1CameraId(api1CameraId)
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 2bb90d9..b8a6d8b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -21,6 +21,7 @@
#include "camera/CameraMetadata.h"
#include "camera/CaptureResult.h"
#include "utils/CameraServiceProxyWrapper.h"
+#include "utils/AttributionAndPermissionUtils.h"
#include "CameraServiceWatchdog.h"
namespace android {
@@ -51,6 +52,7 @@
Camera2ClientBase(const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index c0a0544..9792089 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -78,6 +78,7 @@
using namespace android::camera3;
using namespace android::camera3::SessionConfigurationUtils;
using namespace android::hardware::camera;
+using namespace android::hardware::cameraservice::utils::conversion::aidl;
namespace flags = com::android::internal::camera::flags;
namespace android {
@@ -254,6 +255,8 @@
return res;
}
+ mSupportsExtensionKeys = areExtensionKeysSupported(mDeviceInfo);
+
return OK;
}
@@ -2531,10 +2534,13 @@
config.streams = streams.editArray();
config.hal_buffer_managed_streams = mHalBufManagedStreamIds;
+ config.use_hal_buf_manager = mUseHalBufManager;
// Do the HAL configuration; will potentially touch stream
- // max_buffers, usage, and priv fields, as well as data_space and format
- // fields for IMPLEMENTATION_DEFINED formats.
+ // max_buffers, usage, priv fields, data_space and format
+ // fields for IMPLEMENTATION_DEFINED formats as well as hal buffer managed
+ // streams and use_hal_buf_manager (in case aconfig flag session_hal_buf_manager
+ // is not enabled but the HAL supports session specific hal buffer manager).
int64_t logId = mCameraServiceProxyWrapper->getCurrentLogIdForCamera(mId);
const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
@@ -2554,6 +2560,8 @@
strerror(-res), res);
return res;
}
+ // It is possible that use hal buffer manager behavior was changed by the
+ // configureStreams call.
mUseHalBufManager = config.use_hal_buf_manager;
if (flags::session_hal_buf_manager()) {
bool prevSessionHalBufManager = (mHalBufManagedStreamIds.size() != 0);
@@ -3887,13 +3895,22 @@
for (it = captureRequest->mSettingsList.begin();
it != captureRequest->mSettingsList.end(); it++) {
- res = hardware::cameraservice::utils::conversion::aidl::filterVndkKeys(
- mVndkVersion, it->metadata, false /*isStatic*/);
+ res = filterVndkKeys(mVndkVersion, it->metadata, false /*isStatic*/);
if (res != OK) {
SET_ERR("RequestThread: Failed during VNDK filter of capture requests "
"%d: %s (%d)", halRequest->frame_number, strerror(-res), res);
return INVALID_OPERATION;
}
+
+ if (!parent->mSupportsExtensionKeys) {
+ res = filterExtensionKeys(&it->metadata);
+ if (res != OK) {
+ SET_ERR("RequestThread: Failed during extension filter of capture "
+ "requests %d: %s (%d)", halRequest->frame_number,
+ strerror(-res), res);
+ return INVALID_OPERATION;
+ }
+ }
}
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 498ef55..ac4b039 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1523,6 +1523,9 @@
// AE_TARGET_FPS_RANGE
bool mIsFixedFps = false;
+ // Flag to indicate that we shouldn't forward extension related metadata
+ bool mSupportsExtensionKeys = false;
+
// Injection camera related methods.
class Camera3DeviceInjectionMethods : public virtual RefBase {
public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index f98636b..2ce04e8 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -235,65 +235,6 @@
return OK;
}
-status_t Camera3OutputStream::getBuffersLocked(std::vector<OutstandingBuffer>* outBuffers) {
- status_t res;
-
- if ((res = getBufferPreconditionCheckLocked()) != OK) {
- return res;
- }
-
- if (mUseBufferManager) {
- ALOGE("%s: stream %d is managed by buffer manager and does not support batch operation",
- __FUNCTION__, mId);
- return INVALID_OPERATION;
- }
-
- sp<Surface> consumer = mConsumer;
- /**
- * Release the lock briefly to avoid deadlock for below scenario:
- * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
- * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
- * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
- * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
- * StreamingProcessor lock.
- * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
- * and try to lock bufferQueue lock.
- * Then there is circular locking dependency.
- */
- mLock.unlock();
-
- size_t numBuffersRequested = outBuffers->size();
- std::vector<Surface::BatchBuffer> buffers(numBuffersRequested);
-
- nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC);
- res = consumer->dequeueBuffers(&buffers);
- nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC);
- mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
-
- mLock.lock();
-
- if (res != OK) {
- if (shouldLogError(res, mState)) {
- ALOGE("%s: Stream %d: Can't dequeue %zu output buffers: %s (%d)",
- __FUNCTION__, mId, numBuffersRequested, strerror(-res), res);
- }
- checkRetAndSetAbandonedLocked(res);
- return res;
- }
- checkRemovedBuffersLocked();
-
- /**
- * FenceFD now owned by HAL except in case of error,
- * in which case we reassign it to acquire_fence
- */
- for (size_t i = 0; i < numBuffersRequested; i++) {
- handoutBufferLocked(*(outBuffers->at(i).outBuffer),
- &(buffers[i].buffer->handle), /*acquireFence*/buffers[i].fenceFd,
- /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
- }
- return OK;
-}
-
status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
ANativeWindowBuffer* buffer, int anwReleaseFence,
const std::vector<size_t>&) {
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 65791a9..da0ed87 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -388,8 +388,6 @@
virtual status_t getBufferLocked(camera_stream_buffer *buffer,
const std::vector<size_t>& surface_ids);
- virtual status_t getBuffersLocked(/*out*/std::vector<OutstandingBuffer>* buffers) override;
-
virtual status_t returnBufferLocked(
const camera_stream_buffer &buffer,
nsecs_t timestamp, nsecs_t readoutTimestamp,
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 701c472..79a767a 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -969,11 +969,6 @@
return INVALID_OPERATION;
}
-status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) {
- ALOGE("%s: This type of stream does not support output", __FUNCTION__);
- return INVALID_OPERATION;
-}
-
status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
ALOGE("%s: This type of stream does not support output", __FUNCTION__);
@@ -1047,92 +1042,6 @@
mBufferFreedListener = listener;
}
-status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers,
- nsecs_t waitBufferTimeout) {
- ATRACE_CALL();
- Mutex::Autolock l(mLock);
- status_t res = OK;
-
- if (buffers == nullptr) {
- ALOGI("%s: buffers must not be null!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- size_t numBuffersRequested = buffers->size();
- if (numBuffersRequested == 0) {
- ALOGE("%s: 0 buffers are requested!", __FUNCTION__);
- return BAD_VALUE;
- }
-
- // This function should be only called when the stream is configured already.
- if (mState != STATE_CONFIGURED) {
- ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
- __FUNCTION__, mId, mState);
- if (mState == STATE_ABANDONED) {
- return DEAD_OBJECT;
- } else {
- return INVALID_OPERATION;
- }
- }
-
- size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
- size_t numCachedBuffers = getCachedOutputBufferCountLocked();
- size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
- // Wait for new buffer returned back if we are running into the limit. There
- // are 2 limits:
- // 1. The number of HAL buffers is greater than max_buffers
- // 2. The number of HAL buffers + cached buffers is greater than max_buffers
- // + maxCachedBuffers
- while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers ||
- numOutstandingBuffers + numCachedBuffers + numBuffersRequested >
- camera_stream::max_buffers + maxNumCachedBuffers) {
- ALOGV("%s: Already dequeued %zu(+%zu) output buffers and requesting %zu "
- "(max is %d(+%zu)), waiting.", __FUNCTION__, numOutstandingBuffers,
- numCachedBuffers, numBuffersRequested, camera_stream::max_buffers,
- maxNumCachedBuffers);
- nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
- if (waitBufferTimeout < kWaitForBufferDuration) {
- waitBufferTimeout = kWaitForBufferDuration;
- }
- res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
- nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
- mBufferLimitLatency.add(waitStart, waitEnd);
- if (res != OK) {
- if (res == TIMED_OUT) {
- ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
- __FUNCTION__, waitBufferTimeout / 1000000LL,
- camera_stream::max_buffers);
- }
- return res;
- }
- size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
- size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
- if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
- updatedNumCachedBuffers == numCachedBuffers) {
- ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
- "getBuffer(s) call must not run in parallel!", __FUNCTION__,
- numOutstandingBuffers, updatedNumOutstandingBuffers);
- return INVALID_OPERATION;
- }
- numOutstandingBuffers = updatedNumOutstandingBuffers;
- numCachedBuffers = updatedNumCachedBuffers;
- }
-
- res = getBuffersLocked(buffers);
- if (res == OK) {
- for (auto& outstandingBuffer : *buffers) {
- camera_stream_buffer* buffer = outstandingBuffer.outBuffer;
- fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
- if (buffer->buffer) {
- Mutex::Autolock l(mOutstandingBuffersLock);
- mOutstandingBuffers.push_back(*buffer->buffer);
- }
- }
- }
-
- return res;
-}
-
void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
int64_t dynamicRangeProfile) {
auto& mapper = GraphicBufferMapper::get();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index f06ccf3..0df09cd 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -343,12 +343,6 @@
const std::vector<size_t>& surface_ids = std::vector<size_t>());
/**
- * Similar to getBuffer() except this method fills multiple buffers.
- */
- status_t getBuffers(std::vector<OutstandingBuffer>* buffers,
- nsecs_t waitBufferTimeout);
-
- /**
* Return a buffer to the stream after use by the HAL.
*
* Multiple surfaces could share the same HAL stream, but a request may
@@ -535,8 +529,6 @@
nsecs_t timestamp, nsecs_t readoutTimestamp, int32_t transform,
const std::vector<size_t>& surface_ids = std::vector<size_t>());
- virtual status_t getBuffersLocked(std::vector<OutstandingBuffer>*);
-
virtual status_t getInputBufferLocked(camera_stream_buffer *buffer, Size* size);
virtual status_t returnInputBufferLocked(
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 7fa6273..26fa04f 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -395,11 +395,6 @@
*/
std::vector<size_t> surface_ids;
};
- /**
- * Similar to getBuffer() except this method fills multiple buffers.
- */
- virtual status_t getBuffers(std::vector<OutstandingBuffer>* buffers,
- nsecs_t waitBufferTimeout) = 0;
/**
* Return a buffer to the stream after use by the HAL.
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index 13c500f..e8ef692 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -913,7 +913,6 @@
std::set<int> activeStreams;
camera::device::StreamConfiguration requestedConfiguration;
requestedConfiguration.streams.resize(config->num_streams);
- config->use_hal_buf_manager = mUseHalBufManager;
for (size_t i = 0; i < config->num_streams; i++) {
camera::device::Stream &dst = requestedConfiguration.streams[i];
camera3::camera_stream_t *src = config->streams[i];
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
new file mode 100644
index 0000000..e63b30b
--- /dev/null
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#include "AttributionAndPermissionUtils.h"
+
+#include <binder/AppOpsManager.h>
+#include <binder/PermissionController.h>
+#include <cutils/properties.h>
+#include <private/android_filesystem_config.h>
+
+#include "CameraService.h"
+#include "CameraThreadState.h"
+
+namespace android {
+
+const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
+const std::string AttributionAndPermissionUtils::sManageCameraPermission(
+ "android.permission.MANAGE_CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraPermission(
+ "android.permission.CAMERA");
+const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
+ "android.permission.SYSTEM_CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
+ "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
+const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
+ "android.permission.CAMERA_PRIVACY_ALLOWLIST");
+const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
+ "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
+const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
+const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
+ "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
+
+bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(const std::string &cameraId,
+ const AttributionSourceState &attributionSource) {
+ if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+ // If cameraId is empty, then it means that this check is not used for the
+ // purpose of accessing a specific camera, hence grant permission just
+ // based on uid to the automotive privileged client.
+ if (cameraId.empty())
+ return true;
+
+ auto cameraService = mCameraService.promote();
+ if (cameraService == nullptr) {
+ ALOGE("%s: CameraService unavailable.", __FUNCTION__);
+ return false;
+ }
+
+ // If this call is used for accessing a specific camera then cam_id must be provided.
+ // In that case, only pre-grants the permission for accessing the exterior system only
+ // camera.
+ return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
+ }
+
+ return false;
+}
+
+bool AttributionAndPermissionUtils::checkPermissionForPreflight(const std::string &cameraId,
+ const std::string &permission, const AttributionSourceState &attributionSource,
+ const std::string& message, int32_t attributedOpCode) {
+ if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
+ return true;
+ }
+
+ PermissionChecker permissionChecker;
+ return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
+ toString16(message), attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+// Can camera service trust the caller based on the calling UID?
+bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
+ switch (uid) {
+ case AID_MEDIA: // mediaserver
+ case AID_CAMERASERVER: // cameraserver
+ case AID_RADIO: // telephony
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool AttributionAndPermissionUtils::isAutomotiveDevice() {
+ // Checks the property ro.hardware.type and returns true if it is
+ // automotive.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware.type", value, "");
+ return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
+bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
+ // Checks if the device is running in headless system user mode
+ // by checking the property ro.fw.mu.headless_system_user.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.fw.mu.headless_system_user", value, "");
+ return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
+}
+
+bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
+ // Returns false if this is not an automotive device type.
+ if (!isAutomotiveDevice())
+ return false;
+
+ // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
+ // privileged client uid used for safety critical use cases such as
+ // rear view and surround view.
+ return uid == AID_AUTOMOTIVE_EVS;
+}
+
+status_t AttributionAndPermissionUtils::getUidForPackage(const std::string &packageName,
+ int userId, /*inout*/uid_t& uid, int err) {
+ PermissionController pc;
+ uid = pc.getPackageUid(toString16(packageName), 0);
+ if (uid <= 0) {
+ ALOGE("Unknown package: '%s'", packageName.c_str());
+ dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
+ return BAD_VALUE;
+ }
+
+ if (userId < 0) {
+ ALOGE("Invalid user: %d", userId);
+ dprintf(err, "Invalid user: %d\n", userId);
+ return BAD_VALUE;
+ }
+
+ uid = multiuser_get_uid(userId, uid);
+ return NO_ERROR;
+}
+
+bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
+ return CameraThreadState::getCallingPid() == getpid();
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(cameraId, sCameraPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource, bool checkCameraPermissions) {
+ bool systemCameraPermission = checkPermissionForPreflight(cameraId,
+ sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
+ return systemCameraPermission && (!checkCameraPermissions
+ || hasPermissionsForCamera(cameraId, attributionSource));
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
new file mode 100644
index 0000000..dc4cfb1
--- /dev/null
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 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_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+#define ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+
+#include <android/content/AttributionSourceState.h>
+#include <android/permission/PermissionChecker.h>
+#include <binder/BinderService.h>
+
+namespace android {
+
+class CameraService;
+
+using content::AttributionSourceState;
+using permission::PermissionChecker;
+
+/**
+ * Utility class consolidating methods/data for verifying permissions and the identity of the
+ * caller.
+ */
+class AttributionAndPermissionUtils {
+public:
+ AttributionAndPermissionUtils(wp<CameraService> cameraService) : mCameraService(cameraService)
+ {}
+ virtual ~AttributionAndPermissionUtils() {}
+
+ /**
+ * Pre-grants the permission if the attribution source uid is for an automotive
+ * privileged client. Otherwise uses system service permission checker to check
+ * for the appropriate permission. If this function is called for accessing a specific
+ * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
+ * privileged client so that permission is pre-granted only to access system camera device
+ * which is located outside of the vehicle body frame because camera located inside the vehicle
+ * cabin would need user permission.
+ */
+ virtual bool checkPermissionForPreflight(const std::string &cameraId,
+ const std::string &permission, const AttributionSourceState& attributionSource,
+ const std::string& message, int32_t attributedOpCode);
+ virtual bool isTrustedCallingUid(uid_t uid);
+ virtual bool isAutomotiveDevice();
+ virtual bool isHeadlessSystemUserMode();
+ virtual bool isAutomotivePrivilegedClient(int32_t uid);
+ virtual status_t getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err);
+ virtual bool isCallerCameraServerNotDelegating();
+
+ // Utils for checking specific permissions
+ virtual bool hasPermissionsForCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForSystemCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource, bool checkCameraPermissions = true);
+ virtual bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForCameraPrivacyAllowlist(
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForOpenCloseListener(
+ const AttributionSourceState& attributionSource);
+
+ static const std::string sDumpPermission;
+ static const std::string sManageCameraPermission;
+ static const std::string sCameraPermission;
+ static const std::string sSystemCameraPermission;
+ static const std::string sCameraHeadlessSystemUserPermission;
+ static const std::string sCameraPrivacyAllowlistPermission;
+ static const std::string sCameraSendSystemEventsPermission;
+ static const std::string sCameraOpenCloseListenerPermission;
+ static const std::string sCameraInjectExternalCameraPermission;
+
+protected:
+ wp<CameraService> mCameraService;
+
+ bool checkAutomotivePrivilegedClient(const std::string &cameraId,
+ const AttributionSourceState &attributionSource);
+};
+
+} // namespace android
+
+#endif // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index a70f6cf..7636cbd 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -81,8 +81,6 @@
constexpr MetadataBuilder::ControlRegion kDefaultEmptyControlRegion{};
-constexpr float kAspectRatioEpsilon = 0.05;
-
const std::array<Resolution, 5> kStandardJpegThumbnailSizes{
Resolution(176, 144), Resolution(240, 144), Resolution(256, 144),
Resolution(240, 160), Resolution(240, 180)};
@@ -91,14 +89,15 @@
PixelFormat::IMPLEMENTATION_DEFINED, PixelFormat::YCBCR_420_888,
PixelFormat::BLOB};
-bool isApproximatellySameAspectRatio(const Resolution r1, const Resolution r2) {
- float aspectRatio1 =
- static_cast<float>(r1.width) / static_cast<float>(r1.height);
- float aspectRatio2 =
- static_cast<float>(r2.width) / static_cast<float>(r2.height);
-
- return abs(aspectRatio1 - aspectRatio2) < kAspectRatioEpsilon;
-}
+// The resolutions below will used to extend the set of supported output formats.
+// All resolutions with lower pixel count and same aspect ratio as some supported
+// input resolution will be added to the set of supported output resolutions.
+const std::array<Resolution, 10> kOutputResolutions{
+ Resolution(320, 240), Resolution(640, 360), Resolution(640, 480),
+ Resolution(720, 480), Resolution(720, 576), Resolution(800, 600),
+ Resolution(1024, 576), Resolution(1280, 720), Resolution(1280, 960),
+ Resolution(1280, 1080),
+};
std::vector<Resolution> getSupportedJpegThumbnailSizes(
const std::vector<SupportedStreamConfiguration>& configs) {
@@ -180,6 +179,36 @@
}
}
+ std::map<Resolution, int> additionalResolutionToMaxFpsMap;
+ // Add additional resolutions we can support by downscaling input streams with
+ // same aspect ratio.
+ for (const Resolution& outputResolution : kOutputResolutions) {
+ for (const auto& [resolution, maxFps] : resolutionToMaxFpsMap) {
+ if (resolutionToMaxFpsMap.find(outputResolution) !=
+ resolutionToMaxFpsMap.end()) {
+ // Resolution is already in the map, skip it.
+ continue;
+ }
+
+ if (outputResolution < resolution &&
+ isApproximatellySameAspectRatio(outputResolution, resolution)) {
+ // Lower resolution with same aspect ratio, we can achieve this by
+ // downscaling, let's add it to the map.
+ ALOGD(
+ "Extending set of output resolutions with %dx%d which has same "
+ "aspect ratio as supported input %dx%d.",
+ outputResolution.width, outputResolution.height, resolution.width,
+ resolution.height);
+ additionalResolutionToMaxFpsMap[outputResolution] = maxFps;
+ break;
+ }
+ }
+ }
+
+ // Add all resolution we can achieve by downscaling to the map.
+ resolutionToMaxFpsMap.insert(additionalResolutionToMaxFpsMap.begin(),
+ additionalResolutionToMaxFpsMap.end());
+
return resolutionToMaxFpsMap;
}
@@ -210,6 +239,9 @@
ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED)
.setSensorTimestampSource(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN)
.setSensorPhysicalSize(36.0, 24.0)
+ .setAvailableAberrationCorrectionModes(
+ {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF})
+ .setAvailableNoiseReductionModes({ANDROID_NOISE_REDUCTION_MODE_OFF})
.setAvailableFaceDetectModes({ANDROID_STATISTICS_FACE_DETECT_MODE_OFF})
.setAvailableTestPatternModes({ANDROID_SENSOR_TEST_PATTERN_MODE_OFF})
.setAvailableMaxDigitalZoom(1.0)
@@ -234,17 +266,21 @@
.setControlAeLockAvailable(false)
.setControlAvailableAwbModes({ANDROID_CONTROL_AWB_MODE_AUTO})
.setControlZoomRatioRange(/*min=*/1.0, /*max=*/1.0)
+ .setCroppingType(ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY)
.setJpegAvailableThumbnailSizes(
getSupportedJpegThumbnailSizes(supportedInputConfig))
.setMaxJpegSize(kMaxJpegSize)
+ .setMaxFaceCount(0)
.setMaxFrameDuration(kMaxFrameDuration)
.setMaxNumberOutputStreams(
VirtualCameraDevice::kMaxNumberOfRawStreams,
VirtualCameraDevice::kMaxNumberOfProcessedStreams,
VirtualCameraDevice::kMaxNumberOfStallStreams)
+ .setRequestPartialResultCount(1)
.setPipelineMaxDepth(kPipelineMaxDepth)
.setSyncMaxLatency(ANDROID_SYNC_MAX_LATENCY_UNKNOWN)
- .setAvailableRequestKeys({ANDROID_CONTROL_CAPTURE_INTENT,
+ .setAvailableRequestKeys({ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+ ANDROID_CONTROL_CAPTURE_INTENT,
ANDROID_CONTROL_AE_MODE,
ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
@@ -259,19 +295,20 @@
ANDROID_CONTROL_SCENE_MODE,
ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
ANDROID_CONTROL_ZOOM_RATIO,
- ANDROID_STATISTICS_FACE_DETECT_MODE,
ANDROID_FLASH_MODE,
ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
ANDROID_JPEG_QUALITY,
- ANDROID_JPEG_THUMBNAIL_QUALITY})
+ ANDROID_JPEG_THUMBNAIL_QUALITY,
+ ANDROID_NOISE_REDUCTION_MODE,
+ ANDROID_STATISTICS_FACE_DETECT_MODE})
.setAvailableResultKeys(
- {ANDROID_CONTROL_AE_MODE, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
- ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AWB_MODE,
- ANDROID_CONTROL_EFFECT_MODE, ANDROID_CONTROL_MODE,
- ANDROID_FLASH_MODE, ANDROID_FLASH_STATE,
+ {ANDROID_COLOR_CORRECTION_ABERRATION_MODE, ANDROID_CONTROL_AE_MODE,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, ANDROID_CONTROL_AF_MODE,
+ ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_EFFECT_MODE,
+ ANDROID_CONTROL_MODE, ANDROID_FLASH_MODE, ANDROID_FLASH_STATE,
ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, ANDROID_JPEG_QUALITY,
- ANDROID_JPEG_THUMBNAIL_QUALITY, ANDROID_SENSOR_TIMESTAMP,
- ANDROID_LENS_FOCAL_LENGTH})
+ ANDROID_JPEG_THUMBNAIL_QUALITY, ANDROID_LENS_FOCAL_LENGTH,
+ ANDROID_SENSOR_TIMESTAMP, ANDROID_NOISE_REDUCTION_MODE})
.setAvailableCapabilities(
{ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE});
@@ -393,6 +430,22 @@
return false;
}
+ const std::vector<Stream>& streams = streamConfiguration.streams;
+
+ Resolution firstStreamResolution(streams[0].width, streams[0].height);
+ auto isSameAspectRatioAsFirst = [firstStreamResolution](const Stream& stream) {
+ return isApproximatellySameAspectRatio(
+ firstStreamResolution, Resolution(stream.width, stream.height));
+ };
+ if (!std::all_of(streams.begin(), streams.end(), isSameAspectRatioAsFirst)) {
+ ALOGW(
+ "%s: Requested streams do not have same aspect ratio. Different aspect "
+ "ratios are currently "
+ "not supported by virtual camera. Stream configuration: %s",
+ __func__, streamConfiguration.toString().c_str());
+ return false;
+ }
+
int numberOfProcessedStreams = 0;
int numberOfStallStreams = 0;
for (const Stream& stream : streamConfiguration.streams) {
@@ -415,9 +468,13 @@
numberOfProcessedStreams++;
}
+ Resolution requestedResolution(stream.width, stream.height);
auto matchesSupportedInputConfig =
- [&stream](const SupportedStreamConfiguration& config) {
- return stream.width == config.width && stream.height == config.height;
+ [requestedResolution](const SupportedStreamConfiguration& config) {
+ Resolution supportedInputResolution(config.width, config.height);
+ return requestedResolution <= supportedInputResolution &&
+ isApproximatellySameAspectRatio(requestedResolution,
+ supportedInputResolution);
};
if (std::none_of(mSupportedInputConfigurations.begin(),
mSupportedInputConfigurations.end(),
diff --git a/services/camera/virtualcamera/VirtualCameraRenderThread.cc b/services/camera/virtualcamera/VirtualCameraRenderThread.cc
index 218e114..9b0fc07 100644
--- a/services/camera/virtualcamera/VirtualCameraRenderThread.cc
+++ b/services/camera/virtualcamera/VirtualCameraRenderThread.cc
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "system/camera_metadata.h"
#define LOG_TAG "VirtualCameraRenderThread"
#include "VirtualCameraRenderThread.h"
@@ -93,6 +94,8 @@
const Resolution reportedSensorSize) {
std::unique_ptr<CameraMetadata> metadata =
MetadataBuilder()
+ .setAberrationCorrectionMode(
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF)
.setControlAeMode(ANDROID_CONTROL_AE_MODE_ON)
.setControlAePrecaptureTrigger(
ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE)
@@ -109,6 +112,7 @@
.setJpegThumbnailSize(requestSettings.thumbnailResolution.width,
requestSettings.thumbnailResolution.height)
.setJpegThumbnailQuality(requestSettings.thumbnailJpegQuality)
+ .setNoiseReductionMode(ANDROID_NOISE_REDUCTION_MODE_OFF)
.setPipelineDepth(kPipelineDepth)
.setSensorTimestamp(timestamp)
.build();
@@ -510,12 +514,10 @@
return {};
}
- android_ycbcr ycbcr;
- status_t status =
- gBuffer->lockYCbCr(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &ycbcr);
- if (status != NO_ERROR) {
+ YCbCrLockGuard yCbCrLock(inHwBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
+ if (yCbCrLock.getStatus() != NO_ERROR) {
ALOGE("%s: Failed to lock graphic buffer while generating thumbnail: %d",
- __func__, status);
+ __func__, yCbCrLock.getStatus());
return {};
}
@@ -523,9 +525,9 @@
compressedThumbnail.resize(kJpegThumbnailBufferSize);
ALOGE("%s: Compressing thumbnail %d x %d", __func__, gBuffer->getWidth(),
gBuffer->getHeight());
- std::optional<size_t> compressedSize =
- compressJpeg(gBuffer->getWidth(), gBuffer->getHeight(), quality, ycbcr,
- {}, compressedThumbnail.size(), compressedThumbnail.data());
+ std::optional<size_t> compressedSize = compressJpeg(
+ gBuffer->getWidth(), gBuffer->getHeight(), quality, *yCbCrLock, {},
+ compressedThumbnail.size(), compressedThumbnail.data());
if (!compressedSize.has_value()) {
ALOGE("%s: Failed to compress jpeg thumbnail", __func__);
return {};
@@ -570,65 +572,47 @@
return status;
}
- AHardwareBuffer_Planes planes_info;
-
- int32_t rawFence = fence != nullptr ? fence->get() : -1;
- int result = AHardwareBuffer_lockPlanes(hwBuffer.get(),
- AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
- rawFence, nullptr, &planes_info);
- if (result != OK) {
- ALOGE("%s: Failed to lock planes for BLOB buffer: %d", __func__, result);
+ PlanesLockGuard planesLock(hwBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
+ fence);
+ if (planesLock.getStatus() != OK) {
return cameraStatus(Status::INTERNAL_ERROR);
}
std::shared_ptr<AHardwareBuffer> inHwBuffer = framebuffer->getHardwareBuffer();
GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(inHwBuffer.get());
- std::optional<size_t> compressedSize;
- if (gBuffer != nullptr) {
- android_ycbcr ycbcr;
- if (gBuffer->getPixelFormat() != HAL_PIXEL_FORMAT_YCbCr_420_888) {
- // This should never happen since we're allocating the temporary buffer
- // with YUV420 layout above.
- ALOGE("%s: Cannot compress non-YUV buffer (pixelFormat %d)", __func__,
- gBuffer->getPixelFormat());
- AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
- return cameraStatus(Status::INTERNAL_ERROR);
- }
-
- status_t status =
- gBuffer->lockYCbCr(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, &ycbcr);
- ALOGV("Locked buffers");
- if (status != NO_ERROR) {
- AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
- ALOGE("%s: Failed to lock graphic buffer: %d", __func__, status);
- return cameraStatus(Status::INTERNAL_ERROR);
- }
-
- std::vector<uint8_t> app1ExifData =
- createExif(Resolution(stream->width, stream->height),
- createThumbnail(requestSettings.thumbnailResolution,
- requestSettings.thumbnailJpegQuality));
- compressedSize = compressJpeg(
- gBuffer->getWidth(), gBuffer->getHeight(), requestSettings.jpegQuality,
- ycbcr, app1ExifData, stream->bufferSize - sizeof(CameraBlob),
- planes_info.planes[0].data);
-
- status_t res = gBuffer->unlock();
- if (res != NO_ERROR) {
- ALOGE("Failed to unlock graphic buffer: %d", res);
- }
- } else {
- std::vector<uint8_t> app1ExifData =
- createExif(Resolution(stream->width, stream->height));
- compressedSize = compressBlackJpeg(
- stream->width, stream->height, requestSettings.jpegQuality, app1ExifData,
- stream->bufferSize - sizeof(CameraBlob), planes_info.planes[0].data);
+ if (gBuffer == nullptr) {
+ ALOGE(
+ "%s: Encountered invalid temporary buffer while rendering JPEG "
+ "into BLOB stream",
+ __func__);
+ return cameraStatus(Status::INTERNAL_ERROR);
}
+ if (gBuffer->getPixelFormat() != HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ // This should never happen since we're allocating the temporary buffer
+ // with YUV420 layout above.
+ ALOGE("%s: Cannot compress non-YUV buffer (pixelFormat %d)", __func__,
+ gBuffer->getPixelFormat());
+ return cameraStatus(Status::INTERNAL_ERROR);
+ }
+
+ YCbCrLockGuard yCbCrLock(inHwBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
+ if (yCbCrLock.getStatus() != OK) {
+ return cameraStatus(Status::INTERNAL_ERROR);
+ }
+
+ std::vector<uint8_t> app1ExifData =
+ createExif(Resolution(stream->width, stream->height),
+ createThumbnail(requestSettings.thumbnailResolution,
+ requestSettings.thumbnailJpegQuality));
+ std::optional<size_t> compressedSize = compressJpeg(
+ gBuffer->getWidth(), gBuffer->getHeight(), requestSettings.jpegQuality,
+ *yCbCrLock, app1ExifData, stream->bufferSize - sizeof(CameraBlob),
+ (*planesLock).planes[0].data);
+
if (!compressedSize.has_value()) {
ALOGE("%s: Failed to compress JPEG image", __func__);
- AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
return cameraStatus(Status::INTERNAL_ERROR);
}
@@ -636,12 +620,10 @@
.blobId = CameraBlobId::JPEG,
.blobSizeBytes = static_cast<int32_t>(compressedSize.value())};
- memcpy(reinterpret_cast<uint8_t*>(planes_info.planes[0].data) +
+ memcpy(reinterpret_cast<uint8_t*>((*planesLock).planes[0].data) +
(stream->bufferSize - sizeof(cameraBlob)),
&cameraBlob, sizeof(cameraBlob));
- AHardwareBuffer_unlock(hwBuffer.get(), nullptr);
-
ALOGV("%s: Successfully compressed JPEG image, resulting size %zu B",
__func__, compressedSize.value());
diff --git a/services/camera/virtualcamera/VirtualCameraSession.cc b/services/camera/virtualcamera/VirtualCameraSession.cc
index dfa71f3..2a691c1 100644
--- a/services/camera/virtualcamera/VirtualCameraSession.cc
+++ b/services/camera/virtualcamera/VirtualCameraSession.cc
@@ -21,6 +21,7 @@
#include <algorithm>
#include <atomic>
#include <chrono>
+#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -39,6 +40,7 @@
#include "VirtualCameraDevice.h"
#include "VirtualCameraRenderThread.h"
#include "VirtualCameraStream.h"
+#include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h"
#include "aidl/android/hardware/camera/common/Status.h"
#include "aidl/android/hardware/camera/device/BufferCache.h"
#include "aidl/android/hardware/camera/device/BufferStatus.h"
@@ -48,6 +50,7 @@
#include "aidl/android/hardware/camera/device/NotifyMsg.h"
#include "aidl/android/hardware/camera/device/RequestTemplate.h"
#include "aidl/android/hardware/camera/device/ShutterMsg.h"
+#include "aidl/android/hardware/camera/device/Stream.h"
#include "aidl/android/hardware/camera/device/StreamBuffer.h"
#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
#include "aidl/android/hardware/camera/device/StreamRotation.h"
@@ -106,9 +109,6 @@
// Maximum number of buffers to use per single stream.
constexpr size_t kMaxStreamBuffers = 2;
-constexpr int32_t kDefaultJpegQuality = 80;
-constexpr int32_t kDefaultJpegThumbnailQuality = 70;
-
// Thumbnail size (0,0) correspods to disabling thumbnail.
const Resolution kDefaultJpegThumbnailSize(0, 0);
@@ -142,6 +142,8 @@
int maxFps = getMaxFps(inputConfigs);
auto metadata =
MetadataBuilder()
+ .setAberrationCorrectionMode(
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF)
.setControlCaptureIntent(requestTemplateToIntent(type))
.setControlMode(ANDROID_CONTROL_MODE_AUTO)
.setControlAeMode(ANDROID_CONTROL_AE_MODE_ON)
@@ -160,6 +162,7 @@
.setJpegQuality(VirtualCameraDevice::kDefaultJpegQuality)
.setJpegThumbnailQuality(VirtualCameraDevice::kDefaultJpegQuality)
.setJpegThumbnailSize(0, 0)
+ .setNoiseReductionMode(ANDROID_NOISE_REDUCTION_MODE_OFF)
.build();
if (metadata == nullptr) {
ALOGE("%s: Failed to construct metadata for default request type %s",
@@ -201,6 +204,55 @@
}));
}
+Resolution resolutionFromStream(const Stream& stream) {
+ return Resolution(stream.width, stream.height);
+}
+
+Resolution resolutionFromInputConfig(
+ const SupportedStreamConfiguration& inputConfig) {
+ return Resolution(inputConfig.width, inputConfig.height);
+}
+
+std::optional<SupportedStreamConfiguration> pickInputConfigurationForStreams(
+ const std::vector<Stream>& requestedStreams,
+ const std::vector<SupportedStreamConfiguration>& supportedInputConfigs) {
+ Stream maxResolutionStream = getHighestResolutionStream(requestedStreams);
+ Resolution maxResolution = resolutionFromStream(maxResolutionStream);
+
+ // Find best fitting stream to satisfy all requested streams:
+ // Best fitting => same or higher resolution as input with lowest pixel count
+ // difference and same aspect ratio.
+ auto isBetterInputConfig = [maxResolution](
+ const SupportedStreamConfiguration& configA,
+ const SupportedStreamConfiguration& configB) {
+ int maxResPixelCount = maxResolution.width * maxResolution.height;
+ int pixelCountDiffA =
+ std::abs((configA.width * configA.height) - maxResPixelCount);
+ int pixelCountDiffB =
+ std::abs((configB.width * configB.height) - maxResPixelCount);
+
+ return pixelCountDiffA < pixelCountDiffB;
+ };
+
+ std::optional<SupportedStreamConfiguration> bestConfig;
+ for (const SupportedStreamConfiguration& inputConfig : supportedInputConfigs) {
+ Resolution inputConfigResolution = resolutionFromInputConfig(inputConfig);
+ if (inputConfigResolution < maxResolution ||
+ !isApproximatellySameAspectRatio(inputConfigResolution, maxResolution)) {
+ // We don't want to upscale from lower resolution, or use different aspect
+ // ratio, skip.
+ continue;
+ }
+
+ if (!bestConfig.has_value() ||
+ isBetterInputConfig(inputConfig, bestConfig.value())) {
+ bestConfig = inputConfig;
+ }
+ }
+
+ return bestConfig;
+}
+
RequestSettings createSettingsFromMetadata(const CameraMetadata& metadata) {
return RequestSettings{
.jpegQuality = getJpegQuality(metadata).value_or(
@@ -276,15 +328,13 @@
halStreams.clear();
halStreams.resize(in_requestedConfiguration.streams.size());
- sp<Surface> inputSurface = nullptr;
- int inputWidth;
- int inputHeight;
-
if (!virtualCamera->isStreamCombinationSupported(in_requestedConfiguration)) {
ALOGE("%s: Requested stream configuration is not supported", __func__);
return cameraStatus(Status::ILLEGAL_ARGUMENT);
}
+ sp<Surface> inputSurface = nullptr;
+ std::optional<SupportedStreamConfiguration> inputConfig;
{
std::lock_guard<std::mutex> lock(mLock);
for (int i = 0; i < in_requestedConfiguration.streams.size(); ++i) {
@@ -294,14 +344,20 @@
}
}
- Stream maxResStream = getHighestResolutionStream(streams);
- inputWidth = maxResStream.width;
- inputHeight = maxResStream.height;
+ inputConfig = pickInputConfigurationForStreams(
+ streams, virtualCamera->getInputConfigs());
+ if (!inputConfig.has_value()) {
+ ALOGE(
+ "%s: Failed to pick any input configuration for stream configuration "
+ "request: %s",
+ __func__, in_requestedConfiguration.toString().c_str());
+ return cameraStatus(Status::ILLEGAL_ARGUMENT);
+ }
if (mRenderThread == nullptr) {
// If there's no client callback, start camera in test mode.
const bool testMode = mVirtualCameraClientCallback == nullptr;
mRenderThread = std::make_unique<VirtualCameraRenderThread>(
- mSessionContext, Resolution(inputWidth, inputHeight),
+ mSessionContext, resolutionFromInputConfig(*inputConfig),
virtualCamera->getMaxInputResolution(), mCameraDeviceCallback,
testMode);
mRenderThread->start();
@@ -315,7 +371,7 @@
// create single texture.
mVirtualCameraClientCallback->onStreamConfigured(
/*streamId=*/0, aidl::android::view::Surface(inputSurface.get()),
- inputWidth, inputHeight, Format::YUV_420_888);
+ inputConfig->width, inputConfig->height, inputConfig->pixelFormat);
}
return ndk::ScopedAStatus::ok();
diff --git a/services/camera/virtualcamera/flags/Android.bp b/services/camera/virtualcamera/flags/Android.bp
index 5fa8852..5fa53d8 100644
--- a/services/camera/virtualcamera/flags/Android.bp
+++ b/services/camera/virtualcamera/flags/Android.bp
@@ -35,3 +35,27 @@
export_include_dirs: ["."],
defaults: ["virtual_device_build_flags_defaults"],
}
+
+soong_config_module_type {
+ name: "virtual_device_build_flags_java_library",
+ module_type: "java_library",
+ config_namespace: "vdm",
+ bool_variables: [
+ "virtual_camera_service_enabled",
+ ],
+ properties: [
+ "srcs",
+ ],
+}
+
+virtual_device_build_flags_java_library {
+ name: "virtual_device_build_flag_java",
+ soong_config_variables: {
+ virtual_camera_service_enabled: {
+ srcs: ["java/enabled/**/*.java"],
+ conditions_default: {
+ srcs: ["java/disabled/**/*.java"],
+ },
+ },
+ },
+}
diff --git a/services/camera/virtualcamera/flags/java/disabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java b/services/camera/virtualcamera/flags/java/disabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java
new file mode 100644
index 0000000..128d93c
--- /dev/null
+++ b/services/camera/virtualcamera/flags/java/disabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 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.
+ */
+
+package android.companion.virtualdevice.flags;
+
+/** This file is included only if RELEASE_PACKAGE_VIRTUAL_CAMERA build flag isn't set.*/
+public class VirtualCameraServiceBuildFlag {
+
+ public static boolean isVirtualCameraServiceBuildFlagEnabled() {
+ return false;
+ }
+}
diff --git a/services/camera/virtualcamera/flags/java/enabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java b/services/camera/virtualcamera/flags/java/enabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java
new file mode 100644
index 0000000..02816fb
--- /dev/null
+++ b/services/camera/virtualcamera/flags/java/enabled/android/companion/virtualdevice/flags/VirtualCameraServiceBuildFlag.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 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.
+ */
+
+package android.companion.virtualdevice.flags;
+
+/** This file is included only if RELEASE_PACKAGE_VIRTUAL_CAMERA build flag is set.*/
+public class VirtualCameraServiceBuildFlag {
+
+ public static boolean isVirtualCameraServiceBuildFlagEnabled() {
+ return true;
+ }
+}
diff --git a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
index 9146d8a..ad9d83b 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
@@ -55,6 +55,10 @@
camera_metadata_enum_android_scaler_available_stream_configurations_t;
constexpr int kCameraId = 42;
+constexpr int kQvgaWidth = 320;
+constexpr int kQvgaHeight = 240;
+constexpr int k360pWidth = 640;
+constexpr int k360pHeight = 360;
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
constexpr int kHdWidth = 1280;
@@ -79,7 +83,8 @@
const int width;
const int height;
const int pixelFormat;
- const metadata_stream_t streamConfiguration;
+ const metadata_stream_t streamConfiguration =
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
};
bool operator==(const AvailableStreamConfiguration& a,
@@ -173,24 +178,33 @@
.lensFacing = LensFacing::FRONT},
.expectedAvailableStreamConfigs =
{AvailableStreamConfiguration{
- .width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
+ AvailableStreamConfiguration{
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
+ AvailableStreamConfiguration{
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB},
AvailableStreamConfiguration{
.width = kVgaWidth,
.height = kVgaHeight,
.pixelFormat =
- ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
AvailableStreamConfiguration{
.width = kVgaWidth,
.height = kVgaHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
+ AvailableStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB}}},
VirtualCameraConfigTestParam{
.inputConfig =
VirtualCameraConfiguration{
@@ -210,43 +224,70 @@
.lensFacing = LensFacing::BACK},
.expectedAvailableStreamConfigs = {
AvailableStreamConfiguration{
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
+ AvailableStreamConfiguration{
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
+ AvailableStreamConfiguration{
+ .width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB},
+ AvailableStreamConfiguration{
+ .width = 640,
+ .height = 360,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
+ AvailableStreamConfiguration{
+ .width = 640,
+ .height = 360,
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
+ AvailableStreamConfiguration{
+ .width = 640,
+ .height = 360,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB},
+ AvailableStreamConfiguration{
.width = kVgaWidth,
.height = kVgaHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
AvailableStreamConfiguration{
.width = kVgaWidth,
.height = kVgaHeight,
.pixelFormat =
- ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
AvailableStreamConfiguration{
.width = kVgaWidth,
.height = kVgaHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB},
+ AvailableStreamConfiguration{
+ .width = 1024,
+ .height = 576,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
+ AvailableStreamConfiguration{
+ .width = 1024,
+ .height = 576,
+ .pixelFormat =
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
+ AvailableStreamConfiguration{
+ .width = 1024,
+ .height = 576,
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB},
AvailableStreamConfiguration{
.width = kHdWidth,
.height = kHdHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888},
AvailableStreamConfiguration{
.width = kHdWidth,
.height = kHdHeight,
.pixelFormat =
- ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED},
AvailableStreamConfiguration{
.width = kHdWidth,
.height = kHdHeight,
- .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
- .streamConfiguration =
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}}));
+ .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB}}}));
class VirtualCameraDeviceTest : public ::testing::Test {
public:
diff --git a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
index 1af8b80..5f313a0 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
@@ -37,6 +37,8 @@
namespace virtualcamera {
namespace {
+constexpr int kQvgaWidth = 320;
+constexpr int kQvgaHeight = 240;
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
constexpr int kSvgaWidth = 800;
@@ -104,32 +106,13 @@
MOCK_METHOD(ndk::ScopedAStatus, onStreamClosed, (int), (override));
};
-class VirtualCameraSessionTest : public ::testing::Test {
+class VirtualCameraSessionTestBase : public ::testing::Test {
public:
- void SetUp() override {
+ virtual void SetUp() override {
mMockCameraDeviceCallback =
ndk::SharedRefBase::make<MockCameraDeviceCallback>();
mMockVirtualCameraClientCallback =
ndk::SharedRefBase::make<MockVirtualCameraCallback>();
- mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
- kCameraId,
- VirtualCameraConfiguration{
- .supportedStreamConfigs = {SupportedStreamConfiguration{
- .width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = Format::YUV_420_888,
- .maxFps = kMaxFps},
- SupportedStreamConfiguration{
- .width = kSvgaWidth,
- .height = kSvgaHeight,
- .pixelFormat = Format::YUV_420_888,
- .maxFps = kMaxFps}},
- .virtualCameraCallback = nullptr,
- .sensorOrientation = SensorOrientation::ORIENTATION_0,
- .lensFacing = LensFacing::FRONT});
- mVirtualCameraSession = ndk::SharedRefBase::make<VirtualCameraSession>(
- mVirtualCameraDevice, mMockCameraDeviceCallback,
- mMockVirtualCameraClientCallback);
// Explicitly defining default actions below to prevent gmock from
// default-constructing ndk::ScopedAStatus, because default-constructed
@@ -155,6 +138,35 @@
protected:
std::shared_ptr<MockCameraDeviceCallback> mMockCameraDeviceCallback;
std::shared_ptr<MockVirtualCameraCallback> mMockVirtualCameraClientCallback;
+};
+
+class VirtualCameraSessionTest : public VirtualCameraSessionTestBase {
+ public:
+ void SetUp() override {
+ VirtualCameraSessionTestBase::SetUp();
+
+ mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
+ kCameraId,
+ VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps},
+ SupportedStreamConfiguration{
+ .width = kSvgaWidth,
+ .height = kSvgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = mMockVirtualCameraClientCallback,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0,
+ .lensFacing = LensFacing::FRONT});
+ mVirtualCameraSession = ndk::SharedRefBase::make<VirtualCameraSession>(
+ mVirtualCameraDevice, mMockCameraDeviceCallback,
+ mMockVirtualCameraClientCallback);
+ }
+
+ protected:
std::shared_ptr<VirtualCameraDevice> mVirtualCameraDevice;
std::shared_ptr<VirtualCameraSession> mVirtualCameraSession;
};
@@ -272,6 +284,97 @@
Eq(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)));
}
+TEST_F(VirtualCameraSessionTest, ConfigureWithDifferentAspectRatioFails) {
+ StreamConfiguration streamConfiguration;
+ streamConfiguration.streams = {
+ createStream(kStreamId, kVgaWidth, kVgaHeight, PixelFormat::YCBCR_420_888),
+ createStream(kSecondStreamId, kVgaHeight, kVgaWidth,
+ PixelFormat::YCBCR_420_888)};
+
+ std::vector<HalStream> halStreams;
+
+ // Expect configuration attempt returns CAMERA_DISCONNECTED service specific code.
+ EXPECT_THAT(
+ mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
+ .getServiceSpecificError(),
+ Eq(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)));
+}
+
+class VirtualCameraSessionInputChoiceTest : public VirtualCameraSessionTestBase {
+ public:
+ std::shared_ptr<VirtualCameraSession> createSession(
+ const std::vector<SupportedStreamConfiguration>& supportedInputConfigs) {
+ mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
+ kCameraId, VirtualCameraConfiguration{
+ .supportedStreamConfigs = supportedInputConfigs,
+ .virtualCameraCallback = mMockVirtualCameraClientCallback,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0,
+ .lensFacing = LensFacing::FRONT});
+ return ndk::SharedRefBase::make<VirtualCameraSession>(
+ mVirtualCameraDevice, mMockCameraDeviceCallback,
+ mMockVirtualCameraClientCallback);
+ }
+
+ protected:
+ std::shared_ptr<VirtualCameraDevice> mVirtualCameraDevice;
+};
+
+TEST_F(VirtualCameraSessionInputChoiceTest,
+ configureChoosesCorrectInputStreamForDownsampledOutput) {
+ // Create camera configured to support SVGA YUV input and RGB QVGA input.
+ auto virtualCameraSession = createSession(
+ {SupportedStreamConfiguration{.width = kSvgaWidth,
+ .height = kSvgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps},
+ SupportedStreamConfiguration{.width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat = Format::RGBA_8888,
+ .maxFps = kMaxFps}});
+
+ // Configure VGA stream. Expect SVGA input to be chosen to downscale from.
+ StreamConfiguration streamConfiguration;
+ streamConfiguration.streams = {createStream(
+ kStreamId, kVgaWidth, kVgaHeight, PixelFormat::IMPLEMENTATION_DEFINED)};
+ std::vector<HalStream> halStreams;
+
+ // Expect configuration attempt returns CAMERA_DISCONNECTED service specific code.
+ EXPECT_CALL(*mMockVirtualCameraClientCallback,
+ onStreamConfigured(kStreamId, _, kSvgaWidth, kSvgaHeight,
+ Format::YUV_420_888));
+ EXPECT_TRUE(
+ virtualCameraSession->configureStreams(streamConfiguration, &halStreams)
+ .isOk());
+}
+
+TEST_F(VirtualCameraSessionInputChoiceTest,
+ configureChoosesCorrectInputStreamForMatchingResolution) {
+ // Create camera configured to support SVGA YUV input and RGB QVGA input.
+ auto virtualCameraSession = createSession(
+ {SupportedStreamConfiguration{.width = kSvgaWidth,
+ .height = kSvgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps},
+ SupportedStreamConfiguration{.width = kQvgaWidth,
+ .height = kQvgaHeight,
+ .pixelFormat = Format::RGBA_8888,
+ .maxFps = kMaxFps}});
+
+ // Configure VGA stream. Expect SVGA input to be chosen to downscale from.
+ StreamConfiguration streamConfiguration;
+ streamConfiguration.streams = {createStream(
+ kStreamId, kQvgaWidth, kQvgaHeight, PixelFormat::IMPLEMENTATION_DEFINED)};
+ std::vector<HalStream> halStreams;
+
+ // Expect configuration attempt returns CAMERA_DISCONNECTED service specific code.
+ EXPECT_CALL(*mMockVirtualCameraClientCallback,
+ onStreamConfigured(kStreamId, _, kQvgaWidth, kQvgaHeight,
+ Format::RGBA_8888));
+ EXPECT_TRUE(
+ virtualCameraSession->configureStreams(streamConfiguration, &halStreams)
+ .isOk());
+}
+
} // namespace
} // namespace virtualcamera
} // namespace companion
diff --git a/services/camera/virtualcamera/util/JpegUtil.cc b/services/camera/virtualcamera/util/JpegUtil.cc
index 98f2448..8569eff 100644
--- a/services/camera/virtualcamera/util/JpegUtil.cc
+++ b/services/camera/virtualcamera/util/JpegUtil.cc
@@ -153,18 +153,6 @@
return compress(yLines, cbLines, crLines);
}
- std::optional<size_t> compressBlackImage() {
- // We only really need to prepare one scanline for Y and one shared scanline
- // for Cb & Cr.
- std::vector<uint8_t> yLine(mWidth, 0);
- std::vector<uint8_t> chromaLine(mWidth / 2, 0xff / 2);
-
- std::vector<JSAMPROW> yLines(mHeight, yLine.data());
- std::vector<JSAMPROW> cLines(mHeight / 2, chromaLine.data());
-
- return compress(yLines, cLines, cLines);
- }
-
private:
void setSuccess(const boolean success) {
mSuccess = success;
@@ -279,17 +267,6 @@
return context.compress(ycbcr);
}
-std::optional<size_t> compressBlackJpeg(const int width, const int height,
- const int quality,
- const std::vector<uint8_t>& app1ExifData,
- size_t outBufferSize, void* outBuffer) {
- LibJpegContext context(width, height, quality, outBufferSize, outBuffer);
- if (!app1ExifData.empty()) {
- context.setApp1Data(app1ExifData.data(), app1ExifData.size());
- }
- return context.compressBlackImage();
-}
-
} // namespace virtualcamera
} // namespace companion
} // namespace android
diff --git a/services/camera/virtualcamera/util/JpegUtil.h b/services/camera/virtualcamera/util/JpegUtil.h
index e64fb4f..83ed74b 100644
--- a/services/camera/virtualcamera/util/JpegUtil.h
+++ b/services/camera/virtualcamera/util/JpegUtil.h
@@ -17,10 +17,8 @@
#ifndef ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
#define ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
-#include <memory>
#include <optional>
-#include "android/hardware_buffer.h"
#include "system/graphics.h"
namespace android {
@@ -43,20 +41,6 @@
const std::vector<uint8_t>& app1ExifData,
size_t outBufferSize, void* outBuffer);
-// Jpeg-compress all-black image into the output buffer.
-// * width - width of the image
-// * heigh - height of the image
-// * quality - 0-100, higher number corresponds to higher quality.
-// * app1ExifData - vector containing data to be included in APP1
-// segment. Can be empty.
-// * outBufferSize - capacity of the output buffer.
-// * outBuffer - output buffer to write compressed data into.
-// Returns size of compressed data if the compression was successful,
-// empty optional otherwise.
-std::optional<size_t> compressBlackJpeg(int width, int height, int quality,
- const std::vector<uint8_t>& app1ExifData,
- size_t outBufferSize, void* outBuffer);
-
} // namespace virtualcamera
} // namespace companion
} // namespace android
diff --git a/services/camera/virtualcamera/util/MetadataUtil.cc b/services/camera/virtualcamera/util/MetadataUtil.cc
index d223f17..e3d9e28 100644
--- a/services/camera/virtualcamera/util/MetadataUtil.cc
+++ b/services/camera/virtualcamera/util/MetadataUtil.cc
@@ -481,6 +481,56 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setAvailableAberrationCorrectionModes(
+ const std::vector<camera_metadata_enum_android_color_correction_aberration_mode>&
+ aberrationCorectionModes) {
+ mEntryMap[ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES] =
+ convertTo<uint8_t>(aberrationCorectionModes);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setAberrationCorrectionMode(
+ const camera_metadata_enum_android_color_correction_aberration_mode
+ aberrationCorrectionMode) {
+ mEntryMap[ANDROID_COLOR_CORRECTION_ABERRATION_MODE] =
+ asVectorOf<uint8_t>(aberrationCorrectionMode);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setAvailableNoiseReductionModes(
+ const std::vector<camera_metadata_enum_android_noise_reduction_mode>&
+ noiseReductionModes) {
+ mEntryMap[ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES] =
+ convertTo<uint8_t>(noiseReductionModes);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setNoiseReductionMode(
+ camera_metadata_enum_android_noise_reduction_mode noiseReductionMode) {
+ mEntryMap[ANDROID_NOISE_REDUCTION_MODE] =
+ asVectorOf<uint8_t>(noiseReductionMode);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setRequestPartialResultCount(
+ const int partialResultCount) {
+ mEntryMap[ANDROID_REQUEST_PARTIAL_RESULT_COUNT] =
+ asVectorOf<int32_t>(partialResultCount);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setCroppingType(
+ const camera_metadata_enum_android_scaler_cropping_type croppingType) {
+ mEntryMap[ANDROID_SCALER_CROPPING_TYPE] = asVectorOf<uint8_t>(croppingType);
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setMaxFaceCount(const int maxFaceCount) {
+ mEntryMap[ANDROID_STATISTICS_INFO_MAX_FACE_COUNT] =
+ asVectorOf<int32_t>(maxFaceCount);
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setAvailableMaxDigitalZoom(const float maxZoom) {
mEntryMap[ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] =
asVectorOf<float>(maxZoom);
diff --git a/services/camera/virtualcamera/util/MetadataUtil.h b/services/camera/virtualcamera/util/MetadataUtil.h
index 9ddfd81..b4d60cb 100644
--- a/services/camera/virtualcamera/util/MetadataUtil.h
+++ b/services/camera/virtualcamera/util/MetadataUtil.h
@@ -149,6 +149,36 @@
MetadataBuilder& setAvailableOutputStreamConfigurations(
const std::vector<StreamConfiguration>& streamConfigurations);
+ // See COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES in CameraCharacteristics.java.
+ MetadataBuilder& setAvailableAberrationCorrectionModes(
+ const std::vector<
+ camera_metadata_enum_android_color_correction_aberration_mode>&
+ aberrationCorectionModes);
+
+ // See COLOR_CORRECTION_ABERRATION_MODE in CaptureRequest.java.
+ MetadataBuilder& setAberrationCorrectionMode(
+ camera_metadata_enum_android_color_correction_aberration_mode
+ aberrationCorrectionMode);
+
+ // See NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES in CameraCharacteristics.java.
+ MetadataBuilder& setAvailableNoiseReductionModes(
+ const std::vector<camera_metadata_enum_android_noise_reduction_mode>&
+ noiseReductionModes);
+
+ // See NOISE_REDUCTION_MODE in CaptureRequest.java.
+ MetadataBuilder& setNoiseReductionMode(
+ camera_metadata_enum_android_noise_reduction_mode noiseReductionMode);
+
+ // See REQUEST_PARTIAL_RESULT_COUNT in CameraCharacteristics.java.
+ MetadataBuilder& setRequestPartialResultCount(int partialResultCount);
+
+ // See SCALER_CROPPING_TYPE in CameraCharacteristics.java.
+ MetadataBuilder& setCroppingType(
+ camera_metadata_enum_android_scaler_cropping_type croppingType);
+
+ // See STATISTICS_INFO_MAX_FACE_COUNT in CameraCharacteristic.java.
+ MetadataBuilder& setMaxFaceCount(int maxFaceCount);
+
// See ANDROID_CONTROL_AVAILABLE_MODES in CameraMetadataTag.aidl.
MetadataBuilder& setControlAvailableModes(
const std::vector<camera_metadata_enum_android_control_mode_t>&
diff --git a/services/camera/virtualcamera/util/Util.cc b/services/camera/virtualcamera/util/Util.cc
index ef986a6..b2048bc 100644
--- a/services/camera/virtualcamera/util/Util.cc
+++ b/services/camera/virtualcamera/util/Util.cc
@@ -20,8 +20,13 @@
#include <algorithm>
#include <array>
+#include <cstdint>
+#include <memory>
+#include "android/hardware_buffer.h"
#include "jpeglib.h"
+#include "ui/GraphicBuffer.h"
+#include "utils/Errors.h"
namespace android {
namespace companion {
@@ -40,6 +45,82 @@
constexpr std::array<Format, 2> kSupportedFormats{Format::YUV_420_888,
Format::RGBA_8888};
+YCbCrLockGuard::YCbCrLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer,
+ const uint32_t usageFlags)
+ : mHwBuffer(hwBuffer) {
+ GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(mHwBuffer.get());
+ if (gBuffer == nullptr) {
+ ALOGE("%s: Attempting to lock nullptr buffer.", __func__);
+ return;
+ }
+ mLockStatus = gBuffer->lockYCbCr(usageFlags, &mYCbCr);
+ if (mLockStatus != OK) {
+ ALOGE("%s: Failed to lock graphic buffer: %s", __func__,
+ statusToString(mLockStatus).c_str());
+ }
+}
+
+YCbCrLockGuard::~YCbCrLockGuard() {
+ if (getStatus() != OK) {
+ return;
+ }
+
+ GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(mHwBuffer.get());
+ if (gBuffer == nullptr) {
+ return;
+ }
+ gBuffer->unlock();
+ status_t status = gBuffer->unlock();
+ if (status != NO_ERROR) {
+ ALOGE("Failed to unlock graphic buffer: %s", statusToString(status).c_str());
+ }
+}
+
+status_t YCbCrLockGuard::getStatus() const {
+ return mLockStatus;
+}
+
+const android_ycbcr& YCbCrLockGuard::operator*() const {
+ LOG_ALWAYS_FATAL_IF(getStatus() != OK,
+ "Dereferencing unlocked YCbCrLockGuard, status is %s",
+ statusToString(mLockStatus).c_str());
+ return mYCbCr;
+}
+
+PlanesLockGuard::PlanesLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer,
+ const uint64_t usageFlags, sp<Fence> fence) {
+ if (hwBuffer == nullptr) {
+ ALOGE("%s: Attempting to lock nullptr buffer.", __func__);
+ return;
+ }
+
+ const int32_t rawFence = fence != nullptr ? fence->get() : -1;
+ mLockStatus = static_cast<status_t>(AHardwareBuffer_lockPlanes(
+ hwBuffer.get(), usageFlags, rawFence, nullptr, &mPlanes));
+ if (mLockStatus != OK) {
+ ALOGE("%s: Failed to lock graphic buffer: %s", __func__,
+ statusToString(mLockStatus).c_str());
+ }
+}
+
+PlanesLockGuard::~PlanesLockGuard() {
+ if (getStatus() != OK || mHwBuffer == nullptr) {
+ return;
+ }
+ AHardwareBuffer_unlock(mHwBuffer.get(), /*fence=*/nullptr);
+}
+
+int PlanesLockGuard::getStatus() const {
+ return mLockStatus;
+}
+
+const AHardwareBuffer_Planes& PlanesLockGuard::operator*() const {
+ LOG_ALWAYS_FATAL_IF(getStatus() != OK,
+ "Dereferencing unlocked PlanesLockGuard, status is %s",
+ statusToString(mLockStatus).c_str());
+ return mPlanes;
+}
+
sp<Fence> importFence(const NativeHandle& aidlHandle) {
if (aidlHandle.fds.size() != 1) {
return sp<Fence>::make();
diff --git a/services/camera/virtualcamera/util/Util.h b/services/camera/virtualcamera/util/Util.h
index 15f7969..faae010 100644
--- a/services/camera/virtualcamera/util/Util.h
+++ b/services/camera/virtualcamera/util/Util.h
@@ -17,18 +17,82 @@
#ifndef ANDROID_COMPANION_VIRTUALCAMERA_UTIL_H
#define ANDROID_COMPANION_VIRTUALCAMERA_UTIL_H
+#include <cmath>
#include <cstdint>
+#include <memory>
#include "aidl/android/companion/virtualcamera/Format.h"
#include "aidl/android/hardware/camera/common/Status.h"
#include "aidl/android/hardware/camera/device/StreamBuffer.h"
#include "android/binder_auto_utils.h"
+#include "android/hardware_buffer.h"
+#include "system/graphics.h"
#include "ui/Fence.h"
namespace android {
namespace companion {
namespace virtualcamera {
+// RAII utility class to safely lock AHardwareBuffer and obtain android_ycbcr
+// structure describing YUV plane layout.
+//
+// Access to the buffer is locked immediatelly afer construction.
+class YCbCrLockGuard {
+ public:
+ YCbCrLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer, uint32_t usageFlags);
+ YCbCrLockGuard(YCbCrLockGuard&& other) = default;
+ ~YCbCrLockGuard();
+
+ // Returns OK if the buffer is successfully locked.
+ status_t getStatus() const;
+
+ // Dereferencing instance of this guard returns android_ycbcr structure
+ // describing the layout.
+ // Caller needs to check whether the buffer was successfully locked
+ // before dereferencing.
+ const android_ycbcr& operator*() const;
+
+ // Disable copy.
+ YCbCrLockGuard(const YCbCrLockGuard&) = delete;
+ YCbCrLockGuard& operator=(const YCbCrLockGuard&) = delete;
+
+ private:
+ std::shared_ptr<AHardwareBuffer> mHwBuffer;
+ android_ycbcr mYCbCr = {};
+ status_t mLockStatus = DEAD_OBJECT;
+};
+
+// RAII utility class to safely lock AHardwareBuffer and obtain
+// AHardwareBuffer_Planes (Suitable for interacting with RGBA / BLOB buffers.
+//
+// Access to the buffer is locked immediatelly afer construction.
+class PlanesLockGuard {
+ public:
+ PlanesLockGuard(std::shared_ptr<AHardwareBuffer> hwBuffer,
+ uint64_t usageFlags, sp<Fence> fence = nullptr);
+ PlanesLockGuard(PlanesLockGuard&& other) = default;
+ ~PlanesLockGuard();
+
+ // Returns OK if the buffer is successfully locked.
+ status_t getStatus() const;
+
+ // Dereferencing instance of this guard returns AHardwareBuffer_Planes
+ // structure describing the layout.
+ //
+ // Caller needs to check whether the buffer was successfully locked
+ // before dereferencing.
+ const AHardwareBuffer_Planes& operator*() const;
+
+ // Disable copy.
+ PlanesLockGuard(const PlanesLockGuard&) = delete;
+ PlanesLockGuard& operator=(const YCbCrLockGuard&) = delete;
+
+ private:
+ std::shared_ptr<AHardwareBuffer> mHwBuffer;
+ AHardwareBuffer_Planes mPlanes;
+ status_t mLockStatus = DEAD_OBJECT;
+};
+
// Converts camera AIDL status to ndk::ScopedAStatus
inline ndk::ScopedAStatus cameraStatus(
const ::aidl::android::hardware::camera::common::Status status) {
@@ -66,6 +130,10 @@
: pixCount < otherPixCount;
}
+ bool operator<=(const Resolution& other) const {
+ return *this == other || *this < other;
+ }
+
bool operator==(const Resolution& other) const {
return width == other.width && height == other.height;
}
@@ -74,6 +142,17 @@
int height = 0;
};
+inline bool isApproximatellySameAspectRatio(const Resolution r1,
+ const Resolution r2) {
+ static constexpr float kAspectRatioEpsilon = 0.05;
+ float aspectRatio1 =
+ static_cast<float>(r1.width) / static_cast<float>(r1.height);
+ float aspectRatio2 =
+ static_cast<float>(r2.width) / static_cast<float>(r2.height);
+
+ return std::abs(aspectRatio1 - aspectRatio2) < kAspectRatioEpsilon;
+}
+
std::ostream& operator<<(std::ostream& os, const Resolution& resolution);
} // namespace virtualcamera
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.cpp b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
index d24a3c9..cd00937 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.cpp
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.cpp
@@ -447,6 +447,42 @@
#endif
}
+inline void pushReclaimStats(int32_t callingPid,
+ int32_t requesterUid,
+ int requesterPriority,
+ const std::string& clientName,
+ int32_t noOfConcurrentCodecs,
+ int32_t reclaimStatus,
+ int32_t noOfCodecsReclaimed = 0,
+ int32_t targetIndex = -1,
+ int32_t targetClientPid = -1,
+ int32_t targetClientUid = -1,
+ int32_t targetPriority = -1) {
+ // Post the pushed atom
+ int result = stats_write(
+ MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
+ requesterUid,
+ requesterPriority,
+ clientName.c_str(),
+ noOfConcurrentCodecs,
+ reclaimStatus,
+ noOfCodecsReclaimed,
+ targetIndex,
+ targetClientUid,
+ targetPriority);
+ ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
+ "Requester[pid(%d): uid(%d): priority(%d)] "
+ "Codec: [%s] "
+ "No of concurrent codecs: %d "
+ "Reclaim Status: %d "
+ "No of codecs reclaimed: %d "
+ "Target[%d][pid(%d): uid(%d): priority(%d)] result: %d",
+ __func__, callingPid, requesterUid, requesterPriority,
+ clientName.c_str(), noOfConcurrentCodecs,
+ reclaimStatus, noOfCodecsReclaimed,
+ targetIndex, targetClientPid, targetClientUid, targetPriority, result);
+}
+
void ResourceManagerMetrics::pushReclaimAtom(const ClientInfoParcel& clientInfo,
const std::vector<int>& priorities,
const std::vector<ClientInfo>& targetClients,
@@ -485,33 +521,34 @@
MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED__RECLAIM_STATUS__RECLAIM_FAILED_RECLAIM_RESOURCES;
}
}
+
+ if (targetClients.empty()) {
+ // Push the reclaim atom to stats.
+ pushReclaimStats(callingPid,
+ requesterUid,
+ requesterPriority,
+ clientName,
+ noOfConcurrentCodecs,
+ reclaimStatus);
+ return;
+ }
+
int32_t noOfCodecsReclaimed = targetClients.size();
int32_t targetIndex = 1;
for (const ClientInfo& targetClient : targetClients) {
int targetPriority = priorities[targetIndex];
- // Post the pushed atom
- int result = stats_write(
- MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED,
- requesterUid,
- requesterPriority,
- clientName.c_str(),
- noOfConcurrentCodecs,
- reclaimStatus,
- noOfCodecsReclaimed,
- targetIndex,
- targetClient.mUid,
- targetPriority);
- ALOGI("%s: Pushed MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED atom: "
- "Requester[pid(%d): uid(%d): priority(%d)] "
- "Codec: [%s] "
- "No of concurrent codecs: %d "
- "Reclaim Status: %d "
- "No of codecs reclaimed: %d "
- "Target[%d][pid(%d): uid(%d): priority(%d)] result: %d",
- __func__, callingPid, requesterUid, requesterPriority,
- clientName.c_str(), noOfConcurrentCodecs,
- reclaimStatus, noOfCodecsReclaimed,
- targetIndex, targetClient.mPid, targetClient.mUid, targetPriority, result);
+ // Push the reclaim atom to stats.
+ pushReclaimStats(callingPid,
+ requesterUid,
+ requesterPriority,
+ clientName,
+ noOfConcurrentCodecs,
+ reclaimStatus,
+ noOfCodecsReclaimed,
+ targetIndex,
+ targetClient.mPid,
+ targetClient.mUid,
+ targetPriority);
targetIndex++;
}
}
diff --git a/services/mediaresourcemanager/ResourceManagerMetrics.h b/services/mediaresourcemanager/ResourceManagerMetrics.h
index a9bc34b..7a5a89f 100644
--- a/services/mediaresourcemanager/ResourceManagerMetrics.h
+++ b/services/mediaresourcemanager/ResourceManagerMetrics.h
@@ -96,7 +96,32 @@
};
//
-// ResourceManagerMetrics class that maintaines concurrent codec count based:
+// Resource Manager Metrics is designed to answer some of the questions like:
+// - What apps are causing reclaim and what apps are targeted (reclaimed from) in the process?
+// - which apps use the most codecs and the most codec memory?
+// - What is the % of total successful reclaims?
+//
+// Though, it's not in the context of this class, metrics should also answer:
+// - what % of codec errors are due to codec being reclaimed?
+// - What % of successful codec creation(start) requires codec reclaims?
+// - How often codec start fails even after successful reclaim?
+//
+// The metrics are collected to analyze and understand the codec resource usage
+// and use that information to help with:
+// - minimize the no of reclaims
+// - reduce the codec start delays by minimizing no of times we try to reclaim
+// - minimize the reclaim errors in codec records
+//
+// Success metrics for Resource Manager Service could be defined as:
+// - increase in sucecssful codec creation for the foreground apps
+// - reduce the number of reclaims for codecs
+// - reduce the time to create codec
+//
+// We would like to use this data to come up with a better resource management that would:
+// - increase the successful codec creation (for all kind of apps)
+// - decrease the codec errors due to resources
+//
+// This class that maintains concurrent codec counts based on:
//
// 1. # of concurrent active codecs (initialized, but aren't released yet) of given
// implementation (by codec name) across the system.
@@ -111,7 +136,7 @@
// This should help with understanding the (video) memory usage per
// application.
//
-//
+
class ResourceManagerMetrics {
public:
ResourceManagerMetrics(const sp<ProcessInfoInterface>& processInfo);
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 305f6fe..d37d893 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -586,18 +586,21 @@
// Check if there are any resources to be reclaimed before processing.
if (resources.empty()) {
+ // Invalid reclaim request. So no need to log.
return Status::ok();
}
std::vector<ClientInfo> targetClients;
- if (!getTargetClients(clientInfo, resources, targetClients)) {
- // Nothing to reclaim from.
+ if (getTargetClients(clientInfo, resources, targetClients)) {
+ // Reclaim all the target clients.
+ *_aidl_return = reclaimUnconditionallyFrom(targetClients);
+ } else {
+ // No clients to reclaim from.
ALOGI("%s: There aren't any clients to reclaim from", __func__);
- return Status::ok();
+ // We need to log this failed reclaim as "no clients to reclaim from".
+ targetClients.clear();
}
- *_aidl_return = reclaimUnconditionallyFrom(targetClients);
-
// Log Reclaim Pushed Atom to statsd
pushReclaimAtom(clientInfo, targetClients, *_aidl_return);