Merge "Effect AIDL: add IEffect.reopen to update the effect instances data FMQ" into main
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
index 8c196e7..a1b00be 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
@@ -41,6 +41,7 @@
android.hardware.audio.effect.State getState();
void setParameter(in android.hardware.audio.effect.Parameter param);
android.hardware.audio.effect.Parameter getParameter(in android.hardware.audio.effect.Parameter.Id paramId);
+ android.hardware.audio.effect.IEffect.OpenEffectReturn reopen();
@FixedSize @VintfStability
parcelable Status {
int status;
diff --git a/audio/aidl/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
index 6097f34..266adec 100644
--- a/audio/aidl/android/hardware/audio/effect/IEffect.aidl
+++ b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
@@ -54,7 +54,16 @@
}
/**
- * Return data structure of IEffect.open() interface.
+ * Return data structure of the IEffect.open() and IEffect.reopen() method.
+ *
+ * Contains Fast Message Queues (FMQs) for effect processing status and input/output data.
+ * The status FMQ remains valid and unchanged after opening, while input/output data FMQs can be
+ * modified with changes in input/output AudioConfig. If reallocation of data FMQ is necessary,
+ * the effect instance must release the existing data FMQs to signal the need to the audio
+ * framework.
+ * When the audio framework encounters a valid status FMQ and invalid input/output data FMQs,
+ * it must invoke the IEffect.reopen() method to request the effect instance to reallocate
+ * the FMQ and return to the audio framework.
*/
@VintfStability
parcelable OpenEffectReturn {
@@ -97,7 +106,7 @@
* client responsibility to make sure all parameter/buffer is correct if client wants to reopen
* a closed instance.
*
- * Effect instance close interface should always succeed unless:
+ * Effect instance close method should always succeed unless:
* 1. The effect instance is not in a proper state to be closed, for example it's still in
* State::PROCESSING state.
* 2. There is system/hardware related failure when close.
@@ -154,8 +163,8 @@
/**
* Get a parameter from the effect instance with parameter ID.
*
- * This interface must return the current parameter of the effect instance, if no parameter
- * has been set by client yet, the default value must be returned.
+ * This method must return the current parameter of the effect instance, if no parameter has
+ * been set by client yet, the default value must be returned.
*
* Must be available for the effect instance after open().
*
@@ -165,4 +174,24 @@
* @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported parameter tag.
*/
Parameter getParameter(in Parameter.Id paramId);
+
+ /**
+ * Reopen the effect instance, keeping all previous parameters unchanged, and reallocate only
+ * the Fast Message Queues (FMQs) allocated during the open time as needed.
+ *
+ * When the audio framework encounters a valid status FMQ and invalid data FMQ(s), it calls
+ * this method to reopen the effect and request the latest data FMQ.
+ * Upon receiving this call, if the effect instance's data FMQ(s) is invalid, it must reallocate
+ * the necessary data FMQ(s) and return them to the audio framework. All previous parameters and
+ * states keep unchanged.
+ * Once the audio framework successfully completes the call, it must validate the returned FMQs,
+ * deprecate all old FMQs, and exclusively use the FMQs returned from this method.
+ *
+ * @return The reallocated data FMQ and the original status FMQ.
+ *
+ * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to reallocate FMQ.
+ * This may occur if the effect instance has already been closed or if there is no need to
+ * update any data FMQ.
+ */
+ OpenEffectReturn reopen();
}
diff --git a/audio/aidl/android/hardware/audio/effect/state.gv b/audio/aidl/android/hardware/audio/effect/state.gv
index ce369ba..22c70c8 100644
--- a/audio/aidl/android/hardware/audio/effect/state.gv
+++ b/audio/aidl/android/hardware/audio/effect/state.gv
@@ -31,6 +31,8 @@
IDLE -> INIT[label = "IEffect.close()"];
INIT -> INIT[label = "IEffect.getState\nIEffect.getDescriptor"];
- IDLE -> IDLE[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)"];
- PROCESSING -> PROCESSING[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor"];
+ IDLE -> IDLE[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)\nIEffect.reopen"];
+ PROCESSING
+ -> PROCESSING
+ [label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen"];
}
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index c81c731..3c12f83 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -60,6 +60,16 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus EffectImpl::reopen(OpenEffectReturn* ret) {
+ RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "alreadyClosed");
+
+ // TODO: b/302036943 add reopen implementation
+ auto context = getContext();
+ RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+ context->dupeFmq(ret);
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus EffectImpl::close() {
RETURN_OK_IF(mState == State::INIT);
RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index e7d081f..242a268 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -43,6 +43,7 @@
OpenEffectReturn* ret) override;
virtual ndk::ScopedAStatus close() override;
virtual ndk::ScopedAStatus command(CommandId id) override;
+ virtual ndk::ScopedAStatus reopen(OpenEffectReturn* ret) override;
virtual ndk::ScopedAStatus getState(State* state) override;
virtual ndk::ScopedAStatus setParameter(const Parameter& param) override;