AudioFlinger: Create PatchPanel callback
Test: atest AudioTrackTest AudioRecordTest
Test: Camera YouTube
Bug: 291319167
Merged-In: I3b851a1b1b50edd76305957c8b91521e0cb1d23d
Change-Id: I3b851a1b1b50edd76305957c8b91521e0cb1d23d
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f16a02a..6763519 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -412,6 +412,7 @@
mAAudioHwBurstMinMicros = getAAudioHardwareBurstMinUsecFromSystemProperty();
}
+ mPatchPanel = IAfPatchPanel::create(sp<IAfPatchPanelCallback>::fromExisting(this));
mMelReporter = sp<MelReporter>::make(sp<IAfMelReporterCallback>::fromExisting(this));
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 9d96035..9e34410 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -167,10 +167,10 @@
, public IAfClientCallback
, public IAfDeviceEffectManagerCallback
, public IAfMelReporterCallback
+ , public IAfPatchPanelCallback
{
friend class sp<AudioFlinger>;
// TODO(b/291319167) Create interface and remove friends.
- friend class PatchPanel;
// TODO(b/291012167) replace the Thread friends with an interface.
friend class DirectOutputThread;
friend class MixerThread;
@@ -375,7 +375,7 @@
// ---- begin IAfDeviceEffectManagerCallback interface
bool isAudioPolicyReady() const final { return mAudioPolicyReady.load(); }
- // below also used by IAfMelReporterCallback
+ // 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;
@@ -391,6 +391,41 @@
// ---- end of IAfMelReporterCallback interface
+ // ---- begin IAfPatchPanelCallback interface
+
+ void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) final;
+ void closeThreadInternal_l(const sp<IAfRecordThread>& thread) final;
+ // 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(); }
+ sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t* input,
+ audio_config_t* config,
+ audio_devices_t device,
+ const char* address,
+ audio_source_t source,
+ audio_input_flags_t flags,
+ audio_devices_t outputDevice,
+ const String8& outputDeviceAddress) final;
+ 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;
+ const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+ getAudioHwDevs_l() const final { 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;
+
+ // ---- end of IAfPatchPanelCallback interface
+
/* List available audio ports and their attributes */
status_t listAudioPorts(unsigned int* num_ports, struct audio_port* ports) const;
@@ -412,9 +447,6 @@
const sp<os::ExternalVibration>& externalVibration);
static void onExternalVibrationStop(const sp<os::ExternalVibration>& externalVibration);
- void updateDownStreamPatches_l(const struct audio_patch *patch,
- const std::set<audio_io_handle_t>& streams);
-
std::optional<media::AudioVibratorInfo> getDefaultVibratorInfo_l();
private:
@@ -454,9 +486,6 @@
bool btNrecIsOff() const { return mBtNrecIsOff.load(); }
- void lock() ACQUIRE(mLock) { mLock.lock(); }
- void unlock() RELEASE(mLock) { mLock.unlock(); }
-
private:
audio_mode_t getMode() const { return mMode; }
@@ -628,29 +657,11 @@
}
IAfThreadBase* checkThread_l(audio_io_handle_t ioHandle) const;
- IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const;
IAfPlaybackThread* checkMixerThread_l(audio_io_handle_t output) const;
- IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const;
- IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const;
+
sp<VolumeInterface> getVolumeInterface_l(audio_io_handle_t output) const;
std::vector<sp<VolumeInterface>> getAllVolumeInterfaces_l() const;
- sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
- audio_io_handle_t *input,
- audio_config_t *config,
- audio_devices_t device,
- const char* address,
- audio_source_t source,
- audio_input_flags_t flags,
- audio_devices_t outputDevice,
- const String8& outputDeviceAddress);
- 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);
void closeOutputFinish(const sp<IAfPlaybackThread>& thread);
void closeInputFinish(const sp<IAfRecordThread>& thread);
@@ -675,14 +686,13 @@
// Thus it may fail by returning an ID of the wrong sign,
// or by returning a non-unique ID.
// This is the internal API. For the binder API see newAudioUniqueId().
- // used by IAfDeviceEffectManagerCallback
+ // used by IAfDeviceEffectManagerCallback, IAfPatchPanelCallback
audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) final;
status_t moveEffectChain_l(audio_session_t sessionId,
IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread);
// return thread associated with primary hardware device, or NULL
- IAfPlaybackThread* primaryPlaybackThread_l() const;
DeviceTypeSet primaryOutputDevice_l() const;
// return the playback thread with smallest HAL buffer size, and prefer fast
@@ -726,7 +736,6 @@
std::vector< sp<IAfEffectModule> > purgeStaleEffects_l();
void broadcastParametersToRecordThreads_l(const String8& keyValuePairs);
- void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices);
void forwardParametersToDownstreamPatches_l(
audio_io_handle_t upStream, const String8& keyValuePairs,
const std::function<bool(const sp<IAfPlaybackThread>&)>& useThread = nullptr);
@@ -844,9 +853,7 @@
// for use from destructor
status_t closeOutput_nonvirtual(audio_io_handle_t output);
- void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread);
status_t closeInput_nonvirtual(audio_io_handle_t input);
- void closeThreadInternal_l(const sp<IAfRecordThread>& thread);
void setAudioHwSyncForSession_l(IAfPlaybackThread* thread, audio_session_t sessionId);
status_t checkStreamType(audio_stream_type_t stream) const;
@@ -873,8 +880,7 @@
nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled
- // protected by mLock
- const sp<IAfPatchPanel> mPatchPanel = IAfPatchPanel::create(this);
+ /* const */ sp<IAfPatchPanel> mPatchPanel;
public:
// TODO(b/291319167) access by getter.
diff --git a/services/audioflinger/IAfPatchPanel.h b/services/audioflinger/IAfPatchPanel.h
index 29bd4ab..bc116a9 100644
--- a/services/audioflinger/IAfPatchPanel.h
+++ b/services/audioflinger/IAfPatchPanel.h
@@ -18,12 +18,14 @@
namespace android {
+class IAfMmapThread;
class IAfPatchPanel;
class IAfPatchRecord;
class IAfPatchTrack;
class IAfPlaybackThread;
class IAfRecordThread;
class IAfThreadBase;
+class PatchCommandThread;
class SoftwarePatch {
public:
@@ -51,9 +53,44 @@
const audio_io_handle_t mRecordThreadHandle;
};
+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 sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t* input,
+ audio_config_t* config,
+ audio_devices_t device,
+ const char* address,
+ audio_source_t source,
+ audio_input_flags_t flags,
+ audio_devices_t outputDevice,
+ const String8& outputDeviceAddress) = 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;
+ virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
+ getAudioHwDevs_l() const = 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;
+};
+
class IAfPatchPanel : public virtual RefBase {
public:
- static sp<IAfPatchPanel> create(AudioFlinger* audioFlinger);
+ static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback);
// Extraction of inner Endpoint and Patch classes would require interfaces
// (in the Endpoint case a templated interface) but that seems
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 1bd2a15..7d9049a 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -96,8 +96,8 @@
}
/* static */
-sp<IAfPatchPanel> IAfPatchPanel::create(AudioFlinger* audioFlinger) {
- return sp<PatchPanel>::make(audioFlinger);
+sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) {
+ return sp<PatchPanel>::make(afPatchPanelCallback);
}
status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const {
@@ -119,10 +119,10 @@
{
if (const auto recordThread = thread->asIAfRecordThread();
recordThread) {
- mAudioFlinger.closeThreadInternal_l(recordThread);
+ mAfPatchPanelCallback->closeThreadInternal_l(recordThread);
} else if (const auto playbackThread = thread->asIAfPlaybackThread();
playbackThread) {
- mAudioFlinger.closeThreadInternal_l(playbackThread);
+ mAfPatchPanelCallback->closeThreadInternal_l(playbackThread);
} else {
LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, "
"invalid thread, id: %d type: %d",
@@ -275,8 +275,8 @@
status = INVALID_OPERATION;
goto exit;
}
- const sp<IAfThreadBase> thread =
- mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+ patch->sources[1].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() cannot get playback thread", __func__);
status = INVALID_OPERATION;
@@ -302,7 +302,7 @@
if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
flags = patch->sinks[0].flags.output;
}
- const sp<IAfThreadBase> thread = mAudioFlinger.openOutput_l(
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
patch->sinks[0].ext.device.hw_module,
&output,
&config,
@@ -310,7 +310,7 @@
outputDevice,
outputDeviceAddress,
flags);
- ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
+ ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
if (thread == 0) {
status = NO_MEMORY;
goto exit;
@@ -349,7 +349,7 @@
== AUDIO_STREAM_VOICE_CALL) {
source = AUDIO_SOURCE_VOICE_COMMUNICATION;
}
- const sp<IAfThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
+ const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
&input,
&config,
device,
@@ -358,7 +358,7 @@
flags,
outputDevice,
outputDeviceAddress);
- ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
+ ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
thread.get(), config.channel_mask);
if (thread == 0) {
status = NO_MEMORY;
@@ -374,10 +374,11 @@
}
} else {
if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
patch->sinks[0].ext.mix.handle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(
+ patch->sinks[0].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() bad capture I/O handle %d",
__func__, patch->sinks[0].ext.mix.handle);
@@ -385,9 +386,9 @@
goto exit;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -411,7 +412,7 @@
} break;
case AUDIO_PORT_TYPE_MIX: {
audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
- ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
+ ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
if (index < 0) {
ALOGW("%s() bad src hw module %d", __func__, srcModule);
status = BAD_VALUE;
@@ -437,10 +438,11 @@
device->applyAudioPortConfig(&patch->sinks[i]);
devices.push_back(device);
}
- sp<IAfThreadBase> thread =
- mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
+ patch->sources[0].ext.mix.handle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(
+ patch->sources[0].ext.mix.handle);
if (thread == 0) {
ALOGW("%s() bad playback I/O handle %d",
__func__, patch->sources[0].ext.mix.handle);
@@ -448,13 +450,13 @@
goto exit;
}
}
- if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
- mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
+ if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
+ mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
if (status == NO_ERROR) {
newPatch.setThread(thread);
}
@@ -479,9 +481,10 @@
exit:
ALOGV("%s() status %d", __func__, status);
if (status == NO_ERROR) {
- *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
+ *handle = static_cast<audio_patch_handle_t>(
+ mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
newPatch.mHalHandle = halHandle;
- mAudioFlinger.mPatchCommandThread->createAudioPatch(*handle, newPatch);
+ mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(*handle, newPatch);
if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
addSoftwarePatchToInsertedModules(insertedModule, *handle, &newPatch.mAudioPatch);
}
@@ -793,18 +796,18 @@
if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
- sp<IAfThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
if (thread == 0) {
ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
} else {
status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
@@ -816,18 +819,18 @@
break;
}
audio_io_handle_t ioHandle = src.ext.mix.handle;
- sp<IAfThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
+ sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
if (thread == 0) {
- thread = mAudioFlinger.checkMmapThread_l(ioHandle);
+ thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
if (thread == 0) {
ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- mAudioFlinger.unlock();
+ mAfPatchPanelCallback->unlock();
status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
- mAudioFlinger.lock();
+ mAfPatchPanelCallback->lock();
} break;
default:
status = BAD_VALUE;
@@ -840,7 +843,7 @@
void PatchPanel::erasePatch(audio_patch_handle_t handle) {
mPatches.erase(handle);
removeSoftwarePatchFromInsertedModules(handle);
- mAudioFlinger.mPatchCommandThread->releaseAudioPatch(handle);
+ mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
}
/* List connected audio ports and they attributes */
@@ -904,12 +907,12 @@
AudioHwDevice* PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
{
if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
- ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
+ ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
if (index < 0) {
ALOGW("%s() bad hw module %d", __func__, module);
return nullptr;
}
- return mAudioFlinger.mAudioHwDevs.valueAt(index);
+ return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
}
sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
@@ -924,7 +927,7 @@
{
mInsertedModules[module].sw_patches.insert(handle);
if (!mInsertedModules[module].streams.empty()) {
- mAudioFlinger.updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
+ mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
}
}
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 14b96c9..890b87d 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -21,7 +21,8 @@
class PatchPanel : public IAfPatchPanel {
public:
- explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
+ explicit PatchPanel(const sp<IAfPatchPanelCallback>& afPatchPanelCallback)
+ : mAfPatchPanelCallback(afPatchPanelCallback) {}
/* List connected audio ports and their attributes */
status_t listAudioPorts(unsigned int *num_ports,
@@ -71,7 +72,7 @@
void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
void erasePatch(audio_patch_handle_t handle);
- AudioFlinger &mAudioFlinger;
+ const sp<IAfPatchPanelCallback> mAfPatchPanelCallback;
std::map<audio_patch_handle_t, Patch> mPatches;
// This map allows going from a thread to "downstream" software patches