Loading hal/audio_hw.c +103 −4 Original line number Diff line number Diff line Loading @@ -790,6 +790,15 @@ int start_input_stream(struct stream_in *in) ALOGD("%s: enter: stream(%p)usecase(%d: %s)", __func__, &in->stream, in->usecase, use_case_table[in->usecase]); pthread_mutex_lock(&adev->snd_card_status.lock); if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) { ALOGE("%s: sound card is not active/SSR returning error", __func__); ret = -ENETRESET; pthread_mutex_unlock(&adev->snd_card_status.lock); goto error_config; } pthread_mutex_unlock(&adev->snd_card_status.lock); /* Check if source matches incall recording usecase criteria */ ret = voice_check_and_set_incall_rec_usecase(adev, in); if (ret) Loading Loading @@ -827,8 +836,11 @@ int start_input_stream(struct stream_in *in) pcm_close(in->pcm); in->pcm = NULL; ret = -EIO; in->pcm_error_type = PCM_ERROR_EIO; goto error_open; } in->pcm_error_type = PCM_ERROR_NONE; ALOGV("%s: exit", __func__); return ret; Loading Loading @@ -1169,6 +1181,16 @@ int start_output_stream(struct stream_out *out) ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)", __func__, &out->stream, out->usecase, use_case_table[out->usecase], out->devices); pthread_mutex_lock(&adev->snd_card_status.lock); if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) { ALOGE("%s: sound card is not active/SSR returning error", __func__); ret = -ENETRESET; pthread_mutex_unlock(&adev->snd_card_status.lock); goto error_config; } pthread_mutex_unlock(&adev->snd_card_status.lock); out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK); if (out->pcm_device_id < 0) { ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)", Loading Loading @@ -1215,8 +1237,10 @@ int start_output_stream(struct stream_out *out) pcm_close(out->pcm); out->pcm = NULL; ret = -EIO; out->pcm_error_type = PCM_ERROR_EIO; goto error_open; } out->pcm_error_type = PCM_ERROR_NONE; } else { out->pcm = NULL; out->compr = compress_open(adev->snd_card, Loading Loading @@ -1642,9 +1666,28 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, { struct stream_out *out = (struct stream_out *)stream; struct audio_device *adev = out->dev; int scard_state = SND_CARD_STATE_ONLINE; ssize_t ret = 0; pthread_mutex_lock(&out->lock); pthread_mutex_lock(&adev->snd_card_status.lock); scard_state = adev->snd_card_status.state; pthread_mutex_unlock(&adev->snd_card_status.lock); if (out->pcm) { if (SND_CARD_STATE_OFFLINE == scard_state) { ALOGD(" %s: sound card is not active/SSR state", __func__); ret= -ENETRESET; goto exit; } else if (PCM_ERROR_ENETRESET == out->pcm_error_type) { ALOGD(" %s restarting pcm session on post SSR", __func__); out->standby = false; pthread_mutex_unlock(&out->lock); out_standby(&out->stream.common); pthread_mutex_lock(&out->lock); } } if (out->standby) { out->standby = false; pthread_mutex_lock(&adev->lock); Loading Loading @@ -1693,6 +1736,15 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, } exit: if (-ENETRESET == ret) { pthread_mutex_lock(&adev->snd_card_status.lock); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; out->pcm_error_type = PCM_ERROR_ENETRESET; out->standby = true; /*standby will be called on post SSR */ pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_unlock(&out->lock); if (ret != 0) { Loading @@ -1701,6 +1753,7 @@ exit: out_standby(&out->stream.common); usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) / out_get_sample_rate(&out->stream.common)); } return bytes; } Loading Loading @@ -2032,8 +2085,27 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, struct stream_in *in = (struct stream_in *)stream; struct audio_device *adev = in->dev; int i, ret = -1; int scard_state = SND_CARD_STATE_ONLINE; pthread_mutex_lock(&in->lock); pthread_mutex_lock(&adev->snd_card_status.lock); scard_state = adev->snd_card_status.state; pthread_mutex_unlock(&adev->snd_card_status.lock); if (in->pcm) { if(SND_CARD_STATE_OFFLINE == scard_state) { ALOGD(" %s: sound card is not active/SSR state", __func__); ret= -ENETRESET; goto exit; } else if (PCM_ERROR_ENETRESET == in->pcm_error_type) { ALOGD(" %s restarting pcm session on post SSR", __func__); in->standby = false; pthread_mutex_unlock(&in->lock); in_standby(&in->stream.common); pthread_mutex_lock(&in->lock); } } if (in->standby) { pthread_mutex_lock(&adev->lock); if (in->usecase == USECASE_COMPRESS_VOIP_CALL) Loading Loading @@ -2064,6 +2136,15 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, memset(buffer, 0, bytes); exit: if (-ENETRESET == ret) { pthread_mutex_lock(&adev->snd_card_status.lock); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; in->pcm_error_type = PCM_ERROR_ENETRESET; memset(buffer, 0, bytes); in->standby = true; /*standby will be called on post SSR */ pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_unlock(&in->lock); if (ret != 0) { Loading Loading @@ -2398,10 +2479,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) int ret = 0, err; ALOGD("%s: enter: %s", __func__, kvpairs); pthread_mutex_lock(&adev->lock); parms = str_parms_create_str(kvpairs); err = str_parms_get_str(parms, "SND_CARD_STATUS", value, sizeof(value)); if (err >= 0) { char *snd_card_status = value+2; pthread_mutex_lock(&adev->snd_card_status.lock); if (strstr(snd_card_status, "OFFLINE")) { ALOGD("Received sound card OFFLINE status"); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; } else if (strstr(snd_card_status, "ONLINE")) { ALOGD("Received sound card ONLINE status"); adev->snd_card_status.state = SND_CARD_STATE_ONLINE; } pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_lock(&adev->lock); ret = voice_set_parameters(adev, parms); if (ret != 0) goto done; Loading Loading @@ -2762,6 +2856,9 @@ static int adev_open(const hw_module_t *module, const char *name, list_init(&adev->usecase_list); adev->cur_wfd_channels = 2; adev->offload_usecases_state = 0; pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; /* Loads platform specific libraries dynamically */ adev->platform = platform_init(adev); if (!adev->platform) { Loading @@ -2773,6 +2870,8 @@ static int adev_open(const hw_module_t *module, const char *name, return -EINVAL; } adev->snd_card_status.state = SND_CARD_STATE_ONLINE; if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) { adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW); if (adev->visualizer_lib == NULL) { Loading hal/audio_hw.h +17 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ #define MAX_SUPPORTED_CHANNEL_MASKS 2 #define DEFAULT_HDMI_OUT_CHANNELS 2 #define SND_CARD_STATE_OFFLINE 0 #define SND_CARD_STATE_ONLINE 1 typedef int snd_device_t; /* These are the supported use cases by the hardware. Loading Loading @@ -138,6 +140,12 @@ enum { OFFLOAD_STATE_PAUSED, }; enum { PCM_ERROR_NONE, PCM_ERROR_EIO, PCM_ERROR_ENETRESET, /* For SSR */ }; struct offload_cmd { struct listnode node; int cmd; Loading Loading @@ -178,6 +186,7 @@ struct stream_out { void *offload_cookie; struct compr_gapless_mdata gapless_mdata; int send_new_metadata; int pcm_error_type; struct audio_device *dev; }; Loading @@ -196,6 +205,7 @@ struct stream_in { bool enable_aec; bool enable_ns; audio_format_t format; int pcm_error_type; struct audio_device *dev; }; Loading Loading @@ -223,6 +233,11 @@ struct audio_usecase { union stream_ptr stream; }; struct sound_card_status { pthread_mutex_t lock; int state; }; struct audio_device { struct audio_hw_device device; pthread_mutex_t lock; /* see note below on mutex acquisition order */ Loading Loading @@ -251,6 +266,8 @@ struct audio_device { void *offload_effects_lib; int (*offload_effects_start_output)(audio_io_handle_t, int); int (*offload_effects_stop_output)(audio_io_handle_t, int); struct sound_card_status snd_card_status; }; int select_devices(struct audio_device *adev, Loading Loading
hal/audio_hw.c +103 −4 Original line number Diff line number Diff line Loading @@ -790,6 +790,15 @@ int start_input_stream(struct stream_in *in) ALOGD("%s: enter: stream(%p)usecase(%d: %s)", __func__, &in->stream, in->usecase, use_case_table[in->usecase]); pthread_mutex_lock(&adev->snd_card_status.lock); if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) { ALOGE("%s: sound card is not active/SSR returning error", __func__); ret = -ENETRESET; pthread_mutex_unlock(&adev->snd_card_status.lock); goto error_config; } pthread_mutex_unlock(&adev->snd_card_status.lock); /* Check if source matches incall recording usecase criteria */ ret = voice_check_and_set_incall_rec_usecase(adev, in); if (ret) Loading Loading @@ -827,8 +836,11 @@ int start_input_stream(struct stream_in *in) pcm_close(in->pcm); in->pcm = NULL; ret = -EIO; in->pcm_error_type = PCM_ERROR_EIO; goto error_open; } in->pcm_error_type = PCM_ERROR_NONE; ALOGV("%s: exit", __func__); return ret; Loading Loading @@ -1169,6 +1181,16 @@ int start_output_stream(struct stream_out *out) ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)", __func__, &out->stream, out->usecase, use_case_table[out->usecase], out->devices); pthread_mutex_lock(&adev->snd_card_status.lock); if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) { ALOGE("%s: sound card is not active/SSR returning error", __func__); ret = -ENETRESET; pthread_mutex_unlock(&adev->snd_card_status.lock); goto error_config; } pthread_mutex_unlock(&adev->snd_card_status.lock); out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK); if (out->pcm_device_id < 0) { ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)", Loading Loading @@ -1215,8 +1237,10 @@ int start_output_stream(struct stream_out *out) pcm_close(out->pcm); out->pcm = NULL; ret = -EIO; out->pcm_error_type = PCM_ERROR_EIO; goto error_open; } out->pcm_error_type = PCM_ERROR_NONE; } else { out->pcm = NULL; out->compr = compress_open(adev->snd_card, Loading Loading @@ -1642,9 +1666,28 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, { struct stream_out *out = (struct stream_out *)stream; struct audio_device *adev = out->dev; int scard_state = SND_CARD_STATE_ONLINE; ssize_t ret = 0; pthread_mutex_lock(&out->lock); pthread_mutex_lock(&adev->snd_card_status.lock); scard_state = adev->snd_card_status.state; pthread_mutex_unlock(&adev->snd_card_status.lock); if (out->pcm) { if (SND_CARD_STATE_OFFLINE == scard_state) { ALOGD(" %s: sound card is not active/SSR state", __func__); ret= -ENETRESET; goto exit; } else if (PCM_ERROR_ENETRESET == out->pcm_error_type) { ALOGD(" %s restarting pcm session on post SSR", __func__); out->standby = false; pthread_mutex_unlock(&out->lock); out_standby(&out->stream.common); pthread_mutex_lock(&out->lock); } } if (out->standby) { out->standby = false; pthread_mutex_lock(&adev->lock); Loading Loading @@ -1693,6 +1736,15 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, } exit: if (-ENETRESET == ret) { pthread_mutex_lock(&adev->snd_card_status.lock); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; out->pcm_error_type = PCM_ERROR_ENETRESET; out->standby = true; /*standby will be called on post SSR */ pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_unlock(&out->lock); if (ret != 0) { Loading @@ -1701,6 +1753,7 @@ exit: out_standby(&out->stream.common); usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) / out_get_sample_rate(&out->stream.common)); } return bytes; } Loading Loading @@ -2032,8 +2085,27 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, struct stream_in *in = (struct stream_in *)stream; struct audio_device *adev = in->dev; int i, ret = -1; int scard_state = SND_CARD_STATE_ONLINE; pthread_mutex_lock(&in->lock); pthread_mutex_lock(&adev->snd_card_status.lock); scard_state = adev->snd_card_status.state; pthread_mutex_unlock(&adev->snd_card_status.lock); if (in->pcm) { if(SND_CARD_STATE_OFFLINE == scard_state) { ALOGD(" %s: sound card is not active/SSR state", __func__); ret= -ENETRESET; goto exit; } else if (PCM_ERROR_ENETRESET == in->pcm_error_type) { ALOGD(" %s restarting pcm session on post SSR", __func__); in->standby = false; pthread_mutex_unlock(&in->lock); in_standby(&in->stream.common); pthread_mutex_lock(&in->lock); } } if (in->standby) { pthread_mutex_lock(&adev->lock); if (in->usecase == USECASE_COMPRESS_VOIP_CALL) Loading Loading @@ -2064,6 +2136,15 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, memset(buffer, 0, bytes); exit: if (-ENETRESET == ret) { pthread_mutex_lock(&adev->snd_card_status.lock); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; in->pcm_error_type = PCM_ERROR_ENETRESET; memset(buffer, 0, bytes); in->standby = true; /*standby will be called on post SSR */ pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_unlock(&in->lock); if (ret != 0) { Loading Loading @@ -2398,10 +2479,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) int ret = 0, err; ALOGD("%s: enter: %s", __func__, kvpairs); pthread_mutex_lock(&adev->lock); parms = str_parms_create_str(kvpairs); err = str_parms_get_str(parms, "SND_CARD_STATUS", value, sizeof(value)); if (err >= 0) { char *snd_card_status = value+2; pthread_mutex_lock(&adev->snd_card_status.lock); if (strstr(snd_card_status, "OFFLINE")) { ALOGD("Received sound card OFFLINE status"); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; } else if (strstr(snd_card_status, "ONLINE")) { ALOGD("Received sound card ONLINE status"); adev->snd_card_status.state = SND_CARD_STATE_ONLINE; } pthread_mutex_unlock(&adev->snd_card_status.lock); } pthread_mutex_lock(&adev->lock); ret = voice_set_parameters(adev, parms); if (ret != 0) goto done; Loading Loading @@ -2762,6 +2856,9 @@ static int adev_open(const hw_module_t *module, const char *name, list_init(&adev->usecase_list); adev->cur_wfd_channels = 2; adev->offload_usecases_state = 0; pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; /* Loads platform specific libraries dynamically */ adev->platform = platform_init(adev); if (!adev->platform) { Loading @@ -2773,6 +2870,8 @@ static int adev_open(const hw_module_t *module, const char *name, return -EINVAL; } adev->snd_card_status.state = SND_CARD_STATE_ONLINE; if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) { adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW); if (adev->visualizer_lib == NULL) { Loading
hal/audio_hw.h +17 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ #define MAX_SUPPORTED_CHANNEL_MASKS 2 #define DEFAULT_HDMI_OUT_CHANNELS 2 #define SND_CARD_STATE_OFFLINE 0 #define SND_CARD_STATE_ONLINE 1 typedef int snd_device_t; /* These are the supported use cases by the hardware. Loading Loading @@ -138,6 +140,12 @@ enum { OFFLOAD_STATE_PAUSED, }; enum { PCM_ERROR_NONE, PCM_ERROR_EIO, PCM_ERROR_ENETRESET, /* For SSR */ }; struct offload_cmd { struct listnode node; int cmd; Loading Loading @@ -178,6 +186,7 @@ struct stream_out { void *offload_cookie; struct compr_gapless_mdata gapless_mdata; int send_new_metadata; int pcm_error_type; struct audio_device *dev; }; Loading @@ -196,6 +205,7 @@ struct stream_in { bool enable_aec; bool enable_ns; audio_format_t format; int pcm_error_type; struct audio_device *dev; }; Loading Loading @@ -223,6 +233,11 @@ struct audio_usecase { union stream_ptr stream; }; struct sound_card_status { pthread_mutex_t lock; int state; }; struct audio_device { struct audio_hw_device device; pthread_mutex_t lock; /* see note below on mutex acquisition order */ Loading Loading @@ -251,6 +266,8 @@ struct audio_device { void *offload_effects_lib; int (*offload_effects_start_output)(audio_io_handle_t, int); int (*offload_effects_stop_output)(audio_io_handle_t, int); struct sound_card_status snd_card_status; }; int select_devices(struct audio_device *adev, Loading