[automerger skipped] Merge "AudioFlinger: clean up ctor initialization" into main am: d631feb86e am: 65d3e8c7d7 -s ours
am skip reason: Merged-In Idd3be2e20eb90dff7f794aad096b286b2cd7d938 with SHA-1 92653e55e6 is already in history
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/2779352
Change-Id: I07d6b74f16b79ada806e652b97516a7779d52b6b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 24a11e3..921aab2 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -177,6 +177,7 @@
shared_libs: [
"libcamera2ndk_vendor",
"libcamera_metadata",
+ "libhidlbase",
"libmediandk",
"libnativewindow",
"libutils",
@@ -186,6 +187,7 @@
],
static_libs: [
"android.hardware.camera.common@1.0-helper",
+ "android.hidl.token@1.0",
],
cflags: [
"-D__ANDROID_VNDK__",
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index bd679e5..fe0ef67 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -584,6 +584,19 @@
* <p>Only constrains auto-exposure (AE) algorithm, not
* manual control of ACAMERA_SENSOR_EXPOSURE_TIME and
* ACAMERA_SENSOR_FRAME_DURATION.</p>
+ * <p>Note that the actual achievable max framerate also depends on the minimum frame
+ * duration of the output streams. The max frame rate will be
+ * <code>min(aeTargetFpsRange.maxFps, 1 / max(individual stream min durations)</code>. For example,
+ * if the application sets this key to <code>{60, 60}</code>, but the maximum minFrameDuration among
+ * all configured streams is 33ms, the maximum framerate won't be 60fps, but will be
+ * 30fps.</p>
+ * <p>To start a CaptureSession with a target FPS range different from the
+ * capture request template's default value, the application
+ * is strongly recommended to call
+ * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+ * with the target fps range before creating the capture session. The aeTargetFpsRange is
+ * typically a session parameter. Specifying it at session creation time helps avoid
+ * session reconfiguration delays in cases like 60fps or high speed recording.</p>
*
* @see ACAMERA_SENSOR_EXPOSURE_TIME
* @see ACAMERA_SENSOR_FRAME_DURATION
@@ -1128,6 +1141,12 @@
* ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE field will return
* OFF if the recording output is not stabilized, or if there are no output
* Surface types that can be stabilized.</p>
+ * <p>The application is strongly recommended to call
+ * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+ * with the desired video stabilization mode before creating the capture session.
+ * Video stabilization mode is a session parameter on many devices. Specifying
+ * it at session creation time helps avoid reconfiguration delay caused by difference
+ * between the default value and the first CaptureRequest.</p>
* <p>If a camera device supports both this mode and OIS
* (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
* produce undesirable interaction, so it is recommended not to enable
@@ -5384,7 +5403,7 @@
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_DEFAULT">CameraMetadata#SENSOR_PIXEL_MODE_DEFAULT</a> mode.
* They can be queried through
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#get">CameraCharacteristics#get</a> with
- * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION)</a>.
+ * <a href="https://developer.android.com/reference/CameraCharacteristics.html#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION">CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION</a>.
* Unless reported by both
* <a href="https://developer.android.com/reference/android/hardware/camera2/params/StreamConfigurationMap.html">StreamConfigurationMap</a>s, the outputs from
* <code>android.scaler.streamConfigurationMapMaximumResolution</code> and
@@ -5399,13 +5418,12 @@
* <ul>
* <li>
* <p>The mandatory stream combinations listed in
- * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics/mandatoryMaximumResolutionStreamCombinations.html">mandatoryMaximumResolutionStreamCombinations</a>
- * would not apply.</p>
+ * android.scaler.mandatoryMaximumResolutionStreamCombinations would not apply.</p>
* </li>
* <li>
* <p>The bayer pattern of {@code RAW} streams when
* <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>
- * is selected will be the one listed in <a href="https://developer.android.com/reference/android/sensor/info/binningFactor.html">binningFactor</a>.</p>
+ * is selected will be the one listed in ACAMERA_SENSOR_INFO_BINNING_FACTOR.</p>
* </li>
* <li>
* <p>The following keys will always be present:</p>
@@ -5419,6 +5437,7 @@
* </ul>
*
* @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
+ * @see ACAMERA_SENSOR_INFO_BINNING_FACTOR
* @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION
* @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION
*/
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7f6ea9d..74c6cad 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -31,10 +31,13 @@
#include <stdio.h>
#include <android/log.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <android/hidl/token/1.0/ITokenManager.h>
#include <camera/NdkCameraError.h>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraCaptureSession.h>
+#include <hidl/ServiceManagement.h>
#include <media/NdkImage.h>
#include <media/NdkImageReader.h>
#include <cutils/native_handle.h>
@@ -50,6 +53,8 @@
static constexpr int kTestImageFormat = AIMAGE_FORMAT_YUV_420_888;
using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
+using android::hidl::manager::V1_0::IServiceManager;
+using android::hidl::token::V1_0::ITokenManager;
using ConfiguredWindows = std::set<const native_handle_t *>;
class CameraHelper {
@@ -981,11 +986,19 @@
TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+ auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+ if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+ GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+ }
testBasicTakePictures(/*prepareSurfaces*/ false);
testBasicTakePictures(/*prepareSurfaces*/ true);
}
TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+ auto transport = android::hardware::defaultServiceManager()->getTransport(ITokenManager::descriptor, "default");
+ if (transport.isOk() && transport == IServiceManager::Transport::EMPTY) {
+ GTEST_SKIP() << "This device no longer supports AImageReader_getWindowNativeHandle";
+ }
for (auto & v2 : {true, false}) {
testLogicalCameraPhysicalStream(false/*usePhysicalSettings*/, v2);
testLogicalCameraPhysicalStream(true/*usePhysicalSettings*/, v2);
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 41e9aff..bc57ef7 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -105,6 +105,7 @@
mRTCPAddr = mRTPAddr;
mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1);
+ mVPSBuf = NULL;
mSPSBuf = NULL;
mPPSBuf = NULL;
diff --git a/media/module/foundation/MetaDataBase.cpp b/media/module/foundation/MetaDataBase.cpp
index da383fa..60478c9 100644
--- a/media/module/foundation/MetaDataBase.cpp
+++ b/media/module/foundation/MetaDataBase.cpp
@@ -23,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
+#include <mutex>
+
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/foundation/hexdump.h>
@@ -78,6 +80,7 @@
struct MetaDataBase::MetaDataInternal {
+ std::mutex mLock;
KeyedVector<uint32_t, MetaDataBase::typed_data> mItems;
};
@@ -102,10 +105,12 @@
}
void MetaDataBase::clear() {
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
mInternalData->mItems.clear();
}
bool MetaDataBase::remove(uint32_t key) {
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
ssize_t i = mInternalData->mItems.indexOfKey(key);
if (i < 0) {
@@ -252,6 +257,7 @@
uint32_t key, uint32_t type, const void *data, size_t size) {
bool overwrote_existing = true;
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
ssize_t i = mInternalData->mItems.indexOfKey(key);
if (i < 0) {
typed_data item;
@@ -269,6 +275,7 @@
bool MetaDataBase::findData(uint32_t key, uint32_t *type,
const void **data, size_t *size) const {
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
ssize_t i = mInternalData->mItems.indexOfKey(key);
if (i < 0) {
@@ -283,6 +290,7 @@
}
bool MetaDataBase::hasData(uint32_t key) const {
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
ssize_t i = mInternalData->mItems.indexOfKey(key);
if (i < 0) {
@@ -429,6 +437,7 @@
String8 MetaDataBase::toString() const {
String8 s;
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
for (int i = mInternalData->mItems.size(); --i >= 0;) {
int32_t key = mInternalData->mItems.keyAt(i);
char cc[5];
@@ -443,6 +452,7 @@
}
void MetaDataBase::dumpToLog() const {
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
for (int i = mInternalData->mItems.size(); --i >= 0;) {
int32_t key = mInternalData->mItems.keyAt(i);
char cc[5];
@@ -455,6 +465,7 @@
#if defined(__ANDROID__) && !defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__)
status_t MetaDataBase::writeToParcel(Parcel &parcel) {
status_t ret;
+ std::lock_guard<std::mutex> guard(mInternalData->mLock);
size_t numItems = mInternalData->mItems.size();
ret = parcel.writeUint32(uint32_t(numItems));
if (ret) {
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 2ffd775..ef8c9aa 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -297,6 +297,10 @@
}
void MtpFfsHandle::close() {
+ auto timeout = std::chrono::seconds(2);
+ std::unique_lock lk(m);
+ cv.wait_for(lk, timeout ,[this]{return child_threads==0;});
+
io_destroy(mCtx);
closeEndpoints();
closeConfig();
@@ -669,6 +673,11 @@
char *temp = new char[me.length];
memcpy(temp, me.data, me.length);
me.data = temp;
+
+ std::unique_lock lk(m);
+ child_threads++;
+ lk.unlock();
+
std::thread t([this, me]() { return this->doSendEvent(me); });
t.detach();
return 0;
@@ -680,6 +689,11 @@
if (static_cast<unsigned>(ret) != length)
PLOG(ERROR) << "Mtp error sending event thread!";
delete[] reinterpret_cast<char*>(me.data);
+
+ std::unique_lock lk(m);
+ child_threads--;
+ lk.unlock();
+ cv.notify_one();
}
} // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index e552e03..51cdef0 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -60,6 +60,10 @@
bool mCanceled;
bool mBatchCancel;
+ std::mutex m;
+ std::condition_variable cv;
+ std::atomic<int> child_threads{0};
+
android::base::unique_fd mControl;
// "in" from the host's perspective => sink for mtp server
android::base::unique_fd mBulkIn;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index f069a83..5faaac2 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -92,24 +92,46 @@
}
uint16_t MtpPacket::getUInt16(int offset) const {
- return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
uint32_t MtpPacket::getUInt32(int offset) const {
- return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
- ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
+ ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
void MtpPacket::putUInt16(int offset, uint16_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
void MtpPacket::putUInt32(int offset, uint32_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
uint16_t MtpPacket::getContainerCode() const {
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index caee37d..7b19ac0 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -570,6 +570,9 @@
}
}
+// The LL-NDK API is now deprecated. New devices will no longer have the token
+// manager service installed, so createHalToken will return false and this
+// will return AMEDIA_ERROR_UNKNOWN on those devices.
media_status_t AImageReader::getWindowNativeHandle(native_handle **handle) {
if (mWindowHandle != nullptr) {
*handle = mWindowHandle;
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index b6dcaae..b722b74 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -534,15 +534,22 @@
* Get the native_handle_t corresponding to the ANativeWindow owned by the
* AImageReader provided.
*
+ * This is deprecated in API level 35 and will return AMEDIA_ERROR_UNKNOWN.
+ * The native_handle_t is no longer used with AIDL interfaces and
+ * ANativeWindow is used directly instead.
+ * Use AImageRead_getWindow to get the ANativeWindow and use that object.
+ *
* @param reader The image reader of interest.
* @param handle The output native_handle_t. This native handle is owned by
* this image reader.
*
* @return AMEDIA_OK if the method call succeeds.
* AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL.
- * AMEDIA_ERROR_UNKNOWN if some other error is encountered.
+ * AMEDIA_ERROR_UNKNOWN if some other error is encountered or
+ * the device no longer has android.hidl.token service to
+ * satisfy the request because it is deprecated.
*/
-media_status_t AImageReader_getWindowNativeHandle(
+[[deprecated]] media_status_t AImageReader_getWindowNativeHandle(
AImageReader *reader, /* out */native_handle_t **handle);
#endif
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4c1a213..0d539c0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -280,7 +280,7 @@
void AudioFlinger::onFirstRef()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mMode = AUDIO_MODE_NORMAL;
@@ -306,19 +306,19 @@
status_t AudioFlinger::setVibratorInfos(
const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mAudioVibratorInfos = vibratorInfos;
return NO_ERROR;
}
status_t AudioFlinger::updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (const auto& [trackId, secondaryOutputs] : trackSecondaryOutputs) {
size_t i = 0;
for (; i < mPlaybackThreads.size(); ++i) {
IAfPlaybackThread* thread = mPlaybackThreads.valueAt(i).get();
- Mutex::Autolock _tl(thread->mutex());
+ audio_utils::lock_guard _tl(thread->mutex());
sp<IAfTrack> track = thread->getTrackById_l(trackId);
if (track != nullptr) {
ALOGD("%s trackId: %u", __func__, trackId);
@@ -334,13 +334,13 @@
status_t AudioFlinger::getMmapPolicyInfos(
AudioMMapPolicyType policyType, std::vector<AudioMMapPolicyInfo> *policyInfos) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (const auto it = mPolicyInfos.find(policyType); it != mPolicyInfos.end()) {
*policyInfos = it->second;
return NO_ERROR;
}
if (mDevicesFactoryHal->getHalVersion() > kMaxAAudioPropertyDeviceHalVersion) {
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
for (size_t i = 0; i < mAudioHwDevs.size(); ++i) {
AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
std::vector<AudioMMapPolicyInfo> infos;
@@ -361,20 +361,20 @@
}
int32_t AudioFlinger::getAAudioMixerBurstCount() const {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mAAudioBurstsPerBuffer;
}
int32_t AudioFlinger::getAAudioHardwareBurstMinUsec() const {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mAAudioHwBurstMinMicros;
}
status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port,
media::DeviceConnectedState state) {
status_t final_result = NO_INIT;
- Mutex::Autolock _l(mLock);
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard _l(mutex());
+ audio_utils::lock_guard lock(hardwareMutex());
mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -394,8 +394,8 @@
status_t AudioFlinger::setSimulateDeviceConnections(bool enabled) {
bool at_least_one_succeeded = false;
status_t last_error = INVALID_OPERATION;
- Mutex::Autolock _l(mLock);
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard _l(mutex());
+ audio_utils::lock_guard lock(hardwareMutex());
mHardwareStatus = AUDIO_HW_SET_SIMULATE_CONNECTIONS;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -438,7 +438,7 @@
}
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
- // no mHardwareLock needed, as there are no other references to this
+ // no hardwareMutex() needed, as there are no other references to this
delete mAudioHwDevs.valueAt(i);
}
@@ -560,6 +560,9 @@
return ret;
}
+ // use unique_lock as we may selectively unlock.
+ audio_utils::unique_lock l(mutex());
+
// at this stage, a MmapThread was created when openOutput() or openInput() was called by
// audio policy manager and we can retrieve it
const sp<IAfMmapThread> thread = mMmapThreads.valueFor(io);
@@ -572,12 +575,14 @@
config->channel_mask = thread->channelMask();
config->format = thread->format();
} else {
+ l.unlock();
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
ret = NO_INIT;
+ // we don't reacquire the lock here as nothing left to do.
}
ALOGV("%s done status %d portId %d", __FUNCTION__, ret, portId);
@@ -587,7 +592,7 @@
status_t AudioFlinger::addEffectToHal(
const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
if (audioHwDevice == nullptr) {
return NO_INIT;
@@ -597,7 +602,7 @@
status_t AudioFlinger::removeEffectFromHal(
const struct audio_port_config *device, const sp<EffectHalInterface>& effect) {
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(device->ext.device.hw_module);
if (audioHwDevice == nullptr) {
return NO_INIT;
@@ -617,11 +622,11 @@
{
// if module is 0, the request comes from an old policy manager and we should load
// well known modules
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (module == 0) {
ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
for (size_t i = 0; i < arraysize(audio_interfaces); i++) {
- loadHwModule_l(audio_interfaces[i]);
+ loadHwModule_ll(audio_interfaces[i]);
}
// then try to find a module supporting the requested device.
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
@@ -644,7 +649,7 @@
return NULL;
}
-void AudioFlinger::dumpClients(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::dumpClients_ll(int fd, const Vector<String16>& args __unused)
{
String8 result;
@@ -678,7 +683,7 @@
}
-void AudioFlinger::dumpInternals(int fd, const Vector<String16>& args __unused)
+void AudioFlinger::dumpInternals_l(int fd, const Vector<String16>& args __unused)
{
const size_t SIZE = 256;
char buffer[SIZE];
@@ -717,15 +722,15 @@
dumpPermissionDenial(fd, args);
} else {
// get state of hardware lock
- const bool hardwareLocked = afutils::dumpTryLock(mHardwareLock);
+ const bool hardwareLocked = afutils::dumpTryLock(hardwareMutex());
if (!hardwareLocked) {
String8 result(kHardwareLockedString);
write(fd, result.c_str(), result.size());
} else {
- mHardwareLock.unlock();
+ hardwareMutex().unlock();
}
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
@@ -733,7 +738,7 @@
write(fd, result.c_str(), result.size());
}
- const bool clientLocked = afutils::dumpTryLock(mClientLock);
+ const bool clientLocked = afutils::dumpTryLock(clientMutex());
if (!clientLocked) {
String8 result(kClientLockedString);
write(fd, result.c_str(), result.size());
@@ -746,12 +751,12 @@
write(fd, result.c_str(), result.size());
}
- dumpClients(fd, args);
+ dumpClients_ll(fd, args);
if (clientLocked) {
- mClientLock.unlock();
+ clientMutex().unlock();
}
- dumpInternals(fd, args);
+ dumpInternals_l(fd, args);
// dump playback threads
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
@@ -806,7 +811,7 @@
BUFLOG_RESET;
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
#ifdef TEE_SINK
@@ -878,7 +883,7 @@
sp<Client> AudioFlinger::registerPid(pid_t pid)
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
// If pid is already in the mClients wp<> map, then use that entry
// (for which promote() is always != 0), otherwise create a new entry and Client.
sp<Client> client = mClients.valueFor(pid).promote();
@@ -901,7 +906,7 @@
// If allocation fails, consult the vector of previously unregistered writers
// and garbage-collect one or more them until an allocation succeeds
if (shared == 0) {
- Mutex::Autolock _l(mUnregisteredWritersLock);
+ audio_utils::lock_guard _l(unregisteredWritersMutex());
for (size_t count = mUnregisteredWriters.size(); count > 0; count--) {
{
// Pick the oldest stale writer to garbage-collect
@@ -941,7 +946,7 @@
}
// Rather than removing the writer immediately, append it to a queue of old writers to
// be garbage-collected later. This allows us to continue to view old logs for a while.
- Mutex::Autolock _l(mUnregisteredWritersLock);
+ audio_utils::lock_guard _l(unregisteredWritersMutex());
mUnregisteredWriters.push(writer);
}
@@ -1037,7 +1042,7 @@
}
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* thread = checkPlaybackThread_l(output.outputId);
if (thread == NULL) {
ALOGE("no playback thread found for output handle %d", output.outputId);
@@ -1088,8 +1093,8 @@
output.portId = portId;
if (lStatus == NO_ERROR) {
- // no risk of deadlock because AudioFlinger::mLock is held
- Mutex::Autolock _dl(thread->mutex());
+ // no risk of deadlock because AudioFlinger::mutex() is held
+ audio_utils::lock_guard _dl(thread->mutex());
// Connect secondary outputs. Failure on a secondary output must not imped the primary
// Any secondary output setup failure will lead to a desync between the AP and AF until
// the track is destroyed.
@@ -1097,8 +1102,9 @@
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
if (effectThread != nullptr) {
- Mutex::Autolock _sl(effectThread->mutex());
- if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
+ // No thread safety analysis: double lock on a thread capability.
+ audio_utils::lock_guard_no_thread_safety_analysis _sl(effectThread->mutex());
+ if (moveEffectChain_ll(sessionId, effectThread, thread) == NO_ERROR) {
effectThreadId = thread->id();
effectIds = thread->getEffectIds_l(sessionId);
}
@@ -1127,11 +1133,11 @@
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the Track so that the
- // Client destructor is called by the TrackBase destructor with mClientLock held
- // Don't hold mClientLock when releasing the reference on the track as the
+ // Client destructor is called by the TrackBase destructor with clientMutex() held
+ // Don't hold clientMutex() when releasing the reference on the track as the
// destructor will acquire it.
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
client.clear();
}
track.clear();
@@ -1156,7 +1162,7 @@
uint32_t AudioFlinger::sampleRate(audio_io_handle_t ioHandle) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("sampleRate() unknown thread %d", ioHandle);
@@ -1167,7 +1173,7 @@
audio_format_t AudioFlinger::format(audio_io_handle_t output) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
ALOGW("format() unknown thread %d", output);
@@ -1178,7 +1184,7 @@
size_t AudioFlinger::frameCount(audio_io_handle_t ioHandle) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("frameCount() unknown thread %d", ioHandle);
@@ -1191,7 +1197,7 @@
size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfThreadBase* const thread = checkThread_l(ioHandle);
if (thread == NULL) {
ALOGW("frameCountHAL() unknown thread %d", ioHandle);
@@ -1202,7 +1208,7 @@
uint32_t AudioFlinger::latency(audio_io_handle_t output) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
ALOGW("latency(): no playback thread found for output handle %d", output);
@@ -1223,12 +1229,12 @@
return PERMISSION_DENIED;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mMasterVolume = value;
// Set master volume in the HALs which support it.
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
@@ -1270,7 +1276,7 @@
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// short cut.
if (mMasterBalance == balance) return NO_ERROR;
@@ -1304,7 +1310,7 @@
}
{ // scope for the lock
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return INVALID_OPERATION;
}
@@ -1315,7 +1321,7 @@
}
if (NO_ERROR == ret) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mMode = mode;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
mPlaybackThreads.valueAt(i)->setMode(mode);
@@ -1341,7 +1347,7 @@
return PERMISSION_DENIED;
}
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return INVALID_OPERATION;
}
@@ -1369,7 +1375,7 @@
if (ret != NO_ERROR) {
return false;
}
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return false;
}
@@ -1390,7 +1396,7 @@
{
ALOGV("AudioFlinger::setRecordSilenced(portId:%d, silenced:%d)", portId, silenced);
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
for (size_t i = 0; i < mRecordThreads.size(); i++) {
mRecordThreads[i]->setRecordSilenced(portId, silenced);
}
@@ -1411,12 +1417,12 @@
return PERMISSION_DENIED;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mMasterMute = muted;
// Set master mute in the HALs which support it.
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
@@ -1442,20 +1448,20 @@
float AudioFlinger::masterVolume() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return masterVolume_l();
}
status_t AudioFlinger::getMasterBalance(float *balance) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
*balance = getMasterBalance_l();
return NO_ERROR; // if called through binder, may return a transactional error
}
bool AudioFlinger::masterMute() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return masterMute_l();
}
@@ -1474,7 +1480,8 @@
return mMasterMute;
}
-status_t AudioFlinger::checkStreamType(audio_stream_type_t stream) const
+/* static */
+status_t AudioFlinger::checkStreamType(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
ALOGW("checkStreamType() invalid stream %d", stream);
@@ -1507,7 +1514,7 @@
LOG_ALWAYS_FATAL_IF(stream == AUDIO_STREAM_PATCH && value != 1.0f,
"AUDIO_STREAM_PATCH must have full scale volume");
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
if (volumeInterface == NULL) {
return BAD_VALUE;
@@ -1522,7 +1529,7 @@
if (output == AUDIO_IO_HANDLE_NONE) {
return BAD_VALUE;
}
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == nullptr) {
return BAD_VALUE;
@@ -1535,7 +1542,7 @@
if (output == AUDIO_IO_HANDLE_NONE) {
return BAD_VALUE;
}
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == nullptr) {
return BAD_VALUE;
@@ -1544,7 +1551,7 @@
}
status_t AudioFlinger::setBluetoothVariableLatencyEnabled(bool enabled) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
status_t status = INVALID_OPERATION;
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
// Success if at least one PlaybackThread supports Bluetooth latency modes
@@ -1570,7 +1577,7 @@
if (support == nullptr) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(hardwareMutex());
*support = false;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (mAudioHwDevs.valueAt(i)->supportsBluetoothVariableLatency()) {
@@ -1609,7 +1616,7 @@
return BAD_VALUE;
}
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
mStreamTypes[stream].mute = muted;
std::vector<sp<VolumeInterface>> volumeInterfaces = getAllVolumeInterfaces_l();
for (size_t i = 0; i < volumeInterfaces.size(); i++) {
@@ -1629,7 +1636,7 @@
return 0.0f;
}
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
sp<VolumeInterface> volumeInterface = getVolumeInterface_l(output);
if (volumeInterface == NULL) {
return 0.0f;
@@ -1645,7 +1652,7 @@
return true;
}
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
return streamMute_l(stream);
}
@@ -1664,7 +1671,7 @@
}
}
-// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mLock held
+// forwardAudioHwSyncToDownstreamPatches_l() must be called with AudioFlinger::mutex() held
void AudioFlinger::forwardParametersToDownstreamPatches_l(
audio_io_handle_t upStream, const String8& keyValuePairs,
const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread)
@@ -1769,11 +1776,11 @@
// AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
if (ioHandle == AUDIO_IO_HANDLE_NONE) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// result will remain NO_INIT if no audio device is present
status_t final_result = NO_INIT;
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
mHardwareStatus = AUDIO_HW_SET_PARAMETER;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
@@ -1812,7 +1819,7 @@
// and the thread is exited once the lock is released
sp<IAfThreadBase> thread;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
thread = checkPlaybackThread_l(ioHandle);
if (thread == 0) {
thread = checkRecordThread_l(ioHandle);
@@ -1831,6 +1838,7 @@
}
if (thread != 0) {
status_t result = thread->setParameters(filteredKeyValuePairs);
+ audio_utils::lock_guard _l(mutex());
forwardParametersToDownstreamPatches_l(thread->id(), filteredKeyValuePairs);
return result;
}
@@ -1842,12 +1850,12 @@
ALOGVV("getParameters() io %d, keys %s, calling pid %d",
ioHandle, keys.c_str(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (ioHandle == AUDIO_IO_HANDLE_NONE) {
String8 out_s8;
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
String8 s;
mHardwareStatus = AUDIO_HW_GET_PARAMETER;
@@ -1885,7 +1893,7 @@
return 0;
}
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return 0;
}
@@ -1957,7 +1965,7 @@
uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfRecordThread* const recordThread = checkRecordThread_l(ioHandle);
if (recordThread != NULL) {
@@ -1978,7 +1986,7 @@
return PERMISSION_DENIED;
}
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return INVALID_OPERATION;
}
@@ -1997,7 +2005,7 @@
status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
audio_io_handle_t output) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const playbackThread = checkPlaybackThread_l(output);
if (playbackThread != NULL) {
@@ -2009,14 +2017,14 @@
void AudioFlinger::registerClient(const sp<media::IAudioFlingerClient>& client)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (client == 0) {
return;
}
pid_t pid = IPCThreadState::self()->getCallingPid();
const uid_t uid = IPCThreadState::self()->getCallingUid();
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
if (mNotificationClients.indexOfKey(pid) < 0) {
sp<NotificationClient> notificationClient = new NotificationClient(this,
client,
@@ -2032,9 +2040,10 @@
}
}
- // mClientLock should not be held here because ThreadBase::sendIoConfigEvent() will lock the
- // ThreadBase mutex and the locking order is ThreadBase::mLock then AudioFlinger::mClientLock.
- // the config change is always sent from playback or record threads to avoid deadlock
+ // clientMutex() should not be held here because ThreadBase::sendIoConfigEvent()
+ // will lock the ThreadBase::mutex() and the locking order is
+ // ThreadBase::mutex() then AudioFlinger::clientMutex().
+ // The config change is always sent from playback or record threads to avoid deadlock
// with AudioSystem::gLock
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_REGISTERED, pid);
@@ -2049,9 +2058,9 @@
{
std::vector<sp<IAfEffectModule>> removedEffects;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
mNotificationClients.removeItem(pid);
}
@@ -2088,7 +2097,7 @@
media::AudioIoDescriptor descAidl = VALUE_OR_FATAL(
legacy2aidl_AudioIoDescriptor_AudioIoDescriptor(ioDesc));
- Mutex::Autolock _l(mClientLock);
+ audio_utils::lock_guard _l(clientMutex());
size_t size = mNotificationClients.size();
for (size_t i = 0; i < size; i++) {
if ((pid == 0) || (mNotificationClients.keyAt(i) == pid)) {
@@ -2105,7 +2114,7 @@
convertContainer<std::vector<media::audio::common::AudioLatencyMode>>(
modes, legacy2aidl_audio_latency_mode_t_AudioLatencyMode));
- Mutex::Autolock _l(mClientLock);
+ audio_utils::lock_guard _l(clientMutex());
size_t size = mNotificationClients.size();
for (size_t i = 0; i < size; i++) {
mNotificationClients.valueAt(i)->audioFlingerClient()
@@ -2113,7 +2122,7 @@
}
}
-// removeClient_l() must be called with AudioFlinger::mClientLock held
+// removeClient_l() must be called with AudioFlinger::clientMutex() held
void AudioFlinger::removeClient_l(pid_t pid)
{
ALOGV("removeClient_l() pid %d, calling pid %d", pid,
@@ -2121,7 +2130,7 @@
mClients.removeItem(pid);
}
-// getEffectThread_l() must be called with AudioFlinger::mLock held
+// getEffectThread_l() must be called with AudioFlinger::mutex() held
sp<IAfThreadBase> AudioFlinger::getEffectThread_l(audio_session_t sessionId,
int effectId)
{
@@ -2180,9 +2189,9 @@
void AudioFlinger::MediaLogNotifier::requestMerge() {
- AutoMutex _l(mMutex);
+ audio_utils::lock_guard _l(mMutex);
mPendingRequests = true;
- mCond.signal();
+ mCondition.notify_one();
}
bool AudioFlinger::MediaLogNotifier::threadLoop() {
@@ -2192,10 +2201,10 @@
}
// Wait until there are pending requests
{
- AutoMutex _l(mMutex);
+ audio_utils::unique_lock _l(mMutex);
mPendingRequests = false; // to ignore past requests
while (!mPendingRequests) {
- mCond.wait(mMutex);
+ mCondition.wait(_l);
// TODO may also need an exitPending check
}
mPendingRequests = false;
@@ -2306,7 +2315,7 @@
}
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfRecordThread* const thread = checkRecordThread_l(output.inputId);
if (thread == NULL) {
ALOGW("createRecord() checkRecordThread_l failed, input handle %d", output.inputId);
@@ -2363,7 +2372,7 @@
// session and move it to this thread.
sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
if (chain != 0) {
- Mutex::Autolock _l2(thread->mutex());
+ audio_utils::lock_guard _l2(thread->mutex());
thread->addEffectChain_l(chain);
}
break;
@@ -2382,11 +2391,11 @@
Exit:
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the
- // Client destructor is called by the TrackBase destructor with mClientLock held
- // Don't hold mClientLock when releasing the reference on the track as the
+ // Client destructor is called by the TrackBase destructor with clientMutex() held
+ // Don't hold clientMutex() when releasing the reference on the track as the
// destructor will acquire it.
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
client.clear();
}
recordTrack.clear();
@@ -2407,8 +2416,8 @@
if (config == nullptr) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard _l(mutex());
+ audio_utils::lock_guard lock(hardwareMutex());
RETURN_STATUS_IF_ERROR(
mDevicesFactoryHal->getSurroundSoundConfig(&config->surroundSoundConfig));
RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getEngineConfig(&config->engineConfig));
@@ -2416,7 +2425,7 @@
RETURN_STATUS_IF_ERROR(mDevicesFactoryHal->getDeviceNames(&hwModuleNames));
std::set<AudioMode> allSupportedModes;
for (const auto& name : hwModuleNames) {
- AudioHwDevice* module = loadHwModule_l(name.c_str());
+ AudioHwDevice* module = loadHwModule_ll(name.c_str());
if (module == nullptr) continue;
media::AudioHwModule aidlModule;
if (module->hwDevice()->getAudioPorts(&aidlModule.ports) == OK &&
@@ -2451,14 +2460,15 @@
if (!settingsAllowed()) {
return AUDIO_MODULE_HANDLE_NONE;
}
- Mutex::Autolock _l(mLock);
- AutoMutex lock(mHardwareLock);
- AudioHwDevice* module = loadHwModule_l(name);
+ audio_utils::lock_guard _l(mutex());
+ audio_utils::lock_guard lock(hardwareMutex());
+ AudioHwDevice* module = loadHwModule_ll(name);
return module != nullptr ? module->handle() : AUDIO_MODULE_HANDLE_NONE;
}
-// loadHwModule_l() must be called with AudioFlinger::mLock and AudioFlinger::mHardwareLock held
-AudioHwDevice* AudioFlinger::loadHwModule_l(const char *name)
+// loadHwModule_l() must be called with AudioFlinger::mutex()
+// and AudioFlinger::hardwareMutex() held
+AudioHwDevice* AudioFlinger::loadHwModule_ll(const char *name)
{
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
@@ -2564,14 +2574,14 @@
uint32_t AudioFlinger::getPrimaryOutputSamplingRate() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = fastPlaybackThread_l();
return thread != NULL ? thread->sampleRate() : 0;
}
size_t AudioFlinger::getPrimaryOutputFrameCount() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = fastPlaybackThread_l();
return thread != NULL ? thread->frameCountHAL() : 0;
}
@@ -2584,7 +2594,7 @@
if (!isAudioServerOrSystemServerUid(uid)) {
return PERMISSION_DENIED;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mIsDeviceTypeKnown) {
return INVALID_OPERATION;
}
@@ -2642,8 +2652,8 @@
module = config->ext.mix.hw_module;
}
- Mutex::Autolock _l(mLock);
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard _l(mutex());
+ audio_utils::lock_guard lock(hardwareMutex());
ssize_t index = mAudioHwDevs.indexOfKey(module);
if (index < 0) {
ALOGW("%s() bad hw module %d", __func__, module);
@@ -2656,7 +2666,7 @@
audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ssize_t index = mHwAvSyncIds.indexOfKey(sessionId);
if (index >= 0) {
@@ -2667,7 +2677,7 @@
sp<DeviceHalInterface> dev;
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return AUDIO_HW_SYNC_INVALID;
}
@@ -2716,7 +2726,7 @@
status_t AudioFlinger::systemReady()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ALOGI("%s", __FUNCTION__);
if (mSystemReady) {
ALOGW("%s called twice", __FUNCTION__);
@@ -2759,7 +2769,7 @@
status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
status_t status = INVALID_OPERATION;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
@@ -2783,7 +2793,7 @@
return status;
}
-// setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held
+// setAudioHwSyncForSession_l() must be called with AudioFlinger::mutex() held
void AudioFlinger::setAudioHwSyncForSession_l(
IAfPlaybackThread* const thread, audio_session_t sessionId)
{
@@ -2922,7 +2932,7 @@
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
const sp<IAfThreadBase> thread = openOutput_l(module, &output, &halConfig,
&mixerConfig, deviceType, address, flags);
@@ -2937,7 +2947,7 @@
// the first primary output opened designates the primary hw device if no HW module
// named "primary" was already loaded.
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if ((mPrimaryHardwareDev == nullptr) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
ALOGI("Using module %d as the primary audio interface", module);
mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
@@ -2964,7 +2974,7 @@
audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread1 = checkMixerThread_l(output1);
IAfPlaybackThread* const thread2 = checkMixerThread_l(output2);
@@ -2996,7 +3006,7 @@
sp<IAfPlaybackThread> playbackThread;
sp<IAfMmapPlaybackThread> mmapThread;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
playbackThread = checkPlaybackThread_l(output);
if (playbackThread != NULL) {
ALOGV("closeOutput() %d", output);
@@ -3021,11 +3031,11 @@
checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
if (dstThread != NULL) {
// audioflinger lock is held so order of thread lock acquisition doesn't matter
- Mutex::Autolock _dl(dstThread->mutex());
- Mutex::Autolock _sl(playbackThread->mutex());
+ // Use scoped_lock to avoid deadlock order issues with duplicating threads.
+ audio_utils::scoped_lock sl(dstThread->mutex(), playbackThread->mutex());
Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
for (size_t i = 0; i < effectChains.size(); i ++) {
- moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
+ moveEffectChain_ll(effectChains[i]->sessionId(), playbackThread.get(),
dstThread);
}
}
@@ -3062,6 +3072,7 @@
return NO_ERROR;
}
+/* static */
void AudioFlinger::closeOutputFinish(const sp<IAfPlaybackThread>& thread)
{
AudioStreamOut *out = thread->clearOutput();
@@ -3079,7 +3090,7 @@
status_t AudioFlinger::suspendOutput(audio_io_handle_t output)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
@@ -3094,7 +3105,7 @@
status_t AudioFlinger::restoreOutput(audio_io_handle_t output)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfPlaybackThread* const thread = checkPlaybackThread_l(output);
if (thread == NULL) {
@@ -3111,7 +3122,7 @@
status_t AudioFlinger::openInput(const media::OpenInputRequest& request,
media::OpenInputResponse* response)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
AudioDeviceTypeAddr device = VALUE_OR_RETURN_STATUS(
aidl2legacy_AudioDeviceTypeAddress(request.device));
@@ -3248,7 +3259,7 @@
sp<IAfRecordThread> recordThread;
sp<IAfMmapCaptureThread> mmapThread;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
recordThread = checkRecordThread_l(input);
if (recordThread != 0) {
ALOGV("closeInput() %d", input);
@@ -3261,7 +3272,7 @@
// new capture on the same session
sp<IAfEffectChain> chain;
{
- Mutex::Autolock _sl(recordThread->mutex());
+ audio_utils::lock_guard _sl(recordThread->mutex());
const Vector<sp<IAfEffectChain>> effectChains = recordThread->getEffectChains_l();
// Note: maximum one chain per record thread
if (effectChains.size() != 0) {
@@ -3279,7 +3290,7 @@
continue;
}
if (t->hasAudioSession(chain->sessionId()) != 0) {
- Mutex::Autolock _l2(t->mutex());
+ audio_utils::lock_guard _l2(t->mutex());
ALOGV("closeInput() found thread %d for effect session %d",
t->id(), chain->sessionId());
t->addEffectChain_l(chain);
@@ -3303,7 +3314,7 @@
}
ioConfigChanged(AUDIO_INPUT_CLOSED, sp<AudioIoDescriptor>::make(input));
}
- // FIXME: calling thread->exit() without mLock held should not be needed anymore now that
+ // FIXME: calling thread->exit() without mutex() held should not be needed anymore now that
// we have a different lock for notification client
if (recordThread != 0) {
closeInputFinish(recordThread);
@@ -3333,7 +3344,7 @@
}
status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> &portIds) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ALOGV("%s", __func__);
std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
@@ -3368,7 +3379,7 @@
void AudioFlinger::acquireAudioSessionId(
audio_session_t audioSession, pid_t pid, uid_t uid)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
pid_t caller = IPCThreadState::self()->getCallingPid();
ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
const uid_t callerUid = IPCThreadState::self()->getCallingUid();
@@ -3380,7 +3391,7 @@
}
{
- Mutex::Autolock _cl(mClientLock);
+ audio_utils::lock_guard _cl(clientMutex());
// Ignore requests received from processes not known as notification client. The request
// is likely proxied by mediaserver (e.g CameraService) and releaseAudioSessionId() can be
// called from a different pid leaving a stale session reference. Also we don't know how
@@ -3408,7 +3419,7 @@
{
std::vector<sp<IAfEffectModule>> removedEffects;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
pid_t caller = IPCThreadState::self()->getCallingPid();
ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
const uid_t callerUid = IPCThreadState::self()->getCallingUid();
@@ -3463,7 +3474,7 @@
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
for (size_t j = 0; j < threadChains.size(); j++) {
sp<IAfEffectChain> ec = threadChains[j];
@@ -3475,7 +3486,7 @@
for (size_t i = 0; i < mRecordThreads.size(); i++) {
sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
for (size_t j = 0; j < threadChains.size(); j++) {
sp<IAfEffectChain> ec = threadChains[j];
@@ -3485,7 +3496,7 @@
for (size_t i = 0; i < mMmapThreads.size(); i++) {
const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
for (size_t j = 0; j < threadChains.size(); j++) {
sp<IAfEffectChain> ec = threadChains[j];
@@ -3513,7 +3524,7 @@
}
}
if (!found) {
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
// remove all effects from the chain
while (ec->numberOfEffects()) {
sp<IAfEffectModule> effect = ec->getEffectModule(0);
@@ -3529,7 +3540,7 @@
return removedEffects;
}
-// dumpToThreadLog_l() must be called with AudioFlinger::mLock held
+// dumpToThreadLog_l() must be called with AudioFlinger::mutex() held
void AudioFlinger::dumpToThreadLog_l(const sp<IAfThreadBase> &thread)
{
constexpr int THREAD_DUMP_TIMEOUT_MS = 2;
@@ -3541,7 +3552,7 @@
}
}
-// checkThread_l() must be called with AudioFlinger::mLock held
+// checkThread_l() must be called with AudioFlinger::mutex() held
IAfThreadBase* AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
{
IAfThreadBase* thread = checkMmapThread_l(ioHandle);
@@ -3560,7 +3571,7 @@
return thread;
}
-// checkOutputThread_l() must be called with AudioFlinger::mLock held
+// checkOutputThread_l() must be called with AudioFlinger::mutex() held
sp<IAfThreadBase> AudioFlinger::checkOutputThread_l(audio_io_handle_t ioHandle) const
{
if (audio_unique_id_get_use(ioHandle) != AUDIO_UNIQUE_ID_USE_OUTPUT) {
@@ -3574,33 +3585,33 @@
return thread;
}
-// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
+// checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
IAfPlaybackThread* AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
{
return mPlaybackThreads.valueFor(output).get();
}
-// checkMixerThread_l() must be called with AudioFlinger::mLock held
+// checkMixerThread_l() must be called with AudioFlinger::mutex() held
IAfPlaybackThread* AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
{
IAfPlaybackThread * const thread = checkPlaybackThread_l(output);
return thread != nullptr && thread->type() != IAfThreadBase::DIRECT ? thread : nullptr;
}
-// checkRecordThread_l() must be called with AudioFlinger::mLock held
+// checkRecordThread_l() must be called with AudioFlinger::mutex() held
IAfRecordThread* AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
{
return mRecordThreads.valueFor(input).get();
}
-// checkMmapThread_l() must be called with AudioFlinger::mLock held
+// checkMmapThread_l() must be called with AudioFlinger::mutex() held
IAfMmapThread* AudioFlinger::checkMmapThread_l(audio_io_handle_t io) const
{
return mMmapThreads.valueFor(io).get();
}
-// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
+// checkPlaybackThread_l() must be called with AudioFlinger::mutex() held
sp<VolumeInterface> AudioFlinger::getVolumeInterface_l(audio_io_handle_t output) const
{
sp<VolumeInterface> volumeInterface = mPlaybackThreads.valueFor(output).get();
@@ -3656,7 +3667,7 @@
IAfPlaybackThread* AudioFlinger::primaryPlaybackThread_l() const
{
- AutoMutex lock(mHardwareLock);
+ audio_utils::lock_guard lock(hardwareMutex());
if (mPrimaryHardwareDev == nullptr) {
return nullptr;
}
@@ -3745,7 +3756,7 @@
// The frameCount should also not be smaller than the secondary thread min frame
// count
size_t minFrameCount = AudioSystem::calculateMinFrameCount(
- [&] { Mutex::Autolock _l(secondaryThread->mutex());
+ [&] { audio_utils::lock_guard _l(secondaryThread->mutex());
return secondaryThread->latency_l(); }(),
secondaryThread->frameCount(), // normal frame count
secondaryThread->sampleRate(),
@@ -3813,7 +3824,7 @@
const audioflinger::SyncEventCallback& callBack,
const wp<IAfTrackBase>& cookie)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
auto event = sp<audioflinger::SyncEvent>::make(
type, triggerSession, listenerSession, callBack, cookie);
@@ -3850,7 +3861,7 @@
status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mEffectsFactoryHal.get()) {
return mEffectsFactoryHal->queryNumberEffects(numEffects);
} else {
@@ -3860,7 +3871,7 @@
status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mEffectsFactoryHal.get()) {
return mEffectsFactoryHal->getDescriptor(index, descriptor);
} else {
@@ -3877,7 +3888,7 @@
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!mEffectsFactoryHal.get()) {
return -ENODEV;
@@ -3997,7 +4008,11 @@
lStatus = BAD_VALUE;
goto Exit;
}
- IAfPlaybackThread* const thread = checkPlaybackThread_l(io);
+ IAfPlaybackThread* thread;
+ {
+ audio_utils::lock_guard l(mutex());
+ thread = checkPlaybackThread_l(io);
+ }
if (thread == nullptr) {
ALOGE("%s: invalid output %d specified for AUDIO_SESSION_OUTPUT_STAGE", __func__, io);
lStatus = BAD_VALUE;
@@ -4088,7 +4103,7 @@
ALOGV("createEffect got output %d", io);
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (sessionId == AUDIO_SESSION_DEVICE) {
sp<Client> client = registerPid(currentPid);
@@ -4097,8 +4112,8 @@
&descOut, device, client, effectClient, mPatchPanel->patches_l(),
&enabledOut, &lStatus, probe, request.notifyFramesProcessed);
if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
- // remove local strong reference to Client with mClientLock held
- Mutex::Autolock _cl(mClientLock);
+ // remove local strong reference to Client with clientMutex() held
+ audio_utils::lock_guard _cl(clientMutex());
client.clear();
} else {
// handle must be valid here, but check again to be safe.
@@ -4191,7 +4206,7 @@
// session and used it instead of creating a new one.
sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
if (chain != 0) {
- Mutex::Autolock _l2(thread->mutex());
+ audio_utils::lock_guard _l2(thread->mutex());
thread->addEffectChain_l(chain);
}
}
@@ -4218,8 +4233,8 @@
&descOut, &enabledOut, &lStatus, pinned, probe,
request.notifyFramesProcessed);
if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
- // remove local strong reference to Client with mClientLock held
- Mutex::Autolock _cl(mClientLock);
+ // remove local strong reference to Client with clientMutex() held
+ audio_utils::lock_guard _cl(clientMutex());
client.clear();
} else {
// handle must be valid here, but check again to be safe.
@@ -4267,7 +4282,7 @@
{
ALOGV("%s() session %d, srcOutput %d, dstOutput %d",
__func__, sessionId, srcOutput, dstOutput);
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (srcOutput == dstOutput) {
ALOGW("%s() same dst and src outputs %d", __func__, dstOutput);
return NO_ERROR;
@@ -4283,9 +4298,8 @@
return BAD_VALUE;
}
- Mutex::Autolock _dl(dstThread->mutex());
- Mutex::Autolock _sl(srcThread->mutex());
- return moveEffectChain_l(sessionId, srcThread, dstThread);
+ audio_utils::scoped_lock _ll(dstThread->mutex(), srcThread->mutex());
+ return moveEffectChain_ll(sessionId, srcThread, dstThread);
}
@@ -4293,38 +4307,38 @@
audio_session_t sessionId,
bool suspended)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfThreadBase> thread = getEffectThread_l(sessionId, effectId);
if (thread == nullptr) {
return;
}
- Mutex::Autolock _sl(thread->mutex());
+ audio_utils::lock_guard _sl(thread->mutex());
sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId);
thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
}
-// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
-status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
+// moveEffectChain_ll must be called with the AudioFlinger::mutex()
+// and both srcThread and dstThread mutex()s held
+status_t AudioFlinger::moveEffectChain_ll(audio_session_t sessionId,
IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
-NO_THREAD_SAFETY_ANALYSIS // requires srcThread and dstThread locks
{
- ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
- sessionId, srcThread, dstThread);
+ ALOGV("%s: session %d from thread %p to thread %p",
+ __func__, sessionId, srcThread, dstThread);
sp<IAfEffectChain> chain = srcThread->getEffectChain_l(sessionId);
if (chain == 0) {
- ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
- sessionId, srcThread);
+ ALOGW("%s: effect chain for session %d not on source thread %p",
+ __func__, sessionId, srcThread);
return INVALID_OPERATION;
}
// Check whether the destination thread and all effects in the chain are compatible
if (!chain->isCompatibleWithThread_l(dstThread)) {
- ALOGW("moveEffectChain_l() effect chain failed because"
+ ALOGW("%s: effect chain failed because"
" destination thread %p is not compatible with effects in the chain",
- dstThread);
+ __func__, dstThread);
return INVALID_OPERATION;
}
@@ -4346,7 +4360,7 @@
effect = chain->getEffectFromId_l(0)) {
srcThread->removeEffect_l(effect);
removed.add(effect);
- status = dstThread->addEffect_l(effect);
+ status = dstThread->addEffect_ll(effect);
if (status != NO_ERROR) {
errorString = StringPrintf(
"cannot add effect %p to destination thread", effect.get());
@@ -4372,7 +4386,7 @@
for (const auto& effect : removed) {
dstThread->removeEffect_l(effect); // Note: Depending on error location, the last
// effect may not have been placed on dstThread.
- if (srcThread->addEffect_l(effect) == NO_ERROR) {
+ if (srcThread->addEffect_ll(effect) == NO_ERROR) {
++restored;
if (dstChain == nullptr) {
dstChain = effect->getCallback()->chain().promote();
@@ -4388,7 +4402,7 @@
// If we do not take the dstChain lock, it is possible that processing is ongoing
// while we are starting the effect. This can cause glitches with volume,
// see b/202360137.
- dstChain->lock();
+ dstChain->mutex().lock();
for (const auto& effect : removed) {
if (effect->state() == IAfEffectModule::ACTIVE ||
effect->state() == IAfEffectModule::STOPPING) {
@@ -4396,7 +4410,7 @@
effect->start();
}
}
- dstChain->unlock();
+ dstChain->mutex().unlock();
}
if (status != NO_ERROR) {
@@ -4420,13 +4434,12 @@
const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread)
{
status_t status = NO_ERROR;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
const sp<IAfThreadBase> threadBase = getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
const sp<IAfPlaybackThread> thread = threadBase ? threadBase->asIAfPlaybackThread() : nullptr;
if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
- Mutex::Autolock _dl(dstThread->mutex());
- Mutex::Autolock _sl(thread->mutex());
+ audio_utils::scoped_lock _ll(dstThread->mutex(), thread->mutex());
sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
sp<IAfEffectChain> dstChain;
if (srcChain == 0) {
@@ -4438,16 +4451,16 @@
return INVALID_OPERATION;
}
thread->removeEffect_l(effect);
- status = dstThread->addEffect_l(effect);
+ status = dstThread->addEffect_ll(effect);
if (status != NO_ERROR) {
- thread->addEffect_l(effect);
+ thread->addEffect_ll(effect);
status = INVALID_OPERATION;
goto Exit;
}
dstChain = effect->getCallback()->chain().promote();
if (dstChain == 0) {
- thread->addEffect_l(effect);
+ thread->addEffect_ll(effect);
status = INVALID_OPERATION;
}
@@ -4466,7 +4479,6 @@
}
bool AudioFlinger::isNonOffloadableGlobalEffectEnabled_l() const
-NO_THREAD_SAFETY_ANALYSIS // thread lock for getEffectChain_l.
{
if (mGlobalEffectEnableTime != 0 &&
((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) {
@@ -4485,7 +4497,7 @@
void AudioFlinger::onNonOffloadableGlobalEffectEnable()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mGlobalEffectEnableTime = systemTime();
@@ -4530,7 +4542,7 @@
bool AudioFlinger::updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
audio_session_t session = effect->sessionId();
ssize_t index = mOrphanEffectChains.indexOfKey(session);
ALOGV("updateOrphanEffectChains session %d index %zd", session, index);
@@ -4552,8 +4564,8 @@
status_t AudioFlinger::listAudioPorts(unsigned int* num_ports,
struct audio_port* ports) const
{
- Mutex::Autolock _l(mLock);
- return mPatchPanel->listAudioPorts(num_ports, ports);
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->listAudioPorts_l(num_ports, ports);
}
/* Get supported attributes for a given audio port */
@@ -4563,8 +4575,8 @@
return status;
}
- Mutex::Autolock _l(mLock);
- return mPatchPanel->getAudioPort(port);
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->getAudioPort_l(port);
}
/* Connect a patch between several source and sink ports */
@@ -4576,23 +4588,23 @@
return status;
}
- Mutex::Autolock _l(mLock);
- return mPatchPanel->createAudioPatch(patch, handle);
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->createAudioPatch_l(patch, handle);
}
/* Disconnect a patch */
status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
{
- Mutex::Autolock _l(mLock);
- return mPatchPanel->releaseAudioPatch(handle);
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->releaseAudioPatch_l(handle);
}
/* List connected audio ports and they attributes */
status_t AudioFlinger::listAudioPatches(
unsigned int* num_patches, struct audio_patch* patches) const
{
- Mutex::Autolock _l(mLock);
- return mPatchPanel->listAudioPatches(num_patches, patches);
+ audio_utils::lock_guard _l(mutex());
+ return mPatchPanel->listAudioPatches_l(num_patches, patches);
}
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 66aae3e..2c34144 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -29,6 +29,7 @@
#include "PatchCommandThread.h"
// External classes
+#include <audio_utils/mutex.h>
#include <audio_utils/FdToString.h>
#include <audio_utils/SimpleLog.h>
#include <media/IAudioFlinger.h>
@@ -64,187 +65,213 @@
// ---- begin IAudioFlinger interface
- status_t dump(int fd, const Vector<String16>& args) final;
+ status_t dump(int fd, const Vector<String16>& args) final EXCLUDES_AudioFlinger_Mutex;
status_t createTrack(const media::CreateTrackRequest& input,
- media::CreateTrackResponse& output) final;
+ media::CreateTrackResponse& output) final EXCLUDES_AudioFlinger_Mutex;
status_t createRecord(const media::CreateRecordRequest& input,
- media::CreateRecordResponse& output) final;
+ media::CreateRecordResponse& output) final EXCLUDES_AudioFlinger_Mutex;
- uint32_t sampleRate(audio_io_handle_t ioHandle) const final;
- audio_format_t format(audio_io_handle_t output) const final;
- size_t frameCount(audio_io_handle_t ioHandle) const final;
- size_t frameCountHAL(audio_io_handle_t ioHandle) const final;
- uint32_t latency(audio_io_handle_t output) const final;
+ uint32_t sampleRate(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+ audio_format_t format(audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
+ size_t frameCount(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+ size_t frameCountHAL(audio_io_handle_t ioHandle) const final EXCLUDES_AudioFlinger_Mutex;
+ uint32_t latency(audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
- status_t setMasterVolume(float value) final;
- status_t setMasterMute(bool muted) final;
- float masterVolume() const final;
- bool masterMute() const final;
+ status_t setMasterVolume(float value) final EXCLUDES_AudioFlinger_Mutex;
+ status_t setMasterMute(bool muted) final EXCLUDES_AudioFlinger_Mutex;
+ float masterVolume() const final EXCLUDES_AudioFlinger_Mutex;
+ bool masterMute() const final EXCLUDES_AudioFlinger_Mutex;
// Balance value must be within -1.f (left only) to 1.f (right only) inclusive.
- status_t setMasterBalance(float balance) final;
- status_t getMasterBalance(float* balance) const final;
+ status_t setMasterBalance(float balance) final EXCLUDES_AudioFlinger_Mutex;
+ status_t getMasterBalance(float* balance) const final EXCLUDES_AudioFlinger_Mutex;
status_t setStreamVolume(audio_stream_type_t stream, float value,
- audio_io_handle_t output) final;
- status_t setStreamMute(audio_stream_type_t stream, bool muted) final;
+ audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
+ status_t setStreamMute(audio_stream_type_t stream, bool muted) final
+ EXCLUDES_AudioFlinger_Mutex;
float streamVolume(audio_stream_type_t stream,
- audio_io_handle_t output) const final;
- bool streamMute(audio_stream_type_t stream) const final;
+ audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
+ bool streamMute(audio_stream_type_t stream) const final EXCLUDES_AudioFlinger_Mutex;
- status_t setMode(audio_mode_t mode) final;
+ status_t setMode(audio_mode_t mode) final EXCLUDES_AudioFlinger_Mutex;
- status_t setMicMute(bool state) final;
- bool getMicMute() const final;
+ status_t setMicMute(bool state) final EXCLUDES_AudioFlinger_Mutex;
+ bool getMicMute() const final EXCLUDES_AudioFlinger_Mutex;
- void setRecordSilenced(audio_port_handle_t portId, bool silenced) final;
+ void setRecordSilenced(audio_port_handle_t portId, bool silenced) final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) final;
- String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const final;
+ status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) final
+ EXCLUDES_AudioFlinger_Mutex;
+ String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const final
+ EXCLUDES_AudioFlinger_Mutex;
- void registerClient(const sp<media::IAudioFlingerClient>& client) final;
+ void registerClient(const sp<media::IAudioFlingerClient>& client) final
+ EXCLUDES_AudioFlinger_Mutex;
size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
- audio_channel_mask_t channelMask) const final;
+ audio_channel_mask_t channelMask) const final EXCLUDES_AudioFlinger_Mutex;
status_t openOutput(const media::OpenOutputRequest& request,
- media::OpenOutputResponse* response) final;
+ media::OpenOutputResponse* response) final EXCLUDES_AudioFlinger_Mutex;
audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
- audio_io_handle_t output2) final;
+ audio_io_handle_t output2) final EXCLUDES_AudioFlinger_Mutex;
- status_t closeOutput(audio_io_handle_t output) final;
+ status_t closeOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
- status_t suspendOutput(audio_io_handle_t output) final;
+ status_t suspendOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
- status_t restoreOutput(audio_io_handle_t output) final;
+ status_t restoreOutput(audio_io_handle_t output) final EXCLUDES_AudioFlinger_Mutex;
status_t openInput(const media::OpenInputRequest& request,
- media::OpenInputResponse* response) final;
+ media::OpenInputResponse* response) final EXCLUDES_AudioFlinger_Mutex;
- status_t closeInput(audio_io_handle_t input) final;
+ status_t closeInput(audio_io_handle_t input) final EXCLUDES_AudioFlinger_Mutex;
- status_t setVoiceVolume(float volume) final;
+ status_t setVoiceVolume(float volume) final EXCLUDES_AudioFlinger_Mutex;
status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
- audio_io_handle_t output) const final;
+ audio_io_handle_t output) const final EXCLUDES_AudioFlinger_Mutex;
- uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const final;
+ uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const final
+ EXCLUDES_AudioFlinger_Mutex;
// This is the binder API. For the internal API see nextUniqueId().
- audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) final;
+ audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) final
+ EXCLUDES_AudioFlinger_Mutex;
- void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) final;
+ void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) final
+ EXCLUDES_AudioFlinger_Mutex;
- void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) final;
+ void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t queryNumberEffects(uint32_t* numEffects) const final;
+ status_t queryNumberEffects(uint32_t* numEffects) const final EXCLUDES_AudioFlinger_Mutex;
- status_t queryEffect(uint32_t index, effect_descriptor_t* descriptor) const final;
+ status_t queryEffect(uint32_t index, effect_descriptor_t* descriptor) const final
+ EXCLUDES_AudioFlinger_Mutex;
status_t getEffectDescriptor(const effect_uuid_t* pUuid,
const effect_uuid_t* pTypeUuid,
uint32_t preferredTypeFlag,
- effect_descriptor_t* descriptor) const final;
+ effect_descriptor_t* descriptor) const final EXCLUDES_AudioFlinger_Mutex;
status_t createEffect(const media::CreateEffectRequest& request,
- media::CreateEffectResponse* response) final;
+ media::CreateEffectResponse* response) final EXCLUDES_AudioFlinger_Mutex;
status_t moveEffects(audio_session_t sessionId, audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput) final;
+ audio_io_handle_t dstOutput) final EXCLUDES_AudioFlinger_Mutex;
void setEffectSuspended(int effectId,
audio_session_t sessionId,
- bool suspended) final;
+ bool suspended) final EXCLUDES_AudioFlinger_Mutex;
- audio_module_handle_t loadHwModule(const char* name) final;
+ audio_module_handle_t loadHwModule(const char* name) final EXCLUDES_AudioFlinger_Mutex;
- uint32_t getPrimaryOutputSamplingRate() const final;
- size_t getPrimaryOutputFrameCount() const final;
+ uint32_t getPrimaryOutputSamplingRate() const final EXCLUDES_AudioFlinger_Mutex;
+ size_t getPrimaryOutputFrameCount() const final EXCLUDES_AudioFlinger_Mutex;
- status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) final;
+ status_t setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) final
+ EXCLUDES_AudioFlinger_Mutex;
/* Get attributes for a given audio port */
- status_t getAudioPort(struct audio_port_v7* port) const final;
+ status_t getAudioPort(struct audio_port_v7* port) const final EXCLUDES_AudioFlinger_Mutex;
/* Create an audio patch between several source and sink ports */
status_t createAudioPatch(const struct audio_patch *patch,
- audio_patch_handle_t* handle) final;
+ audio_patch_handle_t* handle) final EXCLUDES_AudioFlinger_Mutex;
/* Release an audio patch */
- status_t releaseAudioPatch(audio_patch_handle_t handle) final;
+ status_t releaseAudioPatch(audio_patch_handle_t handle) final EXCLUDES_AudioFlinger_Mutex;
/* List existing audio patches */
status_t listAudioPatches(unsigned int* num_patches,
- struct audio_patch* patches) const final;
+ struct audio_patch* patches) const final EXCLUDES_AudioFlinger_Mutex;
/* Set audio port configuration */
- status_t setAudioPortConfig(const struct audio_port_config* config) final;
+ status_t setAudioPortConfig(const struct audio_port_config* config) final
+ EXCLUDES_AudioFlinger_Mutex;
/* Get the HW synchronization source used for an audio session */
- audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) final;
+ audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) final
+ EXCLUDES_AudioFlinger_Mutex;
/* Indicate JAVA services are ready (scheduling, power management ...) */
- status_t systemReady() final;
+ status_t systemReady() final EXCLUDES_AudioFlinger_Mutex;
status_t audioPolicyReady() final { mAudioPolicyReady.store(true); return NO_ERROR; }
- status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const final;
+ status_t getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) const final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t setAudioHalPids(const std::vector<pid_t>& pids) final;
+ status_t setAudioHalPids(const std::vector<pid_t>& pids) final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) final;
+ status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) final
+ EXCLUDES_AudioFlinger_Mutex;
status_t updateSecondaryOutputs(
- const TrackSecondaryOutputsMap& trackSecondaryOutputs) final;
+ const TrackSecondaryOutputsMap& trackSecondaryOutputs) final
+ EXCLUDES_AudioFlinger_Mutex;
status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
- std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final;
+ std::vector<media::audio::common::AudioMMapPolicyInfo>* policyInfos) final
+ EXCLUDES_AudioFlinger_Mutex;
- int32_t getAAudioMixerBurstCount() const final;
+ int32_t getAAudioMixerBurstCount() const final EXCLUDES_AudioFlinger_Mutex;
- int32_t getAAudioHardwareBurstMinUsec() const final;
+ int32_t getAAudioHardwareBurstMinUsec() const final EXCLUDES_AudioFlinger_Mutex;
status_t setDeviceConnectedState(const struct audio_port_v7* port,
- media::DeviceConnectedState state) final;
+ media::DeviceConnectedState state) final EXCLUDES_AudioFlinger_Mutex;
- status_t setSimulateDeviceConnections(bool enabled) final;
+ status_t setSimulateDeviceConnections(bool enabled) final EXCLUDES_AudioFlinger_Mutex;
status_t setRequestedLatencyMode(
- audio_io_handle_t output, audio_latency_mode_t mode) final;
+ audio_io_handle_t output, audio_latency_mode_t mode) final
+ EXCLUDES_AudioFlinger_Mutex;
status_t getSupportedLatencyModes(audio_io_handle_t output,
- std::vector<audio_latency_mode_t>* modes) const final;
+ std::vector<audio_latency_mode_t>* modes) const final EXCLUDES_AudioFlinger_Mutex;
- status_t setBluetoothVariableLatencyEnabled(bool enabled) final;
+ status_t setBluetoothVariableLatencyEnabled(bool enabled) final EXCLUDES_AudioFlinger_Mutex;
- status_t isBluetoothVariableLatencyEnabled(bool* enabled) const final;
+ status_t isBluetoothVariableLatencyEnabled(bool* enabled) const final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t supportsBluetoothVariableLatency(bool* support) const final;
+ status_t supportsBluetoothVariableLatency(bool* support) const final
+ EXCLUDES_AudioFlinger_Mutex;
status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
- sp<media::ISoundDose>* soundDose) const final;
+ sp<media::ISoundDose>* soundDose) const final EXCLUDES_AudioFlinger_Mutex;
- status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) final;
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t getAudioPolicyConfig(media::AudioPolicyConfig* config) final;
+ status_t getAudioPolicyConfig(media::AudioPolicyConfig* config) final
+ EXCLUDES_AudioFlinger_Mutex;
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
- const std::function<status_t()>& delegate) final;
+ const std::function<status_t()>& delegate) final EXCLUDES_AudioFlinger_Mutex;
// ---- end of IAudioFlinger interface
// ---- begin IAfClientCallback interface
- Mutex& clientMutex() const final { return mClientLock; }
- void removeClient_l(pid_t pid) final;
- void removeNotificationClient(pid_t pid) final;
+ audio_utils::mutex& clientMutex() const final
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_ClientMutex) {
+ return mClientMutex;
+ }
+ void removeClient_l(pid_t pid) REQUIRES(clientMutex()) final;
+ void removeNotificationClient(pid_t pid) final EXCLUDES_AudioFlinger_Mutex;
status_t moveAuxEffectToIo(
int effectId,
const sp<IAfPlaybackThread>& dstThread,
- sp<IAfPlaybackThread>* srcThread) final;
+ sp<IAfPlaybackThread>* srcThread) final EXCLUDES_AudioFlinger_Mutex;
// ---- end of IAfClientCallback interface
@@ -255,31 +282,35 @@
// below also used by IAfMelReporterCallback, IAfPatchPanelCallback
const sp<PatchCommandThread>& getPatchCommandThread() final { return mPatchCommandThread; }
status_t addEffectToHal(
- const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final;
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final
+ EXCLUDES_AudioFlinger_HardwareMutex;
status_t removeEffectFromHal(
- const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final;
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect) final
+ EXCLUDES_AudioFlinger_HardwareMutex;
// ---- end of IAfDeviceEffectManagerCallback interface
// ---- begin IAfMelReporterCallback interface
// below also used by IAfThreadCallback
- Mutex& mutex() const final { return mLock; }
- sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final REQUIRES(mLock);
+ audio_utils::mutex& mutex() const final
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex)
+ EXCLUDES_BELOW_AudioFlinger_Mutex { return mMutex; }
+ sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const final
+ REQUIRES(mutex());
// ---- end of IAfMelReporterCallback interface
// ---- begin IAfPatchPanelCallback interface
- void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final;
- void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final;
+ void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final REQUIRES(mutex());
+ void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final REQUIRES(mutex());
// return thread associated with primary hardware device, or NULL
- IAfPlaybackThread* primaryPlaybackThread_l() const final;
- IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final;
- IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final;
- IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final;
- void lock() const final ACQUIRE(mLock) { mLock.lock(); }
- void unlock() const final RELEASE(mLock) { mLock.unlock(); }
+ IAfPlaybackThread* primaryPlaybackThread_l() const final REQUIRES(mutex());
+ IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const final
+ REQUIRES(mutex());
+ IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const final REQUIRES(mutex());
+ IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const final REQUIRES(mutex());
sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
audio_io_handle_t* input,
audio_config_t* config,
@@ -288,36 +319,40 @@
audio_source_t source,
audio_input_flags_t flags,
audio_devices_t outputDevice,
- const String8& outputDeviceAddress) final;
+ const String8& outputDeviceAddress) final REQUIRES(mutex());
sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
audio_io_handle_t* output,
audio_config_t* halConfig,
audio_config_base_t* mixerConfig,
audio_devices_t deviceType,
const String8& address,
- audio_output_flags_t flags) final;
+ audio_output_flags_t flags) final REQUIRES(mutex());
const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
- getAudioHwDevs_l() const final { return mAudioHwDevs; }
+ getAudioHwDevs_l() const final REQUIRES(mutex()) { return mAudioHwDevs; }
void updateDownStreamPatches_l(const struct audio_patch* patch,
- const std::set<audio_io_handle_t>& streams) final;
- void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final;
+ const std::set<audio_io_handle_t>& streams) final REQUIRES(mutex());
+ void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) final
+ REQUIRES(mutex());
// ---- end of IAfPatchPanelCallback interface
// ----- begin IAfThreadCallback interface
- bool isNonOffloadableGlobalEffectEnabled_l() const final;
+ bool isNonOffloadableGlobalEffectEnabled_l() const final REQUIRES(mutex());
bool btNrecIsOff() const final { return mBtNrecIsOff.load(); }
- float masterVolume_l() const final;
- bool masterMute_l() const final;
- float getMasterBalance_l() const;
- // no range check, AudioFlinger::mLock held
- bool streamMute_l(audio_stream_type_t stream) const final { return mStreamTypes[stream].mute; }
+ float masterVolume_l() const final REQUIRES(mutex());
+ bool masterMute_l() const final REQUIRES(mutex());
+ float getMasterBalance_l() const REQUIRES(mutex());
+ // no range check, AudioFlinger::mutex() held
+ bool streamMute_l(audio_stream_type_t stream) const final REQUIRES(mutex()) {
+ return mStreamTypes[stream].mute;
+ }
audio_mode_t getMode() const final { return mMode; }
bool isLowRamDevice() const final { return mIsLowRamDevice; }
uint32_t getScreenState() const final { return mScreenState; }
- std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final;
+ std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const final
+ REQUIRES(mutex());
const sp<IAfPatchPanel>& getPatchPanel() const final { return mPatchPanel; }
const sp<MelReporter>& getMelReporter() const final { return mMelReporter; }
const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const final {
@@ -329,34 +364,38 @@
// effect belongs to an effect chain in mOrphanEffectChains, the chain is updated
// and removed from mOrphanEffectChains if it does not contain any effect.
// Return true if the effect was found in mOrphanEffectChains, false otherwise.
- bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final;
+ bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) final
+ EXCLUDES_AudioFlinger_Mutex;
- status_t moveEffectChain_l(audio_session_t sessionId,
- IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final;
+ status_t moveEffectChain_ll(audio_session_t sessionId,
+ IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) final
+ REQUIRES(mutex(), audio_utils::ThreadBase_Mutex);
// This is a helper that is called during incoming binder calls.
// Requests media.log to start merging log buffers
void requestLogMerge() final;
- sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final;
+ sp<NBLog::Writer> newWriter_l(size_t size, const char *name) final REQUIRES(mutex());
void unregisterWriter(const sp<NBLog::Writer>& writer) final;
sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
audio_session_t triggerSession,
audio_session_t listenerSession,
const audioflinger::SyncEventCallback& callBack,
- const wp<IAfTrackBase>& cookie) final;
+ const wp<IAfTrackBase>& cookie) final EXCLUDES_AudioFlinger_Mutex;
void ioConfigChanged(audio_io_config_event_t event,
const sp<AudioIoDescriptor>& ioDesc,
- pid_t pid = 0) final;
- void onNonOffloadableGlobalEffectEnable() final;
+ pid_t pid = 0) final EXCLUDES_AudioFlinger_ClientMutex;
+ void onNonOffloadableGlobalEffectEnable() final EXCLUDES_AudioFlinger_Mutex;
void onSupportedLatencyModesChanged(
- audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final;
+ audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) final
+ EXCLUDES_AudioFlinger_ClientMutex;
// ---- end of IAfThreadCallback interface
/* List available audio ports and their attributes */
- status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const;
+ status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const
+ EXCLUDES_AudioFlinger_Mutex;
sp<EffectsFactoryHalInterface> getEffectsFactory();
@@ -373,7 +412,7 @@
audio_session_t *sessionId,
const sp<MmapStreamCallback>& callback,
sp<MmapStreamInterface>& interface,
- audio_port_handle_t *handle);
+ audio_port_handle_t *handle) EXCLUDES_AudioFlinger_Mutex;
private:
// FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
static const size_t kLogMemorySize = 400 * 1024;
@@ -381,32 +420,33 @@
// When a log writer is unregistered, it is done lazily so that media.log can continue to see it
// for as long as possible. The memory is only freed when it is needed for another log writer.
Vector< sp<NBLog::Writer> > mUnregisteredWriters;
- Mutex mUnregisteredWritersLock;
+ audio_utils::mutex& unregisteredWritersMutex() const { return mUnregisteredWritersMutex; }
+ mutable audio_utils::mutex mUnregisteredWritersMutex;
AudioFlinger() ANDROID_API;
~AudioFlinger() override;
// call in any IAudioFlinger method that accesses mPrimaryHardwareDev
- status_t initCheck() const { return mPrimaryHardwareDev == NULL ?
+ status_t initCheck() const { return mPrimaryHardwareDev == NULL ?
NO_INIT : NO_ERROR; }
// RefBase
void onFirstRef() override;
AudioHwDevice* findSuitableHwDev_l(audio_module_handle_t module,
- audio_devices_t deviceType);
+ audio_devices_t deviceType) REQUIRES(mutex());
// incremented by 2 when screen state changes, bit 0 == 1 means "off"
- // AudioFlinger::setParameters() updates with mLock.
+ // AudioFlinger::setParameters() updates with mutex().
std::atomic_uint32_t mScreenState{};
void dumpPermissionDenial(int fd, const Vector<String16>& args);
- void dumpClients(int fd, const Vector<String16>& args);
- void dumpInternals(int fd, const Vector<String16>& args);
+ void dumpClients_ll(int fd, const Vector<String16>& args) REQUIRES(mutex(), clientMutex());
+ void dumpInternals_l(int fd, const Vector<String16>& args) REQUIRES(mutex());
SimpleLog mThreadLog{16}; // 16 Thread history limit
- void dumpToThreadLog_l(const sp<IAfThreadBase>& thread);
+ void dumpToThreadLog_l(const sp<IAfThreadBase>& thread) REQUIRES(mutex());
// --- Notification Client ---
class NotificationClient : public IBinder::DeathRecipient {
@@ -453,8 +493,8 @@
bool mPendingRequests;
// Mutex and condition variable around mPendingRequests' value
- Mutex mMutex;
- Condition mCond;
+ audio_utils::mutex mMutex;
+ audio_utils::condition_variable mCondition;
// Duration of the sleep period after a processed request
static const int kPostTriggerSleepPeriod = 1000000;
@@ -467,7 +507,8 @@
// If none found, AUDIO_IO_HANDLE_NONE is returned.
template <typename T>
static audio_io_handle_t findIoHandleBySessionId_l(
- audio_session_t sessionId, const T& threads) {
+ audio_session_t sessionId, const T& threads)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) {
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
for (size_t i = 0; i < threads.size(); i++) {
@@ -482,14 +523,14 @@
return io;
}
- IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
- IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
+ IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const REQUIRES(mutex());
+ IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const REQUIRES(mutex());
- sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
- std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;
+ sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const REQUIRES(mutex());
+ std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const REQUIRES(mutex());
- void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
+ static void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
void closeInputFinish(const sp<IAfRecordThread>& thread);
// Allocate an audio_unique_id_t.
@@ -507,21 +548,22 @@
audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;
// return thread associated with primary hardware device, or NULL
- DeviceTypeSet primaryOutputDevice_l() const;
+ DeviceTypeSet primaryOutputDevice_l() const REQUIRES(mutex());
// return the playback thread with smallest HAL buffer size, and prefer fast
- IAfPlaybackThread* fastPlaybackThread_l() const;
+ IAfPlaybackThread* fastPlaybackThread_l() const REQUIRES(mutex());
- sp<IAfThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId);
+ sp<IAfThreadBase> getEffectThread_l(audio_session_t sessionId, int effectId)
+ REQUIRES(mutex());
- IAfThreadBase* hapticPlaybackThread_l() const;
+ IAfThreadBase* hapticPlaybackThread_l() const REQUIRES(mutex());
void updateSecondaryOutputsForTrack_l(
IAfTrack* track,
IAfPlaybackThread* thread,
- const std::vector<audio_io_handle_t>& secondaryOutputs) const;
+ const std::vector<audio_io_handle_t>& secondaryOutputs) const REQUIRES(mutex());
- bool isSessionAcquired_l(audio_session_t audioSession);
+ bool isSessionAcquired_l(audio_session_t audioSession) REQUIRES(mutex());
// Store an effect chain to mOrphanEffectChains keyed vector.
// Called when a thread exits and effects are still attached to it.
@@ -530,17 +572,18 @@
// return ALREADY_EXISTS if a chain with the same session already exists in
// mOrphanEffectChains. Note that this should never happen as there is only one
// chain for a given session and it is attached to only one thread at a time.
- status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain);
+ status_t putOrphanEffectChain_l(const sp<IAfEffectChain>& chain) REQUIRES(mutex());
// Get an effect chain for the specified session in mOrphanEffectChains and remove
// it if found. Returns 0 if not found (this is the most common case).
- sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session);
+ sp<IAfEffectChain> getOrphanEffectChain_l(audio_session_t session) REQUIRES(mutex());
- std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();
+ std::vector< sp<IAfEffectModule> > purgeStaleEffects_l() REQUIRES(mutex());
- void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
- void forwardParametersToDownstreamPatches_l(
+ void broadcastParametersToRecordThreads_l(const String8& keyValuePairs) REQUIRES(mutex());
+ void forwardParametersToDownstreamPatches_l(
audio_io_handle_t upStream, const String8& keyValuePairs,
- const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr);
+ const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr)
+ REQUIRES(mutex());
// for mAudioSessionRefs only
struct AudioSessionRef {
@@ -552,22 +595,24 @@
int mCnt;
};
- mutable Mutex mLock;
+ mutable audio_utils::mutex mMutex;
// protects mClients and mNotificationClients.
- // must be locked after mLock and ThreadBase::mLock if both must be locked
- // avoids acquiring AudioFlinger::mLock from inside thread loop.
+ // must be locked after mutex() and ThreadBase::mutex() if both must be locked
+ // avoids acquiring AudioFlinger::mutex() from inside thread loop.
- mutable Mutex mClientLock;
+ mutable audio_utils::mutex mClientMutex;
- // protected by mClientLock
- DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client()
+ DefaultKeyedVector<pid_t, wp<Client>> mClients GUARDED_BY(clientMutex()); // see ~Client()
- mutable Mutex mHardwareLock;
- // NOTE: If both mLock and mHardwareLock mutexes must be held,
- // always take mLock before mHardwareLock
+ audio_utils::mutex& hardwareMutex() const { return mHardwareMutex; }
+
+ mutable audio_utils::mutex mHardwareMutex;
+ // NOTE: If both mMutex and mHardwareMutex mutexes must be held,
+ // always take mMutex before mHardwareMutex
std::atomic<AudioHwDevice*> mPrimaryHardwareDev = nullptr;
- DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*> mAudioHwDevs{nullptr /* defValue */};
+ DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*> mAudioHwDevs
+ GUARDED_BY(hardwareMutex()) {nullptr /* defValue */};
const sp<DevicesFactoryHalInterface> mDevicesFactoryHal =
DevicesFactoryHalInterface::create();
@@ -602,20 +647,18 @@
};
mutable hardware_call_state mHardwareStatus = AUDIO_HW_IDLE; // for dump only
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfPlaybackThread>> mPlaybackThreads
+ GUARDED_BY(mutex());
+ stream_type_t mStreamTypes[AUDIO_STREAM_CNT] GUARDED_BY(mutex());
- DefaultKeyedVector<audio_io_handle_t, sp<IAfPlaybackThread>> mPlaybackThreads;
- stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
+ float mMasterVolume GUARDED_BY(mutex()) = 1.f;
+ bool mMasterMute GUARDED_BY(mutex()) = false;
+ float mMasterBalance GUARDED_BY(mutex()) = 0.f;
- // member variables below are protected by mLock
- float mMasterVolume = 1.f;
- bool mMasterMute = false;
- float mMasterBalance = 0.f;
- // end of variables protected by mLock
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfRecordThread>> mRecordThreads GUARDED_BY(mutex());
- DefaultKeyedVector<audio_io_handle_t, sp<IAfRecordThread>> mRecordThreads;
-
- // protected by mClientLock
- DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
+ DefaultKeyedVector<pid_t, sp<NotificationClient>> mNotificationClients
+ GUARDED_BY(clientMutex());
// updated by atomic_fetch_add_explicit
volatile atomic_uint_fast32_t mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX]; // ctor init
@@ -623,34 +666,36 @@
std::atomic<audio_mode_t> mMode = AUDIO_MODE_INVALID;
std::atomic<bool> mBtNrecIsOff = false;
- // protected by mLock
- Vector<AudioSessionRef*> mAudioSessionRefs;
+ Vector<AudioSessionRef*> mAudioSessionRefs GUARDED_BY(mutex());
- AudioHwDevice* loadHwModule_l(const char *name);
+ AudioHwDevice* loadHwModule_ll(const char *name) REQUIRES(mutex(), hardwareMutex());
// sync events awaiting for a session to be created.
- std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents;
+ std::list<sp<audioflinger::SyncEvent>> mPendingSyncEvents GUARDED_BY(mutex());
// Effect chains without a valid thread
- DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains;
+ DefaultKeyedVector<audio_session_t, sp<IAfEffectChain>> mOrphanEffectChains
+ GUARDED_BY(mutex());
// list of sessions for which a valid HW A/V sync ID was retrieved from the HAL
- DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds;
+ DefaultKeyedVector<audio_session_t, audio_hw_sync_t> mHwAvSyncIds GUARDED_BY(mutex());
// list of MMAP stream control threads. Those threads allow for wake lock, routing
// and volume control for activity on the associated MMAP stream at the HAL.
// Audio data transfer is directly handled by the client creating the MMAP stream
- DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads;
+ DefaultKeyedVector<audio_io_handle_t, sp<IAfMmapThread>> mMmapThreads GUARDED_BY(mutex());
- sp<Client> registerPid(pid_t pid); // always returns non-0
+ sp<Client> registerPid(pid_t pid) EXCLUDES_AudioFlinger_ClientMutex; // always returns non-0
// for use from destructor
- status_t closeOutput_nonvirtual(audio_io_handle_t output);
- status_t closeInput_nonvirtual(audio_io_handle_t input);
- void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId);
+ status_t closeOutput_nonvirtual(audio_io_handle_t output) EXCLUDES_AudioFlinger_Mutex;
+ status_t closeInput_nonvirtual(audio_io_handle_t input) EXCLUDES_AudioFlinger_Mutex;
+ void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId)
+ REQUIRES(mutex());
- status_t checkStreamType(audio_stream_type_t stream) const;
+ static status_t checkStreamType(audio_stream_type_t stream);
+ // no mutex needed.
void filterReservedParameters(String8& keyValuePairs, uid_t callingUid);
void logFilteredParameters(size_t originalKVPSize, const String8& originalKVPs,
size_t rejectedKVPSize, const String8& rejectedKVPs,
@@ -661,12 +706,13 @@
size_t getClientSharedHeapSize() const;
std::atomic<bool> mIsLowRamDevice = true;
- bool mIsDeviceTypeKnown = false;
- int64_t mTotalMemory = 0;
+ bool mIsDeviceTypeKnown GUARDED_BY(mutex()) = false;
+ int64_t mTotalMemory GUARDED_BY(mutex()) = 0;
std::atomic<size_t> mClientSharedHeapSize = kMinimumClientSharedHeapSizeBytes;
static constexpr size_t kMinimumClientSharedHeapSizeBytes = 1024 * 1024; // 1MB
- nsecs_t mGlobalEffectEnableTime = 0; // when a global effect was last enabled
+ // when a global effect was last enabled
+ nsecs_t mGlobalEffectEnableTime GUARDED_BY(mutex()) = 0;
/* const */ sp<IAfPatchPanel> mPatchPanel;
@@ -677,26 +723,28 @@
/* const */ sp<DeviceEffectManager> mDeviceEffectManager; // set onFirstRef
/* const */ sp<MelReporter> mMelReporter; // set onFirstRef
- bool mSystemReady = false;
+ bool mSystemReady GUARDED_BY(mutex()) = false;
std::atomic<bool> mAudioPolicyReady = false;
- mediautils::UidInfo mUidInfo;
+ mediautils::UidInfo mUidInfo GUARDED_BY(mutex());
+ // no mutex needed.
SimpleLog mRejectedSetParameterLog;
SimpleLog mAppSetParameterLog;
SimpleLog mSystemSetParameterLog;
- std::vector<media::AudioVibratorInfo> mAudioVibratorInfos;
+ std::vector<media::AudioVibratorInfo> mAudioVibratorInfos GUARDED_BY(mutex());
static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER;
std::map<media::audio::common::AudioMMapPolicyType,
- std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos;
- int32_t mAAudioBurstsPerBuffer = 0;
- int32_t mAAudioHwBurstMinMicros = 0;
+ std::vector<media::audio::common::AudioMMapPolicyInfo>> mPolicyInfos
+ GUARDED_BY(mutex());
+ int32_t mAAudioBurstsPerBuffer GUARDED_BY(mutex()) = 0;
+ int32_t mAAudioHwBurstMinMicros GUARDED_BY(mutex()) = 0;
/** Interface for interacting with the AudioService. */
- mediautils::atomic_sp<IAudioManager> mAudioManager;
+ mediautils::atomic_sp<IAudioManager> mAudioManager;
// Bluetooth Variable latency control logic is enabled or disabled
std::atomic<bool> mBluetoothLatencyModesEnabled = true;
diff --git a/services/audioflinger/Client.h b/services/audioflinger/Client.h
index b2e3cf7..ff0d751 100644
--- a/services/audioflinger/Client.h
+++ b/services/audioflinger/Client.h
@@ -17,8 +17,8 @@
#pragma once
#include <afutils/AllocatorFactory.h>
+#include <audio_utils/mutex.h>
#include <android-base/macros.h> // DISALLOW_COPY_AND_ASSIGN
-#include <utils/Mutex.h>
#include <utils/RefBase.h> // avoid transitive dependency
// TODO(b/291318727) Move to nested namespace
@@ -28,13 +28,16 @@
class IAfClientCallback : public virtual RefBase {
public:
- virtual Mutex& clientMutex() const = 0;
- virtual void removeClient_l(pid_t pid) = 0;
- virtual void removeNotificationClient(pid_t pid) = 0;
+ virtual audio_utils::mutex& clientMutex() const
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_ClientMutex) = 0;
+ virtual void removeClient_l(pid_t pid) REQUIRES(clientMutex()) = 0;
+ virtual void removeNotificationClient(pid_t pid) EXCLUDES_AudioFlinger_Mutex = 0;
+
+ // used indirectly by clients.
virtual status_t moveAuxEffectToIo(
int effectId,
const sp<IAfPlaybackThread>& dstThread,
- sp<IAfPlaybackThread>* srcThread) = 0; // used by indirectly by clients.
+ sp<IAfPlaybackThread>* srcThread) EXCLUDES_AudioFlinger_Mutex = 0;
};
class Client : public RefBase {
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 6636717..0a7be75 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -38,7 +38,7 @@
DeviceEffectManager::DeviceEffectManager(
const sp<IAfDeviceEffectManagerCallback>& afDeviceEffectManagerCallback)
: mAfDeviceEffectManagerCallback(afDeviceEffectManagerCallback),
- mMyCallback(new DeviceEffectManagerCallback(*this)) {}
+ mMyCallback(sp<DeviceEffectManagerCallback>::make(*this)) {}
void DeviceEffectManager::onFirstRef() {
mAfDeviceEffectManagerCallback->getPatchCommandThread()->addListener(this);
@@ -59,7 +59,7 @@
ALOGV("%s handle %d mHalHandle %d device sink %08x",
__func__, handle, patch.mHalHandle,
patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (auto& effect : mDeviceEffects) {
status_t status = effect.second->onCreatePatch(handle, patch);
ALOGV("%s Effect onCreatePatch status %d", __func__, status);
@@ -69,13 +69,13 @@
void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
ALOGV("%s", __func__);
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (auto& effect : mDeviceEffects) {
effect.second->onReleasePatch(handle);
}
}
-// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
+// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mutex() held
sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
effect_descriptor_t *descriptor,
const AudioDeviceTypeAddr& device,
@@ -97,7 +97,7 @@
}
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
auto iter = mDeviceEffects.find(device);
if (iter != mDeviceEffects.end()) {
effect = iter->second;
@@ -131,6 +131,7 @@
return handle;
}
+/* static */
status_t DeviceEffectManager::checkEffectCompatibility(
const effect_descriptor_t *desc) {
const sp<EffectsFactoryHalInterface> effectsFactory =
@@ -157,6 +158,7 @@
return NO_ERROR;
}
+/* static */
status_t DeviceEffectManager::createEffectHal(
const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect) {
@@ -173,7 +175,7 @@
void DeviceEffectManager::dump(int fd)
NO_THREAD_SAFETY_ANALYSIS // conditional try lock
{
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
if (!locked) {
String8 result("DeviceEffectManager may be deadlocked\n");
write(fd, result.c_str(), result.size());
@@ -190,13 +192,13 @@
}
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
}
size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mDeviceEffects.erase(effect->device());
return mDeviceEffects.size();
}
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index 6111030..6a5c889 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -20,8 +20,6 @@
#include "IAfEffect.h"
#include "PatchCommandThread.h"
-#include <utils/Mutex.h> // avoid transitive dependency
-
namespace android {
class IAfDeviceEffectManagerCallback : public virtual RefBase {
@@ -30,9 +28,11 @@
virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
virtual status_t addEffectToHal(
- const struct audio_port_config* device, const sp<EffectHalInterface>& effect) = 0;
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect)
+ EXCLUDES_AudioFlinger_HardwareMutex = 0;
virtual status_t removeEffectFromHal(
- const struct audio_port_config* device, const sp<EffectHalInterface>& effect) = 0;
+ const struct audio_port_config* device, const sp<EffectHalInterface>& effect)
+ EXCLUDES_AudioFlinger_HardwareMutex= 0;
};
class DeviceEffectManagerCallback;
@@ -53,10 +53,10 @@
int *enabled,
status_t *status,
bool probe,
- bool notifyFramesProcessed);
+ bool notifyFramesProcessed) REQUIRES(audio_utils::AudioFlinger_Mutex);
size_t removeEffect(const sp<IAfDeviceEffectProxy>& effect);
- status_t createEffectHal(const effect_uuid_t *pEffectUuid,
+ static status_t createEffectHal(const effect_uuid_t *pEffectUuid,
int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect);
status_t addEffectToHal(const struct audio_port_config *device,
@@ -71,16 +71,21 @@
// PatchCommandThread::PatchCommandListener implementation
void onCreateAudioPatch(audio_patch_handle_t handle,
- const IAfPatchPanel::Patch& patch) final;
- void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+ const IAfPatchPanel::Patch& patch) final
+ EXCLUDES_DeviceEffectManager_Mutex;
+ void onReleaseAudioPatch(audio_patch_handle_t handle) final
+ EXCLUDES_DeviceEffectManager_Mutex;
private:
- status_t checkEffectCompatibility(const effect_descriptor_t *desc);
+ static status_t checkEffectCompatibility(const effect_descriptor_t *desc);
- Mutex mLock;
+ audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::DeviceEffectManager_Mutex) {
+ return mMutex;
+ }
+ mutable audio_utils::mutex mMutex;
const sp<IAfDeviceEffectManagerCallback> mAfDeviceEffectManagerCallback;
const sp<DeviceEffectManagerCallback> mMyCallback;
- std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects;
+ std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects GUARDED_BY(mutex());
};
class DeviceEffectManagerCallback : public EffectCallbackInterface {
@@ -89,55 +94,54 @@
: mManager(manager) {}
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
- int32_t sessionId, int32_t deviceId,
- sp<EffectHalInterface> *effect) override {
+ int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect) final {
return mManager.createEffectHal(pEffectUuid, sessionId, deviceId, effect);
}
status_t allocateHalBuffer(size_t size __unused,
- sp<EffectBufferHalInterface>* buffer __unused) override { return NO_ERROR; }
- bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) override {
+ sp<EffectBufferHalInterface>* buffer __unused) final { return NO_ERROR; }
+ bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect __unused) final {
return false;
}
- audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; }
- bool isOutput() const override { return false; }
- bool isOffload() const override { return false; }
- bool isOffloadOrDirect() const override { return false; }
- bool isOffloadOrMmap() const override { return false; }
- bool isSpatializer() const override { return false; }
+ audio_io_handle_t io() const final { return AUDIO_IO_HANDLE_NONE; }
+ bool isOutput() const final { return false; }
+ bool isOffload() const final { return false; }
+ bool isOffloadOrDirect() const final { return false; }
+ bool isOffloadOrMmap() const final { return false; }
+ bool isSpatializer() const final { return false; }
- uint32_t sampleRate() const override { return 0; }
- audio_channel_mask_t inChannelMask(int id __unused) const override {
+ uint32_t sampleRate() const final { return 0; }
+ audio_channel_mask_t inChannelMask(int id __unused) const final {
return AUDIO_CHANNEL_NONE;
}
- uint32_t inChannelCount(int id __unused) const override { return 0; }
- audio_channel_mask_t outChannelMask() const override { return AUDIO_CHANNEL_NONE; }
- uint32_t outChannelCount() const override { return 0; }
+ uint32_t inChannelCount(int id __unused) const final { return 0; }
+ audio_channel_mask_t outChannelMask() const final { return AUDIO_CHANNEL_NONE; }
+ uint32_t outChannelCount() const final { return 0; }
- audio_channel_mask_t hapticChannelMask() const override { return AUDIO_CHANNEL_NONE; }
- size_t frameCount() const override { return 0; }
- uint32_t latency() const override { return 0; }
+ audio_channel_mask_t hapticChannelMask() const final { return AUDIO_CHANNEL_NONE; }
+ size_t frameCount() const final { return 0; }
+ uint32_t latency() const final { return 0; }
- status_t addEffectToHal(const sp<EffectHalInterface>& /* effect */) override {
+ status_t addEffectToHal(const sp<EffectHalInterface>& /* effect */) final {
return NO_ERROR;
}
- status_t removeEffectFromHal(const sp<EffectHalInterface>& /* effect */) override {
+ status_t removeEffectFromHal(const sp<EffectHalInterface>& /* effect */) final {
return NO_ERROR;
}
- bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) override;
- void setVolumeForOutput(float left __unused, float right __unused) const override {}
+ bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) final;
+ void setVolumeForOutput(float left __unused, float right __unused) const final {}
// check if effects should be suspended or restored when a given effect is enable or disabled
void checkSuspendOnEffectEnabled(const sp<IAfEffectBase>& effect __unused,
- bool enabled __unused, bool threadLocked __unused) override {}
- void resetVolume() override {}
- product_strategy_t strategy() const override { return static_cast<product_strategy_t>(0); }
- int32_t activeTrackCnt() const override { return 0; }
- void onEffectEnable(const sp<IAfEffectBase>& effect __unused) override {}
- void onEffectDisable(const sp<IAfEffectBase>& effect __unused) override {}
+ bool enabled __unused, bool threadLocked __unused) final {}
+ void resetVolume() final {}
+ product_strategy_t strategy() const final { return static_cast<product_strategy_t>(0); }
+ int32_t activeTrackCnt() const final { return 0; }
+ void onEffectEnable(const sp<IAfEffectBase>& effect __unused) final {}
+ void onEffectDisable(const sp<IAfEffectBase>& effect __unused) final {}
- wp<IAfEffectChain> chain() const override { return nullptr; }
+ wp<IAfEffectChain> chain() const final { return nullptr; }
bool isAudioPolicyReady() const final;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 223fc29..0f3e130 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -109,7 +109,7 @@
{
}
-// must be called with EffectModule::mLock held
+// must be called with EffectModule::mutex() held
status_t EffectBase::setEnabled_l(bool enabled)
{
@@ -155,7 +155,7 @@
{
status_t status;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
status = setEnabled_l(enabled);
}
if (fromHandle) {
@@ -190,13 +190,13 @@
void EffectBase::setSuspended(bool suspended)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mSuspended = suspended;
}
bool EffectBase::suspended() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mSuspended;
}
@@ -204,7 +204,7 @@
{
status_t status;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
int priority = handle->priority();
size_t size = mHandles.size();
IAfEffectHandle *controlHandle = nullptr;
@@ -250,7 +250,7 @@
product_strategy_t strategy = PRODUCT_STRATEGY_NONE;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if ((isInternal_l() && !mPolicyRegistered)
|| !getCallback()->isAudioPolicyReady()) {
@@ -284,7 +284,7 @@
return NO_ERROR;
}
}
- mPolicyLock.lock();
+ policyMutex().lock();
ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
__func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
if (doRegister) {
@@ -302,7 +302,7 @@
if (registered && doEnable) {
status = AudioSystem::setEffectEnabled(mId, enabled);
}
- mPolicyLock.unlock();
+ policyMutex().unlock();
return status;
}
@@ -310,7 +310,7 @@
ssize_t EffectBase::removeHandle(IAfEffectHandle *handle)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return removeHandle_l(handle);
}
@@ -348,7 +348,7 @@
return mHandles.size();
}
-// must be called with EffectModule::mLock held
+// must be called with EffectModule::mutex() held
IAfEffectHandle *EffectBase::controlHandle_l()
{
// the first valid handle in the list has control over the module
@@ -371,12 +371,12 @@
return mHandles.size();
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ssize_t numHandles = removeHandle_l(handle);
if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
- mLock.unlock();
+ mutex().unlock();
callback->updateOrphanEffectChains(this);
- mLock.lock();
+ mutex().lock();
}
return numHandles;
}
@@ -384,7 +384,7 @@
bool EffectBase::purgeHandles()
{
bool enabled = false;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
IAfEffectHandle *handle = controlHandle_l();
if (handle != NULL) {
enabled = handle->enabled();
@@ -509,7 +509,7 @@
result.appendFormat("\tEffect ID %d:\n", mId);
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
result.append("\t\tCould not lock Fx mutex:\n");
@@ -547,7 +547,7 @@
}
}
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
write(fd, result.c_str(), result.length());
@@ -616,7 +616,7 @@
}
bool EffectModule::updateState() {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
bool started = false;
switch (mState) {
@@ -672,7 +672,7 @@
void EffectModule::process()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mState == DESTROYED || mEffectInterface == 0 || mInBuffer == 0 || mOutBuffer == 0) {
return;
@@ -1016,7 +1016,7 @@
status_t EffectModule::init()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mEffectInterface == 0) {
return NO_INIT;
}
@@ -1046,12 +1046,12 @@
}
}
-// start() must be called with PlaybackThread::mLock or EffectChain::mLock held
+// start() must be called with PlaybackThread::mutex() or EffectChain::mutex() held
status_t EffectModule::start()
{
status_t status;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
status = start_l();
}
if (status == NO_ERROR) {
@@ -1086,7 +1086,7 @@
status_t EffectModule::stop()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return stop_l();
}
@@ -1123,7 +1123,7 @@
return status;
}
-// must be called with EffectChain::mLock held
+// must be called with EffectChain::mutex() held
void EffectModule::release_l()
{
if (mEffectInterface != 0) {
@@ -1159,7 +1159,7 @@
int32_t maxReplySize,
std::vector<uint8_t>* reply)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface.get());
if (mState == DESTROYED || mEffectInterface == 0) {
@@ -1356,7 +1356,7 @@
status_t EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
{
- AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
+ AutoLockReentrant _l(mutex(), mSetVolumeReentrantTid);
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1410,7 +1410,7 @@
return NO_ERROR;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1440,7 +1440,7 @@
status_t EffectModule::setMode(audio_mode_t mode)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1462,7 +1462,7 @@
status_t EffectModule::setAudioSource(audio_source_t source)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1480,7 +1480,7 @@
status_t EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mStatus != NO_ERROR) {
return mStatus;
}
@@ -1513,7 +1513,7 @@
bool EffectModule::isOffloaded() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mOffloaded;
}
@@ -1584,7 +1584,7 @@
status_t EffectModule::getConfigs(
audio_config_base_t* inputCfg, audio_config_base_t* outputCfg, bool* isOutput) const {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mConfig.inputCfg.mask == 0 || mConfig.outputCfg.mask == 0) {
return NO_INIT;
}
@@ -1619,7 +1619,7 @@
EffectBase::dump(fd, args);
String8 result;
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
result.append("\t\tStatus Engine:\n");
result.appendFormat("\t\t%03d %p\n",
@@ -1662,7 +1662,7 @@
}
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
}
@@ -1785,7 +1785,7 @@
Status EffectHandle::enable(int32_t* _aidl_return)
{
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ALOGV("enable %p", this);
sp<IAfEffectBase> effect = mEffect.promote();
if (effect == 0 || mDisconnected) {
@@ -1824,7 +1824,7 @@
Status EffectHandle::disable(int32_t* _aidl_return)
{
ALOGV("disable %p", this);
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfEffectBase> effect = mEffect.promote();
if (effect == 0 || mDisconnected) {
RETURN(DEAD_OBJECT);
@@ -1857,7 +1857,7 @@
void EffectHandle::disconnect(bool unpinIfLast)
{
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
ALOGV("disconnect(%s) %p", unpinIfLast ? "true" : "false", this);
if (mDisconnected) {
if (unpinIfLast) {
@@ -1884,7 +1884,7 @@
}
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l2(mClient->afClientCallback()->clientMutex());
+ audio_utils::lock_guard _l2(mClient->afClientCallback()->clientMutex());
mClient.clear();
}
}
@@ -1896,7 +1896,7 @@
Status EffectHandle::getConfig(
media::EffectConfig* _config, int32_t* _aidl_return) {
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfEffectBase> effect = mEffect.promote();
if (effect == nullptr || mDisconnected) {
RETURN(DEAD_OBJECT);
@@ -1963,7 +1963,7 @@
return disable(_aidl_return);
}
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfEffectBase> effect = mEffect.promote();
if (effect == 0 || mDisconnected) {
RETURN(DEAD_OBJECT);
@@ -2177,7 +2177,7 @@
std::vector<int> EffectChain::getEffectIds() const
{
std::vector<int> ids;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); i++) {
ids.push_back(mEffects[i]->id());
}
@@ -2186,11 +2186,11 @@
void EffectChain::clearInputBuffer()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
clearInputBuffer_l();
}
-// Must be called with EffectChain::mLock locked
+// Must be called with EffectChain::mutex() locked
void EffectChain::clearInputBuffer_l()
{
if (mInBuffer == NULL) {
@@ -2203,7 +2203,7 @@
mInBuffer->commit();
}
-// Must be called with EffectChain::mLock locked
+// Must be called with EffectChain::mutex() locked
void EffectChain::process_l()
{
// never process effects when:
@@ -2262,7 +2262,7 @@
audio_session_t sessionId,
bool pinned)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
effect = new EffectModule(mEffectCallback, desc, id, sessionId, pinned, AUDIO_PORT_HANDLE_NONE);
status_t lStatus = effect->status();
if (lStatus == NO_ERROR) {
@@ -2277,10 +2277,10 @@
// addEffect_l() must be called with IAfThreadBase::mutex() held
status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return addEffect_ll(effect);
}
-// addEffect_l() must be called with IAfThreadBase::mLock and EffectChain::mutex() held
+// addEffect_l() must be called with IAfThreadBase::mutex() and EffectChain::mutex() held
status_t EffectChain::addEffect_ll(const sp<IAfEffectModule>& effect)
{
effect->setCallback(mEffectCallback);
@@ -2447,7 +2447,7 @@
size_t EffectChain::removeEffect_l(const sp<IAfEffectModule>& effect,
bool release)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
@@ -2534,7 +2534,7 @@
return false;
}
-// setVolume_l() must be called with IAfThreadBase::mLock or EffectChain::mLock held
+// setVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
bool EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
{
uint32_t newLeft = *left;
@@ -2610,7 +2610,7 @@
return volumeControlIndex.has_value();
}
-// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mLock held
+// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
void EffectChain::resetVolume_l()
{
if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
@@ -2621,7 +2621,7 @@
}
// containsHapticGeneratingEffect_l must be called with
-// IAfThreadBase::mutex() or EffectChain::mLock held
+// IAfThreadBase::mutex() or EffectChain::mutex() held
bool EffectChain::containsHapticGeneratingEffect_l()
{
for (size_t i = 0; i < mEffects.size(); ++i) {
@@ -2634,7 +2634,7 @@
void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); ++i) {
mEffects[i]->setHapticIntensity(id, intensity);
}
@@ -2642,7 +2642,7 @@
void EffectChain::syncHalEffectsState()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); i++) {
if (mEffects[i]->state() == EffectModule::ACTIVE ||
mEffects[i]->state() == EffectModule::STOPPING) {
@@ -2660,7 +2660,7 @@
result.appendFormat(" %zu effects for session %d\n", numEffects, mSessionId);
if (numEffects) {
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
result.append("\tCould not lock mutex:\n");
@@ -2683,7 +2683,7 @@
}
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
} else {
write(fd, result.c_str(), result.size());
@@ -2732,12 +2732,12 @@
sp<IAfEffectModule> effect = desc->mEffect.promote();
if (effect != 0) {
effect->setSuspended(false);
- effect->lock();
+ effect->mutex().lock();
IAfEffectHandle *handle = effect->controlHandle_l();
if (handle != NULL && !handle->disconnected()) {
effect->setEnabled_l(handle->enabled());
}
- effect->unlock();
+ effect->mutex().unlock();
}
desc->mEffect.clear();
}
@@ -2887,7 +2887,7 @@
bool EffectChain::isNonOffloadableEnabled() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return isNonOffloadableEnabled_l();
}
@@ -2904,7 +2904,7 @@
void EffectChain::setThread(const sp<IAfThreadBase>& thread)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mEffectCallback->setThread(thread);
}
@@ -2933,7 +2933,7 @@
bool EffectChain::isRawCompatible() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (const auto &effect : mEffects) {
if (effect->isProcessImplemented()) {
return false;
@@ -2945,7 +2945,7 @@
bool EffectChain::isFastCompatible() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (const auto &effect : mEffects) {
if (effect->isProcessImplemented()
&& effect->isImplementationSoftware()) {
@@ -2957,7 +2957,7 @@
}
bool EffectChain::isBitPerfectCompatible() const {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (const auto &effect : mEffects) {
if (effect->isProcessImplemented()
&& effect->isImplementationSoftware()) {
@@ -2968,10 +2968,10 @@
return true;
}
-// isCompatibleWithThread_l() must be called with thread->mLock held
+// isCompatibleWithThread_l() must be called with thread->mutex() held
bool EffectChain::isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); i++) {
if (thread->checkEffectCompatibility_l(&(mEffects[i]->desc()), mSessionId) != NO_ERROR) {
return false;
@@ -3275,7 +3275,7 @@
status_t DeviceEffectProxy::setEnabled(bool enabled, bool fromHandle)
{
status_t status = EffectBase::setEnabled(enabled, fromHandle);
- Mutex::Autolock _l(mProxyLock);
+ audio_utils::lock_guard _l(proxyMutex());
if (status == NO_ERROR) {
for (auto& handle : mEffectHandles) {
Status bs;
@@ -3328,7 +3328,7 @@
ALOGV("%s sink %d checkPort status %d", __func__, i, status);
}
if (status == NO_ERROR || status == ALREADY_EXISTS) {
- Mutex::Autolock _l(mProxyLock);
+ audio_utils::lock_guard _l(proxyMutex());
mEffectHandles.emplace(patchHandle, handle);
}
ALOGW_IF(status == BAD_VALUE,
@@ -3338,7 +3338,10 @@
}
status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
- const struct audio_port_config *port, sp<IAfEffectHandle> *handle) {
+ const struct audio_port_config *port, sp<IAfEffectHandle> *handle)
+NO_THREAD_SAFETY_ANALYSIS
+// calling function 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
+{
ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d",
__func__, port->type, port->ext.device.type,
@@ -3360,7 +3363,7 @@
status_t status = NAME_NOT_FOUND;
if (mDescriptor.flags & EFFECT_FLAG_HW_ACC_TUNNEL) {
- Mutex::Autolock _l(mProxyLock);
+ audio_utils::lock_guard _l(proxyMutex());
mDevicePort = *port;
mHalEffect = new EffectModule(mMyCallback,
const_cast<effect_descriptor_t *>(&mDescriptor),
@@ -3424,7 +3427,7 @@
void DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
sp<IAfEffectHandle> effect;
{
- Mutex::Autolock _l(mProxyLock);
+ audio_utils::lock_guard _l(proxyMutex());
if (mEffectHandles.find(patchHandle) != mEffectHandles.end()) {
effect = mEffectHandles.at(patchHandle);
mEffectHandles.erase(patchHandle);
@@ -3435,7 +3438,7 @@
size_t DeviceEffectProxy::removeEffect(const sp<IAfEffectModule>& effect)
{
- Mutex::Autolock _l(mProxyLock);
+ audio_utils::lock_guard _l(proxyMutex());
if (effect == mHalEffect) {
mHalEffect->release_l();
mHalEffect.clear();
@@ -3496,7 +3499,7 @@
const Vector<String16> args;
EffectBase::dump(fd, args);
- const bool locked = afutils::dumpTryLock(mProxyLock);
+ const bool locked = afutils::dumpTryLock(proxyMutex());
if (!locked) {
String8 result("DeviceEffectProxy may be deadlocked\n");
write(fd, result.c_str(), result.size());
@@ -3526,7 +3529,7 @@
}
if (locked) {
- mLock.unlock();
+ proxyMutex().unlock();
}
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 67af74b..6b1d9cf 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -111,8 +111,7 @@
bool isPinned() const final { return mPinned; }
void unPin() final { mPinned = false; }
- void lock() ACQUIRE(mLock) final { mLock.lock(); }
- void unlock() RELEASE(mLock) final { mLock.unlock(); }
+ audio_utils::mutex& mutex() const final { return mMutex; }
status_t updatePolicyState() final;
@@ -135,7 +134,8 @@
DISALLOW_COPY_AND_ASSIGN(EffectBase);
- mutable Mutex mLock; // mutex for process, commands and handles list protection
+ // mutex for process, commands and handles list protection
+ mutable audio_utils::mutex mMutex;
mediautils::atomic_sp<EffectCallbackInterface> mCallback; // parent effect chain
const int mId; // this instance unique ID
const audio_session_t mSessionId; // audio session ID
@@ -148,9 +148,10 @@
// First handle in mHandles has highest priority and controls the effect module
// Audio policy effect state management
- // Mutex protecting transactions with audio policy manager as mLock cannot
+ // Mutex protecting transactions with audio policy manager as mutex() cannot
// be held to avoid cross deadlocks with audio policy mutex
- Mutex mPolicyLock;
+ audio_utils::mutex& policyMutex() const { return mPolicyMutex; }
+ mutable audio_utils::mutex mPolicyMutex;
// Effect is registered in APM or not
bool mPolicyRegistered = false;
// Effect enabled state communicated to APM. Enabled state corresponds to
@@ -272,9 +273,10 @@
uint32_t mInChannelCountRequested;
uint32_t mOutChannelCountRequested;
+ template <typename MUTEX>
class AutoLockReentrant {
public:
- AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
+ AutoLockReentrant(MUTEX& mutex, pid_t allowedTid)
: mMutex(gettid() == allowedTid ? nullptr : &mutex)
{
if (mMutex != nullptr) mMutex->lock();
@@ -283,7 +285,7 @@
if (mMutex != nullptr) mMutex->unlock();
}
private:
- Mutex * const mMutex;
+ MUTEX * const mMutex;
};
static constexpr pid_t INVALID_PID = (pid_t)-1;
@@ -364,7 +366,8 @@
private:
DISALLOW_COPY_AND_ASSIGN(EffectHandle);
- Mutex mLock; // protects IEffect method calls
+ audio_utils::mutex& mutex() const { return mMutex; }
+ mutable audio_utils::mutex mMutex; // protects IEffect method calls
const wp<IAfEffectBase> mEffect; // pointer to controlled EffectModule
const sp<media::IEffectClient> mEffectClient; // callback interface for client notifications
/*const*/ sp<Client> mClient; // client for shared memory allocation, see
@@ -397,12 +400,8 @@
void process_l() final;
- void lock() ACQUIRE(mLock) final {
- mLock.lock();
- }
- void unlock() RELEASE(mLock) final {
- mLock.unlock();
- }
+ audio_utils::mutex& mutex() const final { return mMutex; }
+
status_t createEffect_l(sp<IAfEffectModule>& effect,
effect_descriptor_t *desc,
int id,
@@ -488,7 +487,7 @@
// Is this EffectChain compatible with the bit-perfect audio flag.
bool isBitPerfectCompatible() const final;
- // isCompatibleWithThread_l() must be called with thread->mLock held
+ // isCompatibleWithThread_l() must be called with thread->mutex() held
bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final;
bool containsHapticGeneratingEffect_l() final;
@@ -624,7 +623,7 @@
std::optional<size_t> findVolumeControl_l(size_t from, size_t to) const;
- mutable Mutex mLock; // mutex protecting effect list
+ mutable audio_utils::mutex mMutex; // mutex protecting effect list
Vector<sp<IAfEffectModule>> mEffects; // list of effect modules
audio_session_t mSessionId; // audio session ID
sp<EffectBufferHalInterface> mInBuffer; // chain input buffer
@@ -649,7 +648,7 @@
const sp<EffectCallback> mEffectCallback;
- wp<EffectModule> mVolumeControlEffect;
+ wp<IAfEffectModule> mVolumeControlEffect;
};
class DeviceEffectProxy : public IAfDeviceEffectProxy, public EffectBase {
@@ -754,9 +753,10 @@
const sp<DeviceEffectManagerCallback> mManagerCallback;
const sp<ProxyCallback> mMyCallback;
- mutable Mutex mProxyLock;
- std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyLock
- sp<IAfEffectModule> mHalEffect; // protected by mProxyLock
+ audio_utils::mutex& proxyMutex() const { return mProxyMutex; }
+ mutable audio_utils::mutex mProxyMutex;
+ std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyMutex
+ sp<IAfEffectModule> mHalEffect; // protected by mProxyMutex
struct audio_port_config mDevicePort = { .id = AUDIO_PORT_HANDLE_NONE };
const bool mNotifyFramesProcessed;
};
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 7393448..ea0c6d9 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -21,6 +21,7 @@
#include <android/media/AudioVibratorInfo.h>
#include <android/media/BnEffect.h>
#include <android/media/BnEffectClient.h>
+#include <audio_utils/mutex.h>
#include <media/AudioCommonTypes.h> // product_strategy_t
#include <media/AudioDeviceTypeAddr.h>
#include <media/audiohal/EffectHalInterface.h>
@@ -141,8 +142,7 @@
virtual ssize_t removeHandle_l(IAfEffectHandle *handle) = 0;
virtual IAfEffectHandle* controlHandle_l() = 0;
- virtual void lock() = 0;
- virtual void unlock() = 0;
+ virtual audio_utils::mutex& mutex() const = 0;
};
class IAfEffectModule : public virtual IAfEffectBase {
@@ -218,8 +218,7 @@
virtual void process_l() = 0;
- virtual void lock() = 0;
- virtual void unlock() = 0;
+ virtual audio_utils::mutex& mutex() const = 0;
virtual status_t createEffect_l(sp<IAfEffectModule>& effect,
effect_descriptor_t *desc,
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 20e092d..5a6621e 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -45,8 +45,7 @@
mRecordThreadHandle(recordThreadHandle) {}
SoftwarePatch(const SoftwarePatch&) = default;
- // Must be called under AudioFlinger::mLock
- status_t getLatencyMs_l(double* latencyMs) const;
+ status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex);
audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
@@ -60,12 +59,14 @@
class IAfPatchPanelCallback : public virtual RefBase {
public:
- virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) = 0;
- virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) = 0;
- virtual IAfPlaybackThread* primaryPlaybackThread_l() const = 0;
- virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const = 0;
- virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const = 0;
- virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const = 0;
+ virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0;
+ virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0;
+ virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0;
+ virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const
+ REQUIRES(mutex()) = 0;
+ virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const
+ REQUIRES(mutex()) = 0;
+ virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0;
virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
audio_io_handle_t* input,
audio_config_t* config,
@@ -74,23 +75,25 @@
audio_source_t source,
audio_input_flags_t flags,
audio_devices_t outputDevice,
- const String8& outputDeviceAddress) = 0;
+ const String8& outputDeviceAddress) REQUIRES(mutex()) = 0;
virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
audio_io_handle_t* output,
audio_config_t* halConfig,
audio_config_base_t* mixerConfig,
audio_devices_t deviceType,
const String8& address,
- audio_output_flags_t flags) = 0;
- virtual void lock() const = 0;
- virtual void unlock() const = 0;
+ audio_output_flags_t flags) REQUIRES(mutex()) = 0;
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
- getAudioHwDevs_l() const = 0;
+ getAudioHwDevs_l() const REQUIRES(mutex()) = 0;
virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
virtual void updateDownStreamPatches_l(
- const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) = 0;
- virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) = 0;
+ const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams)
+ REQUIRES(mutex()) = 0;
+ virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices)
+ REQUIRES(mutex()) = 0;
};
class IAfPatchPanel : public virtual RefBase {
@@ -134,9 +137,12 @@
sp<const ThreadType> const_thread() const { return mThread; }
sp<const TrackType> const_track() const { return mTrack; }
- void closeConnections(const sp<IAfPatchPanel>& panel) {
+ void closeConnections_l(const sp<IAfPatchPanel>& panel)
+ REQUIRES(audio_utils::AudioFlinger_Mutex)
+ NO_THREAD_SAFETY_ANALYSIS // this is broken in clang
+ {
if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
- panel->releaseAudioPatch(mHandle);
+ panel->releaseAudioPatch_l(mHandle);
mHandle = AUDIO_PATCH_HANDLE_NONE;
}
if (mThread != nullptr) {
@@ -218,8 +224,10 @@
friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); }
- status_t createConnections(const sp<IAfPatchPanel>& panel);
- void clearConnections(const sp<IAfPatchPanel>& panel);
+ status_t createConnections_l(const sp<IAfPatchPanel>& panel)
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ void clearConnections_l(const sp<IAfPatchPanel>& panel)
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
bool isSoftware() const {
return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE;
@@ -251,22 +259,27 @@
};
/* List connected audio ports and their attributes */
- virtual status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) = 0;
+ virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
/* Get supported attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port_v7* port) = 0;
+ virtual status_t getAudioPort_l(struct audio_port_v7* port)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
/* Create a patch between several source and sink ports */
- virtual status_t createAudioPatch(
+ virtual status_t createAudioPatch_l(
const struct audio_patch* patch,
audio_patch_handle_t* handle,
- bool endpointPatch = false) = 0;
+ bool endpointPatch = false)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
/* Release a patch */
- virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
+ virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
/* List connected audio devices and they attributes */
- virtual status_t listAudioPatches(unsigned int* num_patches, struct audio_patch* patches) = 0;
+ virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
// Retrieves all currently estrablished software patches for a stream
// opened on an intermediate module.
@@ -281,13 +294,14 @@
virtual void dump(int fd) const = 0;
- // Must be called under AudioFlinger::mLock
+ virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
- virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const = 0;
+ virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
- virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const = 0;
-
- virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const = 0;
+ virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
};
} // namespace android
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index be51d51..fc2f805 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -19,6 +19,7 @@
#include <android/media/IAudioTrackCallback.h>
#include <android/media/IEffectClient.h>
#include <audiomanager/IAudioManager.h>
+#include <audio_utils/mutex.h>
#include <audio_utils/MelProcessor.h>
#include <binder/MemoryDealer.h>
#include <datapath/AudioStreamIn.h>
@@ -30,7 +31,6 @@
#include <media/audiohal/StreamHalInterface.h>
#include <media/nblog/NBLog.h>
#include <timing/SyncEvent.h>
-#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <vibrator/ExternalVibration.h>
@@ -67,44 +67,56 @@
// and hence may be used by the Effect / Track framework.
class IAfThreadCallback : public virtual RefBase {
public:
- virtual Mutex& mutex() const = 0;
- virtual bool isNonOffloadableGlobalEffectEnabled_l() const = 0; // Tracks
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
+ virtual bool isNonOffloadableGlobalEffectEnabled_l() const
+ REQUIRES(mutex()) = 0; // Tracks
virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
virtual bool btNrecIsOff() const = 0;
- virtual float masterVolume_l() const = 0;
- virtual bool masterMute_l() const = 0;
- virtual float getMasterBalance_l() const = 0;
- virtual bool streamMute_l(audio_stream_type_t stream) const = 0;
+ virtual float masterVolume_l() const
+ REQUIRES(mutex()) = 0;
+ virtual bool masterMute_l() const
+ REQUIRES(mutex()) = 0;
+ virtual float getMasterBalance_l() const
+ REQUIRES(mutex()) = 0;
+ virtual bool streamMute_l(audio_stream_type_t stream) const
+ REQUIRES(mutex()) = 0;
virtual audio_mode_t getMode() const = 0;
virtual bool isLowRamDevice() const = 0;
virtual bool isAudioPolicyReady() const = 0; // Effects
virtual uint32_t getScreenState() const = 0;
- virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const = 0;
+ virtual std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l() const
+ REQUIRES(mutex()) = 0;
virtual const sp<IAfPatchPanel>& getPatchPanel() const = 0;
virtual const sp<MelReporter>& getMelReporter() const = 0;
virtual const sp<EffectsFactoryHalInterface>& getEffectsFactoryHal() const = 0;
virtual sp<IAudioManager> getOrCreateAudioManager() = 0; // Tracks
- virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect) = 0;
- virtual status_t moveEffectChain_l(audio_session_t sessionId,
- IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread) = 0;
+ virtual bool updateOrphanEffectChains(const sp<IAfEffectModule>& effect)
+ EXCLUDES_AudioFlinger_Mutex = 0;
+ virtual status_t moveEffectChain_ll(audio_session_t sessionId,
+ IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread)
+ REQUIRES(mutex(), audio_utils::ThreadBase_Mutex) = 0;
virtual void requestLogMerge() = 0;
- virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name) = 0;
+ virtual sp<NBLog::Writer> newWriter_l(size_t size, const char *name)
+ REQUIRES(mutex()) = 0;
virtual void unregisterWriter(const sp<NBLog::Writer>& writer) = 0;
virtual sp<audioflinger::SyncEvent> createSyncEvent(AudioSystem::sync_event_t type,
audio_session_t triggerSession,
audio_session_t listenerSession,
const audioflinger::SyncEventCallback& callBack,
- const wp<IAfTrackBase>& cookie) = 0;
+ const wp<IAfTrackBase>& cookie)
+ EXCLUDES_AudioFlinger_Mutex = 0;
virtual void ioConfigChanged(audio_io_config_event_t event,
const sp<AudioIoDescriptor>& ioDesc,
- pid_t pid = 0) = 0;
- virtual void onNonOffloadableGlobalEffectEnable() = 0;
+ pid_t pid = 0) EXCLUDES_AudioFlinger_ClientMutex = 0;
+ virtual void onNonOffloadableGlobalEffectEnable() EXCLUDES_AudioFlinger_Mutex = 0;
virtual void onSupportedLatencyModesChanged(
- audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) = 0;
+ audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes)
+ EXCLUDES_AudioFlinger_ClientMutex = 0;
};
class IAfThreadBase : public virtual RefBase {
@@ -213,7 +225,8 @@
status_t* status /*non-NULL*/,
bool pinned,
bool probe,
- bool notifyFramesProcessed) = 0;
+ bool notifyFramesProcessed)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
// return values for hasAudioSession (bit field)
enum effect_state {
@@ -255,7 +268,8 @@
// add and effect module. Also creates the effect chain is none exists for
// the effects audio session. Only called in a context of moving an effect
// from one thread to another
- virtual status_t addEffect_l(const sp<IAfEffectModule>& effect) = 0;
+ virtual status_t addEffect_ll(const sp<IAfEffectModule>& effect)
+ REQUIRES(audio_utils::AudioFlinger_Mutex, mutex()) = 0;
// remove and effect module. Also removes the effect chain is this was the last
// effect
virtual void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) = 0;
@@ -310,7 +324,8 @@
// deliver stats to mediametrics.
virtual void sendStatistics(bool force) = 0;
- virtual Mutex& mutex() const = 0;
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) = 0;
virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0;
virtual void onEffectDisable() = 0;
@@ -321,8 +336,10 @@
virtual void invalidateTracksForAudioSession(audio_session_t sessionId) const = 0;
virtual bool isStreamInitialized() const = 0;
- virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) = 0;
- virtual void stopMelComputation_l() = 0;
+ virtual void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
+ virtual void stopMelComputation_l()
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
virtual product_strategy_t getStrategyForStream(audio_stream_type_t stream) const = 0;
@@ -398,7 +415,8 @@
audio_port_handle_t portId,
const sp<media::IAudioTrackCallback>& callback,
bool isSpatialized,
- bool isBitPerfect) = 0;
+ bool isBitPerfect)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
virtual status_t addTrack_l(const sp<IAfTrack>& track) = 0;
virtual bool destroyTrack_l(const sp<IAfTrack>& track) = 0;
@@ -502,7 +520,8 @@
pid_t tid,
status_t* status /*non-NULL*/,
audio_port_handle_t portId,
- int32_t maxSharedAudioHistoryMs) = 0;
+ int32_t maxSharedAudioHistoryMs)
+ REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
virtual void destroyTrack_l(const sp<IAfRecordTrack>& track) = 0;
virtual void removeTrack_l(const sp<IAfRecordTrack>& track) = 0;
diff --git a/services/audioflinger/MelReporter.cpp b/services/audioflinger/MelReporter.cpp
index bcc6536..add453f 100644
--- a/services/audioflinger/MelReporter.cpp
+++ b/services/audioflinger/MelReporter.cpp
@@ -65,7 +65,7 @@
void MelReporter::activateInternalSoundDoseComputation() {
{
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!mUseHalSoundDoseInterface) {
// no need to start internal MEL on active patches
return;
@@ -111,8 +111,8 @@
return;
}
- std::lock_guard _laf(mAfMelReporterCallback->mutex());
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
+ audio_utils::lock_guard _l(mutex());
auto activeMelPatchId = activePatchStreamHandle_l(streamHandle);
if (!activeMelPatchId) {
ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle);
@@ -171,8 +171,8 @@
}
if (!newPatch.deviceHandles.empty()) {
- std::lock_guard _afl(mAfMelReporterCallback->mutex());
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
+ audio_utils::lock_guard _l(mutex());
ALOGV("%s add patch handle %d to active devices", __func__, handle);
startMelComputationForActivePatch_l(newPatch);
newPatch.csdActive = true;
@@ -213,7 +213,7 @@
ActiveMelPatch melPatch;
{
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
auto patchIt = mActiveMelPatches.find(handle);
if (patchIt == mActiveMelPatches.end()) {
@@ -226,8 +226,8 @@
mActiveMelPatches.erase(patchIt);
}
- std::lock_guard _afl(mAfMelReporterCallback->mutex());
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
+ audio_utils::lock_guard _l(mutex());
stopMelComputationForPatch_l(melPatch);
}
@@ -239,7 +239,7 @@
void MelReporter::stopInternalMelComputation() {
ALOGV("%s", __func__);
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mActiveMelPatches.clear();
mUseHalSoundDoseInterface = true;
}
@@ -286,7 +286,7 @@
}
std::string MelReporter::dump() {
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
std::string output("\nSound Dose:\n");
output.append(mSoundDoseManager->dump());
return output;
diff --git a/services/audioflinger/MelReporter.h b/services/audioflinger/MelReporter.h
index 2a1f3b3..07ab94d 100644
--- a/services/audioflinger/MelReporter.h
+++ b/services/audioflinger/MelReporter.h
@@ -20,9 +20,9 @@
#include "IAfPatchPanel.h"
#include "PatchCommandThread.h"
+#include <audio_utils/mutex.h>
#include <sounddose/SoundDoseManager.h>
-#include <mutex>
#include <unordered_map>
namespace android {
@@ -31,9 +31,11 @@
class IAfMelReporterCallback : public virtual RefBase {
public:
- virtual Mutex& mutex() const = 0;
+ virtual audio_utils::mutex& mutex() const
+ RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
- virtual sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const = 0;
+ virtual sp<IAfThreadBase> checkOutputThread_l(audio_io_handle_t ioHandle) const
+ REQUIRES(mutex()) = 0;
};
/**
@@ -62,7 +64,7 @@
* implementation, false otherwise.
*/
bool activateHalSoundDoseComputation(const std::string& module,
- const sp<DeviceHalInterface>& device);
+ const sp<DeviceHalInterface>& device) EXCLUDES_MelReporter_Mutex;
/**
* Activates the MEL reporting from internal framework values. These are used
@@ -70,7 +72,7 @@
* Note: the internal CSD computation does not guarantee a certification with
* IEC62368-1 3rd edition or EN50332-3
*/
- void activateInternalSoundDoseComputation();
+ void activateInternalSoundDoseComputation() EXCLUDES_MelReporter_Mutex;
sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback);
@@ -78,8 +80,9 @@
// PatchCommandListener methods
void onCreateAudioPatch(audio_patch_handle_t handle,
- const IAfPatchPanel::Patch& patch) final;
- void onReleaseAudioPatch(audio_patch_handle_t handle) final;
+ const IAfPatchPanel::Patch& patch) final
+ EXCLUDES_AudioFlinger_Mutex;
+ void onReleaseAudioPatch(audio_patch_handle_t handle) final EXCLUDES_AudioFlinger_Mutex;
/**
* The new metadata can determine whether we should compute MEL for the given thread.
@@ -87,7 +90,9 @@
* Otherwise, this method will disable CSD.
**/
void updateMetadataForCsd(audio_io_handle_t streamHandle,
- const std::vector<playback_track_metadata_v7_t>& metadataVec);
+ const std::vector<playback_track_metadata_v7_t>& metadataVec)
+ EXCLUDES_AudioFlinger_Mutex;
+
private:
struct ActiveMelPatch {
audio_io_handle_t streamHandle{AUDIO_IO_HANDLE_NONE};
@@ -99,30 +104,34 @@
bool shouldComputeMelForDeviceType(audio_devices_t device);
void stopInternalMelComputation();
+ audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::MelReporter_Mutex) {
+ return mMutex;
+ }
- /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
- void stopMelComputationForPatch_l(const ActiveMelPatch& patch) REQUIRES(mLock);
+ /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */
+ void stopMelComputationForPatch_l(const ActiveMelPatch& patch) REQUIRES(mutex());
- /** Should be called with the following order of locks: mAudioFlinger.mLock -> mLock. */
- void startMelComputationForActivePatch_l(const ActiveMelPatch& patch) REQUIRES(mLock);
+ /** Should be called with the following order of locks: mAudioFlinger.mutex() -> mutex(). */
+ void startMelComputationForActivePatch_l(const ActiveMelPatch& patch) REQUIRES(mutex());
std::optional<audio_patch_handle_t>
- activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mLock);
+ activePatchStreamHandle_l(audio_io_handle_t streamHandle) REQUIRES(mutex());
- bool useHalSoundDoseInterface_l() REQUIRES(mLock);
+ bool useHalSoundDoseInterface_l() REQUIRES(mutex());
const sp<IAfMelReporterCallback> mAfMelReporterCallback;
- sp<SoundDoseManager> mSoundDoseManager;
+ /* const */ sp<SoundDoseManager> mSoundDoseManager; // set onFirstRef
/**
* Lock for protecting the active mel patches. Do not mix with the AudioFlinger lock.
- * Locking order AudioFlinger::mLock -> PatchCommandThread::mLock -> MelReporter::mLock.
+ * Locking order AudioFlinger::mutex() -> PatchCommandThread::mutex() -> MelReporter::mutex().
*/
- std::mutex mLock;
- std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches GUARDED_BY(mLock);
- std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mLock);
- bool mUseHalSoundDoseInterface GUARDED_BY(mLock) = false;
+ mutable audio_utils::mutex mMutex;
+ std::unordered_map<audio_patch_handle_t, ActiveMelPatch> mActiveMelPatches
+ GUARDED_BY(mutex());
+ std::unordered_map<audio_port_handle_t, int> mActiveDevices GUARDED_BY(mutex());
+ bool mUseHalSoundDoseInterface GUARDED_BY(mutex()) = false;
};
} // namespace android
diff --git a/services/audioflinger/PatchCommandThread.cpp b/services/audioflinger/PatchCommandThread.cpp
index c3259f1..f4c76d6 100644
--- a/services/audioflinger/PatchCommandThread.cpp
+++ b/services/audioflinger/PatchCommandThread.cpp
@@ -29,7 +29,7 @@
PatchCommandThread::~PatchCommandThread() {
exit();
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mCommands.clear();
}
@@ -39,7 +39,7 @@
void PatchCommandThread::addListener(const sp<PatchCommandListener>& listener) {
ALOGV("%s add listener %p", __func__, static_cast<void*>(listener.get()));
- std::lock_guard _l(mListenerLock);
+ audio_utils::lock_guard _l(listenerMutex());
mListeners.emplace_back(listener);
}
@@ -59,9 +59,8 @@
}
bool PatchCommandThread::threadLoop()
-NO_THREAD_SAFETY_ANALYSIS // bug in clang compiler.
{
- std::unique_lock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
while (!exitPending()) {
while (!mCommands.empty() && !exitPending()) {
@@ -71,7 +70,7 @@
std::vector<wp<PatchCommandListener>> listenersCopy;
{
- std::lock_guard _ll(mListenerLock);
+ audio_utils::lock_guard _ll(listenerMutex());
listenersCopy = mListeners;
}
@@ -122,7 +121,7 @@
}
void PatchCommandThread::sendCommand(const sp<Command>& command) {
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mCommands.emplace_back(command);
mWaitWorkCV.notify_one();
}
@@ -148,7 +147,7 @@
void PatchCommandThread::exit() {
ALOGV("%s", __func__);
{
- std::lock_guard _l(mLock);
+ audio_utils::lock_guard _l(mutex());
requestExit();
mWaitWorkCV.notify_one();
}
diff --git a/services/audioflinger/PatchCommandThread.h b/services/audioflinger/PatchCommandThread.h
index a312fb7..8ca96f1 100644
--- a/services/audioflinger/PatchCommandThread.h
+++ b/services/audioflinger/PatchCommandThread.h
@@ -50,10 +50,12 @@
PatchCommandThread() : Thread(false /* canCallJava */) {}
~PatchCommandThread() override;
- void addListener(const sp<PatchCommandListener>& listener);
+ void addListener(const sp<PatchCommandListener>& listener)
+ EXCLUDES_PatchCommandThread_ListenerMutex;
- void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch);
- void releaseAudioPatch(audio_patch_handle_t handle);
+ void createAudioPatch(audio_patch_handle_t handle, const IAfPatchPanel::Patch& patch)
+ EXCLUDES_PatchCommandThread_Mutex;
+ void releaseAudioPatch(audio_patch_handle_t handle) EXCLUDES_PatchCommandThread_Mutex;
// Thread virtuals
void onFirstRef() override;
@@ -62,9 +64,8 @@
void exit();
void createAudioPatchCommand(audio_patch_handle_t handle,
- const IAfPatchPanel::Patch& patch);
- void releaseAudioPatchCommand(audio_patch_handle_t handle);
-
+ const IAfPatchPanel::Patch& patch) EXCLUDES_PatchCommandThread_Mutex;
+ void releaseAudioPatchCommand(audio_patch_handle_t handle) EXCLUDES_PatchCommandThread_Mutex;
private:
class CommandData;
@@ -98,15 +99,22 @@
audio_patch_handle_t mHandle;
};
- void sendCommand(const sp<Command>& command);
+ void sendCommand(const sp<Command>& command) EXCLUDES_PatchCommandThread_Mutex;
- std::string mThreadName;
- std::mutex mLock;
- std::condition_variable mWaitWorkCV;
- std::deque<sp<Command>> mCommands GUARDED_BY(mLock); // list of pending commands
+ audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::PatchCommandThread_Mutex) {
+ return mMutex;
+ }
+ audio_utils::mutex& listenerMutex() const
+ RETURN_CAPABILITY(audio_utils::PatchCommandThread_ListenerMutex) {
+ return mListenerMutex;
+ }
- std::mutex mListenerLock;
- std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(mListenerLock);
+ mutable audio_utils::mutex mMutex;
+ audio_utils::condition_variable mWaitWorkCV;
+ std::deque<sp<Command>> mCommands GUARDED_BY(mutex()); // list of pending commands
+
+ mutable audio_utils::mutex mListenerMutex;
+ std::vector<wp<PatchCommandListener>> mListeners GUARDED_BY(listenerMutex());
};
} // namespace android
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index bfc2754..7d3900b 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -83,7 +83,7 @@
}
/* List connected audio ports and their attributes */
-status_t PatchPanel::listAudioPorts(unsigned int* /* num_ports */,
+status_t PatchPanel::listAudioPorts_l(unsigned int* /* num_ports */,
struct audio_port *ports __unused)
{
ALOGV(__func__);
@@ -91,14 +91,14 @@
}
/* Get supported attributes for a given audio port */
-status_t PatchPanel::getAudioPort(struct audio_port_v7* port)
+status_t PatchPanel::getAudioPort_l(struct audio_port_v7* port)
{
if (port->type != AUDIO_PORT_TYPE_DEVICE) {
// Only query the HAL when the port is a device.
// TODO: implement getAudioPort for mix.
return INVALID_OPERATION;
}
- AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module);
+ AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(port->ext.device.hw_module);
if (hwDevice == nullptr) {
ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
return BAD_VALUE;
@@ -110,7 +110,7 @@
}
/* Connect a patch between several source and sink ports */
-status_t PatchPanel::createAudioPatch(const struct audio_patch* patch,
+status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle,
bool endpointPatch)
//unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent
@@ -144,7 +144,7 @@
// 1) if a software patch is present, release the playback and capture threads and
// tracks created. This will also release the corresponding audio HAL patches
if (removedPatch.isSoftware()) {
- removedPatch.clearConnections(this);
+ removedPatch.clearConnections_l(this);
}
// 2) if the new patch and old patch source or sink are devices from different
// hw modules, clear the audio HAL patches now because they will not be updated
@@ -169,7 +169,7 @@
// removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
hwModule = oldPatch.sinks[0].ext.device.hw_module;
}
- sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
+ sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(hwModule);
if (hwDevice != 0) {
hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
@@ -185,7 +185,7 @@
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: {
audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
- AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
+ AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(srcModule);
if (!audioHwDevice) {
status = BAD_VALUE;
goto exit;
@@ -317,7 +317,7 @@
goto exit;
}
newPatch.mRecord.setThread(thread->asIAfRecordThread().get());
- status = newPatch.createConnections(this);
+ status = newPatch.createConnections_l(this);
if (status != NO_ERROR) {
goto exit;
}
@@ -338,9 +338,9 @@
goto exit;
}
}
- mAfPatchPanelCallback->unlock();
+ mAfPatchPanelCallback->mutex().unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAfPatchPanelCallback->lock();
+ mAfPatchPanelCallback->mutex().lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -406,9 +406,9 @@
mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
}
- mAfPatchPanelCallback->unlock();
+ mAfPatchPanelCallback->mutex().unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAfPatchPanelCallback->lock();
+ mAfPatchPanelCallback->mutex().lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -438,11 +438,11 @@
newPatch.mHalHandle = halHandle;
mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch);
if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
- addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
+ addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch);
}
mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
} else {
- newPatch.clearConnections(this);
+ newPatch.clearConnections_l(this);
}
return status;
}
@@ -453,10 +453,10 @@
mRecord.handle(), mPlayback.handle());
}
-status_t PatchPanel::Patch::createConnections(const sp<IAfPatchPanel>& panel)
+status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
{
// create patch from source device to record thread input
- status_t status = panel->createAudioPatch(
+ status_t status = panel->createAudioPatch_l(
PatchBuilder().addSource(mAudioPatch.sources[0]).
addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
mRecord.handlePtr(),
@@ -468,7 +468,7 @@
// create patch from playback thread output to sink device
if (mAudioPatch.num_sinks != 0) {
- status = panel->createAudioPatch(
+ status = panel->createAudioPatch_l(
PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
mPlayback.handlePtr(),
true /*endpointPatch*/);
@@ -617,15 +617,15 @@
return status;
}
-void PatchPanel::Patch::clearConnections(const sp<IAfPatchPanel>& panel)
+void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel)
{
ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
__func__, mRecord.handle(), mPlayback.handle());
mRecord.stopTrack();
mPlayback.stopTrack();
mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
- mRecord.closeConnections(panel);
- mPlayback.closeConnections(panel);
+ mRecord.closeConnections_l(panel);
+ mPlayback.closeConnections_l(panel);
}
status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const
@@ -715,7 +715,7 @@
}
/* Disconnect a patch */
-status_t PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
+status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle)
//unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent
//to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
//before processing the release patch request.
@@ -734,7 +734,7 @@
const struct audio_port_config &src = patch.sources[0];
switch (src.type) {
case AUDIO_PORT_TYPE_DEVICE: {
- sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
+ sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module);
if (hwDevice == 0) {
ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
status = BAD_VALUE;
@@ -742,7 +742,7 @@
}
if (removedPatch.isSoftware()) {
- removedPatch.clearConnections(this);
+ removedPatch.clearConnections_l(this);
break;
}
@@ -757,15 +757,15 @@
break;
}
}
- mAfPatchPanelCallback->unlock();
+ mAfPatchPanelCallback->mutex().unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAfPatchPanelCallback->lock();
+ mAfPatchPanelCallback->mutex().lock();
} else {
status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
} break;
case AUDIO_PORT_TYPE_MIX: {
- if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
+ if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) {
ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
status = BAD_VALUE;
break;
@@ -780,9 +780,9 @@
break;
}
}
- mAfPatchPanelCallback->unlock();
+ mAfPatchPanelCallback->mutex().unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAfPatchPanelCallback->lock();
+ mAfPatchPanelCallback->mutex().lock();
} break;
default:
status = BAD_VALUE;
@@ -799,7 +799,7 @@
}
/* List connected audio ports and they attributes */
-status_t PatchPanel::listAudioPatches(unsigned int* /* num_patches */,
+status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */,
struct audio_patch *patches __unused)
{
ALOGV(__func__);
@@ -856,7 +856,7 @@
}
}
-AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
+AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module)
{
if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
@@ -867,13 +867,13 @@
return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
}
-sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
+sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module)
{
- AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
+ AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module);
return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
}
-void PatchPanel::addSoftwarePatchToInsertedModules(
+void PatchPanel::addSoftwarePatchToInsertedModules_l(
audio_module_handle_t module, audio_patch_handle_t handle,
const struct audio_patch *patch)
{
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index b8b7b79..1ff8fff 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -30,25 +30,29 @@
: mAfPatchPanelCallback(afPatchPanelCallback) {}
/* List connected audio ports and their attributes */
- status_t listAudioPorts(unsigned int *num_ports,
- struct audio_port* ports) final;
+ status_t listAudioPorts_l(unsigned int *num_ports,
+ struct audio_port* ports) final REQUIRES(audio_utils::AudioFlinger_Mutex);
/* Get supported attributes for a given audio port */
- status_t getAudioPort(struct audio_port_v7* port) final;
+ status_t getAudioPort_l(struct audio_port_v7* port) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
/* Create a patch between several source and sink ports */
- status_t createAudioPatch(const struct audio_patch *patch,
+ status_t createAudioPatch_l(const struct audio_patch *patch,
audio_patch_handle_t *handle,
- bool endpointPatch = false) final;
+ bool endpointPatch = false) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
/* Release a patch */
- status_t releaseAudioPatch(audio_patch_handle_t handle) final;
+ status_t releaseAudioPatch_l(audio_patch_handle_t handle) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
/* List connected audio devices and they attributes */
- status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch* patches) final;
+ status_t listAudioPatches_l(unsigned int *num_patches,
+ struct audio_patch* patches) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
- // Retrieves all currently estrablished software patches for a stream
+ // Retrieves all currently established software patches for a stream
// opened on an intermediate module.
status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
std::vector<SoftwarePatch>* patches) const final;
@@ -60,20 +64,24 @@
void dump(int fd) const final;
- // Call with AudioFlinger mLock held
- const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; }
+ const std::map<audio_patch_handle_t, Patch>& patches_l() const final
+ REQUIRES(audio_utils::AudioFlinger_Mutex) { return mPatches; }
- // Must be called under AudioFlinger::mLock
- status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final;
+ status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
- void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final;
+ void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
private:
- AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
- sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
- void addSoftwarePatchToInsertedModules(
+ AudioHwDevice* findAudioHwDeviceByModule_l(audio_module_handle_t module)
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ sp<DeviceHalInterface> findHwDeviceByModule_l(audio_module_handle_t module)
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ void addSoftwarePatchToInsertedModules_l(
audio_module_handle_t module, audio_patch_handle_t handle,
- const struct audio_patch *patch);
+ const struct audio_patch *patch)
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
void erasePatch(audio_patch_handle_t handle);
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index beb3e1c..15e85f9 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -20,6 +20,7 @@
#include "TrackBase.h"
#include <android/os/BnExternalVibrationController.h>
+#include <audio_utils/mutex.h>
#include <audio_utils/LinearMap.h>
#include <binder/AppOpsManager.h>
@@ -467,7 +468,8 @@
*/
SourceMetadatas mTrackMetadatas;
/** Protects mTrackMetadatas against concurrent access. */
- mutable std::mutex mTrackMetadatasMutex;
+ audio_utils::mutex& trackMetadataMutex() const { return mTrackMetadataMutex; }
+ mutable audio_utils::mutex mTrackMetadataMutex;
}; // end of OutputTrack
// playback track, used by PatchPanel
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 021add4..8d3de38 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -20,6 +20,7 @@
#include "TrackBase.h"
#include <android/content/AttributionSourceState.h>
+#include <audio_utils/mutex.h>
#include <datapath/AudioStreamIn.h> // struct Source
namespace android {
@@ -214,15 +215,16 @@
};
sp<StreamInHalInterface> obtainStream(sp<IAfThreadBase>* thread);
+ audio_utils::mutex& readMutex() const { return mReadMutex; }
PatchRecordAudioBufferProvider mPatchRecordAudioBufferProvider;
std::unique_ptr<void, decltype(free)*> mSinkBuffer; // frame size aligned continuous buffer
std::unique_ptr<void, decltype(free)*> mStubBuffer; // buffer used for AudioBufferProvider
size_t mUnconsumedFrames = 0;
- std::mutex mReadLock;
- std::condition_variable mReadCV;
- size_t mReadBytes = 0; // GUARDED_BY(mReadLock)
- status_t mReadError = NO_ERROR; // GUARDED_BY(mReadLock)
+ mutable audio_utils::mutex mReadMutex;
+ audio_utils::condition_variable mReadCV;
+ size_t mReadBytes = 0; // GUARDED_BY(readMutex())
+ status_t mReadError = NO_ERROR; // GUARDED_BY(readMutex())
int64_t mLastReadFrames = 0; // accessed on RecordThread only
};
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a6a0355..0b73fba 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -685,9 +685,9 @@
// mWaitWorkCV.wait(...);
// // now thread is hung
// }
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
requestExit();
- mWaitWorkCV.broadcast();
+ mWaitWorkCV.notify_all();
}
// When Thread::requestExitAndWait is made virtual and this method is renamed to
// "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
@@ -697,7 +697,7 @@
status_t ThreadBase::setParameters(const String8& keyValuePairs)
{
ALOGV("ThreadBase::setParameters() %s", keyValuePairs.c_str());
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return sendSetParameterConfigEvent_l(keyValuePairs);
}
@@ -716,30 +716,31 @@
}
mConfigEvents.add(event);
ALOGV("sendConfigEvent_l() num events %zu event %d", mConfigEvents.size(), event->mType);
- mWaitWorkCV.signal();
- mLock.unlock();
+ mWaitWorkCV.notify_one();
+ mutex().unlock();
{
- Mutex::Autolock _l(event->mLock);
+ audio_utils::unique_lock _l(event->mutex());
while (event->mWaitStatus) {
- if (event->mCond.waitRelative(event->mLock, kConfigEventTimeoutNs) != NO_ERROR) {
+ if (event->mCondition.wait_for(_l, std::chrono::nanoseconds(kConfigEventTimeoutNs))
+ == std::cv_status::timeout) {
event->mStatus = TIMED_OUT;
event->mWaitStatus = false;
}
}
status = event->mStatus;
}
- mLock.lock();
+ mutex().lock();
return status;
}
void ThreadBase::sendIoConfigEvent(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sendIoConfigEvent_l(event, pid, portId);
}
-// sendIoConfigEvent_l() must be called with ThreadBase::mLock held
+// sendIoConfigEvent_l() must be called with ThreadBase::mutex() held
void ThreadBase::sendIoConfigEvent_l(audio_io_config_event_t event, pid_t pid,
audio_port_handle_t portId)
{
@@ -759,11 +760,11 @@
void ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sendPrioConfigEvent_l(pid, tid, prio, forApp);
}
-// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
+// sendPrioConfigEvent_l() must be called with ThreadBase::mutex() held
void ThreadBase::sendPrioConfigEvent_l(
pid_t pid, pid_t tid, int32_t prio, bool forApp)
{
@@ -771,7 +772,7 @@
sendConfigEvent_l(configEvent);
}
-// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held
+// sendSetParameterConfigEvent_l() must be called with ThreadBase::mutex() held
status_t ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair)
{
sp<ConfigEvent> configEvent;
@@ -794,7 +795,7 @@
const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<ConfigEvent> configEvent = (ConfigEvent *)new CreateAudioPatchConfigEvent(*patch, *handle);
status_t status = sendConfigEvent_l(configEvent);
if (status == NO_ERROR) {
@@ -808,7 +809,7 @@
status_t ThreadBase::sendReleaseAudioPatchConfigEvent(
const audio_patch_handle_t handle)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<ConfigEvent> configEvent = (ConfigEvent *)new ReleaseAudioPatchConfigEvent(handle);
return sendConfigEvent_l(configEvent);
}
@@ -820,7 +821,7 @@
// The update out device operation is only for record thread.
return INVALID_OPERATION;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<ConfigEvent> configEvent = (ConfigEvent *)new UpdateOutDevicesConfigEvent(outDevices);
return sendConfigEvent_l(configEvent);
}
@@ -835,7 +836,7 @@
void ThreadBase::sendCheckOutputStageEffectsEvent()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sendCheckOutputStageEffectsEvent_l();
}
@@ -930,10 +931,10 @@
break;
}
{
- Mutex::Autolock _l(event->mLock);
+ audio_utils::lock_guard _l(event->mutex());
if (event->mWaitStatus) {
event->mWaitStatus = false;
- event->mCond.signal();
+ event->mCondition.notify_one();
}
}
ALOGV_IF(mConfigEvents.isEmpty(), "processConfigEvents_l() DONE thread %p", this);
@@ -1026,7 +1027,7 @@
dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input",
this, mThreadName, getTid(), type(), threadTypeToString(type()));
- const bool locked = afutils::dumpTryLock(mLock);
+ const bool locked = afutils::dumpTryLock(mutex());
if (!locked) {
dprintf(fd, " Thread may be deadlocked\n");
}
@@ -1037,7 +1038,7 @@
dumpEffectChains_l(fd, args);
if (locked) {
- mLock.unlock();
+ mutex().unlock();
}
dprintf(fd, " Local log:\n");
@@ -1152,7 +1153,7 @@
void ThreadBase::acquireWakeLock()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
acquireWakeLock_l();
}
@@ -1206,7 +1207,7 @@
void ThreadBase::releaseWakeLock()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
releaseWakeLock_l();
}
@@ -1265,7 +1266,7 @@
void ThreadBase::clearPowerManager()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
releaseWakeLock_l();
mPowerManager.clear();
}
@@ -1396,7 +1397,7 @@
NO_THREAD_SAFETY_ANALYSIS // manual locking
{
if (!threadLocked) {
- mLock.lock();
+ mutex().lock();
}
if (mType != RECORD) {
@@ -1411,11 +1412,11 @@
}
if (!threadLocked) {
- mLock.unlock();
+ mutex().unlock();
}
}
-// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
+// checkEffectCompatibility_l() must be called with ThreadBase::mutex() held
status_t RecordThread::checkEffectCompatibility_l(
const effect_descriptor_t *desc, audio_session_t sessionId)
{
@@ -1459,7 +1460,7 @@
return NO_ERROR;
}
-// checkEffectCompatibility_l() must be called with ThreadBase::mLock held
+// checkEffectCompatibility_l() must be called with ThreadBase::mutex() held
status_t PlaybackThread::checkEffectCompatibility_l(
const effect_descriptor_t *desc, audio_session_t sessionId)
{
@@ -1614,7 +1615,7 @@
return NO_ERROR;
}
-// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held
+// ThreadBase::createEffect_l() must be called with AudioFlinger::mutex() held
sp<IAfEffectHandle> ThreadBase::createEffect_l(
const sp<Client>& client,
const sp<IEffectClient>& effectClient,
@@ -1643,8 +1644,8 @@
ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
- { // scope for mLock
- Mutex::Autolock _l(mLock);
+ { // scope for mutex()
+ audio_utils::lock_guard _l(mutex());
lStatus = checkEffectCompatibility_l(desc, sessionId);
if (probe || lStatus != NO_ERROR) {
@@ -1706,7 +1707,7 @@
Exit:
if (!probe && lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (effectCreated) {
chain->removeEffect_l(effect);
}
@@ -1726,7 +1727,7 @@
bool remove = false;
sp<IAfEffectModule> effect;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfEffectBase> effectBase = handle->effect().promote();
if (effectBase == nullptr) {
return;
@@ -1752,7 +1753,7 @@
void ThreadBase::onEffectEnable(const sp<IAfEffectModule>& effect) {
if (isOffloadOrMmap()) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
broadcast_l();
}
if (!effect->isOffloadable()) {
@@ -1768,7 +1769,7 @@
void ThreadBase::onEffectDisable() {
if (isOffloadOrMmap()) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
broadcast_l();
}
}
@@ -1776,7 +1777,7 @@
sp<IAfEffectModule> ThreadBase::getEffect(audio_session_t sessionId,
int effectId) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return getEffect_l(sessionId, effectId);
}
@@ -1793,9 +1794,9 @@
return chain != nullptr ? chain->getEffectIds() : std::vector<int>{};
}
-// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
-// PlaybackThread::mLock held
-status_t ThreadBase::addEffect_l(const sp<IAfEffectModule>& effect)
+// PlaybackThread::addEffect_ll() must be called with AudioFlinger::mutex() and
+// ThreadBase::mutex() held
+status_t ThreadBase::addEffect_ll(const sp<IAfEffectModule>& effect)
{
// check for existing effect chain with the requested audio session
audio_session_t sessionId = effect->sessionId();
@@ -1803,22 +1804,22 @@
bool chainCreated = false;
ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(),
- "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x",
- this, effect->desc().name, effect->desc().flags);
+ "%s: on offloaded thread %p: effect %s does not support offload flags %#x",
+ __func__, this, effect->desc().name, effect->desc().flags);
if (chain == 0) {
// create a new chain for this session
- ALOGV("addEffect_l() new effect chain for session %d", sessionId);
+ ALOGV("%s: new effect chain for session %d", __func__, sessionId);
chain = IAfEffectChain::create(this, sessionId);
addEffectChain_l(chain);
chain->setStrategy(getStrategyForSession_l(sessionId));
chainCreated = true;
}
- ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
+ ALOGV("%s: %p chain %p effect %p", __func__, this, chain.get(), effect.get());
if (chain->getEffectFromId_l(effect->id()) != 0) {
- ALOGW("addEffect_l() %p effect %s already present in chain %p",
- this, effect->desc().name, chain.get());
+ ALOGW("%s: %p effect %s already present in chain %p",
+ __func__, this, effect->desc().name, chain.get());
return BAD_VALUE;
}
@@ -1865,7 +1866,7 @@
{
effectChains = mEffectChains;
for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->lock();
+ mEffectChains[i]->mutex().lock();
}
}
@@ -1874,13 +1875,13 @@
NO_THREAD_SAFETY_ANALYSIS // calls EffectChain::unlock()
{
for (size_t i = 0; i < effectChains.size(); i++) {
- effectChains[i]->unlock();
+ effectChains[i]->mutex().unlock();
}
}
sp<IAfEffectChain> ThreadBase::getEffectChain(audio_session_t sessionId) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return getEffectChain_l(sessionId);
}
@@ -1898,7 +1899,7 @@
void ThreadBase::setMode(audio_mode_t mode)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffectChains.size();
for (size_t i = 0; i < size; i++) {
mEffectChains[i]->setMode_l(mode);
@@ -1918,7 +1919,7 @@
void ThreadBase::systemReady()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mSystemReady) {
return;
}
@@ -2038,7 +2039,7 @@
// If threadLoop is currently unlocked a signal of mWaitWorkCV will
// be lost so we also flag to prevent it blocking on mWaitWorkCV
mSignalPending = true;
- mWaitWorkCV.broadcast();
+ mWaitWorkCV.notify_all();
}
// Call only from threadLoop() or when it is idle.
@@ -2114,7 +2115,7 @@
return AudioSystem::getStrategyForStream(stream);
}
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
void ThreadBase::startMelComputation_l(
const sp<audio_utils::MelProcessor>& /*processor*/)
{
@@ -2122,7 +2123,7 @@
ALOGW("%s: ThreadBase does not support CSD", __func__);
}
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
void ThreadBase::stopMelComputation_l()
{
// Do nothing
@@ -2178,7 +2179,7 @@
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
mNBLogWriter = afThreadCallback->newWriter_l(kLogSize, mThreadName);
- // Assumes constructor is called by AudioFlinger with it's mLock held, but
+ // Assumes constructor is called by AudioFlinger with its mutex() held, but
// it would be safer to explicitly pass initial masterVolume/masterMute as
// parameter.
//
@@ -2378,7 +2379,7 @@
}
}
-// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
+// PlaybackThread::createTrack_l() must be called with AudioFlinger::mutex() held
sp<IAfTrack> PlaybackThread::createTrack_l(
const sp<Client>& client,
audio_stream_type_t streamType,
@@ -2482,8 +2483,8 @@
}
// check compatibility with audio effects.
- { // scope for mLock
- Mutex::Autolock _l(mLock);
+ { // scope for mutex()
+ audio_utils::lock_guard _l(mutex());
for (audio_session_t session : {
AUDIO_SESSION_DEVICE,
AUDIO_SESSION_OUTPUT_STAGE,
@@ -2689,8 +2690,8 @@
goto Exit;
}
- { // scope for mLock
- Mutex::Autolock _l(mLock);
+ { // scope for mutex()
+ audio_utils::lock_guard _l(mutex());
// all tracks in same audio session must share the same routing strategy otherwise
// conflicts will happen when tracks are moved from one output to another by audio policy
@@ -2734,7 +2735,7 @@
}
mTracks.add(track);
{
- Mutex::Autolock _atCbL(mAudioTrackCbLock);
+ audio_utils::lock_guard _atCbL(audioTrackCbMutex());
if (callback.get() != nullptr) {
mAudioTrackCallbacks.emplace(track, callback);
}
@@ -2786,7 +2787,7 @@
uint32_t PlaybackThread::latency() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return latency_l();
}
uint32_t PlaybackThread::latency_l() const
@@ -2800,7 +2801,7 @@
void PlaybackThread::setMasterVolume(float value)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// Don't apply master volume in SW if our HAL can do it for us.
if (mOutput && mOutput->audioHwDev &&
mOutput->audioHwDev->canSetMasterVolume()) {
@@ -2820,7 +2821,7 @@
if (isDuplicating()) {
return;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// Don't apply master mute in SW if our HAL can do it for us.
if (mOutput && mOutput->audioHwDev &&
mOutput->audioHwDev->canSetMasterMute()) {
@@ -2832,21 +2833,21 @@
void PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mStreamTypes[stream].volume = value;
broadcast_l();
}
void PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mStreamTypes[stream].mute = muted;
broadcast_l();
}
float PlaybackThread::streamVolume(audio_stream_type_t stream) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mStreamTypes[stream].volume;
}
@@ -2855,9 +2856,9 @@
mOutput->stream->setVolume(left, right);
}
-// addTrack_l() must be called with ThreadBase::mLock held
+// addTrack_l() must be called with ThreadBase::mutex() held
status_t PlaybackThread::addTrack_l(const sp<IAfTrack>& track)
-NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mutex()
{
status_t status = ALREADY_EXISTS;
@@ -2867,15 +2868,15 @@
// effectively get the latency it requested.
if (track->isExternalTrack()) {
IAfTrackBase::track_state state = track->state();
- mLock.unlock();
+ mutex().unlock();
status = AudioSystem::startOutput(track->portId());
- mLock.lock();
+ mutex().lock();
// abort track was stopped/paused while we released the lock
if (state != track->state()) {
if (status == NO_ERROR) {
- mLock.unlock();
+ mutex().unlock();
AudioSystem::stopOutput(track->portId());
- mLock.lock();
+ mutex().lock();
}
return INVALID_OPERATION;
}
@@ -2914,17 +2915,17 @@
|| (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
- mLock.unlock();
+ mutex().unlock();
const os::HapticScale intensity = afutils::onExternalVibrationStart(
track->getExternalVibration());
std::optional<media::AudioVibratorInfo> vibratorInfo;
{
// TODO(b/184194780): Use the vibrator information from the vibrator that will be
// used to play this track.
- Mutex::Autolock _l(mAfThreadCallback->mutex());
+ audio_utils::lock_guard _l(mAfThreadCallback->mutex());
vibratorInfo = std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
}
- mLock.lock();
+ mutex().lock();
track->setHapticIntensity(intensity);
if (vibratorInfo) {
track->setHapticMaxAmplitude(vibratorInfo->maxAmplitude);
@@ -2990,7 +2991,7 @@
mTracks.remove(track);
{
- Mutex::Autolock _atCbL(mAudioTrackCbLock);
+ audio_utils::lock_guard _atCbL(audioTrackCbMutex());
mAudioTrackCallbacks.erase(track);
}
if (track->isFastTrack()) {
@@ -3009,7 +3010,7 @@
String8 PlaybackThread::getParameters(const String8& keys)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
String8 out_s8;
if (initCheck() == NO_ERROR && mOutput->stream->getParameters(keys, &out_s8) == OK) {
return out_s8;
@@ -3018,7 +3019,7 @@
}
status_t DirectOutputThread::selectPresentation(int presentationId, int programId) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!isStreamInitialized()) {
return NO_INIT;
}
@@ -3088,7 +3089,7 @@
audio_utils::metadata::ByteString metaDataStr =
audio_utils::metadata::byteStringFromData(metadata);
std::vector metadataVec(metaDataStr.begin(), metaDataStr.end());
- Mutex::Autolock _l(mAudioTrackCbLock);
+ audio_utils::lock_guard _l(audioTrackCbMutex());
for (const auto& callbackPair : mAudioTrackCallbacks) {
callbackPair.second->onCodecFormatChanged(metadataVec);
}
@@ -3097,17 +3098,17 @@
void PlaybackThread::resetWriteBlocked(uint32_t sequence)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// reject out of sequence requests
if ((mWriteAckSequence & 1) && (sequence == mWriteAckSequence)) {
mWriteAckSequence &= ~1;
- mWaitWorkCV.signal();
+ mWaitWorkCV.notify_one();
}
}
void PlaybackThread::resetDraining(uint32_t sequence)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// reject out of sequence requests
if ((mDrainSequence & 1) && (sequence == mDrainSequence)) {
// Register discontinuity when HW drain is completed because that can cause
@@ -3116,11 +3117,13 @@
// elsewhere, e.g. in flush).
mTimestampVerifier.discontinuity(mTimestampVerifier.DISCONTINUITY_MODE_ZERO);
mDrainSequence &= ~1;
- mWaitWorkCV.signal();
+ mWaitWorkCV.notify_one();
}
}
void PlaybackThread::readOutputParameters_l()
+NO_THREAD_SAFETY_ANALYSIS
+// 'moveEffectChain_ll' requires holding mutex 'AudioFlinger_Mutex' exclusively
{
// unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL
const audio_config_base_t audioConfig = mOutput->getAudioProperties();
@@ -3285,13 +3288,14 @@
// force reconfiguration of effect chains and engines to take new buffer size and audio
// parameters into account
- // Note that mLock is not held when readOutputParameters_l() is called from the constructor
+ // Note that mutex() is not held when readOutputParameters_l() is called from the constructor
// but in this case nothing is done below as no audio sessions have effect yet so it doesn't
// matter.
- // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
+ // create a copy of mEffectChains as calling moveEffectChain_ll()
+ // can reorder some effect chains
Vector<sp<IAfEffectChain>> effectChains = mEffectChains;
for (size_t i = 0; i < effectChains.size(); i ++) {
- mAfThreadCallback->moveEffectChain_l(effectChains[i]->sessionId(),
+ mAfThreadCallback->moveEffectChain_ll(effectChains[i]->sessionId(),
this/* srcThread */, this/* dstThread */);
}
@@ -3349,7 +3353,7 @@
if (halFrames == NULL || dspFrames == NULL) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (initCheck() != NO_ERROR) {
return INVALID_OPERATION;
}
@@ -3390,13 +3394,13 @@
AudioStreamOut* PlaybackThread::getOutput() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return mOutput;
}
AudioStreamOut* PlaybackThread::clearOutput()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
AudioStreamOut *output = mOutput;
mOutput = NULL;
// FIXME FastMixer might also have a raw ptr to mOutputSink;
@@ -3407,7 +3411,7 @@
return output;
}
-// this method must always be called either with ThreadBase mLock held or inside the thread loop
+// this method must always be called either with ThreadBase mutex() held or inside the thread loop
sp<StreamHalInterface> PlaybackThread::stream() const
{
if (mOutput == NULL) {
@@ -3427,7 +3431,7 @@
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<IAfTrack> track = mTracks[i];
@@ -3557,7 +3561,7 @@
return bytesWritten;
}
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
void PlaybackThread::startMelComputation_l(
const sp<audio_utils::MelProcessor>& processor)
{
@@ -3567,7 +3571,7 @@
}
}
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
void PlaybackThread::stopMelComputation_l()
{
auto outputSink = static_cast<AudioStreamOutSink*>(mOutputSink.get());
@@ -3595,7 +3599,7 @@
void PlaybackThread::threadLoop_exit()
{
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); i++) {
sp<IAfTrack> track = mTracks[i];
track->invalidate();
@@ -3663,12 +3667,12 @@
void PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
invalidateTracks_l(streamType);
}
void PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
invalidateTracks_l(portIds);
}
@@ -3872,7 +3876,7 @@
status_t PlaybackThread::attachAuxEffect(
const sp<IAfTrack>& track, int EffectId)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return attachAuxEffect_l(track, EffectId);
}
@@ -3914,6 +3918,18 @@
{
aflog::setThreadWriter(mNBLogWriter.get());
+ if (mType == SPATIALIZER) {
+ const pid_t tid = getTid();
+ if (tid == -1) { // odd: we are here, we must be a running thread.
+ ALOGW("%s: Cannot update Spatializer mixer thread priority, no tid", __func__);
+ } else {
+ const int priorityBoost = requestSpatializerPriority(getpid(), tid);
+ if (priorityBoost > 0) {
+ stream()->setHalThreadPriority(priorityBoost);
+ }
+ }
+ }
+
Vector<sp<IAfTrack>> tracksToRemove;
mStandbyTimeNs = systemTime();
@@ -3973,11 +3989,11 @@
// If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
//
- // Note: we access outDeviceTypes() outside of mLock.
+ // Note: we access outDeviceTypes() outside of mutex().
if (isMsdDevice() && outDeviceTypes().count(AUDIO_DEVICE_OUT_BUS) != 0) {
// Here, we try for the AF lock, but do not block on it as the latency
// is more informational.
- if (mAfThreadCallback->mutex().tryLock() == NO_ERROR) {
+ if (mAfThreadCallback->mutex().try_lock()) {
std::vector<SoftwarePatch> swPatches;
double latencyMs = 0.; // not required; initialized for clang-tidy
status_t status = INVALID_OPERATION;
@@ -4019,16 +4035,16 @@
}
MetadataUpdate metadataUpdate;
- { // scope for mLock
+ { // scope for mutex()
- Mutex::Autolock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
processConfigEvents_l();
if (mCheckOutputStageEffects.load()) {
continue;
}
- // See comment at declaration of logString for why this is done under mLock
+ // See comment at declaration of logString for why this is done under mutex()
if (logString != NULL) {
mNBLogWriter->logTimestamp();
mNBLogWriter->log(logString);
@@ -4053,8 +4069,9 @@
const int64_t waitNs = computeWaitTimeNs_l();
ALOGV("wait async completion (wait time: %lld)", (long long)waitNs);
- status_t status = mWaitWorkCV.waitRelative(mLock, waitNs);
- if (status == TIMED_OUT) {
+ std::cv_status cvstatus =
+ mWaitWorkCV.wait_for(_l, std::chrono::nanoseconds(waitNs));
+ if (cvstatus == std::cv_status::timeout) {
mSignalPending = true; // if timeout recheck everything
}
ALOGV("async completion/wake");
@@ -4096,7 +4113,7 @@
releaseWakeLock_l();
// wait until we have something to do...
ALOGV("%s going to sleep", myName.c_str());
- mWaitWorkCV.wait(mLock);
+ mWaitWorkCV.wait(_l);
ALOGV("%s waking up", myName.c_str());
acquireWakeLock_l();
@@ -4169,9 +4186,9 @@
&& (mKernelPositionOnStandby
!= mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL])))) {
mHalStarted = true;
- mWaitHalStartCV.broadcast();
+ mWaitHalStartCV.notify_all();
}
- } // mLock scope ends
+ } // mutex() scope ends
if (mBytesRemaining == 0) {
mCurrentWriteLength = 0;
@@ -4402,7 +4419,7 @@
const double processMs =
(lastIoBeginNs - mLastIoEndNs) * 1e-6;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mIoJitterMs.add(jitterMs);
mProcessTimeMs.add(processMs);
@@ -4503,7 +4520,7 @@
} else {
ATRACE_BEGIN("sleep");
- Mutex::Autolock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
// suspended requires accurate metering of sleep time.
if (isSuspended()) {
// advance by expected sleepTime
@@ -4528,7 +4545,7 @@
mSleepTimeUs = deltaNs / 1000;
}
if (!mSignalPending && mConfigEvents.isEmpty() && !exitPending()) {
- mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)mSleepTimeUs));
+ mWaitWorkCV.wait_for(_l, std::chrono::microseconds(mSleepTimeUs));
}
ATRACE_END();
}
@@ -4701,9 +4718,9 @@
#endif
}
-// removeTracks_l() must be called with ThreadBase::mLock held
+// removeTracks_l() must be called with ThreadBase::mutex() held
void PlaybackThread::removeTracks_l(const Vector<sp<IAfTrack>>& tracksToRemove)
-NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mutex()
{
for (const auto& track : tracksToRemove) {
mActiveTracks.remove(track);
@@ -4729,11 +4746,11 @@
if (mHapticChannelCount > 0 &&
((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
|| (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
- mLock.unlock();
+ mutex().unlock();
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
afutils::onExternalVibrationStop(track->getExternalVibration());
- mLock.lock();
+ mutex().lock();
// When the track is stop, set the haptic intensity as MUTE
// for the HapticGenerator effect.
@@ -4931,13 +4948,13 @@
void PlaybackThread::addPatchTrack(const sp<IAfPatchTrack>& track)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mTracks.add(track);
}
void PlaybackThread::deletePatchTrack(const sp<IAfPatchTrack>& track)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
destroyTrack_l(track);
}
@@ -5187,7 +5204,7 @@
void MixerThread::onFirstRef() {
PlaybackThread::onFirstRef();
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mOutput != nullptr && mOutput->stream != nullptr) {
status_t status = mOutput->stream->setLatencyModeCallback(this);
if (status != INVALID_OPERATION) {
@@ -5302,7 +5319,7 @@
bool PlaybackThread::waitingAsyncCallback()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return waitingAsyncCallback_l();
}
@@ -5407,7 +5424,7 @@
// TODO add standby time extension fct of effect tail
}
-// prepareTracks_l() must be called with ThreadBase::mLock held
+// prepareTracks_l() must be called with ThreadBase::mutex() held
PlaybackThread::mixer_state MixerThread::prepareTracks_l(
Vector<sp<IAfTrack>>* tracksToRemove)
{
@@ -6203,7 +6220,7 @@
return mixerStatus;
}
-// trackCountForUid_l() must be called with ThreadBase::mLock held
+// trackCountForUid_l() must be called with ThreadBase::mutex() held
uint32_t PlaybackThread::trackCountForUid_l(uid_t uid) const
{
uint32_t trackCount = 0;
@@ -6246,7 +6263,7 @@
mPreviousNs = 0;
}
-// isTrackAllowed_l() must be called with ThreadBase::mLock held
+// isTrackAllowed_l() must be called with ThreadBase::mutex() held
bool MixerThread::isTrackAllowed_l(
audio_channel_mask_t channelMask, audio_format_t format,
audio_session_t sessionId, uid_t uid) const
@@ -6266,7 +6283,7 @@
return true;
}
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
bool MixerThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
@@ -6484,14 +6501,14 @@
if (modes == nullptr) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
*modes = mSupportedLatencyModes;
return NO_ERROR;
}
void MixerThread::onRecommendedLatencyModeChanged(
std::vector<audio_latency_mode_t> modes) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (modes != mSupportedLatencyModes) {
ALOGD("%s: thread(%d) supported latency modes: %s",
__func__, mId, toString(modes).c_str());
@@ -6542,7 +6559,7 @@
void DirectOutputThread::setMasterBalance(float balance)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mMasterBalance != balance) {
mMasterBalance.store(balance);
mBalance.computeStereoBalance(balance, &mMasterBalanceLeft, &mMasterBalanceRight);
@@ -6922,7 +6939,7 @@
void DirectOutputThread::threadLoop_exit()
{
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); i++) {
if (mTracks[i]->isFlushPending()) {
mTracks[i]->flushAck();
@@ -6953,7 +6970,7 @@
return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
}
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
bool DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
@@ -7088,12 +7105,12 @@
bool asyncError;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
while (!((mWriteAckSequence & 1) ||
(mDrainSequence & 1) ||
mAsyncError ||
exitPending())) {
- mWaitWorkCV.wait(mLock);
+ mWaitWorkCV.wait(_l);
}
if (exitPending()) {
@@ -7129,50 +7146,50 @@
void AsyncCallbackThread::exit()
{
ALOGV("AsyncCallbackThread::exit");
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
requestExit();
- mWaitWorkCV.broadcast();
+ mWaitWorkCV.notify_all();
}
void AsyncCallbackThread::setWriteBlocked(uint32_t sequence)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// bit 0 is cleared
mWriteAckSequence = sequence << 1;
}
void AsyncCallbackThread::resetWriteBlocked()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// ignore unexpected callbacks
if (mWriteAckSequence & 2) {
mWriteAckSequence |= 1;
- mWaitWorkCV.signal();
+ mWaitWorkCV.notify_one();
}
}
void AsyncCallbackThread::setDraining(uint32_t sequence)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// bit 0 is cleared
mDrainSequence = sequence << 1;
}
void AsyncCallbackThread::resetDraining()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// ignore unexpected callbacks
if (mDrainSequence & 2) {
mDrainSequence |= 1;
- mWaitWorkCV.signal();
+ mWaitWorkCV.notify_one();
}
}
void AsyncCallbackThread::setAsyncError()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mAsyncError = true;
- mWaitWorkCV.signal();
+ mWaitWorkCV.notify_one();
}
@@ -7468,7 +7485,7 @@
bool OffloadThread::waitingAsyncCallback()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return waitingAsyncCallback_l();
}
@@ -7495,14 +7512,14 @@
void OffloadThread::invalidateTracks(audio_stream_type_t streamType)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (PlaybackThread::invalidateTracks_l(streamType)) {
mFlushPending = true;
}
}
void OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (PlaybackThread::invalidateTracks_l(portIds)) {
mFlushPending = true;
}
@@ -7644,7 +7661,7 @@
void DuplicatingThread::addOutputTrack(IAfPlaybackThread* thread)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass.
// Adjust for thread->sampleRate() to determine minimum buffer frame count.
// Then triple buffer because Threads do not run synchronously and may not be clock locked.
@@ -7681,7 +7698,7 @@
void DuplicatingThread::removeOutputTrack(IAfPlaybackThread* thread)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mOutputTracks.size(); i++) {
if (mOutputTracks[i]->thread() == thread) {
mOutputTracks[i]->destroy();
@@ -7696,7 +7713,7 @@
ALOGV("removeOutputTrack(): unknown thread: %p", thread);
}
-// caller must hold mLock
+// caller must hold mutex()
void DuplicatingThread::updateWaitTime_l()
{
mWaitTimeMs = UINT_MAX;
@@ -7773,21 +7790,6 @@
{
}
-void SpatializerThread::onFirstRef() {
- MixerThread::onFirstRef();
-
- const pid_t tid = getTid();
- if (tid == -1) {
- // Unusual: PlaybackThread::onFirstRef() should set the threadLoop running.
- ALOGW("%s: Cannot update Spatializer mixer thread priority, not running", __func__);
- } else {
- const int priorityBoost = requestSpatializerPriority(getpid(), tid);
- if (priorityBoost > 0) {
- stream()->setHalThreadPriority(priorityBoost);
- }
- }
-}
-
void SpatializerThread::setHalLatencyMode_l() {
// if mSupportedLatencyModes is empty, the HAL stream does not support
// latency mode control and we can exit.
@@ -7830,18 +7832,20 @@
if (mode != AUDIO_LATENCY_MODE_LOW && mode != AUDIO_LATENCY_MODE_FREE) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mRequestedLatencyMode = mode;
return NO_ERROR;
}
void SpatializerThread::checkOutputStageEffects()
+NO_THREAD_SAFETY_ANALYSIS
+// 'createEffect_l' requires holding mutex 'AudioFlinger_Mutex' exclusively
{
bool hasVirtualizer = false;
bool hasDownMixer = false;
sp<IAfEffectHandle> finalDownMixer;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfEffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_STAGE);
if (chain != 0) {
hasVirtualizer = chain->getEffectFromType_l(FX_IID_SPATIALIZER) != nullptr;
@@ -7882,7 +7886,7 @@
}
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mFinalDownMixer = finalDownMixer;
}
}
@@ -8088,13 +8092,13 @@
void RecordThread::preExit()
{
ALOGV(" preExit()");
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); i++) {
sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
- mStartStopCond.broadcast();
+ mStartStopCV.notify_all();
}
bool RecordThread::threadLoop()
@@ -8106,7 +8110,7 @@
reacquire_wakelock:
sp<IAfRecordTrack> activeTrack;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
acquireWakeLock_l();
}
@@ -8130,13 +8134,13 @@
bool silenceFastCapture = false;
- { // scope for mLock
- Mutex::Autolock _l(mLock);
+ { // scope for mutex()
+ audio_utils::unique_lock _l(mutex());
processConfigEvents_l();
// check exitPending here because checkForNewParameters_l() and
- // checkForNewParameters_l() can temporarily release mLock
+ // checkForNewParameters_l() can temporarily release mutex()
if (exitPending()) {
break;
}
@@ -8144,7 +8148,7 @@
// sleep with mutex unlocked
if (sleepUs > 0) {
ATRACE_BEGIN("sleepC");
- mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)sleepUs));
+ (void)mWaitWorkCV.wait_for(_l, std::chrono::microseconds(sleepUs));
ATRACE_END();
sleepUs = 0;
continue;
@@ -8158,7 +8162,7 @@
releaseWakeLock_l();
ALOGV("RecordThread: loop stopping");
// go to sleep
- mWaitWorkCV.wait(mLock);
+ mWaitWorkCV.wait(_l);
ALOGV("RecordThread: loop starting");
goto reacquire_wakelock;
}
@@ -8265,7 +8269,7 @@
standbyIfNotAlreadyInStandby();
}
if (doBroadcast) {
- mStartStopCond.broadcast();
+ mStartStopCV.notify_all();
}
// sleep if there are no active tracks to process
@@ -8634,7 +8638,7 @@
{0, 0} /* lastTimestamp */, mSampleRate);
const double processMs = (lastIoBeginNs - mLastIoEndNs) * 1e-6;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mIoJitterMs.add(jitterMs);
mProcessTimeMs.add(processMs);
}
@@ -8647,13 +8651,13 @@
standbyIfNotAlreadyInStandby();
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); i++) {
sp<IAfRecordTrack> track = mTracks[i];
track->invalidate();
}
mActiveTracks.clear();
- mStartStopCond.broadcast();
+ mStartStopCV.notify_all();
}
releaseWakeLock();
@@ -8712,7 +8716,7 @@
}
}
-// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
+// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mutex() held
sp<IAfRecordTrack> RecordThread::createRecordTrack_l(
const sp<Client>& client,
const audio_attributes_t& attr,
@@ -8804,7 +8808,7 @@
mFastTrackAvail
) {
// check compatibility with audio effects.
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// Do not accept FAST flag if the session has software effects
sp<IAfEffectChain> chain = getEffectChain_l(sessionId);
if (chain != 0) {
@@ -8868,8 +8872,8 @@
*pFrameCount = frameCount;
*pNotificationFrameCount = notificationFrameCount;
- { // scope for mLock
- Mutex::Autolock _l(mLock);
+ { // scope for mutex()
+ audio_utils::lock_guard _l(mutex());
int32_t startFrames = -1;
if (!mSharedAudioPackageName.empty()
&& mSharedAudioPackageName == attributionSource.packageName
@@ -8930,7 +8934,7 @@
{
// This section is a rendezvous between binder thread executing start() and RecordThread
- AutoMutex lock(mLock);
+ audio_utils::lock_guard lock(mutex());
if (recordTrack->isInvalid()) {
recordTrack->clearSyncStartEvent();
ALOGW("%s track %d: invalidated before startInput", __func__, recordTrack->portId());
@@ -8954,9 +8958,9 @@
recordTrack->setState(IAfTrackBase::STARTING_1);
mActiveTracks.add(recordTrack);
if (recordTrack->isExternalTrack()) {
- mLock.unlock();
+ mutex().unlock();
status = AudioSystem::startInput(recordTrack->portId());
- mLock.lock();
+ mutex().lock();
if (recordTrack->isInvalid()) {
recordTrack->clearSyncStartEvent();
if (status == NO_ERROR && recordTrack->state() == IAfTrackBase::STARTING_1) {
@@ -9002,7 +9006,7 @@
}
recordTrack->setState(IAfTrackBase::STARTING_2);
// signal thread to start
- mWaitWorkCV.broadcast();
+ mWaitWorkCV.notify_all();
return status;
}
}
@@ -9023,7 +9027,7 @@
bool RecordThread::stop(IAfRecordTrack* recordTrack) {
ALOGV("RecordThread::stop");
- AutoMutex _l(mLock);
+ audio_utils::unique_lock _l(mutex());
// if we're invalid, we can't be on the ActiveTracks.
if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->state() == IAfTrackBase::PAUSING) {
return false;
@@ -9034,8 +9038,8 @@
// NOTE: Waiting here is important to keep stop synchronous.
// This is needed for proper patchRecord peer release.
while (recordTrack->state() == IAfTrackBase::PAUSING && !recordTrack->isInvalid()) {
- mWaitWorkCV.broadcast(); // signal thread to stop
- mStartStopCond.wait(mLock);
+ mWaitWorkCV.notify_all(); // signal thread to stop
+ mStartStopCV.wait(_l);
}
if (recordTrack->state() == IAfTrackBase::PAUSED) { // successful stop
@@ -9064,7 +9068,7 @@
audio_session_t eventSession = event->triggerSession();
status_t ret = NAME_NOT_FOUND;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size(); i++) {
sp<IAfRecordTrack> track = mTracks[i];
@@ -9083,7 +9087,7 @@
std::vector<media::MicrophoneInfoFw>* activeMicrophones) const
{
ALOGV("RecordThread::getActiveMicrophones");
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!isStreamInitialized()) {
return NO_INIT;
}
@@ -9095,7 +9099,7 @@
audio_microphone_direction_t direction)
{
ALOGV("setPreferredMicrophoneDirection(%d)", direction);
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!isStreamInitialized()) {
return NO_INIT;
}
@@ -9105,7 +9109,7 @@
status_t RecordThread::setPreferredMicrophoneFieldDimension(float zoom)
{
ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (!isStreamInitialized()) {
return NO_INIT;
}
@@ -9115,7 +9119,7 @@
status_t RecordThread::shareAudioHistory(
const std::string& sharedAudioPackageName, audio_session_t sharedSessionId,
int64_t sharedAudioStartMs) {
- AutoMutex _l(mLock);
+ audio_utils::lock_guard _l(mutex());
return shareAudioHistory_l(sharedAudioPackageName, sharedSessionId, sharedAudioStartMs);
}
@@ -9181,7 +9185,7 @@
return change;
}
-// destroyTrack_l() must be called with ThreadBase::mLock held
+// destroyTrack_l() must be called with ThreadBase::mutex() held
void RecordThread::destroyTrack_l(const sp<IAfRecordTrack>& track)
{
track->terminate();
@@ -9281,7 +9285,7 @@
void RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mTracks.size() ; i++) {
sp<IAfRecordTrack> track = mTracks[i];
if (track != 0 && track->portId() == portId) {
@@ -9406,7 +9410,7 @@
void RecordThread::checkBtNrec()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
checkBtNrec_l();
}
@@ -9515,7 +9519,7 @@
String8 RecordThread::getParameters(const String8& keys)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (initCheck() == NO_ERROR) {
String8 out_s8;
if (mInput->stream->getParameters(keys, &out_s8) == OK) {
@@ -9591,7 +9595,7 @@
uint32_t RecordThread::getInputFramesLost() const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
uint32_t result;
if (initCheck() == NO_ERROR && mInput->stream->getInputFramesLost(&result) == OK) {
return result;
@@ -9602,7 +9606,7 @@
KeyedVector<audio_session_t, bool> RecordThread::sessionIds() const
{
KeyedVector<audio_session_t, bool> ids;
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t j = 0; j < mTracks.size(); ++j) {
sp<IAfRecordTrack> track = mTracks[j];
audio_session_t sessionId = track->sessionId();
@@ -9615,14 +9619,14 @@
AudioStreamIn* RecordThread::clearInput()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
AudioStreamIn *input = mInput;
mInput = NULL;
mInputSource.clear();
return input;
}
-// this method must always be called either with ThreadBase mLock held or inside the thread loop
+// this method must always be called either with ThreadBase mutex() held or inside the thread loop
sp<StreamHalInterface> RecordThread::stream() const
{
if (mInput == NULL) {
@@ -9740,7 +9744,7 @@
void RecordThread::updateOutDevices(const DeviceDescriptorBaseVector& outDevices)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mOutDevices = outDevices;
mOutDeviceTypeAddrs = deviceTypeAddrsFromDescriptors(mOutDevices);
for (size_t i = 0; i < mEffectChains.size(); i++) {
@@ -9877,7 +9881,7 @@
void RecordThread::addPatchTrack(const sp<IAfPatchRecord>& record)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
mTracks.add(record);
if (record->getSource()) {
mSource = record->getSource();
@@ -9886,7 +9890,7 @@
void RecordThread::deletePatchTrack(const sp<IAfPatchRecord>& record)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (mSource == record->getSource()) {
mSource = mInput;
}
@@ -10011,7 +10015,7 @@
{
ActiveTracks<IAfMmapTrack> activeTracks;
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (const sp<IAfMmapTrack>& t : mActiveTracks) {
activeTracks.add(t);
}
@@ -10155,24 +10159,24 @@
{
// Add the track record before starting input so that the silent status for the
// client can be cached.
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
setClientSilencedState_l(portId, false /*silenced*/);
}
ret = AudioSystem::startInput(portId);
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// abort if start is rejected by audio policy manager
if (ret != NO_ERROR) {
ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
if (!mActiveTracks.isEmpty()) {
- mLock.unlock();
+ mutex().unlock();
if (isOutput()) {
AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
- mLock.lock();
+ mutex().lock();
} else {
mHalStream->stop();
}
@@ -10237,7 +10241,7 @@
return NO_ERROR;
}
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
sp<IAfMmapTrack> track;
for (const sp<IAfMmapTrack>& t : mActiveTracks) {
@@ -10253,7 +10257,7 @@
mActiveTracks.remove(track);
eraseClientSilencedState_l(track->portId());
- mLock.unlock();
+ mutex().unlock();
if (isOutput()) {
AudioSystem::stopOutput(track->portId());
AudioSystem::releaseOutput(track->portId());
@@ -10261,7 +10265,7 @@
AudioSystem::stopInput(track->portId());
AudioSystem::releaseInput(track->portId());
}
- mLock.lock();
+ mutex().lock();
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
@@ -10350,7 +10354,7 @@
Vector<sp<IAfEffectChain>> effectChains;
{ // under Thread lock
- Mutex::Autolock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
if (mSignalPending) {
// A signal was raised while we were unlocked
@@ -10366,7 +10370,7 @@
// wait until we have something to do...
ALOGV("%s going to sleep", myName.c_str());
- mWaitWorkCV.wait(mLock);
+ mWaitWorkCV.wait(_l);
ALOGV("%s waking up", myName.c_str());
checkSilentMode_l();
@@ -10409,7 +10413,7 @@
return false;
}
-// checkForNewParameter_l() must be called with ThreadBase::mLock held
+// checkForNewParameter_l() must be called with ThreadBase::mutex() held
bool MmapThread::checkForNewParameter_l(const String8& keyValuePair,
status_t& status)
{
@@ -10430,7 +10434,7 @@
String8 MmapThread::getParameters(const String8& keys)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
String8 out_s8;
if (initCheck() == NO_ERROR && mHalStream->getParameters(keys, &out_s8) == OK) {
return out_s8;
@@ -10465,7 +10469,7 @@
status_t MmapThread::createAudioPatch_l(const struct audio_patch* patch,
audio_patch_handle_t *handle)
-NO_THREAD_SAFETY_ANALYSIS // elease and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS // elease and re-acquire mutex()
{
status_t status = NO_ERROR;
@@ -10541,9 +10545,9 @@
}
sp<MmapStreamCallback> callback = mCallback.promote();
if (mDeviceId != deviceId && callback != 0) {
- mLock.unlock();
+ mutex().unlock();
callback->onRoutingChanged(deviceId);
- mLock.lock();
+ mutex().lock();
}
mPatch = *patch;
mDeviceId = deviceId;
@@ -10694,7 +10698,7 @@
}
void MmapThread::checkInvalidTracks_l()
-NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mLock
+NO_THREAD_SAFETY_ANALYSIS // release and re-acquire mutex()
{
sp<MmapStreamCallback> callback;
for (const sp<IAfMmapTrack>& track : mActiveTracks) {
@@ -10708,9 +10712,9 @@
}
}
if (callback != 0) {
- mLock.unlock();
+ mutex().unlock();
callback->onRoutingChanged(AUDIO_PORT_HANDLE_NONE);
- mLock.lock();
+ mutex().lock();
}
}
@@ -10788,7 +10792,7 @@
AudioStreamOut* MmapPlaybackThread::clearOutput()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
AudioStreamOut *output = mOutput;
mOutput = NULL;
return output;
@@ -10796,7 +10800,7 @@
void MmapPlaybackThread::setMasterVolume(float value)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// Don't apply master volume in SW if our HAL can do it for us.
if (mAudioHwDev &&
mAudioHwDev->canSetMasterVolume()) {
@@ -10808,7 +10812,7 @@
void MmapPlaybackThread::setMasterMute(bool muted)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
// Don't apply master mute in SW if our HAL can do it for us.
if (mAudioHwDev && mAudioHwDev->canSetMasterMute()) {
mMasterMute = false;
@@ -10819,7 +10823,7 @@
void MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (stream == mStreamType) {
mStreamVolume = value;
broadcast_l();
@@ -10828,7 +10832,7 @@
float MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (stream == mStreamType) {
return mStreamVolume;
}
@@ -10837,7 +10841,7 @@
void MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (stream == mStreamType) {
mStreamMute= muted;
broadcast_l();
@@ -10846,7 +10850,7 @@
void MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
if (streamType == mStreamType) {
for (const sp<IAfMmapTrack>& track : mActiveTracks) {
track->invalidate();
@@ -10857,7 +10861,7 @@
void MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
bool trackMatch = false;
for (const sp<IAfMmapTrack>& track : mActiveTracks) {
if (portIds.find(track->portId()) != portIds.end()) {
@@ -10906,9 +10910,9 @@
if (callback != 0) {
mHalVolFloat = volume; // SW volume control worked, so update value.
mNoCallbackWarningCount = 0;
- mLock.unlock();
+ mutex().unlock();
callback->onVolumeChanged(volume);
- mLock.lock();
+ mutex().lock();
} else {
if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) {
ALOGW("Could not set MMAP stream volume: no volume callback!");
@@ -11005,7 +11009,7 @@
return NO_ERROR;
}
-// startMelComputation_l() must be called with AudioFlinger::mLock held
+// startMelComputation_l() must be called with AudioFlinger::mutex() held
void MmapPlaybackThread::startMelComputation_l(
const sp<audio_utils::MelProcessor>& processor)
{
@@ -11019,7 +11023,7 @@
// assigned constant for each thread
}
-// stopMelComputation_l() must be called with AudioFlinger::mLock held
+// stopMelComputation_l() must be called with AudioFlinger::mutex() held
void MmapPlaybackThread::stopMelComputation_l()
{
ALOGV("%s: pausing mel processor for thread %d", __func__, id());
@@ -11068,7 +11072,7 @@
AudioStreamIn* MmapCaptureThread::clearInput()
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
AudioStreamIn *input = mInput;
mInput = NULL;
return input;
@@ -11126,7 +11130,7 @@
void MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{
- Mutex::Autolock _l(mLock);
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mActiveTracks.size() ; i++) {
if (mActiveTracks[i]->portId() == portId) {
mActiveTracks[i]->setSilenced_l(silenced);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 3098892..3105ad7 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -77,20 +77,20 @@
// Config event sequence by client if status needed (e.g binder thread calling setParameters()):
// 1. create SetParameterConfigEvent. This sets mWaitStatus in config event
- // 2. Lock mLock
+ // 2. Lock mutex()
// 3. Call sendConfigEvent_l(): Append to mConfigEvents and mWaitWorkCV.signal
// 4. sendConfigEvent_l() reads status from event->mStatus;
// 5. sendConfigEvent_l() returns status
// 6. Unlock
//
// Parameter sequence by server: threadLoop calling processConfigEvents_l():
- // 1. Lock mLock
+ // 1. Lock mutex()
// 2. If there is an entry in mConfigEvents proceed ...
// 3. Read first entry in mConfigEvents
// 4. Remove first entry from mConfigEvents
// 5. Process
// 6. Set event->mStatus
- // 7. event->mCond.signal
+ // 7. event->mCondition.notify_one()
// 8. Unlock
class ConfigEvent: public RefBase {
@@ -103,9 +103,10 @@
}
}
+ audio_utils::mutex& mutex() const { return mMutex; }
const int mType; // event type e.g. CFG_EVENT_IO
- Mutex mLock; // mutex associated with mCond
- Condition mCond; // condition for status return
+ mutable audio_utils::mutex mMutex; // mutex associated with mCondition
+ audio_utils::condition_variable mCondition; // condition for status return
status_t mStatus; // status communicated to sender
bool mWaitStatus; // true if sender is waiting for status
bool mRequiresSystemReady; // true if must wait for system ready to enter event queue
@@ -322,7 +323,7 @@
void exit() final;
status_t setParameters(const String8& keyValuePairs) final;
- // sendConfigEvent_l() must be called with ThreadBase::mLock held
+ // sendConfigEvent_l() must be called with ThreadBase::mutex() held
// Can temporarily release the lock if waiting for a reply from
// processConfigEvents_l().
status_t sendConfigEvent_l(sp<ConfigEvent>& event);
@@ -389,7 +390,8 @@
status_t *status /*non-NULL*/,
bool pinned,
bool probe,
- bool notifyFramesProcessed) final;
+ bool notifyFramesProcessed) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
// return values for hasAudioSession (bit field)
enum effect_state {
@@ -428,7 +430,8 @@
// add and effect module. Also creates the effect chain is none exists for
// the effects audio session. Only called in a context of moving an effect
// from one thread to another
- status_t addEffect_l(const sp<IAfEffectModule>& effect) final;
+ status_t addEffect_ll(const sp<IAfEffectModule>& effect) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex, mutex());
// remove and effect module. Also removes the effect chain is this was the last
// effect
void removeEffect_l(const sp<IAfEffectModule>& effect, bool release = false) final;
@@ -439,7 +442,7 @@
// TODO(b/291317898) - remove hasAudioSession_l below.
uint32_t hasAudioSession_l(audio_session_t sessionId) const override = 0;
uint32_t hasAudioSession(audio_session_t sessionId) const final {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mutex());
return hasAudioSession_l(sessionId);
}
@@ -507,19 +510,19 @@
// deliver stats to mediametrics.
void sendStatistics(bool force) final;
- Mutex& mutex() const final {
- return mLock;
+ audio_utils::mutex& mutex() const final RETURN_CAPABILITY(audio_utils::ThreadBase_Mutex) {
+ return mMutex;
}
- mutable Mutex mLock;
+ mutable audio_utils::mutex mMutex;
void onEffectEnable(const sp<IAfEffectModule>& effect) final;
void onEffectDisable() final;
- // invalidateTracksForAudioSession_l must be called with holding mLock.
+ // invalidateTracksForAudioSession_l must be called with holding mutex().
void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override {}
// Invalidate all the tracks with the given audio session.
void invalidateTracksForAudioSession(audio_session_t sessionId) const final {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mutex());
invalidateTracksForAudioSession_l(sessionId);
}
@@ -534,8 +537,10 @@
}
}
- void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
- void stopMelComputation_l() override;
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ void stopMelComputation_l() override
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
protected:
@@ -599,7 +604,7 @@
const type_t mType;
// Used by parameters, config events, addTrack_l, exit
- Condition mWaitWorkCV;
+ audio_utils::condition_variable mWaitWorkCV;
const sp<IAfThreadCallback> mAfThreadCallback;
ThreadMetrics mThreadMetrics;
@@ -937,7 +942,8 @@
audio_port_handle_t portId,
const sp<media::IAudioTrackCallback>& callback,
bool isSpatialized,
- bool isBitPerfect) final;
+ bool isBitPerfect) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
bool isTrackActive(const sp<IAfTrack>& track) const final {
return mActiveTracks.indexOf(track) >= 0;
@@ -1041,7 +1047,7 @@
}
void setDownStreamPatch(const struct audio_patch* patch) final {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mutex());
mDownStreamPatch = *patch;
}
@@ -1063,11 +1069,13 @@
return INVALID_OPERATION;
}
- void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override;
- void stopMelComputation_l() override;
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) override
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ void stopMelComputation_l() override
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
void setStandby() final {
- Mutex::Autolock _l(mLock);
+ std::lock_guard _l(mutex());
setStandby_l();
}
@@ -1079,7 +1087,7 @@
}
bool waitForHalStart() final {
- Mutex::Autolock _l(mLock);
+ audio_utils::unique_lock _l(mutex());
static const nsecs_t kWaitHalTimeoutNs = seconds(2);
nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
while (!mHalStarted) {
@@ -1088,7 +1096,7 @@
break;
}
nsecs_t waitTimeLeftNs = endWaitTimetNs - timeNs;
- mWaitHalStartCV.waitRelative(mLock, waitTimeLeftNs);
+ mWaitHalStartCV.wait_for(_l, std::chrono::nanoseconds(waitTimeLeftNs));
}
return mHalStarted;
}
@@ -1369,7 +1377,8 @@
sp<AsyncCallbackThread> mCallbackThread;
- Mutex mAudioTrackCbLock;
+ audio_utils::mutex& audioTrackCbMutex() const { return mAudioTrackCbMutex; }
+ mutable audio_utils::mutex mAudioTrackCbMutex;
// Record of IAudioTrackCallback
std::map<sp<IAfTrack>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;
@@ -1390,7 +1399,7 @@
// output stream start detection based on render position returned by the kernel
// condition signalled when the output stream has started
- Condition mWaitHalStartCV;
+ audio_utils::condition_variable mWaitHalStartCV;
// true when the output stream render position has moved, reset to false in standby
bool mHalStarted = false;
// last kernel render position saved when entering standby
@@ -1717,9 +1726,11 @@
// setDraining(). The sequence is shifted one bit to the left and the lsb is used
// to indicate that the callback has been received via resetDraining()
uint32_t mDrainSequence;
- Condition mWaitWorkCV;
- Mutex mLock;
+ audio_utils::condition_variable mWaitWorkCV;
+ mutable audio_utils::mutex mMutex;
bool mAsyncError;
+
+ audio_utils::mutex& mutex() const { return mMutex; }
};
class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
@@ -1795,9 +1806,6 @@
bool hasFastMixer() const final { return false; }
- // RefBase
- void onFirstRef() final;
-
status_t setRequestedLatencyMode(audio_latency_mode_t mode) final;
protected:
@@ -1859,7 +1867,8 @@
pid_t tid,
status_t *status /*non-NULL*/,
audio_port_handle_t portId,
- int32_t maxSharedAudioHistoryMs) final;
+ int32_t maxSharedAudioHistoryMs) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
status_t start(IAfRecordTrack* recordTrack,
AudioSystem::sync_event_t event,
@@ -1976,10 +1985,10 @@
Source *mSource;
SortedVector <sp<IAfRecordTrack>> mTracks;
// mActiveTracks has dual roles: it indicates the current active track(s), and
- // is used together with mStartStopCond to indicate start()/stop() progress
+ // is used together with mStartStopCV to indicate start()/stop() progress
ActiveTracks<IAfRecordTrack> mActiveTracks;
- Condition mStartStopCond;
+ audio_utils::condition_variable mStartStopCV;
// resampler converts input at HAL Hz to output at AudioRecord client Hz
void *mRsmpInBuffer; // size = mRsmpInFramesOA
@@ -2081,7 +2090,7 @@
virtual void threadLoop_exit() final;
virtual void threadLoop_standby() final;
virtual bool shouldStandby_l() final { return false; }
- virtual status_t exitStandby_l() REQUIRES(mLock);
+ virtual status_t exitStandby_l() REQUIRES(mutex());
status_t initCheck() const final { return mHalStream == nullptr ? NO_INIT : NO_ERROR; }
size_t frameCount() const final { return mFrameCount; }
@@ -2217,8 +2226,10 @@
status_t reportData(const void* buffer, size_t frameCount) final;
- void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final;
- void stopMelComputation_l() final;
+ void startMelComputation_l(const sp<audio_utils::MelProcessor>& processor) final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
+ void stopMelComputation_l() final
+ REQUIRES(audio_utils::AudioFlinger_Mutex);
protected:
void dumpInternals_l(int fd, const Vector<String16>& args) final;
@@ -2245,7 +2256,7 @@
AudioStreamIn* clearInput() final;
- status_t exitStandby_l() REQUIRES(mLock) final;
+ status_t exitStandby_l() REQUIRES(mutex()) final;
MetadataUpdate updateMetadata_l() final;
void processVolume_l() final;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2340018..31246ec 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -277,7 +277,7 @@
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
if (mClient != 0) {
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l(mClient->afClientCallback()->clientMutex());
+ audio_utils::lock_guard _l(mClient->afClientCallback()->clientMutex());
// If the client's reference count drops to zero, the associated destructor
// must run with AudioFlinger lock held. Thus the explicit clear() rather than
// relying on the automatic clear() at end of scope.
@@ -642,7 +642,7 @@
auto thread = mThread.promote();
if (thread != nullptr && thread->type() == IAfThreadBase::OFFLOAD) {
// Wake up Thread if offloaded, otherwise it may be several seconds for update.
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
thread->broadcast_l();
}
}
@@ -889,7 +889,7 @@
bool wasActive = false;
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const playbackThread = thread->asIAfPlaybackThread().get();
wasActive = playbackThread->destroyTrack_l(this);
}
@@ -1169,8 +1169,8 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
if (isOffloaded()) {
- Mutex::Autolock _laf(thread->afThreadCallback()->mutex());
- Mutex::Autolock _lth(thread->mutex());
+ audio_utils::lock_guard _laf(thread->afThreadCallback()->mutex());
+ audio_utils::lock_guard _lth(thread->mutex());
sp<IAfEffectChain> ec = thread->getEffectChain_l(mSessionId);
if (thread->afThreadCallback()->isNonOffloadableGlobalEffectEnabled_l() ||
(ec != 0 && ec->isNonOffloadableEnabled())) {
@@ -1178,7 +1178,7 @@
return PERMISSION_DENIED;
}
}
- Mutex::Autolock _lth(thread->mutex());
+ audio_utils::lock_guard _lth(thread->mutex());
track_state state = mState;
// here the track could be either new, or restarted
// in both cases "unstop" the track
@@ -1302,7 +1302,7 @@
ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
track_state state = mState;
if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
// If the track is not active (PAUSED and buffers full), flush buffers
@@ -1335,7 +1335,7 @@
ALOGV("%s(%d): calling pid %d", __func__, mId, IPCThreadState::self()->getCallingPid());
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const playbackThread = thread->asIAfPlaybackThread().get();
switch (mState) {
case STOPPING_1:
@@ -1372,7 +1372,7 @@
ALOGV("%s(%d)", __func__, mId);
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const playbackThread = thread->asIAfPlaybackThread().get();
// Flush the ring buffer now if the track is not active in the PlaybackThread.
@@ -1503,7 +1503,7 @@
// Signal thread to fetch new volume.
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
thread->broadcast_l();
}
}
@@ -1667,7 +1667,7 @@
return INVALID_OPERATION;
}
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const playbackThread = thread->asIAfPlaybackThread().get();
return playbackThread->getTimestamp_l(timestamp);
}
@@ -1870,7 +1870,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
t->broadcast_l();
}
}
@@ -1882,7 +1882,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock _l(t->mutex());
+ audio_utils::lock_guard _l(t->mutex());
status = t->getOutput_l()->stream->getDualMonoMode(mode);
ALOGD_IF((status == NO_ERROR) && (mDualMonoMode != *mode),
"%s: mode %d inconsistent", __func__, mDualMonoMode);
@@ -1898,7 +1898,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock lock(t->mutex());
+ audio_utils::lock_guard lock(t->mutex());
status = t->getOutput_l()->stream->setDualMonoMode(mode);
if (status == NO_ERROR) {
mDualMonoMode = mode;
@@ -1915,7 +1915,7 @@
sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock lock(t->mutex());
+ audio_utils::lock_guard lock(t->mutex());
status = t->getOutput_l()->stream->getAudioDescriptionMixLevel(leveldB);
ALOGD_IF((status == NO_ERROR) && (mAudioDescriptionMixLevel != *leveldB),
"%s: level %.3f inconsistent", __func__, mAudioDescriptionMixLevel);
@@ -1931,7 +1931,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock lock(t->mutex());
+ audio_utils::lock_guard lock(t->mutex());
status = t->getOutput_l()->stream->setAudioDescriptionMixLevel(leveldB);
if (status == NO_ERROR) {
mAudioDescriptionMixLevel = leveldB;
@@ -1949,7 +1949,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock lock(t->mutex());
+ audio_utils::lock_guard lock(t->mutex());
status = t->getOutput_l()->stream->getPlaybackRateParameters(playbackRate);
ALOGD_IF((status == NO_ERROR) &&
!isAudioPlaybackRateEqual(mPlaybackRateParameters, *playbackRate),
@@ -1967,7 +1967,7 @@
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != nullptr) {
auto* const t = thread->asIAfPlaybackThread().get();
- Mutex::Autolock lock(t->mutex());
+ audio_utils::lock_guard lock(t->mutex());
status = t->getOutput_l()->stream->setPlaybackRateParameters(playbackRate);
if (status == NO_ERROR) {
mPlaybackRateParameters = playbackRate;
@@ -2090,7 +2090,7 @@
const sp<IAfThreadBase> thread = mTrack->mThread.promote();
if (thread != 0) {
// Lock for updating mHapticPlaybackEnabled.
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const playbackThread = thread->asIAfPlaybackThread().get();
if ((mTrack->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
&& playbackThread->hapticChannelCount() > 0) {
@@ -2353,13 +2353,13 @@
void OutputTrack::copyMetadataTo(MetadataInserter& backInserter) const
{
- std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
+ audio_utils::lock_guard lock(trackMetadataMutex());
backInserter = std::copy(mTrackMetadatas.begin(), mTrackMetadatas.end(), backInserter);
}
void OutputTrack::setMetadatas(const SourceMetadatas& metadatas) {
{
- std::lock_guard<std::mutex> lock(mTrackMetadatasMutex);
+ audio_utils::lock_guard lock(trackMetadataMutex());
mTrackMetadatas = metadatas;
}
// No need to adjust metadata track volumes as OutputTrack volumes are always 0dBFS.
@@ -2846,7 +2846,7 @@
track_state priorState = mState;
const sp<IAfThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mutex());
+ audio_utils::lock_guard _l(thread->mutex());
auto* const recordThread = thread->asIAfRecordThread().get();
priorState = mState;
if (!mSharedAudioPackageName.empty()) {
@@ -3270,7 +3270,7 @@
*thread = mThread.promote();
if (!*thread) return nullptr;
auto* const recordThread = (*thread)->asIAfRecordThread().get();
- Mutex::Autolock _l(recordThread->mutex());
+ audio_utils::lock_guard _l(recordThread->mutex());
return recordThread->getInput() ? recordThread->getInput()->stream : nullptr;
}
@@ -3307,7 +3307,7 @@
}
{
- std::lock_guard<std::mutex> lock(mReadLock);
+ audio_utils::lock_guard lock(readMutex());
mReadBytes += bytesRead;
mReadError = NO_ERROR;
}
@@ -3334,7 +3334,7 @@
stream_error:
stream->standby();
{
- std::lock_guard<std::mutex> lock(mReadLock);
+ audio_utils::lock_guard lock(readMutex());
mReadError = result;
}
mReadCV.notify_one();
@@ -3363,7 +3363,7 @@
{
bytes = std::min(bytes, mFrameCount * mFrameSize);
{
- std::unique_lock<std::mutex> lock(mReadLock);
+ audio_utils::unique_lock lock(readMutex());
mReadCV.wait(lock, [&]{ return mReadError != NO_ERROR || mReadBytes != 0; });
if (mReadError != NO_ERROR) {
mLastReadFrames = 0;
diff --git a/services/audioflinger/afutils/DumpTryLock.h b/services/audioflinger/afutils/DumpTryLock.h
index c185a68..e4ad112 100644
--- a/services/audioflinger/afutils/DumpTryLock.h
+++ b/services/audioflinger/afutils/DumpTryLock.h
@@ -17,7 +17,9 @@
#pragma once
+#include <audio_utils/mutex.h>
#include <utils/Mutex.h>
+#include <utils/Timers.h>
namespace android::afutils {
@@ -28,4 +30,19 @@
return err == NO_ERROR;
}
-} // android::afutils
\ No newline at end of file
+// Note: the std::timed_mutex try_lock_for and try_lock_until methods are inefficient.
+// It is better to use std::mutex and call this method.
+//
+inline bool dumpTryLock(audio_utils::mutex& mutex) TRY_ACQUIRE(true, mutex)
+{
+ static constexpr int64_t kDumpLockTimeoutNs = 1'000'000'000;
+
+ const int64_t timeoutNs = kDumpLockTimeoutNs + systemTime(SYSTEM_TIME_REALTIME);
+ const struct timespec ts = {
+ .tv_sec = static_cast<time_t>(timeoutNs / 1000000000),
+ .tv_nsec = static_cast<long>(timeoutNs % 1000000000),
+ };
+ return pthread_mutex_timedlock(mutex.native_handle(), &ts) == 0;
+}
+
+} // android::afutils
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index d7aa5c9..0620553 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -25,6 +25,7 @@
#include <sys/time.h>
#include <dlfcn.h>
+#include <android/content/pm/IPackageManagerNative.h>
#include <audio_utils/clock.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
@@ -215,6 +216,26 @@
{
delete interface;
}
+
+namespace {
+int getTargetSdkForPackageName(std::string_view packageName) {
+ const auto binder = defaultServiceManager()->checkService(String16{"package_native"});
+ int targetSdk = -1;
+ if (binder != nullptr) {
+ const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
+ if (pm != nullptr) {
+ const auto status = pm->getTargetSdkVersionForPackage(
+ String16{packageName.data(), packageName.size()}, &targetSdk);
+ return status.isOk() ? targetSdk : -1;
+ }
+ }
+ return targetSdk;
+}
+
+bool doesPackageTargetAtLeastU(std::string_view packageName) {
+ return getTargetSdkForPackageName(packageName) >= __ANDROID_API_U__;
+}
+} // anonymous
// ----------------------------------------------------------------------------
AudioPolicyService::AudioPolicyService()
@@ -1926,10 +1947,14 @@
checkOp();
mOpCallback = new RecordAudioOpCallback(this);
ALOGV("start watching op %d for %s", mAppOp, mAttributionSource.toString().c_str());
+ int flags = doesPackageTargetAtLeastU(
+ mAttributionSource.packageName.value_or("")) ?
+ AppOpsManager::WATCH_FOREGROUND_CHANGES : 0;
// TODO: We need to always watch AppOpsManager::OP_RECORD_AUDIO too
// since it controls the mic permission for legacy apps.
mAppOpsManager.startWatchingMode(mAppOp, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
mAttributionSource.packageName.value_or(""))),
+ flags,
mOpCallback);
}
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index de24e1e..f903c62 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -20,7 +20,6 @@
"libmedia",
"libmediautils",
"libutils",
- "libmediautils",
"libstats_media_metrics",
"libstatspull",
"libstatssocket",