blob: 14b96c9e81bb07162d81b02c02ae03e44eaa3b3a [file] [log] [blame]
Eric Laurent1c333e22014-05-20 10:48:17 -07001/*
2**
3** Copyright 2014, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
Andy Hung07434ef2023-07-13 18:11:33 -070018#pragma once
Eric Laurent1c333e22014-05-20 10:48:17 -070019
Andy Hung07434ef2023-07-13 18:11:33 -070020namespace android {
21
Andy Hungd63e79d2023-07-13 16:52:46 -070022class PatchPanel : public IAfPatchPanel {
Eric Laurent1c333e22014-05-20 10:48:17 -070023public:
Mikhail Naganovdea53042018-04-26 13:10:21 -070024 explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
Eric Laurent1c333e22014-05-20 10:48:17 -070025
26 /* List connected audio ports and their attributes */
27 status_t listAudioPorts(unsigned int *num_ports,
Andy Hungd63e79d2023-07-13 16:52:46 -070028 struct audio_port* ports) final;
Eric Laurent1c333e22014-05-20 10:48:17 -070029
30 /* Get supported attributes for a given audio port */
Andy Hungd63e79d2023-07-13 16:52:46 -070031 status_t getAudioPort(struct audio_port_v7* port) final;
Eric Laurent1c333e22014-05-20 10:48:17 -070032
33 /* Create a patch between several source and sink ports */
34 status_t createAudioPatch(const struct audio_patch *patch,
Francois Gaffiee0dc36d2021-04-01 16:01:00 +020035 audio_patch_handle_t *handle,
Andy Hungd63e79d2023-07-13 16:52:46 -070036 bool endpointPatch = false) final;
Eric Laurent1c333e22014-05-20 10:48:17 -070037
38 /* Release a patch */
Andy Hungd63e79d2023-07-13 16:52:46 -070039 status_t releaseAudioPatch(audio_patch_handle_t handle) final;
Eric Laurent1c333e22014-05-20 10:48:17 -070040
41 /* List connected audio devices and they attributes */
42 status_t listAudioPatches(unsigned int *num_patches,
Andy Hungd63e79d2023-07-13 16:52:46 -070043 struct audio_patch* patches) final;
Eric Laurent1c333e22014-05-20 10:48:17 -070044
Mikhail Naganovadca70f2018-07-09 12:49:25 -070045 // Retrieves all currently estrablished software patches for a stream
46 // opened on an intermediate module.
47 status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
Andy Hungd63e79d2023-07-13 16:52:46 -070048 std::vector<SoftwarePatch>* patches) const final;
Mikhail Naganovadca70f2018-07-09 12:49:25 -070049
50 // Notifies patch panel about all opened and closed streams.
Eric Laurent74c38dc2020-12-23 18:19:44 +010051 void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream,
Andy Hungd63e79d2023-07-13 16:52:46 -070052 struct audio_patch* patch) final;
53 void notifyStreamClosed(audio_io_handle_t stream) final;
Mikhail Naganovadca70f2018-07-09 12:49:25 -070054
Andy Hungd63e79d2023-07-13 16:52:46 -070055 void dump(int fd) const final;
Eric Laurent83b88082014-06-20 18:31:16 -070056
Eric Laurent9b2064c2019-11-22 17:25:04 -080057 // Call with AudioFlinger mLock held
Andy Hungd63e79d2023-07-13 16:52:46 -070058 const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; }
59
60 // Must be called under AudioFlinger::mLock
61 status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final;
62
63 void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final;
Eric Laurent9b2064c2019-11-22 17:25:04 -080064
65private:
Mikhail Naganovadca70f2018-07-09 12:49:25 -070066 AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
Mikhail Naganov444ecc32018-05-01 17:40:05 -070067 sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
Mikhail Naganovadca70f2018-07-09 12:49:25 -070068 void addSoftwarePatchToInsertedModules(
Eric Laurent74c38dc2020-12-23 18:19:44 +010069 audio_module_handle_t module, audio_patch_handle_t handle,
70 const struct audio_patch *patch);
Mikhail Naganovadca70f2018-07-09 12:49:25 -070071 void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
Eric Laurent9b2064c2019-11-22 17:25:04 -080072 void erasePatch(audio_patch_handle_t handle);
Mikhail Naganov444ecc32018-05-01 17:40:05 -070073
Mikhail Naganovdea53042018-04-26 13:10:21 -070074 AudioFlinger &mAudioFlinger;
75 std::map<audio_patch_handle_t, Patch> mPatches;
Mikhail Naganovadca70f2018-07-09 12:49:25 -070076
77 // This map allows going from a thread to "downstream" software patches
78 // when a processing module inserted in between. Example:
79 //
80 // from map value.streams map key
81 // [Mixer thread] --> [Virtual output device] --> [Processing module] ---\
82 // [Harware module] <-- [Physical output device] <-- [S/W Patch] <--/
83 // from map value.sw_patches
84 //
85 // This allows the mixer thread to look up the threads of the software patch
86 // for propagating timing info, parameters, etc.
87 //
88 // The current assumptions are:
89 // 1) The processing module acts as a mixer with several outputs which
90 // represent differently downmixed and / or encoded versions of the same
91 // mixed stream. There is no 1:1 correspondence between the input streams
92 // and the software patches, but rather a N:N correspondence between
93 // a group of streams and a group of patches.
94 // 2) There are only a couple of inserted processing modules in the system,
95 // so when looking for a stream or patch handle we can iterate over
96 // all modules.
97 struct ModuleConnections {
98 std::set<audio_io_handle_t> streams;
99 std::set<audio_patch_handle_t> sw_patches;
100 };
101 std::map<audio_module_handle_t, ModuleConnections> mInsertedModules;
Eric Laurent1c333e22014-05-20 10:48:17 -0700102};
Andy Hungbd72c542023-06-20 18:56:17 -0700103
Andy Hung07434ef2023-07-13 18:11:33 -0700104} // namespace android