AudioFlinger: Extract Effect inner classes

Add new interfaces for accessing effects.

IAfEffectBase
IAfEffectModule
IAfEffectChain
IAfEffectHandle
IAfDeviceEffectProxy

Test: atest android.media.audio.cts.AudioEffectTest android.media.audio.cts.AudioPreProcessingTest android.media.audio.cts.BassBoostTest android.media.audio.cts.EnvReverbTest android.media.audio.cts.EqualizerTest android.media.audio.cts.LoudnessEnhancerTest android.media.audio.cts.PresetReverbTest android.media.audio.cts.VirtualizerTest android.media.audio.cts.VisualizerTest
Bug: 288339104
Bug: 288339921
Change-Id: Id27f9f7e9da53890f8e22ad45e174ff8eeb68b09
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
new file mode 100644
index 0000000..7c3be0f
--- /dev/null
+++ b/services/audioflinger/IAfEffect.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace android {
+
+class IAfDeviceEffectProxy;
+class IAfEffectBase;
+class IAfEffectChain;
+class IAfEffectHandle;
+class IAfEffectModule;
+
+// Interface implemented by the EffectModule parent or owner (e.g an EffectChain) to abstract
+// interactions between the EffectModule and the reset of the audio framework.
+class EffectCallbackInterface : public RefBase {
+public:
+    // Trivial methods usually implemented with help from ThreadBase
+    virtual audio_io_handle_t io() const = 0;
+    virtual bool isOutput() const = 0;
+    virtual bool isOffload() const = 0;
+    virtual bool isOffloadOrDirect() const = 0;
+    virtual bool isOffloadOrMmap() const = 0;
+    virtual bool isSpatializer() const = 0;
+    virtual uint32_t sampleRate() const = 0;
+    virtual audio_channel_mask_t inChannelMask(int id) const = 0;
+    virtual uint32_t inChannelCount(int id) const = 0;
+    virtual audio_channel_mask_t outChannelMask() const = 0;
+    virtual uint32_t outChannelCount() const = 0;
+    virtual audio_channel_mask_t hapticChannelMask() const = 0;
+    virtual size_t frameCount() const = 0;
+
+    // Non trivial methods usually implemented with help from ThreadBase:
+    // pay attention to mutex locking order
+    virtual uint32_t latency() const { return 0; }
+    virtual status_t addEffectToHal(const sp<EffectHalInterface>& effect) = 0;
+    virtual status_t removeEffectFromHal(const sp<EffectHalInterface>& effect) = 0;
+    virtual void setVolumeForOutput(float left, float right) const = 0;
+    virtual bool disconnectEffectHandle(IAfEffectHandle *handle, bool unpinIfLast) = 0;
+    virtual void checkSuspendOnEffectEnabled(
+            const sp<IAfEffectBase>& effect, bool enabled, bool threadLocked) = 0;
+    virtual void onEffectEnable(const sp<IAfEffectBase>& effect) = 0;
+    virtual void onEffectDisable(const sp<IAfEffectBase>& effect) = 0;
+
+    // Methods usually implemented with help from AudioFlinger: pay attention to mutex locking order
+    virtual status_t createEffectHal(const effect_uuid_t *pEffectUuid,
+            int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect) = 0;
+    virtual status_t allocateHalBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) = 0;
+    virtual bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect) = 0;
+
+    // Methods usually implemented with help from EffectChain: pay attention to mutex locking order
+    virtual product_strategy_t strategy() const = 0;
+    virtual int32_t activeTrackCnt() const = 0;
+    virtual void resetVolume() = 0;
+    virtual wp<IAfEffectChain> chain() const = 0;
+    virtual bool isAudioPolicyReady() const = 0;
+};
+
+class IAfEffectBase : public virtual RefBase {
+    friend class EffectChain;
+    friend class EffectHandle;
+
+public:
+    enum effect_state {
+        IDLE,
+        RESTART,
+        STARTING,
+        ACTIVE,
+        STOPPING,
+        STOPPED,
+        DESTROYED
+    };
+    virtual int id() const = 0;
+    virtual effect_state state() const = 0;
+    virtual audio_session_t sessionId() const = 0;
+    virtual const effect_descriptor_t& desc() const = 0;
+    virtual bool isOffloadable() const = 0;
+    virtual bool isImplementationSoftware() const = 0;
+    virtual bool isProcessImplemented() const = 0;
+    virtual bool isVolumeControl() const = 0;
+    virtual bool isVolumeMonitor() const = 0;
+    virtual bool isEnabled() const = 0;
+    virtual bool isPinned() const = 0;
+    virtual void unPin() = 0;
+    virtual status_t updatePolicyState() = 0;
+    virtual bool purgeHandles() = 0;
+    virtual void checkSuspendOnEffectEnabled(bool enabled, bool threadLocked) = 0;
+
+    // mCallback is atomic so this can be lock-free.
+    virtual void setCallback(const sp<EffectCallbackInterface>& callback) = 0;
+    virtual sp<EffectCallbackInterface> getCallback() const = 0;
+
+    virtual status_t addHandle(IAfEffectHandle *handle) = 0;
+    virtual ssize_t removeHandle(IAfEffectHandle *handle) = 0;
+
+    virtual sp<IAfEffectModule> asEffectModule() = 0;
+    virtual sp<IAfDeviceEffectProxy> asDeviceEffectProxy() = 0;
+
+    virtual void dump(int fd, const Vector<String16>& args) const = 0;
+
+private:
+    virtual status_t setEnabled(bool enabled, bool fromHandle) = 0;
+    virtual status_t setEnabled_l(bool enabled) = 0;
+    virtual void setSuspended(bool suspended) = 0;
+    virtual bool suspended() const = 0;
+
+    virtual status_t command(int32_t cmdCode,
+            const std::vector<uint8_t>& cmdData,
+            int32_t maxReplySize,
+            std::vector<uint8_t>* reply) = 0;
+
+    virtual ssize_t disconnectHandle(IAfEffectHandle *handle, bool unpinIfLast) = 0;
+    virtual ssize_t removeHandle_l(IAfEffectHandle *handle) = 0;
+    virtual IAfEffectHandle* controlHandle_l() = 0;
+
+    virtual void lock() = 0;
+    virtual void unlock() = 0;
+};
+
+class IAfEffectModule : public virtual IAfEffectBase {
+    friend class DeviceEffectProxy;
+    friend class EffectChain;
+
+public:
+    static sp<IAfEffectModule> create(
+            const sp<EffectCallbackInterface>& callabck,
+            effect_descriptor_t *desc,
+            int id,
+            audio_session_t sessionId,
+            bool pinned,
+            audio_port_handle_t deviceId);
+
+    virtual int16_t *inBuffer() const = 0;
+    virtual status_t setDevices(const AudioDeviceTypeAddrVector &devices) = 0;
+    virtual status_t setInputDevice(const AudioDeviceTypeAddr &device) = 0;
+    virtual status_t setVolume(uint32_t *left, uint32_t *right, bool controller) = 0;
+    virtual status_t setOffloaded(bool offloaded, audio_io_handle_t io) = 0;
+    virtual bool isOffloaded() const = 0;
+
+    virtual status_t setAudioSource(audio_source_t source) = 0;
+    virtual status_t setMode(audio_mode_t mode) = 0;
+
+    virtual status_t start() = 0;
+    virtual status_t getConfigs(audio_config_base_t* inputCfg,
+            audio_config_base_t* outputCfg,
+            bool* isOutput) const = 0;
+
+    static bool isHapticGenerator(const effect_uuid_t* type);
+    virtual bool isHapticGenerator() const = 0;
+    virtual status_t setHapticIntensity(int id, os::HapticScale intensity) = 0;
+    virtual status_t setVibratorInfo(const media::AudioVibratorInfo& vibratorInfo) = 0;
+
+private:
+    virtual void process() = 0;
+    virtual bool updateState() = 0;
+    virtual void reset_l() = 0;
+    virtual status_t configure() = 0;
+    virtual status_t init() = 0;
+    virtual uint32_t status() const = 0;
+    virtual bool isProcessEnabled() const = 0;
+    virtual bool isOffloadedOrDirect() const = 0;
+    virtual bool isVolumeControlEnabled() const = 0;
+
+    virtual void setInBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+    virtual void setOutBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+    virtual int16_t *outBuffer() const = 0;
+
+    // Updates the access mode if it is out of date.  May issue a new effect configure.
+    virtual void updateAccessMode() = 0;
+
+    virtual status_t stop() = 0;
+    virtual void addEffectToHal_l() = 0;
+    virtual void release_l() = 0;
+};
+
+class IAfEffectChain : public RefBase {
+    // Most of these methods are accessed from AudioFlinger::Thread
+public:
+    static sp<IAfEffectChain> create(
+            const wp<Thread /*ThreadBase*/>& wThread,  // TODO(b/288339104) type
+            audio_session_t sessionId);
+
+    // special key used for an entry in mSuspendedEffects keyed vector
+    // corresponding to a suspend all request.
+    static constexpr int kKeyForSuspendAll = 0;
+
+    // minimum duration during which we force calling effect process when last track on
+    // a session is stopped or removed to allow effect tail to be rendered
+    static constexpr int kProcessTailDurationMs = 1000;
+
+    virtual void process_l() = 0;
+
+    virtual void lock() = 0;
+    virtual void unlock() = 0;
+
+    virtual status_t createEffect_l(sp<IAfEffectModule>& effect,
+                            effect_descriptor_t *desc,
+                            int id,
+                            audio_session_t sessionId,
+                            bool pinned) = 0;
+
+    virtual status_t addEffect_l(const sp<IAfEffectModule>& handle) = 0;
+    virtual status_t addEffect_ll(const sp<IAfEffectModule>& handle) = 0;
+    virtual size_t removeEffect_l(const sp<IAfEffectModule>& handle, bool release = false) = 0;
+
+    virtual audio_session_t sessionId() const = 0;
+    virtual void setSessionId(audio_session_t sessionId) = 0;
+
+    virtual sp<IAfEffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor) const = 0;
+    virtual sp<IAfEffectModule> getEffectFromId_l(int id) const = 0;
+    virtual sp<IAfEffectModule> getEffectFromType_l(const effect_uuid_t *type) const = 0;
+    virtual std::vector<int> getEffectIds() const = 0;
+    virtual bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false) = 0;
+    virtual void resetVolume_l() = 0;
+    virtual void setDevices_l(const AudioDeviceTypeAddrVector &devices) = 0;
+    virtual void setInputDevice_l(const AudioDeviceTypeAddr &device) = 0;
+    virtual void setMode_l(audio_mode_t mode) = 0;
+    virtual void setAudioSource_l(audio_source_t source) = 0;
+
+    virtual void setInBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+    virtual float *inBuffer() const = 0;
+    virtual void setOutBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+    virtual float *outBuffer() const = 0;
+
+    virtual void incTrackCnt() = 0;
+    virtual void decTrackCnt() = 0;
+    virtual int32_t trackCnt() const = 0;
+
+    virtual void incActiveTrackCnt() = 0;
+    virtual void decActiveTrackCnt() = 0;
+    virtual int32_t activeTrackCnt() const = 0;
+
+    virtual product_strategy_t strategy() const = 0;
+    virtual void setStrategy(product_strategy_t strategy) = 0;
+
+    // suspend or restore effects of the specified type. The number of suspend requests is counted
+    // and restore occurs once all suspend requests are cancelled.
+    virtual void setEffectSuspended_l(
+            const effect_uuid_t *type, bool suspend) = 0;
+    // suspend all eligible effects
+    virtual void setEffectSuspendedAll_l(bool suspend) = 0;
+    // check if effects should be suspended or restored when a given effect is enable or disabled
+    virtual void checkSuspendOnEffectEnabled(const sp<IAfEffectModule>& effect, bool enabled) = 0;
+
+    virtual void clearInputBuffer() = 0;
+
+    // At least one non offloadable effect in the chain is enabled
+    virtual bool isNonOffloadableEnabled() const = 0;
+    virtual bool isNonOffloadableEnabled_l() const = 0;
+
+    virtual void syncHalEffectsState() = 0;
+
+    // flags is an ORed set of audio_output_flags_t which is updated on return.
+    virtual void checkOutputFlagCompatibility(audio_output_flags_t *flags) const = 0;
+
+    // flags is an ORed set of audio_input_flags_t which is updated on return.
+    virtual void checkInputFlagCompatibility(audio_input_flags_t *flags) const = 0;
+
+    // Is this EffectChain compatible with the RAW audio flag.
+    virtual bool isRawCompatible() const = 0;
+
+    // Is this EffectChain compatible with the FAST audio flag.
+    virtual bool isFastCompatible() const = 0;
+
+    // Is this EffectChain compatible with the bit-perfect audio flag.
+    virtual bool isBitPerfectCompatible() const = 0;
+
+    // isCompatibleWithThread_l() must be called with thread->mLock held
+    //  TODO(b/288339104) type
+    virtual bool isCompatibleWithThread_l(const sp<Thread>& thread) const = 0;
+
+    virtual bool containsHapticGeneratingEffect_l() = 0;
+
+    virtual void setHapticIntensity_l(int id, os::HapticScale intensity) = 0;
+
+    virtual sp<EffectCallbackInterface> effectCallback() const = 0;
+
+    virtual wp<Thread> thread() const = 0;  // TODO(b/288339104) type
+    virtual void setThread(const sp<Thread>& thread) = 0;  // TODO(b/288339104) type
+
+    virtual bool isFirstEffect(int id) const = 0;
+
+    virtual size_t numberOfEffects() const = 0;
+    virtual sp<IAfEffectModule> getEffectModule(size_t index) const = 0;
+
+    virtual void dump(int fd, const Vector<String16>& args) const = 0;
+};
+
+class IAfEffectHandle : public virtual RefBase {
+    friend class EffectBase;
+    friend class EffectChain;
+    friend class EffectModule;
+
+public:
+    static sp<IAfEffectHandle> create(
+            const sp<IAfEffectBase>& effect,
+            const sp<RefBase /*AudioFlinger::Client */>& client,  // TODO(b/288339104) type
+            const sp<media::IEffectClient>& effectClient,
+            int32_t priority, bool notifyFramesProcessed);
+
+    virtual status_t initCheck() const = 0;
+    virtual bool enabled() const = 0;
+    virtual int id() const = 0;
+    virtual wp<IAfEffectBase> effect() const = 0;
+    virtual sp<android::media::IEffect> asIEffect() = 0;
+    // TODO(b/288339104) type
+    virtual sp<RefBase /* AudioFlinger::Client */> client() const = 0;
+
+private:
+    virtual void setControl(bool hasControl, bool signal, bool enabled) = 0;
+    virtual bool hasControl() const = 0;
+    virtual void setEnabled(bool enabled) = 0;
+    virtual bool disconnected() const = 0;
+    virtual int priority() const = 0;
+
+    virtual void commandExecuted(uint32_t cmdCode,
+            const std::vector<uint8_t>& cmdData,
+            const std::vector<uint8_t>& replyData) = 0;
+    virtual void framesProcessed(int32_t frames) const = 0;
+
+    virtual void dumpToBuffer(char* buffer, size_t size) const = 0;
+};
+
+class IAfDeviceEffectProxy : public virtual IAfEffectBase {
+public:
+    // TODO(b/288339104) type
+    static sp<IAfDeviceEffectProxy> create(const AudioDeviceTypeAddr& device,
+                const sp</* DeviceEffectManagerCallback */ RefBase>& callback,
+                effect_descriptor_t *desc, int id, bool notifyFramesProcessed);
+
+    virtual status_t init(
+            const /* std::map<audio_patch_handle_t,
+            PatchPanel::Patch>& */ void * patches) = 0; // TODO(b/288339104) type
+    virtual const AudioDeviceTypeAddr& device() const = 0;
+
+    virtual status_t onCreatePatch(
+            audio_patch_handle_t patchHandle,
+            /* const PatchPanel::Patch& */ const void * patch) = 0;
+    virtual void onReleasePatch(audio_patch_handle_t patchHandle) = 0;
+
+    virtual void dump2(int fd, int spaces) const = 0; // TODO(b/288339104) naming?
+
+private:
+    // used by DeviceEffectProxy
+    virtual bool isOutput() const = 0;
+    virtual uint32_t sampleRate() const = 0;
+    virtual audio_channel_mask_t channelMask() const = 0;
+    virtual uint32_t channelCount() const = 0;
+
+    virtual size_t removeEffect(const sp<IAfEffectModule>& effect) = 0;
+    virtual status_t addEffectToHal(const sp<EffectHalInterface>& effect) = 0;
+    virtual status_t removeEffectFromHal(const sp<EffectHalInterface>& effect) = 0;
+};
+
+} // namespace android