hal: integrate ADM module
HAL dynamically loads the ADM module and registers all the input
and output streams and also notifies all read and write operarations.
authored-by: Ravi Kumar Alamanda <ralama@codeaurora.org>
Bug: 10546170
Change-Id: Ie599f990c5d7224a6261e703c099fb98b5980c35
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 486ce8f..70ce0dc 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -838,7 +838,10 @@
break;
}
+ ALOGV("%s: pcm_prepare start", __func__);
+ pcm_prepare(in->pcm);
ALOGV("%s: exit", __func__);
+
return ret;
error_open:
@@ -1174,6 +1177,10 @@
}
break;
}
+ ALOGV("%s: pcm_prepare start", __func__);
+ if (pcm_is_ready(out->pcm))
+ pcm_prepare(out->pcm);
+
} else {
out->pcm = NULL;
out->compr = compress_open(adev->snd_card, out->pcm_device_id,
@@ -1315,6 +1322,9 @@
pthread_mutex_lock(&out->lock);
if (!out->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, out->handle);
+
pthread_mutex_lock(&adev->lock);
out->standby = true;
if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1589,6 +1599,8 @@
out->standby = true;
goto exit;
}
+ if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+ adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1615,14 +1627,22 @@
if (out->pcm) {
if (out->muted)
memset((void *)buffer, 0, bytes);
+
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, out->handle);
+
if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
}
else
ret = pcm_write(out->pcm, (void *)buffer, bytes);
+
if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
+
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, out->handle);
}
}
@@ -1849,6 +1869,9 @@
}
if (!in->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, in->capture_handle);
+
pthread_mutex_lock(&adev->lock);
in->standby = true;
if (in->pcm) {
@@ -1950,8 +1973,13 @@
goto exit;
}
in->standby = 0;
+ if (adev->adm_register_input_stream)
+ adev->adm_register_input_stream(adev->adm_data, in->capture_handle, in->flags);
}
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, in->capture_handle);
+
if (in->pcm) {
if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
ret = pcm_mmap_read(in->pcm, buffer, bytes);
@@ -1959,6 +1987,9 @@
ret = pcm_read(in->pcm, buffer, bytes);
}
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
+
/*
* Instead of writing zeroes here, we could trust the hardware
* to always provide zeroes when muted.
@@ -2518,6 +2549,7 @@
in->standby = 1;
in->channel_mask = config->channel_mask;
in->capture_handle = handle;
+ in->flags = flags;
/* Update config params with the requested sample rate and channels */
if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
@@ -2743,10 +2775,13 @@
for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
pcm_params_free(adev->use_case_table[i]);
}
+ if (adev->adm_deinit)
+ adev->adm_deinit(adev->adm_data);
free(device);
}
pthread_mutex_unlock(&adev_init_lock);
+
return 0;
}
@@ -2873,6 +2908,29 @@
}
}
+ if (access(ADM_LIBRARY_PATH, R_OK) == 0) {
+ adev->adm_lib = dlopen(ADM_LIBRARY_PATH, RTLD_NOW);
+ if (adev->adm_lib == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, ADM_LIBRARY_PATH);
+ } else {
+ ALOGV("%s: DLOPEN successful for %s", __func__, ADM_LIBRARY_PATH);
+ adev->adm_init = (adm_init_t)
+ dlsym(adev->adm_lib, "adm_init");
+ adev->adm_deinit = (adm_deinit_t)
+ dlsym(adev->adm_lib, "adm_deinit");
+ adev->adm_register_input_stream = (adm_register_input_stream_t)
+ dlsym(adev->adm_lib, "adm_register_input_stream");
+ adev->adm_register_output_stream = (adm_register_output_stream_t)
+ dlsym(adev->adm_lib, "adm_register_output_stream");
+ adev->adm_deregister_stream = (adm_deregister_stream_t)
+ dlsym(adev->adm_lib, "adm_deregister_stream");
+ adev->adm_request_focus = (adm_request_focus_t)
+ dlsym(adev->adm_lib, "adm_request_focus");
+ adev->adm_abandon_focus = (adm_abandon_focus_t)
+ dlsym(adev->adm_lib, "adm_abandon_focus");
+ }
+ }
+
adev->bt_wb_speech_enabled = false;
adev->enable_voicerx = false;
@@ -2902,6 +2960,9 @@
audio_device_ref_count++;
pthread_mutex_unlock(&adev_init_lock);
+ if (adev->adm_init)
+ adev->adm_data = adev->adm_init();
+
ALOGV("%s: exit", __func__);
return 0;
}