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_media_volume(mm_radio_t *radio, unsigned int level);
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_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
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");
202 return MM_ERROR_RADIO_INTERNAL;
205 ret = pthread_mutex_init(&radio->volume_lock, NULL);
207 MMRADIO_LOG_ERROR("volume mutex creation failed");
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");
222 return MM_ERROR_RADIO_INTERNAL;
226 ret = radio_hal_interface_init(&(radio->hal_inf));
228 MMRADIO_LOG_ERROR("mmradio hal interface init failed");
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_ERROR("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 ret = mm_sound_remove_volume_changed_callback(radio->volume_subs_id);
320 if (ret != MM_ERROR_NONE)
321 MMRADIO_LOG_WARNING("mm_sound_remove_volume_changed_callback error");
323 /*Finish if there are scans*/
324 _mmradio_stop_scan(radio);
326 /*Stop radio if started*/
327 _mmradio_stop(radio);
329 /* close radio device here !!!! */
330 radio_hal_close(radio->hal_inf);
331 radio_hal_unprepare(radio->hal_inf);
332 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
333 sound_manager_destroy_virtual_stream(radio->vstream);
334 sound_manager_destroy_stream_information(radio->stream_info);
336 pthread_mutex_destroy(&radio->seek_cancel_mutex);
338 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
340 MMRADIO_LOG_FLEAVE();
345 int _mmradio_destroy(mm_radio_t *radio)
347 int ret = MM_ERROR_NONE;
348 MMRADIO_LOG_FENTER();
350 MMRADIO_CHECK_INSTANCE(radio);
351 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
353 _mmradio_unrealize(radio);
355 ret = radio_hal_interface_deinit(radio->hal_inf);
357 MMRADIO_LOG_ERROR("mmradio hal interface deinit failed");
361 /* destroy command lock */
362 ret = pthread_mutex_destroy(&radio->cmd_lock);
364 MMRADIO_LOG_ERROR("mutex destroy failed\n");
367 ret = pthread_mutex_destroy(&radio->volume_lock);
369 MMRADIO_LOG_ERROR("volume mutex destroy failed\n");
372 #ifdef TIZEN_FEATURE_SOUND_FOCUS
373 ret = mmradio_sound_focus_deregister(&radio->sound_focus);
375 MMRADIO_LOG_ERROR("failed to deregister sound focus");
376 return MM_ERROR_RADIO_INTERNAL;
379 MMRADIO_LOG_FLEAVE();
381 return MM_ERROR_NONE;
384 /* unit should be KHz */
385 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
387 int ret = MM_ERROR_NONE;
389 MMRADIO_LOG_FENTER();
391 MMRADIO_CHECK_INSTANCE(radio);
392 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
394 MMRADIO_LOG_INFO("Setting %d frequency", freq);
398 ret = radio_hal_set_frequency(radio->hal_inf, freq);
399 if (ret != MM_ERROR_NONE) {
400 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
401 MMRADIO_LOG_FLEAVE();
405 MMRADIO_LOG_FLEAVE();
411 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
413 int ret = MM_ERROR_NONE;
415 MMRADIO_LOG_FENTER();
417 MMRADIO_CHECK_INSTANCE(radio);
418 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
420 return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
422 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
423 if (ret != MM_ERROR_NONE) {
424 MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
429 /* update freq in handle */
430 MMRADIO_LOG_INFO("Updating %d frequency", freq);
433 *pFreq = (int)radio->freq;
435 MMRADIO_LOG_FLEAVE();
440 int _mmradio_mute(mm_radio_t *radio)
442 int ret = MM_ERROR_NONE;
443 MMRADIO_LOG_FENTER();
445 MMRADIO_CHECK_INSTANCE(radio);
446 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
448 ret = radio_hal_mute(radio->hal_inf);
449 if (ret == MM_ERROR_NOT_SUPPORT_API) {
450 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
451 } else if (ret != MM_ERROR_NONE) {
452 MMRADIO_LOG_ERROR("radio_hal_mute error");
453 MMRADIO_LOG_FLEAVE();
457 radio->is_muted = TRUE;
458 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
459 MMRADIO_LOG_FLEAVE();
464 int _mmradio_unmute(mm_radio_t *radio)
466 int ret = MM_ERROR_NONE;
467 MMRADIO_LOG_FENTER();
469 MMRADIO_CHECK_INSTANCE(radio);
470 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
472 ret = radio_hal_unmute(radio->hal_inf);
473 if (ret == MM_ERROR_NOT_SUPPORT_API) {
474 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
475 } else if (ret != MM_ERROR_NONE) {
476 MMRADIO_LOG_ERROR("radio_hal_unmute error");
477 MMRADIO_LOG_FLEAVE();
481 radio->is_muted = FALSE;
482 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
483 MMRADIO_LOG_FLEAVE();
488 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
490 MMRADIO_LOG_FENTER();
492 MMRADIO_CHECK_INSTANCE(radio);
494 radio->msg_cb = callback;
495 radio->msg_cb_param = user_param;
497 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x", callback, user_param);
499 MMRADIO_LOG_FLEAVE();
501 return MM_ERROR_NONE;
504 int _mmradio_get_state(mm_radio_t *radio, int *pState)
508 MMRADIO_LOG_FENTER();
510 MMRADIO_CHECK_INSTANCE(radio);
511 return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT);
513 state = __mmradio_get_state(radio);
517 MMRADIO_LOG_FLEAVE();
519 return MM_ERROR_NONE;
522 int _mmradio_start(mm_radio_t *radio)
524 int ret = MM_ERROR_NONE;
525 unsigned int volume = 0;
527 MMRADIO_LOG_FENTER();
529 MMRADIO_CHECK_INSTANCE(radio);
530 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
532 MMRADIO_LOG_INFO("now tune to frequency : %d", radio->freq);
534 #ifdef TIZEN_FEATURE_SOUND_FOCUS
535 if (radio->sound_focus.handle > 0) {
536 ret = mmradio_acquire_sound_focus(&radio->sound_focus);
537 if (ret != MM_ERROR_NONE) {
538 MMRADIO_LOG_ERROR("failed to set sound focus");
544 if (!radio->is_ready) {
545 ret = radio_hal_prepare(radio->hal_inf);
546 if (ret == MM_ERROR_NOT_SUPPORT_API) {
547 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
548 } else if (ret != MM_ERROR_NONE) {
549 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
553 ret = radio_hal_open(radio->hal_inf);
554 if (ret == MM_ERROR_NOT_SUPPORT_API) {
555 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
556 } else if (ret != MM_ERROR_NONE) {
557 MMRADIO_LOG_ERROR("radio_hal_init error");
560 radio->is_ready = TRUE;
562 MMRADIO_LOG_DEBUG("radio prepared and opened");
565 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
566 if (ret != MM_ERROR_NONE)
567 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
569 ret = __mmradio_set_media_volume(radio, volume);
570 if (ret != MM_ERROR_NONE) {
571 MMRADIO_LOG_ERROR("failed to media volume");
575 ret = radio_hal_start(radio->hal_inf);
576 if (ret == MM_ERROR_NOT_SUPPORT_API) {
577 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
579 MMRADIO_LOG_ERROR("failed to radio_hal_start");
583 /* set stored frequency */
584 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
586 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency");
590 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
591 ret = sound_manager_start_virtual_stream(radio->vstream);
593 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream");
598 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
600 MMRADIO_LOG_FLEAVE();
602 return MM_ERROR_NONE;
604 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
606 sound_manager_stop_virtual_stream(radio->vstream);
609 radio_hal_close(radio->hal_inf);
611 radio_hal_unprepare(radio->hal_inf);
612 radio->is_ready = FALSE;
616 int _mmradio_stop(mm_radio_t *radio)
618 int ret = MM_ERROR_NONE;
620 MMRADIO_LOG_FENTER();
622 MMRADIO_CHECK_INSTANCE(radio);
623 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
625 radio->seek_unmute = FALSE;
626 /*cancel if any seek*/
627 _mmradio_seek_cancel(radio);
628 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
629 ret = sound_manager_stop_virtual_stream(radio->vstream);
630 if (ret != MM_ERROR_NONE) {
631 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
636 ret = radio_hal_stop(radio->hal_inf);
637 if (ret == MM_ERROR_NOT_SUPPORT_API) {
638 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
640 MMRADIO_LOG_ERROR("failed to radio_hal_stop");
644 /* close radio device here !!!! */
645 ret = radio_hal_close(radio->hal_inf);
646 if (ret == MM_ERROR_NOT_SUPPORT_API) {
647 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
648 } else if (ret != MM_ERROR_NONE) {
649 MMRADIO_LOG_ERROR("radio_hal_close_device error");
653 ret = radio_hal_unprepare(radio->hal_inf);
654 if (ret == MM_ERROR_NOT_SUPPORT_API) {
655 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
656 } else if (ret != MM_ERROR_NONE) {
657 MMRADIO_LOG_ERROR("radio_hal_close_device error");
661 radio->is_ready = FALSE;
663 #ifdef TIZEN_FEATURE_SOUND_FOCUS
664 if (radio->sound_focus.handle > 0) {
665 ret = mmradio_release_sound_focus(&radio->sound_focus);
667 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed");
672 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
674 MMRADIO_LOG_FLEAVE();
676 return MM_ERROR_NONE;
679 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
681 int ret = MM_ERROR_NONE;
683 MMRADIO_LOG_FENTER();
685 MMRADIO_CHECK_INSTANCE(radio);
686 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
688 if (radio->is_seeking) {
689 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
690 return MM_ERROR_RADIO_INTERNAL;
693 radio->seek_unmute = FALSE;
694 radio->is_seeking = TRUE;
695 radio->seek_cancel = FALSE;
697 if (!radio->is_muted) {
698 ret = radio_hal_mute(radio->hal_inf);
699 if (ret == MM_ERROR_NOT_SUPPORT_API) {
700 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
702 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
705 radio->seek_unmute = TRUE;
708 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
709 radio->seek_direction = direction;
711 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
714 MMRADIO_LOG_DEBUG("failed create thread");
715 radio->is_seeking = FALSE;
716 radio->seek_cancel = TRUE;
717 if (radio->seek_unmute) {
718 ret = radio_hal_mute(radio->hal_inf);
719 if (ret == MM_ERROR_NOT_SUPPORT_API) {
720 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
722 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
723 radio->seek_unmute = FALSE;
727 return MM_ERROR_RADIO_INTERNAL;
730 MMRADIO_LOG_FLEAVE();
732 return MM_ERROR_NONE;
735 void _mmradio_seek_cancel(mm_radio_t *radio)
737 int ret = MM_ERROR_NONE;
738 char str_error[READ_MAX_BUFFER_SIZE];
739 MMRADIO_LOG_FENTER();
741 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
743 /*cancel any outstanding seek request*/
744 radio->seek_cancel = TRUE;
745 if (radio->seek_thread) {
746 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
747 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
748 if (ret == EBUSY) { /* it was already locked by other */
749 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
750 } else if (ret == 0) {
751 MMRADIO_LOG_INFO("trylock is successful. unlock now");
752 pthread_mutex_unlock(&radio->seek_cancel_mutex);
754 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
756 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
757 pthread_join(radio->seek_thread, NULL);
758 MMRADIO_LOG_DEBUG("done");
759 radio->is_seeking = FALSE;
760 radio->seek_thread = 0;
762 MMRADIO_LOG_FLEAVE();
766 int _mmradio_start_scan(mm_radio_t *radio)
768 int ret = MM_ERROR_NONE;
770 MMRADIO_LOG_FENTER();
772 MMRADIO_CHECK_INSTANCE(radio);
773 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
777 radio->stop_scan = false;
779 if (!radio->is_ready) {
780 ret = radio_hal_prepare(radio->hal_inf);
781 if (ret == MM_ERROR_NOT_SUPPORT_API) {
782 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
783 } else if (ret != MM_ERROR_NONE) {
784 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
788 ret = radio_hal_open(radio->hal_inf);
789 if (ret == MM_ERROR_NOT_SUPPORT_API) {
790 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
791 } else if (ret != MM_ERROR_NONE) {
792 MMRADIO_LOG_ERROR("radio_hal_init error");
793 MMRADIO_LOG_FLEAVE();
796 radio->is_ready = TRUE;
798 MMRADIO_LOG_DEBUG("radio prepared and opened");
801 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
803 if (scan_tr_id != 0) {
804 MMRADIO_LOG_ERROR("failed to create thread : scan");
805 return MM_ERROR_RADIO_NOT_INITIALIZED;
808 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
810 MMRADIO_LOG_FLEAVE();
812 return MM_ERROR_NONE;
815 int _mmradio_stop_scan(mm_radio_t *radio)
818 char str_error[READ_MAX_BUFFER_SIZE];
819 MMRADIO_LOG_FENTER();
821 MMRADIO_CHECK_INSTANCE(radio);
822 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
824 radio->stop_scan = true;
826 if (radio->scan_thread > 0) {
827 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
828 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
829 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
830 if (ret == EBUSY) { /* it was already locked by other */
831 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
832 } else if (ret == 0) {
833 MMRADIO_LOG_INFO("trylock is successful. unlock now");
834 pthread_mutex_unlock(&radio->seek_cancel_mutex);
836 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
838 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
839 pthread_join(radio->scan_thread, NULL);
840 radio->scan_thread = 0;
843 MMRADIO_LOG_FLEAVE();
845 return MM_ERROR_NONE;
848 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
850 int ret = MM_ERROR_NONE;
851 uint32_t strength = 0;
852 MMRADIO_LOG_FENTER();
853 MMRADIO_CHECK_INSTANCE(radio);
855 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
857 /* just return stored frequency if radio device is not ready */
858 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
859 if (ret == MM_ERROR_NOT_SUPPORT_API) {
860 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
861 } else if (ret != MM_ERROR_NONE) {
862 debug_error("radio_hal_get_signal_strength error");
864 MMRADIO_LOG_FLEAVE();
867 *value = (int)strength;
868 MMRADIO_LOG_FLEAVE();
869 return MM_ERROR_NONE;
872 void __mmradio_scan_thread(mm_radio_t *radio)
874 int ret = MM_ERROR_NONE;
877 MMRADIO_LOG_FENTER();
878 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
880 ret = radio_hal_mute(radio->hal_inf);
882 if (ret == MM_ERROR_NOT_SUPPORT_API) {
883 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
884 } else if (ret != MM_ERROR_NONE) {
885 MMRADIO_LOG_ERROR("radio_hal_mute error");
888 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
890 if (ret != MM_ERROR_NONE)
893 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
894 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
896 while (!radio->stop_scan) {
898 MMMessageParamType param = { 0, };
900 MMRADIO_LOG_DEBUG("scanning....");
902 pthread_mutex_lock(&radio->seek_cancel_mutex);
904 if (radio->stop_scan) {
905 MMRADIO_LOG_INFO("scan was canceled");
906 pthread_mutex_unlock(&radio->seek_cancel_mutex);
910 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
912 pthread_mutex_unlock(&radio->seek_cancel_mutex);
914 if (ret != MM_ERROR_NONE) {
915 MMRADIO_LOG_ERROR("radio scanning error");
919 /* now we can get new frequency from radio device */
920 if (radio->stop_scan)
923 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
924 if (ret != MM_ERROR_NONE) {
925 MMRADIO_LOG_ERROR("failed to get current frequency");
927 if (freq <= prev_freq) {
928 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
932 prev_freq = param.radio_scan.frequency = (int)freq;
933 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
935 /* drop if max freq is scanned */
936 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
937 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
941 if (radio->stop_scan) {
942 /* doesn't need to post */
946 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
950 if (radio->old_state == MM_RADIO_STATE_READY) {
951 MMRADIO_LOG_DEBUG("old state is ready");
952 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
953 MMRADIO_LOG_DEBUG("old state is playing");
954 ret = radio_hal_unmute(radio->hal_inf);
955 if (ret == MM_ERROR_NOT_SUPPORT_API) {
956 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
957 } else if (ret != MM_ERROR_NONE) {
958 MMRADIO_LOG_ERROR("radio_hal_unmute error");
961 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
962 if (ret == MM_ERROR_NOT_SUPPORT_API) {
963 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
964 } else if (ret != MM_ERROR_NONE) {
965 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
972 radio->scan_thread = 0;
974 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
975 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
977 /* close radio device here !!!! */
978 ret = radio_hal_close(radio->hal_inf);
979 if (ret == MM_ERROR_NOT_SUPPORT_API)
980 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
981 else if (ret != MM_ERROR_NONE)
982 MMRADIO_LOG_ERROR("radio_hal_close_device error");
984 ret = radio_hal_unprepare(radio->hal_inf);
985 if (ret == MM_ERROR_NOT_SUPPORT_API)
986 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
987 else if (ret != MM_ERROR_NONE)
988 MMRADIO_LOG_ERROR("radio_hal_close_device error");
990 radio->is_ready = FALSE;
992 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
995 if (!radio->stop_scan)
996 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
998 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
1000 MMRADIO_LOG_FLEAVE();
1007 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1009 MMRADIO_LOG_FENTER();
1011 MMRADIO_CHECK_INSTANCE(radio);
1013 if (freq >= radio->region_setting.band_max
1014 || freq <= radio->region_setting.band_min)
1017 MMRADIO_LOG_FLEAVE();
1022 void __mmradio_seek_thread(mm_radio_t *radio)
1024 int ret = MM_ERROR_NONE;
1026 MMMessageParamType param = {0, };
1028 MMRADIO_LOG_FENTER();
1029 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1031 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1033 MMRADIO_LOG_DEBUG("seeking....");
1035 if (!radio->seek_cancel) {
1037 MMRADIO_LOG_DEBUG("try to seek ");
1038 pthread_mutex_lock(&radio->seek_cancel_mutex);
1039 MMRADIO_LOG_DEBUG("seek start");
1041 if (radio->seek_cancel) {
1042 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1043 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1047 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1048 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1050 MMRADIO_LOG_ERROR("radio_hal_seek failed");
1054 /* now we can get new frequency from radio device */
1055 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1057 MMRADIO_LOG_ERROR("failed to get current frequency");
1061 MMRADIO_LOG_DEBUG("found frequency");
1063 /* if same freq is found, ignore it and search next one. */
1064 if (freq == radio->prev_seek_freq) {
1065 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1069 /* check if it's limit freq or not */
1070 if (__is_tunable_frequency(radio, freq)) {
1071 /* now tune to new frequency */
1072 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1074 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1079 if (radio->seek_unmute) {
1080 /* now turn on radio
1081 * In the case of limit freq, tuner should be unmuted.
1082 * Otherwise, sound can't output even though application set new frequency.
1084 ret = radio_hal_unmute(radio->hal_inf);
1086 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1089 radio->seek_unmute = FALSE;
1092 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1093 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1094 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1097 radio->seek_thread = 0;
1098 radio->is_seeking = FALSE;
1100 MMRADIO_LOG_FLEAVE();
1107 if (radio->seek_unmute) {
1108 /* now turn on radio
1109 * In the case of limit freq, tuner should be unmuted.
1110 * Otherwise, sound can't output even though application set new frequency.
1112 ret = radio_hal_unmute(radio->hal_inf);
1114 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1115 radio->seek_unmute = FALSE;
1117 /* freq -1 means it's failed to seek */
1118 param.radio_scan.frequency = -1;
1119 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1120 radio->is_seeking = FALSE;
1125 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1127 MMRADIO_CHECK_INSTANCE(radio);
1129 MMRADIO_LOG_FENTER();
1131 if (!radio->msg_cb) {
1132 debug_warning("failed to post a message");
1136 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1138 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1140 MMRADIO_LOG_FLEAVE();
1145 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1147 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1149 MMRADIO_LOG_FENTER();
1151 MMRADIO_CHECK_INSTANCE(radio);
1153 radio_state = __mmradio_get_state(radio);
1155 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1158 case MMRADIO_COMMAND_CREATE:
1160 if (radio_state != 0)
1165 case MMRADIO_COMMAND_REALIZE:
1167 if (radio_state == MM_RADIO_STATE_READY ||
1168 radio_state == MM_RADIO_STATE_PLAYING ||
1169 radio_state == MM_RADIO_STATE_SCANNING)
1172 if (radio_state == 0)
1177 case MMRADIO_COMMAND_UNREALIZE:
1179 if (radio_state == MM_RADIO_STATE_NULL)
1182 /* we can call unrealize at any higher state */
1186 case MMRADIO_COMMAND_START:
1188 if (radio_state == MM_RADIO_STATE_PLAYING)
1191 if (radio_state != MM_RADIO_STATE_READY)
1196 case MMRADIO_COMMAND_STOP:
1198 if (radio_state == MM_RADIO_STATE_READY)
1201 if (radio_state != MM_RADIO_STATE_PLAYING)
1206 case MMRADIO_COMMAND_START_SCAN:
1208 if (radio_state == MM_RADIO_STATE_SCANNING)
1211 if (radio_state == MM_RADIO_STATE_NULL)
1216 case MMRADIO_COMMAND_STOP_SCAN:
1218 if (radio_state == MM_RADIO_STATE_READY)
1221 if (radio_state != MM_RADIO_STATE_SCANNING)
1226 case MMRADIO_COMMAND_DESTROY:
1227 case MMRADIO_COMMAND_MUTE:
1228 case MMRADIO_COMMAND_UNMUTE:
1229 case MMRADIO_COMMAND_SET_FREQ:
1230 case MMRADIO_COMMAND_GET_FREQ:
1231 case MMRADIO_COMMAND_SET_REGION:
1232 case MMRADIO_COMMAND_SET_VOLUME:
1233 case MMRADIO_COMMAND_GET_VOLUME:
1235 /* we can do it at any state */
1239 case MMRADIO_COMMAND_SEEK:
1241 if (radio_state != MM_RADIO_STATE_PLAYING)
1246 case MMRADIO_COMMAND_GET_REGION:
1248 if (radio_state == MM_RADIO_STATE_NULL)
1254 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1258 MMRADIO_LOG_DEBUG("status OK");
1260 radio->cmd = command;
1262 MMRADIO_LOG_FLEAVE();
1264 return MM_ERROR_NONE;
1267 debug_warning("invalid state. current : %d command : %d", radio_state, command);
1268 MMRADIO_LOG_FLEAVE();
1269 return MM_ERROR_RADIO_INVALID_STATE;
1272 debug_warning("mm-radio is in the desired state(%d). doing noting", radio_state);
1273 MMRADIO_LOG_FLEAVE();
1274 return MM_ERROR_RADIO_NO_OP;
1278 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1280 MMMessageParamType msg = { 0, };
1281 int msg_type = MM_MESSAGE_UNKNOWN;
1283 MMRADIO_LOG_FENTER();
1286 debug_warning("calling set_state with invalid radio handle");
1290 if (radio->current_state == new_state && radio->pending_state == 0) {
1291 debug_warning("we are in same state");
1296 radio->old_state = radio->current_state;
1297 radio->current_state = new_state;
1299 /* fill message param */
1300 msg.state.previous = radio->old_state;
1301 msg.state.current = radio->current_state;
1303 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1304 /* post message to application */
1305 switch (radio->sound_focus.by_focus_cb) {
1306 case MMRADIO_FOCUS_CB_NONE:
1308 msg_type = MM_MESSAGE_STATE_CHANGED;
1309 MMRADIO_POST_MSG(radio, msg_type, &msg);
1313 case MMRADIO_FOCUS_CB_POSTMSG:
1315 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1316 msg.union_type = MM_MSG_UNION_CODE;
1317 msg.code = radio->sound_focus.event_src;
1318 MMRADIO_POST_MSG(radio, msg_type, &msg);
1322 case MMRADIO_FOCUS_CB_SKIP_POSTMSG:
1327 msg_type = MM_MESSAGE_STATE_CHANGED;
1328 MMRADIO_POST_MSG(radio, msg_type, &msg);
1331 MMRADIO_LOG_FLEAVE();
1336 static int __mmradio_get_state(mm_radio_t *radio)
1338 MMRADIO_CHECK_INSTANCE(radio);
1340 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1341 radio->current_state, radio->old_state, radio->pending_state);
1343 return radio->current_state;
1346 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1347 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1348 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1349 const char *additional_info, void *user_data)
1351 mm_radio_t *radio = (mm_radio_t *)user_data;
1352 enum MMMessageInterruptedCode event_source;
1353 int result = MM_ERROR_NONE;
1354 int postMsg = false;
1356 MMRADIO_LOG_FENTER();
1357 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1358 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1360 mmradio_get_sound_focus_reason(focus_state, reason_for_change, FALSE, &event_source, &postMsg);
1361 radio->sound_focus.event_src = event_source;
1363 switch (focus_state) {
1364 case FOCUS_IS_RELEASED:{
1365 radio->sound_focus.cur_focus_type &= ~focus_type;
1366 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
1368 result = _mmradio_stop(radio);
1370 MMRADIO_LOG_ERROR("failed to stop radio");
1372 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1374 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1378 case FOCUS_IS_ACQUIRED:{
1379 MMMessageParamType msg = { 0, };
1380 msg.union_type = MM_MSG_UNION_CODE;
1381 msg.code = event_source;
1383 radio->sound_focus.cur_focus_type |= focus_type;
1385 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1386 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1388 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1390 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1395 MMRADIO_LOG_DEBUG("Unknown focus_state");
1399 MMRADIO_LOG_FLEAVE();
1402 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1403 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1404 const char *additional_info, void *user_data)
1406 mm_radio_t *radio = (mm_radio_t *)user_data;
1407 enum MMMessageInterruptedCode event_source;
1408 int result = MM_ERROR_NONE;
1409 int postMsg = false;
1411 MMRADIO_LOG_FENTER();
1412 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1413 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1415 mmradio_get_sound_focus_reason(focus_state, reason_for_change, TRUE, &event_source, &postMsg);
1416 radio->sound_focus.event_src = event_source;
1418 switch (focus_state) {
1419 case FOCUS_IS_ACQUIRED: {
1420 radio->sound_focus.cur_focus_type &= ~focus_type;
1421 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
1423 result = _mmradio_stop(radio);
1425 MMRADIO_LOG_ERROR("failed to stop radio");
1426 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1428 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1432 case FOCUS_IS_RELEASED: {
1433 MMMessageParamType msg = { 0, };
1434 msg.union_type = MM_MSG_UNION_CODE;
1435 msg.code = event_source;
1437 radio->sound_focus.cur_focus_type |= focus_type;
1439 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1440 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1442 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
1444 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1449 MMRADIO_LOG_DEBUG("Unknown focus_state");
1453 MMRADIO_LOG_FLEAVE();
1457 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1459 mm_radio_t *radio = (mm_radio_t *)user_data;
1460 int ret = MM_ERROR_NONE;
1461 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1462 if (type == VOLUME_TYPE_MEDIA) {
1463 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1464 ret = __mmradio_set_media_volume(radio, volume);
1465 if (ret != MM_ERROR_NONE)
1466 MMRADIO_LOG_ERROR("__mmradio_set_media_volume error");
1471 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1473 MMRADIO_LOG_FENTER();
1474 MMRADIO_CHECK_INSTANCE(radio);
1475 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1477 return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT);
1479 *type = radio->region_setting.country;
1481 MMRADIO_LOG_FLEAVE();
1482 return MM_ERROR_NONE;
1485 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1487 MMRADIO_LOG_FENTER();
1488 MMRADIO_CHECK_INSTANCE(radio);
1489 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1491 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1493 *min_freq = radio->region_setting.band_min;
1494 *max_freq = radio->region_setting.band_max;
1496 MMRADIO_LOG_FLEAVE();
1497 return MM_ERROR_NONE;
1500 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1502 MMRADIO_LOG_FENTER();
1503 MMRADIO_CHECK_INSTANCE(radio);
1504 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1506 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1508 *ch_spacing = radio->region_setting.channel_spacing;
1510 MMRADIO_LOG_FLEAVE();
1511 return MM_ERROR_NONE;
1514 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1516 int ret = MM_ERROR_NONE;
1518 MMRADIO_LOG_FENTER();
1520 MMRADIO_CHECK_INSTANCE(radio);
1521 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1523 MMRADIO_LOG_INFO("Setting %f volume", volume);
1525 MMRADIO_VOLUME_LOCK(radio);
1526 radio->local_volume = volume;
1527 MMRADIO_VOLUME_UNLOCK(radio);
1529 ret = radio_hal_set_volume(radio->hal_inf, volume);
1530 if (ret != MM_ERROR_NONE)
1531 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1533 MMRADIO_LOG_FLEAVE();
1538 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1540 int ret = MM_ERROR_NONE;
1542 MMRADIO_LOG_FENTER();
1544 MMRADIO_CHECK_INSTANCE(radio);
1545 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1547 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1549 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1550 if (ret != MM_ERROR_NONE) {
1551 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1556 MMRADIO_VOLUME_LOCK(radio);
1557 radio->local_volume = volume;
1558 *pVolume = (float)radio->local_volume;
1559 MMRADIO_VOLUME_UNLOCK(radio);
1561 MMRADIO_LOG_FLEAVE();
1566 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1568 int ret = MM_ERROR_NONE;
1570 MMRADIO_LOG_FENTER();
1572 MMRADIO_CHECK_INSTANCE(radio);
1573 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1575 MMRADIO_LOG_INFO("Setting %d volume", level);
1577 MMRADIO_VOLUME_LOCK(radio);
1578 radio->media_volume = level;
1579 MMRADIO_VOLUME_UNLOCK(radio);
1581 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1582 if (ret != MM_ERROR_NONE)
1583 MMRADIO_LOG_ERROR("radio_hal_set_media_volume error");
1585 MMRADIO_LOG_FLEAVE();