Merge "Extend output format with downscalable resolutions" into main
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/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/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/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index d723493..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",
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 4bc5c8a..d1b1849 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -66,113 +66,183 @@
using media::audio::common::Int;
std::mutex AudioSystem::gMutex;
-sp<IAudioFlinger> AudioSystem::gAudioFlinger;
-sp<IBinder> AudioSystem::gAudioFlingerBinder;
-sp<IAudioFlinger> AudioSystem::gLocalAudioFlinger;
-sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
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;
+std::mutex AudioSystem::gApsCallbackMutex;
std::mutex AudioSystem::gErrorCallbacksMutex;
std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
std::mutex AudioSystem::gSoundTriggerMutex;
sp<CaptureStateListenerImpl> AudioSystem::gSoundTriggerCaptureStateListener;
-std::mutex AudioSystem::gAPSMutex;
-sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
-sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;
-
// 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.
-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;
- }
- std::lock_guard _l(gMutex);
- if (gAudioFlinger != nullptr) {
- ALOGW("setAudioFlingerBinder: ignoring; AudioFlinger connection already established.");
- return;
- }
- gAudioFlingerBinder = audioFlinger;
-}
+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;
-status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) {
- std::lock_guard _l(gMutex);
- 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;
- {
- std::lock_guard _l(gMutex);
- 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 getAudioFlingerImpl();
+ return gAudioFlingerServiceHandler.getService();
}
sp<IAudioFlinger> AudioSystem::get_audio_flinger_for_fuzzer() {
- return getAudioFlingerImpl(false);
+ return gAudioFlingerServiceHandler.getService(false /* canStartThreadPool */);
}
-const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
- // calling get_audio_flinger() will initialize gAudioFlingerClient if needed
- const sp<IAudioFlinger> af = get_audio_flinger();
- if (af == 0) return 0;
- std::lock_guard _l(gMutex);
- return gAudioFlingerClient;
+sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
+ return gAudioFlingerServiceHandler.getClient();
+}
+
+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) {
@@ -557,14 +627,7 @@
}
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) {
- {
- std::lock_guard _l(AudioSystem::gMutex);
- AudioSystem::gAudioFlinger.clear();
- }
-
- // clear output handles and stream to output map caches
- clearIoCache();
-
+ gAudioFlingerServiceHandler.clearService();
reportError(DEAD_OBJECT);
ALOGW("AudioFlinger server died!");
@@ -863,44 +926,35 @@
gVolRangeInitReqCallback = cb;
}
-// establish binder interface to AudioPolicy service
-sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() {
- sp<IAudioPolicyService> ap;
- sp<AudioPolicyServiceClient> apc;
- {
- std::lock_guard _l(gAPSMutex);
- 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() {
- std::lock_guard _l(gAPSMutex);
- gAudioPolicyService.clear();
+ gAudioPolicyServiceHandler.clearService();
}
// ---------------------------------------------------------------------------
@@ -1501,13 +1555,7 @@
void AudioSystem::clearAudioConfigCache() {
// called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances
ALOGV("clearAudioConfigCache()");
- {
- std::lock_guard _l(gMutex);
- if (gAudioFlingerClient != 0) {
- gAudioFlingerClient->clearIoCache();
- }
- gAudioFlinger.clear();
- }
+ gAudioFlingerServiceHandler.clearService();
clearAudioPolicyService();
}
@@ -1670,12 +1718,11 @@
status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callback) {
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;
- std::lock_guard _l(gAPSMutex);
- 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);
}
@@ -1686,12 +1733,11 @@
status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callback) {
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;
- std::lock_guard _l(gAPSMutex);
- 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);
}
@@ -1701,12 +1747,11 @@
status_t AudioSystem::addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
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;
- std::lock_guard _l(gAPSMutex);
- 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);
}
@@ -1716,12 +1761,11 @@
status_t AudioSystem::removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
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;
- std::lock_guard _l(gAPSMutex);
- 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);
}
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 3061633..338534d 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -100,6 +100,10 @@
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
@@ -407,6 +411,11 @@
// and output configuration cache (gOutputs)
static void clearAudioConfigCache();
+ // 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();
@@ -781,8 +790,6 @@
static int32_t getAAudioHardwareBurstMinUsec();
-private:
-
class AudioFlingerClient: public IBinder::DeathRecipient, public media::BnAudioFlingerClient
{
public:
@@ -892,24 +899,22 @@
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);
[[clang::no_destroy]] static std::mutex gMutex;
- [[clang::no_destroy]] static sp<IAudioFlinger> gAudioFlinger GUARDED_BY(gMutex);
- [[clang::no_destroy]] static sp<IBinder> gAudioFlingerBinder GUARDED_BY(gMutex);
- [[clang::no_destroy]] static sp<IAudioFlinger> gLocalAudioFlinger GUARDED_BY(gMutex);
- [[clang::no_destroy]] static sp<AudioFlingerClient> gAudioFlingerClient GUARDED_BY(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);
+ [[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);
@@ -917,12 +922,6 @@
[[clang::no_destroy]] static std::mutex gSoundTriggerMutex;
[[clang::no_destroy]] static sp<CaptureStateListenerImpl> gSoundTriggerCaptureStateListener
GUARDED_BY(gSoundTriggerMutex);
-
- [[clang::no_destroy]] static std::mutex gAPSMutex;
- [[clang::no_destroy]] static sp<media::IAudioPolicyService> gAudioPolicyService
- GUARDED_BY(gAPSMutex);
- [[clang::no_destroy]] static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient
- GUARDED_BY(gAPSMutex);
};
} // namespace android
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/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/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/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))
) {