4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 /*===========================================================================================
24 ========================================================================================== */
32 #include <sys/ioctl.h>
38 #include <mm_message.h>
41 #include "mm_radio_priv_hal.h"
43 /*===========================================================================================
44 LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
45 ========================================================================================== */
46 /*---------------------------------------------------------------------------
47 GLOBAL CONSTANT DEFINITIONS:
48 ---------------------------------------------------------------------------*/
50 /*---------------------------------------------------------------------------
51 IMPORTED VARIABLE DECLARATIONS:
52 ---------------------------------------------------------------------------*/
54 /*---------------------------------------------------------------------------
55 IMPORTED FUNCTION DECLARATIONS:
56 ---------------------------------------------------------------------------*/
58 /*---------------------------------------------------------------------------
60 ---------------------------------------------------------------------------*/
61 #define DEFAULT_DEVICE "/dev/radio0"
64 #define DEFAULT_FREQ 107700
67 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
68 #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
69 /* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
70 #define DEFAULT_WRAP_AROUND 1
72 #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
73 #define READ_MAX_BUFFER_SIZE 1024
74 #define DEFAULT_MAX_MEDIA_VOLUME 15
75 /*---------------------------------------------------------------------------
76 LOCAL CONSTANT DEFINITIONS:
77 ---------------------------------------------------------------------------*/
79 /*---------------------------------------------------------------------------
80 LOCAL DATA TYPE DEFINITIONS:
81 ---------------------------------------------------------------------------*/
83 /*---------------------------------------------------------------------------
84 GLOBAL VARIABLE DEFINITIONS:
85 ---------------------------------------------------------------------------*/
88 /*---------------------------------------------------------------------------
89 LOCAL VARIABLE DEFINITIONS:
90 ---------------------------------------------------------------------------*/
91 /* radio region configuration table */
92 static const MMRadioRegion_t region_table[] = {
93 { /* Notrh America, South America, South Korea, Taiwan, Australia */
94 MM_RADIO_REGION_GROUP_USA, /* region type */
95 MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
96 MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
97 MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
100 { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
101 MM_RADIO_REGION_GROUP_EUROPE,
102 MM_RADIO_DEEMPHASIS_50_US,
103 MM_RADIO_FREQ_MIN_87500_KHZ,
104 MM_RADIO_FREQ_MAX_108000_KHZ,
108 MM_RADIO_REGION_GROUP_JAPAN,
109 MM_RADIO_DEEMPHASIS_50_US,
110 MM_RADIO_FREQ_MIN_76100_KHZ,
111 MM_RADIO_FREQ_MAX_89900_KHZ,
116 /*---------------------------------------------------------------------------
117 LOCAL FUNCTION PROTOTYPES:
118 ---------------------------------------------------------------------------*/
119 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
120 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
121 static int __mmradio_get_state(mm_radio_t *radio);
122 static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
123 void _mmradio_seek_cancel(mm_radio_t *radio);
124 static void __mmradio_seek_thread(mm_radio_t *radio);
125 static void __mmradio_scan_thread(mm_radio_t *radio);
126 static bool __is_tunable_frequency(mm_radio_t *radio, int freq);
128 #ifdef TIZEN_FEATURE_SOUND_FOCUS
129 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
130 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
131 const char *additional_info, void *user_data);
132 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
133 mm_sound_focus_state_e focus_state, const char *reason_for_change,
134 const char *additional_info, void *user_data);
137 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data);
138 static int __mmradio_set_total_volume(mm_radio_t *radio);
140 int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
142 int ret = MM_ERROR_NONE;
146 MMRADIO_LOG_FENTER();
148 MMRADIO_CHECK_INSTANCE(radio);
149 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
151 /* if needed, radio region must be updated.
152 * Otherwise, just applying settings to device without it.
155 count = ARRAY_SIZE(region_table);
157 /* TODO: if auto is supported...get the region info. here */
159 /* update radio region settings */
160 for (index = 0; index < count; index++) {
161 /* find the region from pre-defined table */
162 if (region_table[index].country == region) {
163 radio->region_setting.country = region_table[index].country;
164 radio->region_setting.deemphasis = region_table[index].deemphasis;
165 radio->region_setting.band_min = region_table[index].band_min;
166 radio->region_setting.band_max = region_table[index].band_max;
167 radio->region_setting.channel_spacing = region_table[index].channel_spacing;
172 MMRADIO_LOG_DEBUG("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz\n",
173 radio->region_setting.country, radio->region_setting.deemphasis,
174 radio->region_setting.band_min, radio->region_setting.band_max);
176 MMRADIO_LOG_FLEAVE();
181 int _mmradio_create_radio(mm_radio_t *radio)
183 int ret = MM_ERROR_NONE;
185 MMRADIO_LOG_FENTER();
187 MMRADIO_CHECK_INSTANCE(radio);
188 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
190 /* set default value */
191 radio->freq = DEFAULT_FREQ;
192 #ifdef TIZEN_FEATURE_SOUND_FOCUS
193 memset(&radio->sound_focus, 0, sizeof(mm_radio_sound_focus));
195 memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
196 radio->local_volume = 1.0;
198 /* create command lock */
199 ret = pthread_mutex_init(&radio->cmd_lock, NULL);
201 MMRADIO_LOG_ERROR("mutex creation failed\n");
202 return MM_ERROR_RADIO_INTERNAL;
205 ret = pthread_mutex_init(&radio->volume_lock, NULL);
207 MMRADIO_LOG_ERROR("volume mutex creation failed\n");
208 return MM_ERROR_RADIO_INTERNAL;
211 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
213 #ifdef TIZEN_FEATURE_SOUND_FOCUS
214 ret = mmradio_sound_focus_register(&radio->sound_focus,
215 (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb,
216 (mm_sound_focus_changed_watch_cb)__mmradio_sound_focus_watch_cb,
220 /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
221 MMRADIO_LOG_ERROR("mmradio_audio_focus_register is failed\n");
222 return MM_ERROR_RADIO_INTERNAL;
226 ret = radio_hal_interface_init(&(radio->hal_inf));
228 MMRADIO_LOG_ERROR("mmradio hal interface init failed\n");
232 MMRADIO_LOG_FLEAVE();
234 return MM_ERROR_NONE;
237 int _mmradio_realize(mm_radio_t *radio)
239 int ret = MM_ERROR_NONE;
243 MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
245 MMRADIO_LOG_FENTER();
247 MMRADIO_CHECK_INSTANCE(radio);
248 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
250 ret = pthread_mutex_init(&radio->seek_cancel_mutex, NULL);
252 MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret);
253 return MM_ERROR_RADIO_INTERNAL;
256 if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
257 /* not initialized yet. set it with default region */
258 region = RADIO_DEFAULT_REGION;
261 /* already initialized by application */
262 region = radio->region_setting.country;
265 ret = _mmradio_apply_region(radio, region, update);
267 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
268 ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
269 if (ret != MM_ERROR_NONE) {
270 MMRADIO_LOG_ERROR("sound_manager_create_stream_information_internal error");
271 MMRADIO_LOG_FLEAVE();
274 ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
275 if (ret != MM_ERROR_NONE) {
276 MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
277 MMRADIO_LOG_FLEAVE();
282 ret = sound_manager_get_max_volume(SOUND_TYPE_MEDIA, &max);
283 if (ret != MM_ERROR_NONE) {
284 MMRADIO_LOG_WARNING("sound_manager_get_max_volume error");
285 radio->max_media_volume = DEFAULT_MAX_MEDIA_VOLUME;
287 radio->max_media_volume = max;
290 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
292 if (ret != MM_ERROR_NONE)
293 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
295 MMRADIO_VOLUME_LOCK(radio);
296 radio->media_volume = volume;
297 MMRADIO_VOLUME_UNLOCK(radio);
299 ret = mm_sound_add_volume_changed_callback(__mmradio_volume_changed_cb, (void *)radio, &radio->volume_subs_id);
300 if (ret != MM_ERROR_NONE)
301 MMRADIO_LOG_WARNING("mm_sound_add_volume_changed_callback error");
303 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
305 MMRADIO_LOG_FLEAVE();
307 return MM_ERROR_NONE;
310 int _mmradio_unrealize(mm_radio_t *radio)
312 int ret = MM_ERROR_NONE;
314 MMRADIO_LOG_FENTER();
316 MMRADIO_CHECK_INSTANCE(radio);
317 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
319 /*Finish if there are scans*/
320 _mmradio_stop_scan(radio);
322 /*Stop radio if started*/
323 _mmradio_stop(radio);
325 /* close radio device here !!!! */
326 radio_hal_close(radio->hal_inf);
327 radio_hal_unprepare(radio->hal_inf);
328 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
329 sound_manager_destroy_virtual_stream(radio->vstream);
330 sound_manager_destroy_stream_information(radio->stream_info);
332 pthread_mutex_destroy(&radio->seek_cancel_mutex);
334 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
336 MMRADIO_LOG_FLEAVE();
341 int _mmradio_destroy(mm_radio_t *radio)
343 int ret = MM_ERROR_NONE;
344 MMRADIO_LOG_FENTER();
346 MMRADIO_CHECK_INSTANCE(radio);
347 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
349 _mmradio_unrealize(radio);
351 ret = radio_hal_interface_deinit(radio->hal_inf);
353 MMRADIO_LOG_ERROR("mmradio hal interface deinit failed\n");
356 #ifdef TIZEN_FEATURE_SOUND_FOCUS
357 ret = mmradio_sound_focus_deregister(&radio->sound_focus);
359 MMRADIO_LOG_ERROR("failed to deregister sound focus\n");
360 return MM_ERROR_RADIO_INTERNAL;
363 MMRADIO_LOG_FLEAVE();
365 return MM_ERROR_NONE;
368 /* unit should be KHz */
369 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
371 int ret = MM_ERROR_NONE;
373 MMRADIO_LOG_FENTER();
375 MMRADIO_CHECK_INSTANCE(radio);
376 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
378 MMRADIO_LOG_DEBUG("Setting %d frequency\n", freq);
382 ret = radio_hal_set_frequency(radio->hal_inf, freq);
383 if (ret != MM_ERROR_NONE) {
384 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
385 MMRADIO_LOG_FLEAVE();
389 MMRADIO_LOG_FLEAVE();
395 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
397 int ret = MM_ERROR_NONE;
399 MMRADIO_LOG_FENTER();
401 MMRADIO_CHECK_INSTANCE(radio);
402 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
404 return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
406 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
407 if (ret != MM_ERROR_NONE) {
408 MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
413 /* update freq in handle */
416 *pFreq = (int)radio->freq;
418 MMRADIO_LOG_FLEAVE();
423 int _mmradio_mute(mm_radio_t *radio)
425 int ret = MM_ERROR_NONE;
426 MMRADIO_LOG_FENTER();
428 MMRADIO_CHECK_INSTANCE(radio);
429 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
431 ret = radio_hal_mute(radio->hal_inf);
432 if (ret == MM_ERROR_NOT_SUPPORT_API) {
433 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
434 } else if (ret != MM_ERROR_NONE) {
435 MMRADIO_LOG_ERROR("radio_hal_mute error");
436 MMRADIO_LOG_FLEAVE();
440 radio->is_muted = TRUE;
441 MMRADIO_LOG_FLEAVE();
446 int _mmradio_unmute(mm_radio_t *radio)
448 int ret = MM_ERROR_NONE;
449 MMRADIO_LOG_FENTER();
451 MMRADIO_CHECK_INSTANCE(radio);
452 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
454 ret = radio_hal_unmute(radio->hal_inf);
455 if (ret == MM_ERROR_NOT_SUPPORT_API) {
456 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
457 } else if (ret != MM_ERROR_NONE) {
458 MMRADIO_LOG_ERROR("radio_hal_unmute error");
459 MMRADIO_LOG_FLEAVE();
463 radio->is_muted = FALSE;
465 MMRADIO_LOG_FLEAVE();
470 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
472 MMRADIO_LOG_FENTER();
474 MMRADIO_CHECK_INSTANCE(radio);
476 radio->msg_cb = callback;
477 radio->msg_cb_param = user_param;
479 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x\n", callback, user_param);
481 MMRADIO_LOG_FLEAVE();
483 return MM_ERROR_NONE;
486 int _mmradio_get_state(mm_radio_t *radio, int *pState)
490 MMRADIO_LOG_FENTER();
492 MMRADIO_CHECK_INSTANCE(radio);
493 return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT);
495 state = __mmradio_get_state(radio);
499 MMRADIO_LOG_FLEAVE();
501 return MM_ERROR_NONE;
504 int _mmradio_start(mm_radio_t *radio)
506 int ret = MM_ERROR_NONE;
507 unsigned int volume = 0;
509 MMRADIO_LOG_FENTER();
511 MMRADIO_CHECK_INSTANCE(radio);
512 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
514 MMRADIO_LOG_DEBUG("now tune to frequency : %d\n", radio->freq);
516 #ifdef TIZEN_FEATURE_SOUND_FOCUS
517 if (radio->sound_focus.handle > 0) {
518 ret = mmradio_acquire_sound_focus(&radio->sound_focus);
519 if (ret != MM_ERROR_NONE) {
520 MMRADIO_LOG_ERROR("failed to set sound focus");
526 if (!radio->is_ready) {
527 ret = radio_hal_prepare(radio->hal_inf);
528 if (ret == MM_ERROR_NOT_SUPPORT_API) {
529 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
530 } else if (ret != MM_ERROR_NONE) {
531 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
535 ret = radio_hal_open(radio->hal_inf);
536 if (ret == MM_ERROR_NOT_SUPPORT_API) {
537 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
538 } else if (ret != MM_ERROR_NONE) {
539 MMRADIO_LOG_ERROR("radio_hal_init error");
542 radio->is_ready = TRUE;
544 MMRADIO_LOG_DEBUG("radio prepared and opened");
547 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
548 if (ret != MM_ERROR_NONE)
549 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
551 MMRADIO_VOLUME_LOCK(radio);
552 radio->media_volume = volume;
553 MMRADIO_VOLUME_UNLOCK(radio);
555 ret = __mmradio_set_total_volume(radio);
556 if (ret == MM_ERROR_NOT_SUPPORT_API) {
557 MMRADIO_LOG_WARNING("radio_hal_set_volume is not supported");
559 MMRADIO_LOG_ERROR("failed to radio_hal_set_volume\n");
563 ret = radio_hal_start(radio->hal_inf);
564 if (ret == MM_ERROR_NOT_SUPPORT_API) {
565 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
567 MMRADIO_LOG_ERROR("failed to radio_hal_start\n");
571 /* set stored frequency */
572 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
574 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency\n");
578 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
579 ret = sound_manager_start_virtual_stream(radio->vstream);
581 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream\n");
586 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
588 MMRADIO_LOG_FLEAVE();
590 return MM_ERROR_NONE;
592 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
594 sound_manager_stop_virtual_stream(radio->vstream);
597 radio_hal_close(radio->hal_inf);
599 radio_hal_unprepare(radio->hal_inf);
600 radio->is_ready = FALSE;
604 int _mmradio_stop(mm_radio_t *radio)
606 int ret = MM_ERROR_NONE;
608 MMRADIO_LOG_FENTER();
610 MMRADIO_CHECK_INSTANCE(radio);
611 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
613 radio->seek_unmute = FALSE;
614 /*cancel if any seek*/
615 _mmradio_seek_cancel(radio);
616 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
617 ret = sound_manager_stop_virtual_stream(radio->vstream);
618 if (ret != MM_ERROR_NONE) {
619 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
624 ret = radio_hal_stop(radio->hal_inf);
625 if (ret == MM_ERROR_NOT_SUPPORT_API) {
626 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
628 MMRADIO_LOG_ERROR("failed to radio_hal_stop\n");
632 /* close radio device here !!!! */
633 ret = radio_hal_close(radio->hal_inf);
634 if (ret == MM_ERROR_NOT_SUPPORT_API) {
635 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
636 } else if (ret != MM_ERROR_NONE) {
637 MMRADIO_LOG_ERROR("radio_hal_close_device error");
641 ret = radio_hal_unprepare(radio->hal_inf);
642 if (ret == MM_ERROR_NOT_SUPPORT_API) {
643 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
644 } else if (ret != MM_ERROR_NONE) {
645 MMRADIO_LOG_ERROR("radio_hal_close_device error");
649 radio->is_ready = FALSE;
651 #ifdef TIZEN_FEATURE_SOUND_FOCUS
652 if (radio->sound_focus.handle > 0) {
653 ret = mmradio_release_sound_focus(&radio->sound_focus);
655 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed\n");
660 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
662 MMRADIO_LOG_FLEAVE();
664 return MM_ERROR_NONE;
667 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
669 int ret = MM_ERROR_NONE;
671 MMRADIO_LOG_FENTER();
673 MMRADIO_CHECK_INSTANCE(radio);
674 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
676 if (radio->is_seeking) {
677 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
678 return MM_ERROR_RADIO_INTERNAL;
681 radio->seek_unmute = FALSE;
682 radio->is_seeking = TRUE;
683 radio->seek_cancel = FALSE;
685 if (!radio->is_muted) {
686 ret = radio_hal_mute(radio->hal_inf);
687 if (ret == MM_ERROR_NOT_SUPPORT_API) {
688 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
690 MMRADIO_LOG_ERROR("failed to radio_hal_mute\n");
693 radio->seek_unmute = TRUE;
696 MMRADIO_LOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction);
697 radio->seek_direction = direction;
699 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
702 MMRADIO_LOG_DEBUG("failed create thread\n");
703 radio->is_seeking = FALSE;
704 radio->seek_cancel = TRUE;
705 if (radio->seek_unmute) {
706 ret = radio_hal_mute(radio->hal_inf);
707 if (ret == MM_ERROR_NOT_SUPPORT_API) {
708 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
710 MMRADIO_LOG_ERROR("failed to radio_hal_mute\n");
711 radio->seek_unmute = FALSE;
715 return MM_ERROR_RADIO_INTERNAL;
718 MMRADIO_LOG_FLEAVE();
720 return MM_ERROR_NONE;
723 void _mmradio_seek_cancel(mm_radio_t *radio)
725 int ret = MM_ERROR_NONE;
726 char str_error[READ_MAX_BUFFER_SIZE];
727 MMRADIO_LOG_FENTER();
729 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
731 /*cancel any outstanding seek request*/
732 radio->seek_cancel = TRUE;
733 if (radio->seek_thread) {
734 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
735 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
736 if (ret == EBUSY) { /* it was already locked by other */
737 MMRADIO_LOG_DEBUG("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
738 } else if (ret == 0) {
739 MMRADIO_LOG_DEBUG("trylock is successful. unlock now");
740 pthread_mutex_unlock(&radio->seek_cancel_mutex);
742 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
744 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
745 pthread_join(radio->seek_thread, NULL);
746 MMRADIO_LOG_DEBUG("done");
747 radio->is_seeking = FALSE;
748 radio->seek_thread = 0;
750 MMRADIO_LOG_FLEAVE();
754 int _mmradio_start_scan(mm_radio_t *radio)
756 int ret = MM_ERROR_NONE;
758 MMRADIO_LOG_FENTER();
760 MMRADIO_CHECK_INSTANCE(radio);
761 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
765 radio->stop_scan = false;
767 if (!radio->is_ready) {
768 ret = radio_hal_prepare(radio->hal_inf);
769 if (ret == MM_ERROR_NOT_SUPPORT_API) {
770 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
771 } else if (ret != MM_ERROR_NONE) {
772 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
776 ret = radio_hal_open(radio->hal_inf);
777 if (ret == MM_ERROR_NOT_SUPPORT_API) {
778 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
779 } else if (ret != MM_ERROR_NONE) {
780 MMRADIO_LOG_ERROR("radio_hal_init error");
781 MMRADIO_LOG_FLEAVE();
784 radio->is_ready = TRUE;
786 MMRADIO_LOG_DEBUG("radio prepared and opened");
789 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
791 if (scan_tr_id != 0) {
792 MMRADIO_LOG_DEBUG("failed to create thread : scan\n");
793 return MM_ERROR_RADIO_NOT_INITIALIZED;
796 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
798 MMRADIO_LOG_FLEAVE();
800 return MM_ERROR_NONE;
803 int _mmradio_stop_scan(mm_radio_t *radio)
806 char str_error[READ_MAX_BUFFER_SIZE];
807 MMRADIO_LOG_FENTER();
809 MMRADIO_CHECK_INSTANCE(radio);
810 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
812 radio->stop_scan = true;
814 if (radio->scan_thread > 0) {
815 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
816 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
817 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
818 if (ret == EBUSY) { /* it was already locked by other */
819 MMRADIO_LOG_DEBUG("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
820 } else if (ret == 0) {
821 MMRADIO_LOG_DEBUG("trylock is successful. unlock now");
822 pthread_mutex_unlock(&radio->seek_cancel_mutex);
824 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
826 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
827 pthread_cancel(radio->scan_thread);
828 pthread_join(radio->scan_thread, NULL);
829 radio->scan_thread = 0;
832 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
833 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
835 MMRADIO_LOG_FLEAVE();
837 return MM_ERROR_NONE;
840 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
842 int ret = MM_ERROR_NONE;
843 uint32_t strength = 0;
844 MMRADIO_LOG_FENTER();
845 MMRADIO_CHECK_INSTANCE(radio);
847 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
849 /* just return stored frequency if radio device is not ready */
850 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
851 if (ret == MM_ERROR_NOT_SUPPORT_API) {
852 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
853 } else if (ret != MM_ERROR_NONE) {
854 debug_error("radio_hal_get_signal_strength error\n");
856 MMRADIO_LOG_FLEAVE();
859 *value = (int)strength;
860 MMRADIO_LOG_FLEAVE();
861 return MM_ERROR_NONE;
864 void __mmradio_scan_thread(mm_radio_t *radio)
866 int ret = MM_ERROR_NONE;
869 MMRADIO_LOG_FENTER();
870 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
872 ret = radio_hal_mute(radio->hal_inf);
874 if (ret == MM_ERROR_NOT_SUPPORT_API) {
875 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
876 } else if (ret != MM_ERROR_NONE) {
877 MMRADIO_LOG_ERROR("radio_hal_mute error");
880 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
882 if (ret != MM_ERROR_NONE)
885 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
886 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
888 while (!radio->stop_scan) {
890 MMMessageParamType param = { 0, };
892 MMRADIO_LOG_DEBUG("scanning....\n");
894 pthread_mutex_lock(&radio->seek_cancel_mutex);
896 if (radio->stop_scan) {
897 MMRADIO_LOG_DEBUG("scan was canceled");
898 pthread_mutex_unlock(&radio->seek_cancel_mutex);
902 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
904 pthread_mutex_unlock(&radio->seek_cancel_mutex);
906 if (ret != MM_ERROR_NONE) {
907 MMRADIO_LOG_ERROR("radio scanning error");
911 /* now we can get new frequency from radio device */
912 if (radio->stop_scan)
915 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
916 if (ret != MM_ERROR_NONE) {
917 MMRADIO_LOG_ERROR("failed to get current frequency\n");
919 if (freq < prev_freq) {
920 MMRADIO_LOG_DEBUG("scanning wrapped around. stopping scan\n");
924 if (freq == prev_freq)
927 prev_freq = param.radio_scan.frequency = (int)freq;
928 MMRADIO_LOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency);
930 /* drop if max freq is scanned */
931 if (param.radio_scan.frequency == radio->region_setting.band_max) {
932 MMRADIO_LOG_DEBUG("%d freq is dropping...and stopping scan\n", param.radio_scan.frequency);
936 if (radio->stop_scan) {
937 /* doesn't need to post */
941 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
945 if (radio->old_state == MM_RADIO_STATE_READY) {
946 MMRADIO_LOG_DEBUG("old state is ready");
947 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
948 MMRADIO_LOG_DEBUG("old state is playing");
949 ret = radio_hal_unmute(radio->hal_inf);
950 if (ret == MM_ERROR_NOT_SUPPORT_API) {
951 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
952 } else if (ret != MM_ERROR_NONE) {
953 MMRADIO_LOG_ERROR("radio_hal_unmute error");
956 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
957 if (ret == MM_ERROR_NOT_SUPPORT_API) {
958 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
959 } else if (ret != MM_ERROR_NONE) {
960 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
967 radio->scan_thread = 0;
969 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
970 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
972 /* close radio device here !!!! */
973 ret = radio_hal_close(radio->hal_inf);
974 if (ret == MM_ERROR_NOT_SUPPORT_API)
975 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
976 else if (ret != MM_ERROR_NONE)
977 MMRADIO_LOG_ERROR("radio_hal_close_device error");
979 ret = radio_hal_unprepare(radio->hal_inf);
980 if (ret == MM_ERROR_NOT_SUPPORT_API)
981 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
982 else if (ret != MM_ERROR_NONE)
983 MMRADIO_LOG_ERROR("radio_hal_close_device error");
985 radio->is_ready = FALSE;
987 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
990 if (!radio->stop_scan)
991 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
993 MMRADIO_LOG_FLEAVE();
1000 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1002 MMRADIO_LOG_FENTER();
1004 MMRADIO_CHECK_INSTANCE(radio);
1006 if (freq >= radio->region_setting.band_max
1007 || freq <= radio->region_setting.band_min)
1010 MMRADIO_LOG_FLEAVE();
1015 void __mmradio_seek_thread(mm_radio_t *radio)
1017 int ret = MM_ERROR_NONE;
1019 MMMessageParamType param = {0, };
1021 MMRADIO_LOG_FENTER();
1022 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1024 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1026 MMRADIO_LOG_DEBUG("seeking....\n");
1028 if (!radio->seek_cancel) {
1030 MMRADIO_LOG_DEBUG("try to seek ");
1031 pthread_mutex_lock(&radio->seek_cancel_mutex);
1032 MMRADIO_LOG_DEBUG("seek start\n");
1034 if (radio->seek_cancel) {
1035 MMRADIO_LOG_DEBUG("seek was canceled so we return failure to application");
1036 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1040 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1041 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1043 MMRADIO_LOG_ERROR("radio_hal_seek failed\n");
1047 /* now we can get new frequency from radio device */
1048 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1050 MMRADIO_LOG_ERROR("failed to get current frequency\n");
1054 MMRADIO_LOG_DEBUG("found frequency\n");
1056 /* if same freq is found, ignore it and search next one. */
1057 if (freq == radio->prev_seek_freq) {
1058 MMRADIO_LOG_DEBUG("It's same with previous found one. So, trying next one. \n");
1062 /* check if it's limit freq or not */
1063 if (__is_tunable_frequency(radio, freq)) {
1064 /* now tune to new frequency */
1065 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1067 MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
1072 if (radio->seek_unmute) {
1073 /* now turn on radio
1074 * In the case of limit freq, tuner should be unmuted.
1075 * Otherwise, sound can't output even though application set new frequency.
1077 ret = radio_hal_unmute(radio->hal_inf);
1079 MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
1082 radio->seek_unmute = FALSE;
1085 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1086 MMRADIO_LOG_DEBUG("seeking : new frequency : [%d]\n", param.radio_scan.frequency);
1087 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1090 radio->seek_thread = 0;
1091 radio->is_seeking = FALSE;
1093 MMRADIO_LOG_FLEAVE();
1100 if (radio->seek_unmute) {
1101 /* now turn on radio
1102 * In the case of limit freq, tuner should be unmuted.
1103 * Otherwise, sound can't output even though application set new frequency.
1105 ret = radio_hal_unmute(radio->hal_inf);
1107 MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
1108 radio->seek_unmute = FALSE;
1110 /* freq -1 means it's failed to seek */
1111 param.radio_scan.frequency = -1;
1112 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1113 radio->is_seeking = FALSE;
1118 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1120 MMRADIO_CHECK_INSTANCE(radio);
1122 MMRADIO_LOG_FENTER();
1124 if (!radio->msg_cb) {
1125 debug_warning("failed to post a message\n");
1129 MMRADIO_LOG_DEBUG("address of msg_cb : %p\n", radio->msg_cb);
1131 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1133 MMRADIO_LOG_FLEAVE();
1138 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1140 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1142 MMRADIO_LOG_FENTER();
1144 MMRADIO_CHECK_INSTANCE(radio);
1146 radio_state = __mmradio_get_state(radio);
1148 MMRADIO_LOG_DEBUG("incomming command : %d current state : %d\n", command, radio_state);
1151 case MMRADIO_COMMAND_CREATE:
1153 if (radio_state != 0)
1158 case MMRADIO_COMMAND_REALIZE:
1160 if (radio_state == MM_RADIO_STATE_READY ||
1161 radio_state == MM_RADIO_STATE_PLAYING ||
1162 radio_state == MM_RADIO_STATE_SCANNING)
1165 if (radio_state == 0)
1170 case MMRADIO_COMMAND_UNREALIZE:
1172 if (radio_state == MM_RADIO_STATE_NULL)
1175 /* we can call unrealize at any higher state */
1179 case MMRADIO_COMMAND_START:
1181 if (radio_state == MM_RADIO_STATE_PLAYING)
1184 if (radio_state != MM_RADIO_STATE_READY)
1189 case MMRADIO_COMMAND_STOP:
1191 if (radio_state == MM_RADIO_STATE_READY)
1194 if (radio_state != MM_RADIO_STATE_PLAYING)
1199 case MMRADIO_COMMAND_START_SCAN:
1201 if (radio_state == MM_RADIO_STATE_SCANNING)
1204 if (radio_state == MM_RADIO_STATE_NULL)
1209 case MMRADIO_COMMAND_STOP_SCAN:
1211 if (radio_state == MM_RADIO_STATE_READY)
1214 if (radio_state != MM_RADIO_STATE_SCANNING)
1219 case MMRADIO_COMMAND_DESTROY:
1220 case MMRADIO_COMMAND_MUTE:
1221 case MMRADIO_COMMAND_UNMUTE:
1222 case MMRADIO_COMMAND_SET_FREQ:
1223 case MMRADIO_COMMAND_GET_FREQ:
1224 case MMRADIO_COMMAND_SET_REGION:
1225 case MMRADIO_COMMAND_SET_VOLUME:
1226 case MMRADIO_COMMAND_GET_VOLUME:
1228 /* we can do it at any state */
1232 case MMRADIO_COMMAND_SEEK:
1234 if (radio_state != MM_RADIO_STATE_PLAYING)
1239 case MMRADIO_COMMAND_GET_REGION:
1241 if (radio_state == MM_RADIO_STATE_NULL)
1247 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it\n");
1251 MMRADIO_LOG_DEBUG("status OK\n");
1253 radio->cmd = command;
1255 MMRADIO_LOG_FLEAVE();
1257 return MM_ERROR_NONE;
1260 debug_warning("invalid state. current : %d command : %d\n", radio_state, command);
1261 MMRADIO_LOG_FLEAVE();
1262 return MM_ERROR_RADIO_INVALID_STATE;
1265 debug_warning("mm-radio is in the desired state(%d). doing noting\n", radio_state);
1266 MMRADIO_LOG_FLEAVE();
1267 return MM_ERROR_RADIO_NO_OP;
1271 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1273 MMMessageParamType msg = { 0, };
1274 int msg_type = MM_MESSAGE_UNKNOWN;
1276 MMRADIO_LOG_FENTER();
1277 MMRADIO_CHECK_INSTANCE(radio);
1280 debug_warning("calling set_state with invalid radio handle\n");
1284 if (radio->current_state == new_state && radio->pending_state == 0) {
1285 debug_warning("we are in same state\n");
1290 radio->old_state = radio->current_state;
1291 radio->current_state = new_state;
1293 /* fill message param */
1294 msg.state.previous = radio->old_state;
1295 msg.state.current = radio->current_state;
1297 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1298 /* post message to application */
1299 switch (radio->sound_focus.by_focus_cb) {
1300 case MMRADIO_FOCUS_CB_NONE:
1302 msg_type = MM_MESSAGE_STATE_CHANGED;
1303 MMRADIO_POST_MSG(radio, msg_type, &msg);
1307 case MMRADIO_FOCUS_CB_POSTMSG:
1309 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1310 msg.union_type = MM_MSG_UNION_CODE;
1311 msg.code = radio->sound_focus.event_src;
1312 MMRADIO_POST_MSG(radio, msg_type, &msg);
1316 case MMRADIO_FOCUS_CB_SKIP_POSTMSG:
1321 msg_type = MM_MESSAGE_STATE_CHANGED;
1322 MMRADIO_POST_MSG(radio, msg_type, &msg);
1325 MMRADIO_LOG_FLEAVE();
1330 static int __mmradio_get_state(mm_radio_t *radio)
1332 MMRADIO_CHECK_INSTANCE(radio);
1334 MMRADIO_LOG_DEBUG("radio state : current : [%d] old : [%d] pending : [%d]\n",
1335 radio->current_state, radio->old_state, radio->pending_state);
1337 return radio->current_state;
1340 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1341 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1342 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1343 const char *additional_info, void *user_data)
1345 mm_radio_t *radio = (mm_radio_t *)user_data;
1346 enum MMMessageInterruptedCode event_source;
1347 int result = MM_ERROR_NONE;
1348 int postMsg = false;
1350 MMRADIO_LOG_FENTER();
1351 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1353 mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
1354 radio->sound_focus.event_src = event_source;
1356 switch (focus_state) {
1357 case FOCUS_IS_RELEASED:{
1358 radio->sound_focus.cur_focus_type &= ~focus_type;
1359 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
1361 result = _mmradio_stop(radio);
1363 MMRADIO_LOG_ERROR("failed to stop radio\n");
1365 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1369 case FOCUS_IS_ACQUIRED:{
1370 MMMessageParamType msg = { 0, };
1371 msg.union_type = MM_MSG_UNION_CODE;
1372 msg.code = event_source;
1374 radio->sound_focus.cur_focus_type |= focus_type;
1376 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1377 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1379 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1381 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1386 MMRADIO_LOG_DEBUG("Unknown focus_state\n");
1390 MMRADIO_LOG_FLEAVE();
1393 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1394 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1395 const char *additional_info, void *user_data)
1397 mm_radio_t *radio = (mm_radio_t *)user_data;
1398 enum MMMessageInterruptedCode event_source;
1399 int result = MM_ERROR_NONE;
1400 int postMsg = false;
1402 MMRADIO_LOG_FENTER();
1403 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1405 mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
1406 radio->sound_focus.event_src = event_source;
1408 switch (focus_state) {
1409 case FOCUS_IS_ACQUIRED: {
1410 radio->sound_focus.cur_focus_type &= ~focus_type;
1411 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
1413 result = _mmradio_stop(radio);
1415 MMRADIO_LOG_ERROR("failed to stop radio\n");
1417 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1421 case FOCUS_IS_RELEASED: {
1422 MMMessageParamType msg = { 0, };
1423 msg.union_type = MM_MSG_UNION_CODE;
1424 msg.code = event_source;
1426 radio->sound_focus.cur_focus_type |= focus_type;
1428 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1429 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1431 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1433 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1438 MMRADIO_LOG_DEBUG("Unknown focus_state\n");
1442 MMRADIO_LOG_FLEAVE();
1446 static int __mmradio_set_total_volume(mm_radio_t *radio)
1448 int ret = MM_ERROR_NONE;
1449 float total_volume = 0.0f;
1451 MMRADIO_CHECK_INSTANCE(radio);
1453 MMRADIO_VOLUME_LOCK(radio);
1454 if (radio->max_media_volume != 0)
1455 total_volume = ((float)radio->media_volume / (float)radio->max_media_volume) * radio->local_volume;
1457 MMRADIO_LOG_WARNING("max media voulme is zero");
1459 ret = radio_hal_set_volume(radio->hal_inf, total_volume);
1460 if (ret != MM_ERROR_NONE)
1461 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1463 MMRADIO_VOLUME_UNLOCK(radio);
1468 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1470 mm_radio_t *radio = (mm_radio_t *)user_data;
1471 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1472 if (type == VOLUME_TYPE_MEDIA) {
1473 MMRADIO_LOG_DEBUG("Change FM Radio volume to %d", volume);
1474 MMRADIO_VOLUME_LOCK(radio);
1475 radio->media_volume = volume;
1476 MMRADIO_VOLUME_UNLOCK(radio);
1477 __mmradio_set_total_volume(radio);
1481 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1483 MMRADIO_LOG_FENTER();
1484 MMRADIO_CHECK_INSTANCE(radio);
1485 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1487 return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT);
1489 *type = radio->region_setting.country;
1491 MMRADIO_LOG_FLEAVE();
1492 return MM_ERROR_NONE;
1495 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1497 MMRADIO_LOG_FENTER();
1498 MMRADIO_CHECK_INSTANCE(radio);
1499 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1501 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1503 *min_freq = radio->region_setting.band_min;
1504 *max_freq = radio->region_setting.band_max;
1506 MMRADIO_LOG_FLEAVE();
1507 return MM_ERROR_NONE;
1510 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1512 MMRADIO_LOG_FENTER();
1513 MMRADIO_CHECK_INSTANCE(radio);
1514 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1516 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1518 *ch_spacing = radio->region_setting.channel_spacing;
1520 MMRADIO_LOG_FLEAVE();
1521 return MM_ERROR_NONE;
1524 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1526 int ret = MM_ERROR_NONE;
1528 MMRADIO_LOG_FENTER();
1530 MMRADIO_CHECK_INSTANCE(radio);
1531 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1533 MMRADIO_LOG_DEBUG("Setting %f volume\n", volume);
1535 MMRADIO_VOLUME_LOCK(radio);
1536 radio->local_volume = volume;
1537 MMRADIO_VOLUME_UNLOCK(radio);
1539 ret = __mmradio_set_total_volume(radio);
1541 MMRADIO_LOG_FLEAVE();
1546 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1548 int ret = MM_ERROR_NONE;
1549 float total_volume = 0.0;
1551 MMRADIO_LOG_FENTER();
1553 MMRADIO_CHECK_INSTANCE(radio);
1554 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1556 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1558 ret = radio_hal_get_volume(radio->hal_inf, &total_volume);
1559 if (ret != MM_ERROR_NONE) {
1560 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1565 MMRADIO_VOLUME_LOCK(radio);
1567 if (radio->media_volume)
1568 volume = total_volume * ((float)radio->max_media_volume / (float)radio->media_volume);
1570 MMRADIO_LOG_DEBUG("total_volume = %f, max_media_volue = %d, media_volume = %d, volume = %f",
1571 total_volume, radio->max_media_volume, radio->media_volume, volume);
1573 /* update volume in handle */
1574 if (fabs(radio->local_volume - volume) >= FLT_EPSILON) {
1575 radio->local_volume = volume;
1578 *pVolume = (float)radio->local_volume;
1579 MMRADIO_VOLUME_UNLOCK(radio);
1581 MMRADIO_LOG_FLEAVE();