audioflinger: add effect creation probe mode
Add an argument to IAudioFlinger::createEffect() API to
ask AudioFlinger to just run the pre flight checks but not
create the actual audio effect instance and allocate resources.
This is the basis of an API for apps to query if a given
effect can be created without having to allocate the resources
and risk an exception when calling the constructor.
Bug: 150699608
Test: CTS and GTS Tests for audio effects
Change-Id: Ibdda22fd945c88c33e3c7342a7a5ed3e02d399ac
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 74a09d1..ecda56b 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3375,6 +3375,7 @@
const AudioDeviceTypeAddr& device,
const String16& opPackageName,
pid_t pid,
+ bool probe,
status_t *status,
int *id,
int *enabled)
@@ -3490,10 +3491,10 @@
if (sessionId == AUDIO_SESSION_DEVICE) {
sp<Client> client = registerPid(pid);
- ALOGV("%s device type %d address %s", __func__, device.mType, device.getAddress());
+ ALOGV("%s device type %#x address %s", __func__, device.mType, device.getAddress());
handle = mDeviceEffectManager.createEffect_l(
&desc, device, client, effectClient, mPatchPanel.patches_l(),
- enabled, &lStatus);
+ enabled, &lStatus, probe);
if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
// remove local strong reference to Client with mClientLock held
Mutex::Autolock _cl(mClientLock);
@@ -3588,7 +3589,7 @@
// create effect on selected output thread
bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
handle = thread->createEffect_l(client, effectClient, priority, sessionId,
- &desc, enabled, &lStatus, pinned);
+ &desc, enabled, &lStatus, pinned, probe);
if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
// remove local strong reference to Client with mClientLock held
Mutex::Autolock _cl(mClientLock);
@@ -3600,7 +3601,7 @@
}
Register:
- if (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS) {
+ if (!probe && (lStatus == NO_ERROR || lStatus == ALREADY_EXISTS)) {
// Check CPU and memory usage
sp<EffectBase> effect = handle->effect().promote();
if (effect != nullptr) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 6d7bf3c..40519b0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -238,6 +238,7 @@
const AudioDeviceTypeAddr& device,
const String16& opPackageName,
pid_t pid,
+ bool probe,
status_t *status /*non-NULL*/,
int *id,
int *enabled);
diff --git a/services/audioflinger/DeviceEffectManager.cpp b/services/audioflinger/DeviceEffectManager.cpp
index 87a4c6e..a3c3b84 100644
--- a/services/audioflinger/DeviceEffectManager.cpp
+++ b/services/audioflinger/DeviceEffectManager.cpp
@@ -74,13 +74,14 @@
const sp<IEffectClient>& effectClient,
const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
int *enabled,
- status_t *status) {
+ status_t *status,
+ bool probe) {
sp<DeviceEffectProxy> effect;
sp<EffectHandle> handle;
status_t lStatus;
lStatus = checkEffectCompatibility(descriptor);
- if (lStatus != NO_ERROR) {
+ if (probe || lStatus != NO_ERROR) {
*status = lStatus;
return handle;
}
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index 14ff14d..81e6065 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -36,7 +36,8 @@
const sp<IEffectClient>& effectClient,
const std::map<audio_patch_handle_t, PatchPanel::Patch>& patches,
int *enabled,
- status_t *status);
+ status_t *status,
+ bool probe);
void createAudioPatch(audio_patch_handle_t handle, const PatchPanel::Patch& patch);
void releaseAudioPatch(audio_patch_handle_t handle);
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 82b9c96..8a65122 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -3047,7 +3047,7 @@
int enabled;
*handle = thread->createEffect_l(nullptr, nullptr, 0, AUDIO_SESSION_DEVICE,
const_cast<effect_descriptor_t *>(&mDescriptor),
- &enabled, &status, false);
+ &enabled, &status, false, false /*probe*/);
ALOGV("%s thread->createEffect_l status %d", __func__, status);
} else {
status = BAD_VALUE;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f24dcd7..dc39b62 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1365,7 +1365,8 @@
effect_descriptor_t *desc,
int *enabled,
status_t *status,
- bool pinned)
+ bool pinned,
+ bool probe)
{
sp<EffectModule> effect;
sp<EffectHandle> handle;
@@ -1387,7 +1388,7 @@
Mutex::Autolock _l(mLock);
lStatus = checkEffectCompatibility_l(desc, sessionId);
- if (lStatus != NO_ERROR) {
+ if (probe || lStatus != NO_ERROR) {
goto Exit;
}
@@ -1433,7 +1434,7 @@
}
Exit:
- if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
+ if (!probe && lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
Mutex::Autolock _l(mLock);
if (effectCreated) {
chain->removeEffect_l(effect);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 153cf7c..8149e95 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -342,7 +342,8 @@
effect_descriptor_t *desc,
int *enabled,
status_t *status /*non-NULL*/,
- bool pinned);
+ bool pinned,
+ bool probe);
// return values for hasAudioSession (bit field)
enum effect_state {