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>
37 #include <mm_message.h>
40 #include "mm_radio_priv_hal.h"
42 /*===========================================================================================
43 LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
44 ========================================================================================== */
45 /*---------------------------------------------------------------------------
46 GLOBAL CONSTANT DEFINITIONS:
47 ---------------------------------------------------------------------------*/
49 /*---------------------------------------------------------------------------
50 IMPORTED VARIABLE DECLARATIONS:
51 ---------------------------------------------------------------------------*/
53 /*---------------------------------------------------------------------------
54 IMPORTED FUNCTION DECLARATIONS:
55 ---------------------------------------------------------------------------*/
57 /*---------------------------------------------------------------------------
59 ---------------------------------------------------------------------------*/
60 #define DEFAULT_DEVICE "/dev/radio0"
63 #define DEFAULT_FREQ 107700
66 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
67 #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
68 /* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
69 #define DEFAULT_WRAP_AROUND 1
71 #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
72 #define READ_MAX_BUFFER_SIZE 1024
73 #define DEFAULT_MAX_MEDIA_VOLUME 15
74 /*---------------------------------------------------------------------------
75 LOCAL CONSTANT DEFINITIONS:
76 ---------------------------------------------------------------------------*/
78 /*---------------------------------------------------------------------------
79 LOCAL DATA TYPE DEFINITIONS:
80 ---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------
83 GLOBAL VARIABLE DEFINITIONS:
84 ---------------------------------------------------------------------------*/
87 /*---------------------------------------------------------------------------
88 LOCAL VARIABLE DEFINITIONS:
89 ---------------------------------------------------------------------------*/
90 /* radio region configuration table */
91 static const MMRadioRegion_t region_table[] = {
92 { /* Notrh America, South America, South Korea, Taiwan, Australia */
93 MM_RADIO_REGION_GROUP_USA, /* region type */
94 MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
95 MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
96 MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
99 { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
100 MM_RADIO_REGION_GROUP_EUROPE,
101 MM_RADIO_DEEMPHASIS_50_US,
102 MM_RADIO_FREQ_MIN_87500_KHZ,
103 MM_RADIO_FREQ_MAX_108000_KHZ,
107 MM_RADIO_REGION_GROUP_JAPAN,
108 MM_RADIO_DEEMPHASIS_50_US,
109 MM_RADIO_FREQ_MIN_76100_KHZ,
110 MM_RADIO_FREQ_MAX_89900_KHZ,
115 /*---------------------------------------------------------------------------
116 LOCAL FUNCTION PROTOTYPES:
117 ---------------------------------------------------------------------------*/
118 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
119 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
120 static int __mmradio_get_state(mm_radio_t *radio);
121 static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
122 void _mmradio_seek_cancel(mm_radio_t *radio);
123 static void __mmradio_seek_thread(mm_radio_t *radio);
124 static void __mmradio_scan_thread(mm_radio_t *radio);
125 static bool __is_tunable_frequency(mm_radio_t *radio, int freq);
127 #ifdef TIZEN_FEATURE_SOUND_FOCUS
128 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
129 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
130 const char *additional_info, void *user_data);
131 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
132 mm_sound_focus_state_e focus_state, const char *reason_for_change,
133 const char *additional_info, void *user_data);
136 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data);
137 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level);
139 int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
141 int ret = MM_ERROR_NONE;
145 MMRADIO_LOG_FENTER();
147 MMRADIO_CHECK_INSTANCE(radio);
148 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
150 /* if needed, radio region must be updated.
151 * Otherwise, just applying settings to device without it.
154 count = ARRAY_SIZE(region_table);
156 /* TODO: if auto is supported...get the region info. here */
158 /* update radio region settings */
159 for (index = 0; index < count; index++) {
160 /* find the region from pre-defined table */
161 if (region_table[index].country == region) {
162 radio->region_setting.country = region_table[index].country;
163 radio->region_setting.deemphasis = region_table[index].deemphasis;
164 radio->region_setting.band_min = region_table[index].band_min;
165 radio->region_setting.band_max = region_table[index].band_max;
166 radio->region_setting.channel_spacing = region_table[index].channel_spacing;
171 MMRADIO_LOG_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
172 radio->region_setting.country, radio->region_setting.deemphasis,
173 radio->region_setting.band_min, radio->region_setting.band_max);
175 MMRADIO_LOG_FLEAVE();
180 int _mmradio_create_radio(mm_radio_t *radio)
182 int ret = MM_ERROR_NONE;
184 MMRADIO_LOG_FENTER();
186 MMRADIO_CHECK_INSTANCE(radio);
187 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
189 /* set default value */
190 radio->freq = DEFAULT_FREQ;
191 #ifdef TIZEN_FEATURE_SOUND_FOCUS
192 memset(&radio->sound_focus, 0, sizeof(mm_radio_sound_focus));
194 memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
195 radio->local_volume = 1.0;
197 /* create command lock */
198 ret = pthread_mutex_init(&radio->cmd_lock, NULL);
200 MMRADIO_LOG_ERROR("mutex creation failed");
201 return MM_ERROR_RADIO_INTERNAL;
204 ret = pthread_mutex_init(&radio->volume_lock, NULL);
206 MMRADIO_LOG_ERROR("volume mutex creation failed");
207 return MM_ERROR_RADIO_INTERNAL;
210 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
212 /* initialize resource manager */
213 ret = mmradio_resource_manager_init(&radio->resource_manager, radio);
215 MMRADIO_LOG_ERROR("failed to initialize resource manager\n");
216 return MM_ERROR_RADIO_INTERNAL;
219 #ifdef TIZEN_FEATURE_SOUND_FOCUS
220 ret = mmradio_sound_focus_register(&radio->sound_focus,
221 (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb,
222 (mm_sound_focus_changed_watch_cb)__mmradio_sound_focus_watch_cb,
226 /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
227 MMRADIO_LOG_ERROR("mmradio_audio_focus_register is failed");
228 return MM_ERROR_RADIO_INTERNAL;
232 ret = radio_hal_interface_init(&(radio->hal_inf));
234 MMRADIO_LOG_ERROR("mmradio hal interface init failed");
238 MMRADIO_LOG_FLEAVE();
240 return MM_ERROR_NONE;
243 int _mmradio_realize(mm_radio_t *radio)
245 int ret = MM_ERROR_NONE;
249 MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
251 MMRADIO_LOG_FENTER();
253 MMRADIO_CHECK_INSTANCE(radio);
254 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
256 ret = pthread_mutex_init(&radio->seek_cancel_mutex, NULL);
258 MMRADIO_LOG_ERROR("Mutex creation failed %d", ret);
259 return MM_ERROR_RADIO_INTERNAL;
262 if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
263 /* not initialized yet. set it with default region */
264 region = RADIO_DEFAULT_REGION;
267 /* already initialized by application */
268 region = radio->region_setting.country;
271 ret = _mmradio_apply_region(radio, region, update);
273 ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO);
274 if (ret != MM_ERROR_NONE) {
275 MMRADIO_LOG_ERROR("resource manager prepare fail");
276 return MM_ERROR_RADIO_INTERNAL;
279 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
280 ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
281 if (ret != MM_ERROR_NONE) {
282 MMRADIO_LOG_ERROR("sound_manager_create_stream_information_internal error");
283 MMRADIO_LOG_FLEAVE();
286 ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
287 if (ret != MM_ERROR_NONE) {
288 MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
289 MMRADIO_LOG_FLEAVE();
294 ret = sound_manager_get_max_volume(SOUND_TYPE_MEDIA, &max);
295 if (ret != MM_ERROR_NONE) {
296 MMRADIO_LOG_WARNING("sound_manager_get_max_volume error");
297 radio->max_media_volume = DEFAULT_MAX_MEDIA_VOLUME;
299 radio->max_media_volume = max;
302 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
304 if (ret != MM_ERROR_NONE)
305 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
307 MMRADIO_VOLUME_LOCK(radio);
308 radio->media_volume = volume;
309 MMRADIO_VOLUME_UNLOCK(radio);
311 ret = mm_sound_add_volume_changed_callback(__mmradio_volume_changed_cb, (void *)radio, &radio->volume_subs_id);
312 if (ret != MM_ERROR_NONE)
313 MMRADIO_LOG_WARNING("mm_sound_add_volume_changed_callback error");
315 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
317 MMRADIO_LOG_FLEAVE();
319 return MM_ERROR_NONE;
322 int _mmradio_unrealize(mm_radio_t *radio)
324 int ret = MM_ERROR_NONE;
326 MMRADIO_LOG_FENTER();
328 MMRADIO_CHECK_INSTANCE(radio);
329 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
331 ret = mm_sound_remove_volume_changed_callback(radio->volume_subs_id);
332 if (ret != MM_ERROR_NONE)
333 MMRADIO_LOG_WARNING("mm_sound_remove_volume_changed_callback error");
335 /*Finish if there are scans*/
336 _mmradio_stop_scan(radio);
338 /*Stop radio if started*/
339 _mmradio_stop(radio);
341 /* close radio device here !!!! */
342 radio_hal_close(radio->hal_inf);
343 radio_hal_unprepare(radio->hal_inf);
344 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
345 sound_manager_destroy_virtual_stream(radio->vstream);
346 sound_manager_destroy_stream_information(radio->stream_info);
348 mmradio_resource_manager_unprepare(&radio->resource_manager);
349 if (ret != MM_ERROR_NONE)
350 MMRADIO_LOG_ERROR("resource manager unprepare fail");
352 pthread_mutex_destroy(&radio->seek_cancel_mutex);
354 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
356 MMRADIO_LOG_FLEAVE();
361 int _mmradio_destroy(mm_radio_t *radio)
363 int ret = MM_ERROR_NONE;
364 MMRADIO_LOG_FENTER();
366 MMRADIO_CHECK_INSTANCE(radio);
367 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
369 _mmradio_unrealize(radio);
371 ret = radio_hal_interface_deinit(radio->hal_inf);
373 MMRADIO_LOG_ERROR("mmradio hal interface deinit failed");
377 /* destroy command lock */
378 ret = pthread_mutex_destroy(&radio->cmd_lock);
380 MMRADIO_LOG_ERROR("mutex destroy failed\n");
383 ret = pthread_mutex_destroy(&radio->volume_lock);
385 MMRADIO_LOG_ERROR("volume mutex destroy failed\n");
388 #ifdef TIZEN_FEATURE_SOUND_FOCUS
389 ret = mmradio_sound_focus_deregister(&radio->sound_focus);
391 MMRADIO_LOG_ERROR("failed to deregister sound focus");
392 return MM_ERROR_RADIO_INTERNAL;
396 ret = mmradio_resource_manager_deinit(&radio->resource_manager);
398 MMRADIO_LOG_ERROR("failed to initialize resource manager\n");
399 return MM_ERROR_RADIO_INTERNAL;
402 MMRADIO_LOG_FLEAVE();
404 return MM_ERROR_NONE;
407 /* unit should be KHz */
408 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
410 int ret = MM_ERROR_NONE;
412 MMRADIO_LOG_FENTER();
414 MMRADIO_CHECK_INSTANCE(radio);
415 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
417 MMRADIO_LOG_INFO("Setting %d frequency", freq);
421 ret = radio_hal_set_frequency(radio->hal_inf, freq);
422 if (ret != MM_ERROR_NONE) {
423 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
424 MMRADIO_LOG_FLEAVE();
428 MMRADIO_LOG_FLEAVE();
434 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
436 int ret = MM_ERROR_NONE;
438 MMRADIO_LOG_FENTER();
440 MMRADIO_CHECK_INSTANCE(radio);
441 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
443 return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
445 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
446 if (ret != MM_ERROR_NONE) {
447 MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
452 /* update freq in handle */
453 MMRADIO_LOG_INFO("Updating %d frequency", freq);
456 *pFreq = (int)radio->freq;
458 MMRADIO_LOG_FLEAVE();
463 int _mmradio_mute(mm_radio_t *radio)
465 int ret = MM_ERROR_NONE;
466 MMRADIO_LOG_FENTER();
468 MMRADIO_CHECK_INSTANCE(radio);
469 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
471 ret = radio_hal_mute(radio->hal_inf);
472 if (ret == MM_ERROR_NOT_SUPPORT_API) {
473 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
474 } else if (ret != MM_ERROR_NONE) {
475 MMRADIO_LOG_ERROR("radio_hal_mute error");
476 MMRADIO_LOG_FLEAVE();
480 radio->is_muted = TRUE;
481 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
482 MMRADIO_LOG_FLEAVE();
487 int _mmradio_unmute(mm_radio_t *radio)
489 int ret = MM_ERROR_NONE;
490 MMRADIO_LOG_FENTER();
492 MMRADIO_CHECK_INSTANCE(radio);
493 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
495 ret = radio_hal_unmute(radio->hal_inf);
496 if (ret == MM_ERROR_NOT_SUPPORT_API) {
497 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
498 } else if (ret != MM_ERROR_NONE) {
499 MMRADIO_LOG_ERROR("radio_hal_unmute error");
500 MMRADIO_LOG_FLEAVE();
504 radio->is_muted = FALSE;
505 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
506 MMRADIO_LOG_FLEAVE();
511 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
513 MMRADIO_LOG_FENTER();
515 MMRADIO_CHECK_INSTANCE(radio);
517 radio->msg_cb = callback;
518 radio->msg_cb_param = user_param;
520 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x", callback, user_param);
522 MMRADIO_LOG_FLEAVE();
524 return MM_ERROR_NONE;
527 int _mmradio_get_state(mm_radio_t *radio, int *pState)
531 MMRADIO_LOG_FENTER();
533 MMRADIO_CHECK_INSTANCE(radio);
534 return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT);
536 state = __mmradio_get_state(radio);
540 MMRADIO_LOG_FLEAVE();
542 return MM_ERROR_NONE;
545 int _mmradio_start(mm_radio_t *radio)
547 int ret = MM_ERROR_NONE;
548 unsigned int volume = 0;
550 MMRADIO_LOG_FENTER();
552 MMRADIO_CHECK_INSTANCE(radio);
553 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
555 MMRADIO_LOG_INFO("now tune to frequency : %d", radio->freq);
557 #ifdef TIZEN_FEATURE_SOUND_FOCUS
558 if (radio->sound_focus.handle > 0) {
559 ret = mmradio_acquire_sound_focus(&radio->sound_focus);
560 if (ret != MM_ERROR_NONE) {
561 MMRADIO_LOG_ERROR("failed to set sound focus");
567 if (!radio->is_ready) {
568 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
569 if (ret != MM_ERROR_NONE) {
570 MMRADIO_LOG_ERROR("failed to acquire resource manager");
573 ret = radio_hal_prepare(radio->hal_inf);
574 if (ret == MM_ERROR_NOT_SUPPORT_API) {
575 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
576 } else if (ret != MM_ERROR_NONE) {
577 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
581 ret = radio_hal_open(radio->hal_inf);
582 if (ret == MM_ERROR_NOT_SUPPORT_API) {
583 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
584 } else if (ret != MM_ERROR_NONE) {
585 MMRADIO_LOG_ERROR("radio_hal_init error");
588 radio->is_ready = TRUE;
590 MMRADIO_LOG_DEBUG("radio prepared and opened");
593 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
594 if (ret != MM_ERROR_NONE)
595 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
597 ret = __mmradio_set_media_volume(radio, volume);
598 if (ret != MM_ERROR_NONE) {
599 MMRADIO_LOG_ERROR("failed to media volume");
603 ret = radio_hal_start(radio->hal_inf);
604 if (ret == MM_ERROR_NOT_SUPPORT_API) {
605 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
607 MMRADIO_LOG_ERROR("failed to radio_hal_start");
611 /* set stored frequency */
612 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
614 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency");
618 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
619 ret = sound_manager_start_virtual_stream(radio->vstream);
621 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream");
626 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
628 MMRADIO_LOG_FLEAVE();
630 return MM_ERROR_NONE;
632 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
634 sound_manager_stop_virtual_stream(radio->vstream);
637 radio_hal_close(radio->hal_inf);
639 radio_hal_unprepare(radio->hal_inf);
640 radio->is_ready = FALSE;
644 int _mmradio_stop(mm_radio_t *radio)
646 int ret = MM_ERROR_NONE;
648 MMRADIO_LOG_FENTER();
650 MMRADIO_CHECK_INSTANCE(radio);
651 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
653 radio->seek_unmute = FALSE;
654 /*cancel if any seek*/
655 _mmradio_seek_cancel(radio);
656 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
657 ret = sound_manager_stop_virtual_stream(radio->vstream);
658 if (ret != MM_ERROR_NONE) {
659 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
664 ret = radio_hal_stop(radio->hal_inf);
665 if (ret == MM_ERROR_NOT_SUPPORT_API) {
666 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
668 MMRADIO_LOG_ERROR("failed to radio_hal_stop");
672 /* close radio device here !!!! */
673 ret = radio_hal_close(radio->hal_inf);
674 if (ret == MM_ERROR_NOT_SUPPORT_API) {
675 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
676 } else if (ret != MM_ERROR_NONE) {
677 MMRADIO_LOG_ERROR("radio_hal_close_device error");
681 ret = radio_hal_unprepare(radio->hal_inf);
682 if (ret == MM_ERROR_NOT_SUPPORT_API) {
683 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
684 } else if (ret != MM_ERROR_NONE) {
685 MMRADIO_LOG_ERROR("radio_hal_close_device error");
689 radio->is_ready = FALSE;
691 ret = mmradio_resource_manager_release(&radio->resource_manager);
692 if (ret != MM_ERROR_NONE) {
693 MMRADIO_LOG_ERROR("failed to release resource");
697 #ifdef TIZEN_FEATURE_SOUND_FOCUS
698 if (radio->sound_focus.handle > 0) {
699 ret = mmradio_release_sound_focus(&radio->sound_focus);
701 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed");
706 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
708 MMRADIO_LOG_FLEAVE();
710 return MM_ERROR_NONE;
713 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
715 int ret = MM_ERROR_NONE;
717 MMRADIO_LOG_FENTER();
719 MMRADIO_CHECK_INSTANCE(radio);
720 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
722 if (radio->is_seeking) {
723 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
724 return MM_ERROR_RADIO_INTERNAL;
727 radio->seek_unmute = FALSE;
728 radio->is_seeking = TRUE;
729 radio->seek_cancel = FALSE;
731 if (!radio->is_muted) {
732 ret = radio_hal_mute(radio->hal_inf);
733 if (ret == MM_ERROR_NOT_SUPPORT_API) {
734 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
736 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
739 radio->seek_unmute = TRUE;
742 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
743 radio->seek_direction = direction;
745 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
748 MMRADIO_LOG_DEBUG("failed create thread");
749 radio->is_seeking = FALSE;
750 radio->seek_cancel = TRUE;
751 if (radio->seek_unmute) {
752 ret = radio_hal_mute(radio->hal_inf);
753 if (ret == MM_ERROR_NOT_SUPPORT_API) {
754 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
756 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
757 radio->seek_unmute = FALSE;
761 return MM_ERROR_RADIO_INTERNAL;
764 MMRADIO_LOG_FLEAVE();
766 return MM_ERROR_NONE;
769 void _mmradio_seek_cancel(mm_radio_t *radio)
771 int ret = MM_ERROR_NONE;
772 char str_error[READ_MAX_BUFFER_SIZE];
773 MMRADIO_LOG_FENTER();
775 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
777 /*cancel any outstanding seek request*/
778 radio->seek_cancel = TRUE;
779 if (radio->seek_thread) {
780 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
781 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
782 if (ret == EBUSY) { /* it was already locked by other */
783 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
784 } else if (ret == 0) {
785 MMRADIO_LOG_INFO("trylock is successful. unlock now");
786 pthread_mutex_unlock(&radio->seek_cancel_mutex);
788 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
790 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
791 pthread_join(radio->seek_thread, NULL);
792 MMRADIO_LOG_DEBUG("done");
793 radio->is_seeking = FALSE;
794 radio->seek_thread = 0;
796 MMRADIO_LOG_FLEAVE();
800 int _mmradio_start_scan(mm_radio_t *radio)
802 int ret = MM_ERROR_NONE;
804 MMRADIO_LOG_FENTER();
806 MMRADIO_CHECK_INSTANCE(radio);
807 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
811 radio->stop_scan = false;
813 if (!radio->is_ready) {
814 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
815 if (ret != MM_ERROR_NONE) {
816 MMRADIO_LOG_ERROR("failed to acquire resource manager");
820 ret = radio_hal_prepare(radio->hal_inf);
821 if (ret == MM_ERROR_NOT_SUPPORT_API) {
822 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
823 } else if (ret != MM_ERROR_NONE) {
824 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
828 ret = radio_hal_open(radio->hal_inf);
829 if (ret == MM_ERROR_NOT_SUPPORT_API) {
830 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
831 } else if (ret != MM_ERROR_NONE) {
832 MMRADIO_LOG_ERROR("radio_hal_init error");
833 MMRADIO_LOG_FLEAVE();
836 radio->is_ready = TRUE;
838 MMRADIO_LOG_DEBUG("radio prepared and opened");
841 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
843 if (scan_tr_id != 0) {
844 MMRADIO_LOG_ERROR("failed to create thread : scan");
845 return MM_ERROR_RADIO_NOT_INITIALIZED;
848 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
850 MMRADIO_LOG_FLEAVE();
852 return MM_ERROR_NONE;
855 int _mmradio_stop_scan(mm_radio_t *radio)
858 char str_error[READ_MAX_BUFFER_SIZE];
859 MMRADIO_LOG_FENTER();
861 MMRADIO_CHECK_INSTANCE(radio);
862 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
864 radio->stop_scan = true;
866 if (radio->scan_thread > 0) {
867 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
868 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
869 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
870 if (ret == EBUSY) { /* it was already locked by other */
871 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
872 } else if (ret == 0) {
873 MMRADIO_LOG_INFO("trylock is successful. unlock now");
874 pthread_mutex_unlock(&radio->seek_cancel_mutex);
876 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
878 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
879 pthread_join(radio->scan_thread, NULL);
880 radio->scan_thread = 0;
883 MMRADIO_LOG_FLEAVE();
885 return MM_ERROR_NONE;
888 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
890 int ret = MM_ERROR_NONE;
891 int32_t strength = 0;
892 MMRADIO_LOG_FENTER();
893 MMRADIO_CHECK_INSTANCE(radio);
895 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
897 /* just return stored frequency if radio device is not ready */
898 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
899 if (ret == MM_ERROR_NOT_SUPPORT_API) {
900 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
901 } else if (ret != MM_ERROR_NONE) {
902 MMRADIO_LOG_ERROR("radio_hal_get_signal_strength error");
904 MMRADIO_LOG_FLEAVE();
907 *value = (int)strength;
908 MMRADIO_LOG_FLEAVE();
909 return MM_ERROR_NONE;
912 void __mmradio_scan_thread(mm_radio_t *radio)
914 int ret = MM_ERROR_NONE;
917 MMRADIO_LOG_FENTER();
918 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
920 ret = radio_hal_mute(radio->hal_inf);
922 if (ret == MM_ERROR_NOT_SUPPORT_API) {
923 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
924 } else if (ret != MM_ERROR_NONE) {
925 MMRADIO_LOG_ERROR("radio_hal_mute error");
928 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
930 if (ret != MM_ERROR_NONE)
933 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
934 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
936 while (!radio->stop_scan) {
938 MMMessageParamType param = { 0, };
940 MMRADIO_LOG_DEBUG("scanning....");
942 pthread_mutex_lock(&radio->seek_cancel_mutex);
944 if (radio->stop_scan) {
945 MMRADIO_LOG_INFO("scan was canceled");
946 pthread_mutex_unlock(&radio->seek_cancel_mutex);
950 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
952 pthread_mutex_unlock(&radio->seek_cancel_mutex);
954 if (ret != MM_ERROR_NONE) {
955 MMRADIO_LOG_ERROR("radio scanning error");
959 /* now we can get new frequency from radio device */
960 if (radio->stop_scan)
963 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
964 if (ret != MM_ERROR_NONE) {
965 MMRADIO_LOG_ERROR("failed to get current frequency");
967 if (freq <= prev_freq) {
968 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
972 prev_freq = param.radio_scan.frequency = (int)freq;
973 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
975 /* drop if max freq is scanned */
976 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
977 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
981 if (radio->stop_scan) {
982 /* doesn't need to post */
986 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
990 if (radio->old_state == MM_RADIO_STATE_READY) {
991 MMRADIO_LOG_DEBUG("old state is ready");
992 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
993 MMRADIO_LOG_DEBUG("old state is playing");
994 ret = radio_hal_unmute(radio->hal_inf);
995 if (ret == MM_ERROR_NOT_SUPPORT_API) {
996 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
997 } else if (ret != MM_ERROR_NONE) {
998 MMRADIO_LOG_ERROR("radio_hal_unmute error");
1001 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
1002 if (ret == MM_ERROR_NOT_SUPPORT_API) {
1003 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
1004 } else if (ret != MM_ERROR_NONE) {
1005 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
1012 radio->scan_thread = 0;
1014 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
1015 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
1017 /* close radio device here !!!! */
1018 ret = radio_hal_close(radio->hal_inf);
1019 if (ret == MM_ERROR_NOT_SUPPORT_API)
1020 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
1021 else if (ret != MM_ERROR_NONE)
1022 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1024 ret = radio_hal_unprepare(radio->hal_inf);
1025 if (ret == MM_ERROR_NOT_SUPPORT_API)
1026 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
1027 else if (ret != MM_ERROR_NONE)
1028 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1030 radio->is_ready = FALSE;
1032 ret = mmradio_resource_manager_release(&radio->resource_manager);
1033 if (ret != MM_ERROR_NONE)
1034 MMRADIO_LOG_ERROR("failed to release resource");
1036 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
1039 if (!radio->stop_scan)
1040 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
1042 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
1044 MMRADIO_LOG_FLEAVE();
1051 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1053 MMRADIO_LOG_FENTER();
1055 MMRADIO_CHECK_INSTANCE(radio);
1057 if (freq >= radio->region_setting.band_max
1058 || freq <= radio->region_setting.band_min)
1061 MMRADIO_LOG_FLEAVE();
1066 void __mmradio_seek_thread(mm_radio_t *radio)
1068 int ret = MM_ERROR_NONE;
1070 MMMessageParamType param = {0, };
1072 MMRADIO_LOG_FENTER();
1073 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1075 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1077 MMRADIO_LOG_DEBUG("seeking....");
1079 if (!radio->seek_cancel) {
1081 MMRADIO_LOG_DEBUG("try to seek ");
1082 pthread_mutex_lock(&radio->seek_cancel_mutex);
1083 MMRADIO_LOG_DEBUG("seek start");
1085 if (radio->seek_cancel) {
1086 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1087 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1091 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1092 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1094 MMRADIO_LOG_ERROR("radio_hal_seek failed");
1098 /* now we can get new frequency from radio device */
1099 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1101 MMRADIO_LOG_ERROR("failed to get current frequency");
1105 MMRADIO_LOG_DEBUG("found frequency");
1107 /* if same freq is found, ignore it and search next one. */
1108 if (freq == radio->prev_seek_freq) {
1109 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1113 /* check if it's limit freq or not */
1114 if (__is_tunable_frequency(radio, freq)) {
1115 /* now tune to new frequency */
1116 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1118 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1121 radio->freq = (int)freq;
1122 MMRADIO_LOG_WARNING("setting frequency : [%d]", radio->freq);
1125 if (radio->seek_unmute) {
1126 /* now turn on radio
1127 * In the case of limit freq, tuner should be unmuted.
1128 * Otherwise, sound can't output even though application set new frequency.
1130 ret = radio_hal_unmute(radio->hal_inf);
1132 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1135 radio->seek_unmute = FALSE;
1138 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1139 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1140 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1143 radio->seek_thread = 0;
1144 radio->is_seeking = FALSE;
1146 MMRADIO_LOG_FLEAVE();
1153 if (radio->seek_unmute) {
1154 /* now turn on radio
1155 * In the case of limit freq, tuner should be unmuted.
1156 * Otherwise, sound can't output even though application set new frequency.
1158 ret = radio_hal_unmute(radio->hal_inf);
1160 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1161 radio->seek_unmute = FALSE;
1163 /* freq -1 means it's failed to seek */
1164 param.radio_scan.frequency = -1;
1165 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1166 radio->is_seeking = FALSE;
1167 radio->seek_thread = 0;
1172 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1174 MMRADIO_CHECK_INSTANCE(radio);
1176 MMRADIO_LOG_FENTER();
1178 if (!radio->msg_cb) {
1179 MMRADIO_LOG_WARNING("failed to post a message");
1183 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1185 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1187 MMRADIO_LOG_FLEAVE();
1192 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1194 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1196 MMRADIO_LOG_FENTER();
1198 MMRADIO_CHECK_INSTANCE(radio);
1200 radio_state = __mmradio_get_state(radio);
1202 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1205 case MMRADIO_COMMAND_CREATE:
1207 if (radio_state != 0)
1212 case MMRADIO_COMMAND_REALIZE:
1214 if (radio_state == MM_RADIO_STATE_READY ||
1215 radio_state == MM_RADIO_STATE_PLAYING ||
1216 radio_state == MM_RADIO_STATE_SCANNING)
1219 if (radio_state == 0)
1224 case MMRADIO_COMMAND_UNREALIZE:
1226 if (radio_state == MM_RADIO_STATE_NULL)
1229 /* we can call unrealize at any higher state */
1233 case MMRADIO_COMMAND_START:
1235 if (radio_state == MM_RADIO_STATE_PLAYING)
1238 if (radio_state != MM_RADIO_STATE_READY)
1243 case MMRADIO_COMMAND_STOP:
1245 if (radio_state == MM_RADIO_STATE_READY)
1248 if (radio_state != MM_RADIO_STATE_PLAYING)
1253 case MMRADIO_COMMAND_START_SCAN:
1255 if (radio_state == MM_RADIO_STATE_SCANNING)
1258 if (radio_state == MM_RADIO_STATE_NULL)
1263 case MMRADIO_COMMAND_STOP_SCAN:
1265 if (radio_state == MM_RADIO_STATE_READY)
1268 if (radio_state != MM_RADIO_STATE_SCANNING)
1273 case MMRADIO_COMMAND_DESTROY:
1274 case MMRADIO_COMMAND_MUTE:
1275 case MMRADIO_COMMAND_UNMUTE:
1276 case MMRADIO_COMMAND_SET_FREQ:
1277 case MMRADIO_COMMAND_GET_FREQ:
1278 case MMRADIO_COMMAND_SET_REGION:
1279 case MMRADIO_COMMAND_SET_VOLUME:
1280 case MMRADIO_COMMAND_GET_VOLUME:
1282 /* we can do it at any state */
1286 case MMRADIO_COMMAND_SEEK:
1288 if (radio_state != MM_RADIO_STATE_PLAYING)
1293 case MMRADIO_COMMAND_GET_REGION:
1295 if (radio_state == MM_RADIO_STATE_NULL)
1301 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1305 MMRADIO_LOG_DEBUG("status OK");
1307 radio->cmd = command;
1309 MMRADIO_LOG_FLEAVE();
1311 return MM_ERROR_NONE;
1314 MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
1315 MMRADIO_LOG_FLEAVE();
1316 return MM_ERROR_RADIO_INVALID_STATE;
1319 MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
1320 MMRADIO_LOG_FLEAVE();
1321 return MM_ERROR_RADIO_NO_OP;
1325 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1327 MMMessageParamType msg = { 0, };
1328 int msg_type = MM_MESSAGE_UNKNOWN;
1330 MMRADIO_LOG_FENTER();
1333 MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
1337 if (radio->current_state == new_state && radio->pending_state == 0) {
1338 MMRADIO_LOG_WARNING("we are in same state");
1343 radio->old_state = radio->current_state;
1344 radio->current_state = new_state;
1346 /* fill message param */
1347 msg.state.previous = radio->old_state;
1348 msg.state.current = radio->current_state;
1350 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1351 /* post message to application */
1352 if (radio->sound_focus.by_focus_cb) {
1353 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1354 msg.union_type = MM_MSG_UNION_CODE;
1355 msg.code = radio->sound_focus.event_src;
1356 MMRADIO_POST_MSG(radio, msg_type, &msg);
1357 } else if (radio->resource_manager.by_rm_cb) {
1358 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1359 msg.union_type = MM_MSG_UNION_CODE;
1360 msg.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1361 MMRADIO_POST_MSG(radio, msg_type, &msg);
1363 msg_type = MM_MESSAGE_STATE_CHANGED;
1364 MMRADIO_POST_MSG(radio, msg_type, &msg);
1367 if (radio->resource_manager.by_rm_cb) {
1368 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1369 msg.union_type = MM_MSG_UNION_CODE;
1370 msg.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1371 MMRADIO_POST_MSG(radio, msg_type, &msg);
1373 msg_type = MM_MESSAGE_STATE_CHANGED;
1374 MMRADIO_POST_MSG(radio, msg_type, &msg);
1379 MMRADIO_LOG_FLEAVE();
1384 static int __mmradio_get_state(mm_radio_t *radio)
1386 MMRADIO_CHECK_INSTANCE(radio);
1388 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1389 radio->current_state, radio->old_state, radio->pending_state);
1391 return radio->current_state;
1394 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1395 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1396 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1397 const char *additional_info, void *user_data)
1399 mm_radio_t *radio = (mm_radio_t *)user_data;
1400 enum MMMessageInterruptedCode event_source;
1401 int result = MM_ERROR_NONE;
1402 int postMsg = false;
1404 MMRADIO_LOG_FENTER();
1405 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1406 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1408 mmradio_get_sound_focus_reason(focus_state, reason_for_change, FALSE, &event_source, &postMsg);
1409 radio->sound_focus.event_src = event_source;
1411 switch (focus_state) {
1412 case FOCUS_IS_RELEASED:{
1413 radio->sound_focus.cur_focus_type &= ~focus_type;
1414 radio->sound_focus.by_focus_cb = true;
1416 MMRADIO_CMD_LOCK(radio);
1417 result = _mmradio_stop(radio);
1419 MMRADIO_LOG_ERROR("failed to stop radio");
1420 MMRADIO_CMD_UNLOCK(radio);
1422 radio->sound_focus.by_focus_cb = false;
1424 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1428 case FOCUS_IS_ACQUIRED:{
1429 MMMessageParamType msg = { 0, };
1430 msg.union_type = MM_MSG_UNION_CODE;
1431 msg.code = event_source;
1433 radio->sound_focus.cur_focus_type |= focus_type;
1435 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1436 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1438 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1443 MMRADIO_LOG_DEBUG("Unknown focus_state");
1447 MMRADIO_LOG_FLEAVE();
1450 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1451 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1452 const char *additional_info, void *user_data)
1454 mm_radio_t *radio = (mm_radio_t *)user_data;
1455 enum MMMessageInterruptedCode event_source;
1456 int result = MM_ERROR_NONE;
1457 int postMsg = false;
1459 MMRADIO_LOG_FENTER();
1460 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1461 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1463 mmradio_get_sound_focus_reason(focus_state, reason_for_change, TRUE, &event_source, &postMsg);
1464 radio->sound_focus.event_src = event_source;
1466 switch (focus_state) {
1467 case FOCUS_IS_ACQUIRED: {
1468 radio->sound_focus.cur_focus_type &= ~focus_type;
1469 radio->sound_focus.by_focus_cb = true;
1471 MMRADIO_CMD_LOCK(radio);
1472 result = _mmradio_stop(radio);
1474 MMRADIO_LOG_ERROR("failed to stop radio");
1475 MMRADIO_CMD_UNLOCK(radio);
1477 radio->sound_focus.by_focus_cb = false;
1479 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1483 case FOCUS_IS_RELEASED: {
1484 MMMessageParamType msg = { 0, };
1485 msg.union_type = MM_MSG_UNION_CODE;
1486 msg.code = event_source;
1488 radio->sound_focus.cur_focus_type |= focus_type;
1490 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1491 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1493 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1498 MMRADIO_LOG_DEBUG("Unknown focus_state");
1502 MMRADIO_LOG_FLEAVE();
1506 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1508 mm_radio_t *radio = (mm_radio_t *)user_data;
1509 int ret = MM_ERROR_NONE;
1510 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1511 if (type == VOLUME_TYPE_MEDIA) {
1512 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1513 ret = __mmradio_set_media_volume(radio, volume);
1514 if (ret != MM_ERROR_NONE)
1515 MMRADIO_LOG_ERROR("__mmradio_set_media_volume error");
1520 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1522 MMRADIO_LOG_FENTER();
1523 MMRADIO_CHECK_INSTANCE(radio);
1524 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1526 return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT);
1528 *type = radio->region_setting.country;
1530 MMRADIO_LOG_FLEAVE();
1531 return MM_ERROR_NONE;
1534 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1536 MMRADIO_LOG_FENTER();
1537 MMRADIO_CHECK_INSTANCE(radio);
1538 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1540 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1542 *min_freq = radio->region_setting.band_min;
1543 *max_freq = radio->region_setting.band_max;
1545 MMRADIO_LOG_FLEAVE();
1546 return MM_ERROR_NONE;
1549 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1551 MMRADIO_LOG_FENTER();
1552 MMRADIO_CHECK_INSTANCE(radio);
1553 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1555 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1557 *ch_spacing = radio->region_setting.channel_spacing;
1559 MMRADIO_LOG_FLEAVE();
1560 return MM_ERROR_NONE;
1563 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1565 int ret = MM_ERROR_NONE;
1567 MMRADIO_LOG_FENTER();
1569 MMRADIO_CHECK_INSTANCE(radio);
1570 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1572 MMRADIO_LOG_INFO("Setting %f volume", volume);
1574 MMRADIO_VOLUME_LOCK(radio);
1575 radio->local_volume = volume;
1576 MMRADIO_VOLUME_UNLOCK(radio);
1578 ret = radio_hal_set_volume(radio->hal_inf, volume);
1579 if (ret != MM_ERROR_NONE)
1580 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1582 MMRADIO_LOG_FLEAVE();
1587 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1589 int ret = MM_ERROR_NONE;
1591 MMRADIO_LOG_FENTER();
1593 MMRADIO_CHECK_INSTANCE(radio);
1594 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1596 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1598 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1599 if (ret != MM_ERROR_NONE) {
1600 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1605 MMRADIO_VOLUME_LOCK(radio);
1606 radio->local_volume = volume;
1607 *pVolume = (float)radio->local_volume;
1608 MMRADIO_VOLUME_UNLOCK(radio);
1610 MMRADIO_LOG_FLEAVE();
1615 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1617 int ret = MM_ERROR_NONE;
1619 MMRADIO_LOG_FENTER();
1621 MMRADIO_CHECK_INSTANCE(radio);
1622 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1624 MMRADIO_LOG_INFO("Setting %d volume", level);
1626 MMRADIO_VOLUME_LOCK(radio);
1627 radio->media_volume = level;
1628 MMRADIO_VOLUME_UNLOCK(radio);
1630 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1631 if (ret != MM_ERROR_NONE)
1632 MMRADIO_LOG_ERROR("radio_hal_set_media_volume error");
1634 MMRADIO_LOG_FLEAVE();