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 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
274 ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
275 if (ret != MM_ERROR_NONE) {
276 MMRADIO_LOG_ERROR("sound_manager_create_stream_information_internal error");
277 MMRADIO_LOG_FLEAVE();
280 ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
281 if (ret != MM_ERROR_NONE) {
282 MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
283 MMRADIO_LOG_FLEAVE();
288 ret = sound_manager_get_max_volume(SOUND_TYPE_MEDIA, &max);
289 if (ret != MM_ERROR_NONE) {
290 MMRADIO_LOG_WARNING("sound_manager_get_max_volume error");
291 radio->max_media_volume = DEFAULT_MAX_MEDIA_VOLUME;
293 radio->max_media_volume = max;
296 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
298 if (ret != MM_ERROR_NONE)
299 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
301 MMRADIO_VOLUME_LOCK(radio);
302 radio->media_volume = volume;
303 MMRADIO_VOLUME_UNLOCK(radio);
305 ret = mm_sound_add_volume_changed_callback(__mmradio_volume_changed_cb, (void *)radio, &radio->volume_subs_id);
306 if (ret != MM_ERROR_NONE)
307 MMRADIO_LOG_WARNING("mm_sound_add_volume_changed_callback error");
309 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
311 MMRADIO_LOG_FLEAVE();
313 return MM_ERROR_NONE;
316 int _mmradio_unrealize(mm_radio_t *radio)
318 int ret = MM_ERROR_NONE;
320 MMRADIO_LOG_FENTER();
322 MMRADIO_CHECK_INSTANCE(radio);
323 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
325 ret = mm_sound_remove_volume_changed_callback(radio->volume_subs_id);
326 if (ret != MM_ERROR_NONE)
327 MMRADIO_LOG_WARNING("mm_sound_remove_volume_changed_callback error");
329 /*Finish if there are scans*/
330 _mmradio_stop_scan(radio);
332 /*Stop radio if started*/
333 _mmradio_stop(radio);
335 /* close radio device here !!!! */
336 radio_hal_close(radio->hal_inf);
337 radio_hal_unprepare(radio->hal_inf);
338 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
339 sound_manager_destroy_virtual_stream(radio->vstream);
340 sound_manager_destroy_stream_information(radio->stream_info);
343 pthread_mutex_destroy(&radio->seek_cancel_mutex);
345 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
347 MMRADIO_LOG_FLEAVE();
352 int _mmradio_destroy(mm_radio_t *radio)
354 int ret = MM_ERROR_NONE;
355 MMRADIO_LOG_FENTER();
357 MMRADIO_CHECK_INSTANCE(radio);
358 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
360 _mmradio_unrealize(radio);
362 ret = radio_hal_interface_deinit(radio->hal_inf);
364 MMRADIO_LOG_ERROR("mmradio hal interface deinit failed");
368 /* destroy command lock */
369 ret = pthread_mutex_destroy(&radio->cmd_lock);
371 MMRADIO_LOG_ERROR("mutex destroy failed\n");
374 ret = pthread_mutex_destroy(&radio->volume_lock);
376 MMRADIO_LOG_ERROR("volume mutex destroy failed\n");
379 #ifdef TIZEN_FEATURE_SOUND_FOCUS
380 ret = mmradio_sound_focus_deregister(&radio->sound_focus);
382 MMRADIO_LOG_ERROR("failed to deregister sound focus");
383 return MM_ERROR_RADIO_INTERNAL;
387 ret = mmradio_resource_manager_deinit(&radio->resource_manager);
389 MMRADIO_LOG_ERROR("failed to initialize resource manager\n");
390 return MM_ERROR_RADIO_INTERNAL;
393 MMRADIO_LOG_FLEAVE();
395 return MM_ERROR_NONE;
398 /* unit should be KHz */
399 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
401 int ret = MM_ERROR_NONE;
403 MMRADIO_LOG_FENTER();
405 MMRADIO_CHECK_INSTANCE(radio);
406 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
408 MMRADIO_LOG_INFO("Setting %d frequency", freq);
412 ret = radio_hal_set_frequency(radio->hal_inf, freq);
413 if (ret != MM_ERROR_NONE) {
414 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
415 MMRADIO_LOG_FLEAVE();
419 MMRADIO_LOG_FLEAVE();
425 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
427 int ret = MM_ERROR_NONE;
429 MMRADIO_LOG_FENTER();
431 MMRADIO_CHECK_INSTANCE(radio);
432 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
434 return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
436 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
437 if (ret != MM_ERROR_NONE) {
438 MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
443 /* update freq in handle */
444 MMRADIO_LOG_INFO("Updating %d frequency", freq);
447 *pFreq = (int)radio->freq;
449 MMRADIO_LOG_FLEAVE();
454 int _mmradio_mute(mm_radio_t *radio)
456 int ret = MM_ERROR_NONE;
457 MMRADIO_LOG_FENTER();
459 MMRADIO_CHECK_INSTANCE(radio);
460 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
462 ret = radio_hal_mute(radio->hal_inf);
463 if (ret == MM_ERROR_NOT_SUPPORT_API) {
464 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
465 } else if (ret != MM_ERROR_NONE) {
466 MMRADIO_LOG_ERROR("radio_hal_mute error");
467 MMRADIO_LOG_FLEAVE();
471 radio->is_muted = TRUE;
472 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
473 MMRADIO_LOG_FLEAVE();
478 int _mmradio_unmute(mm_radio_t *radio)
480 int ret = MM_ERROR_NONE;
481 MMRADIO_LOG_FENTER();
483 MMRADIO_CHECK_INSTANCE(radio);
484 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
486 ret = radio_hal_unmute(radio->hal_inf);
487 if (ret == MM_ERROR_NOT_SUPPORT_API) {
488 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
489 } else if (ret != MM_ERROR_NONE) {
490 MMRADIO_LOG_ERROR("radio_hal_unmute error");
491 MMRADIO_LOG_FLEAVE();
495 radio->is_muted = FALSE;
496 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
497 MMRADIO_LOG_FLEAVE();
502 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
504 MMRADIO_LOG_FENTER();
506 MMRADIO_CHECK_INSTANCE(radio);
508 radio->msg_cb = callback;
509 radio->msg_cb_param = user_param;
511 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x", callback, user_param);
513 MMRADIO_LOG_FLEAVE();
515 return MM_ERROR_NONE;
518 int _mmradio_get_state(mm_radio_t *radio, int *pState)
522 MMRADIO_LOG_FENTER();
524 MMRADIO_CHECK_INSTANCE(radio);
525 return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT);
527 state = __mmradio_get_state(radio);
531 MMRADIO_LOG_FLEAVE();
533 return MM_ERROR_NONE;
536 int _mmradio_start(mm_radio_t *radio)
538 int ret = MM_ERROR_NONE;
539 unsigned int volume = 0;
541 MMRADIO_LOG_FENTER();
543 MMRADIO_CHECK_INSTANCE(radio);
544 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
546 MMRADIO_LOG_INFO("now tune to frequency : %d", radio->freq);
548 #ifdef TIZEN_FEATURE_SOUND_FOCUS
549 if (radio->sound_focus.handle > 0) {
550 ret = mmradio_acquire_sound_focus(&radio->sound_focus);
551 if (ret != MM_ERROR_NONE) {
552 MMRADIO_LOG_ERROR("failed to set sound focus");
558 if (!radio->is_ready) {
559 ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO);
560 if (ret != MM_ERROR_NONE) {
561 MMRADIO_LOG_ERROR("resource manager prepare fail");
562 return MM_ERROR_RADIO_INTERNAL;
564 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
565 if (ret != MM_ERROR_NONE) {
566 MMRADIO_LOG_ERROR("failed to acquire resource manager");
567 mmradio_resource_manager_unprepare(&radio->resource_manager);
570 ret = radio_hal_prepare(radio->hal_inf);
571 if (ret == MM_ERROR_NOT_SUPPORT_API) {
572 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
573 } else if (ret != MM_ERROR_NONE) {
574 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
578 ret = radio_hal_open(radio->hal_inf);
579 if (ret == MM_ERROR_NOT_SUPPORT_API) {
580 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
581 } else if (ret != MM_ERROR_NONE) {
582 MMRADIO_LOG_ERROR("radio_hal_init error");
585 radio->is_ready = TRUE;
587 MMRADIO_LOG_DEBUG("radio prepared and opened");
590 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
591 if (ret != MM_ERROR_NONE)
592 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
594 ret = __mmradio_set_media_volume(radio, volume);
595 if (ret != MM_ERROR_NONE) {
596 MMRADIO_LOG_ERROR("failed to media volume");
600 ret = radio_hal_start(radio->hal_inf);
601 if (ret == MM_ERROR_NOT_SUPPORT_API) {
602 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
604 MMRADIO_LOG_ERROR("failed to radio_hal_start");
608 /* set stored frequency */
609 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
611 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency");
615 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
616 ret = sound_manager_start_virtual_stream(radio->vstream);
618 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream");
623 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
625 MMRADIO_LOG_FLEAVE();
627 return MM_ERROR_NONE;
629 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
631 sound_manager_stop_virtual_stream(radio->vstream);
634 radio_hal_close(radio->hal_inf);
636 radio_hal_unprepare(radio->hal_inf);
637 radio->is_ready = FALSE;
641 int _mmradio_stop(mm_radio_t *radio)
643 int ret = MM_ERROR_NONE;
644 mm_radio_resource_state_e resource_state = MM_RADIO_RESOURCE_STATE_NONE;
646 MMRADIO_LOG_FENTER();
648 MMRADIO_CHECK_INSTANCE(radio);
649 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
651 radio->seek_unmute = FALSE;
652 /*cancel if any seek*/
653 _mmradio_seek_cancel(radio);
654 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
655 ret = sound_manager_stop_virtual_stream(radio->vstream);
656 if (ret != MM_ERROR_NONE) {
657 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
662 ret = radio_hal_stop(radio->hal_inf);
663 if (ret == MM_ERROR_NOT_SUPPORT_API) {
664 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
666 MMRADIO_LOG_ERROR("failed to radio_hal_stop");
670 /* close radio device here !!!! */
671 ret = radio_hal_close(radio->hal_inf);
672 if (ret == MM_ERROR_NOT_SUPPORT_API) {
673 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
674 } else if (ret != MM_ERROR_NONE) {
675 MMRADIO_LOG_ERROR("radio_hal_close_device error");
679 ret = radio_hal_unprepare(radio->hal_inf);
680 if (ret == MM_ERROR_NOT_SUPPORT_API) {
681 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
682 } else if (ret != MM_ERROR_NONE) {
683 MMRADIO_LOG_ERROR("radio_hal_close_device error");
687 radio->is_ready = FALSE;
689 if (!radio->resource_manager.by_rm_cb && /* is being released */
690 mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
691 if (resource_state == MM_RADIO_RESOURCE_STATE_ACQUIRED) {
692 ret = mmradio_resource_manager_release(&radio->resource_manager);
693 if (ret != MM_ERROR_NONE) {
694 MMRADIO_LOG_ERROR("failed to release resource, ret(0x%x)", ret);
700 if (mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
701 if (resource_state == MM_RADIO_RESOURCE_STATE_PREPARED) {
702 ret = mmradio_resource_manager_unprepare(&radio->resource_manager);
703 if (ret != MM_ERROR_NONE)
704 MMRADIO_LOG_ERROR("resource manager unprepare fail");
708 #ifdef TIZEN_FEATURE_SOUND_FOCUS
709 if (radio->sound_focus.handle > 0) {
710 ret = mmradio_release_sound_focus(&radio->sound_focus);
712 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed");
717 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
719 MMRADIO_LOG_FLEAVE();
721 return MM_ERROR_NONE;
724 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
726 int ret = MM_ERROR_NONE;
728 MMRADIO_LOG_FENTER();
730 MMRADIO_CHECK_INSTANCE(radio);
731 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
733 if (radio->is_seeking) {
734 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
735 return MM_ERROR_RADIO_INTERNAL;
738 radio->seek_unmute = FALSE;
739 radio->is_seeking = TRUE;
740 radio->seek_cancel = FALSE;
742 if (!radio->is_muted) {
743 ret = radio_hal_mute(radio->hal_inf);
744 if (ret == MM_ERROR_NOT_SUPPORT_API) {
745 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
747 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
750 radio->seek_unmute = TRUE;
753 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
754 radio->seek_direction = direction;
756 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
759 MMRADIO_LOG_DEBUG("failed create thread");
760 radio->is_seeking = FALSE;
761 radio->seek_cancel = TRUE;
762 if (radio->seek_unmute) {
763 ret = radio_hal_mute(radio->hal_inf);
764 if (ret == MM_ERROR_NOT_SUPPORT_API) {
765 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
767 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
768 radio->seek_unmute = FALSE;
772 return MM_ERROR_RADIO_INTERNAL;
775 MMRADIO_LOG_FLEAVE();
777 return MM_ERROR_NONE;
780 void _mmradio_seek_cancel(mm_radio_t *radio)
782 int ret = MM_ERROR_NONE;
783 char str_error[READ_MAX_BUFFER_SIZE];
784 MMRADIO_LOG_FENTER();
786 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
788 /*cancel any outstanding seek request*/
789 radio->seek_cancel = TRUE;
790 if (radio->seek_thread) {
791 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
792 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
793 if (ret == EBUSY) { /* it was already locked by other */
794 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
795 } else if (ret == 0) {
796 MMRADIO_LOG_INFO("trylock is successful. unlock now");
797 pthread_mutex_unlock(&radio->seek_cancel_mutex);
799 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
801 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
802 pthread_join(radio->seek_thread, NULL);
803 MMRADIO_LOG_DEBUG("done");
804 radio->is_seeking = FALSE;
805 radio->seek_thread = 0;
807 MMRADIO_LOG_FLEAVE();
811 int _mmradio_start_scan(mm_radio_t *radio)
813 int ret = MM_ERROR_NONE;
815 MMRADIO_LOG_FENTER();
817 MMRADIO_CHECK_INSTANCE(radio);
818 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
822 radio->stop_scan = false;
824 if (!radio->is_ready) {
825 ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO);
826 if (ret != MM_ERROR_NONE) {
827 MMRADIO_LOG_ERROR("resource manager prepare fail");
828 return MM_ERROR_RADIO_INTERNAL;
830 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
831 if (ret != MM_ERROR_NONE) {
832 MMRADIO_LOG_ERROR("failed to acquire resource manager");
833 mmradio_resource_manager_unprepare(&radio->resource_manager);
837 ret = radio_hal_prepare(radio->hal_inf);
838 if (ret == MM_ERROR_NOT_SUPPORT_API) {
839 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
840 } else if (ret != MM_ERROR_NONE) {
841 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
845 ret = radio_hal_open(radio->hal_inf);
846 if (ret == MM_ERROR_NOT_SUPPORT_API) {
847 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
848 } else if (ret != MM_ERROR_NONE) {
849 MMRADIO_LOG_ERROR("radio_hal_init error");
850 MMRADIO_LOG_FLEAVE();
853 radio->is_ready = TRUE;
855 MMRADIO_LOG_DEBUG("radio prepared and opened");
858 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
860 if (scan_tr_id != 0) {
861 MMRADIO_LOG_ERROR("failed to create thread : scan");
862 return MM_ERROR_RADIO_NOT_INITIALIZED;
865 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
867 MMRADIO_LOG_FLEAVE();
869 return MM_ERROR_NONE;
872 int _mmradio_stop_scan(mm_radio_t *radio)
875 char str_error[READ_MAX_BUFFER_SIZE];
876 MMRADIO_LOG_FENTER();
878 MMRADIO_CHECK_INSTANCE(radio);
879 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
881 radio->stop_scan = true;
883 if (radio->scan_thread > 0) {
884 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
885 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
886 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
887 if (ret == EBUSY) { /* it was already locked by other */
888 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
889 } else if (ret == 0) {
890 MMRADIO_LOG_INFO("trylock is successful. unlock now");
891 pthread_mutex_unlock(&radio->seek_cancel_mutex);
893 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
895 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
896 pthread_join(radio->scan_thread, NULL);
897 radio->scan_thread = 0;
900 MMRADIO_LOG_FLEAVE();
902 return MM_ERROR_NONE;
905 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
907 int ret = MM_ERROR_NONE;
908 int32_t strength = 0;
909 MMRADIO_LOG_FENTER();
910 MMRADIO_CHECK_INSTANCE(radio);
912 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
914 /* just return stored frequency if radio device is not ready */
915 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
916 if (ret == MM_ERROR_NOT_SUPPORT_API) {
917 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
918 } else if (ret != MM_ERROR_NONE) {
919 MMRADIO_LOG_ERROR("radio_hal_get_signal_strength error");
921 MMRADIO_LOG_FLEAVE();
924 *value = (int)strength;
925 MMRADIO_LOG_FLEAVE();
926 return MM_ERROR_NONE;
929 void __mmradio_scan_thread(mm_radio_t *radio)
931 int ret = MM_ERROR_NONE;
933 mm_radio_resource_state_e resource_state = MM_RADIO_RESOURCE_STATE_NONE;
935 MMRADIO_LOG_FENTER();
936 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
938 ret = radio_hal_mute(radio->hal_inf);
940 if (ret == MM_ERROR_NOT_SUPPORT_API) {
941 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
942 } else if (ret != MM_ERROR_NONE) {
943 MMRADIO_LOG_ERROR("radio_hal_mute error");
946 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
948 if (ret != MM_ERROR_NONE)
951 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
952 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
954 while (!radio->stop_scan) {
956 MMMessageParamType param = { 0, };
958 MMRADIO_LOG_DEBUG("scanning....");
960 pthread_mutex_lock(&radio->seek_cancel_mutex);
962 if (radio->stop_scan) {
963 MMRADIO_LOG_INFO("scan was canceled");
964 pthread_mutex_unlock(&radio->seek_cancel_mutex);
968 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
970 pthread_mutex_unlock(&radio->seek_cancel_mutex);
972 if (ret != MM_ERROR_NONE) {
973 MMRADIO_LOG_ERROR("radio scanning error");
977 /* now we can get new frequency from radio device */
978 if (radio->stop_scan)
981 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
982 if (ret != MM_ERROR_NONE) {
983 MMRADIO_LOG_ERROR("failed to get current frequency");
985 if (freq <= prev_freq) {
986 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
990 prev_freq = param.radio_scan.frequency = (int)freq;
991 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
993 /* drop if max freq is scanned */
994 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
995 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
999 if (radio->stop_scan) {
1000 /* doesn't need to post */
1004 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
1008 if (radio->old_state == MM_RADIO_STATE_READY) {
1009 MMRADIO_LOG_DEBUG("old state is ready");
1010 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
1011 MMRADIO_LOG_DEBUG("old state is playing");
1012 ret = radio_hal_unmute(radio->hal_inf);
1013 if (ret == MM_ERROR_NOT_SUPPORT_API) {
1014 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
1015 } else if (ret != MM_ERROR_NONE) {
1016 MMRADIO_LOG_ERROR("radio_hal_unmute error");
1019 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
1020 if (ret == MM_ERROR_NOT_SUPPORT_API) {
1021 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
1022 } else if (ret != MM_ERROR_NONE) {
1023 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
1030 radio->scan_thread = 0;
1032 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
1033 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
1035 /* close radio device here !!!! */
1036 ret = radio_hal_close(radio->hal_inf);
1037 if (ret == MM_ERROR_NOT_SUPPORT_API)
1038 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
1039 else if (ret != MM_ERROR_NONE)
1040 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1042 ret = radio_hal_unprepare(radio->hal_inf);
1043 if (ret == MM_ERROR_NOT_SUPPORT_API)
1044 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
1045 else if (ret != MM_ERROR_NONE)
1046 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1048 radio->is_ready = FALSE;
1050 if (!radio->resource_manager.by_rm_cb && /* is being released */
1051 mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
1052 if (resource_state == MM_RADIO_RESOURCE_STATE_ACQUIRED) {
1053 ret = mmradio_resource_manager_release(&radio->resource_manager);
1054 if (ret != MM_ERROR_NONE)
1055 MMRADIO_LOG_ERROR("failed to release resource, ret(0x%x)", ret);
1059 if (mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
1060 if (resource_state == MM_RADIO_RESOURCE_STATE_PREPARED) {
1061 ret = mmradio_resource_manager_unprepare(&radio->resource_manager);
1062 if (ret != MM_ERROR_NONE)
1063 MMRADIO_LOG_ERROR("resource manager unprepare fail");
1067 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
1070 if (!radio->stop_scan)
1071 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
1073 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
1075 MMRADIO_LOG_FLEAVE();
1082 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1084 MMRADIO_LOG_FENTER();
1086 MMRADIO_CHECK_INSTANCE(radio);
1088 if (freq >= radio->region_setting.band_max
1089 || freq <= radio->region_setting.band_min)
1092 MMRADIO_LOG_FLEAVE();
1097 void __mmradio_seek_thread(mm_radio_t *radio)
1099 int ret = MM_ERROR_NONE;
1101 MMMessageParamType param = {0, };
1103 MMRADIO_LOG_FENTER();
1104 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1106 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1108 MMRADIO_LOG_DEBUG("seeking....");
1110 if (!radio->seek_cancel) {
1112 MMRADIO_LOG_DEBUG("try to seek ");
1113 pthread_mutex_lock(&radio->seek_cancel_mutex);
1114 MMRADIO_LOG_DEBUG("seek start");
1116 if (radio->seek_cancel) {
1117 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1118 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1122 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1123 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1125 MMRADIO_LOG_ERROR("radio_hal_seek failed");
1129 /* now we can get new frequency from radio device */
1130 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1132 MMRADIO_LOG_ERROR("failed to get current frequency");
1136 MMRADIO_LOG_DEBUG("found frequency");
1138 /* if same freq is found, ignore it and search next one. */
1139 if (freq == radio->prev_seek_freq) {
1140 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1144 /* check if it's limit freq or not */
1145 if (__is_tunable_frequency(radio, freq)) {
1146 /* now tune to new frequency */
1147 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1149 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1152 radio->freq = (int)freq;
1153 MMRADIO_LOG_WARNING("setting frequency : [%d]", radio->freq);
1156 if (radio->seek_unmute) {
1157 /* now turn on radio
1158 * In the case of limit freq, tuner should be unmuted.
1159 * Otherwise, sound can't output even though application set new frequency.
1161 ret = radio_hal_unmute(radio->hal_inf);
1163 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1166 radio->seek_unmute = FALSE;
1169 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1170 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1171 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1174 radio->seek_thread = 0;
1175 radio->is_seeking = FALSE;
1177 MMRADIO_LOG_FLEAVE();
1184 if (radio->seek_unmute) {
1185 /* now turn on radio
1186 * In the case of limit freq, tuner should be unmuted.
1187 * Otherwise, sound can't output even though application set new frequency.
1189 ret = radio_hal_unmute(radio->hal_inf);
1191 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1192 radio->seek_unmute = FALSE;
1194 /* freq -1 means it's failed to seek */
1195 param.radio_scan.frequency = -1;
1196 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1197 radio->is_seeking = FALSE;
1198 radio->seek_thread = 0;
1203 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1205 MMRADIO_CHECK_INSTANCE(radio);
1207 MMRADIO_LOG_FENTER();
1209 if (!radio->msg_cb) {
1210 MMRADIO_LOG_WARNING("failed to post a message");
1214 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1216 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1218 MMRADIO_LOG_FLEAVE();
1223 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1225 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1227 MMRADIO_LOG_FENTER();
1229 MMRADIO_CHECK_INSTANCE(radio);
1231 radio_state = __mmradio_get_state(radio);
1233 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1236 case MMRADIO_COMMAND_CREATE:
1238 if (radio_state != 0)
1243 case MMRADIO_COMMAND_REALIZE:
1245 if (radio_state == MM_RADIO_STATE_READY ||
1246 radio_state == MM_RADIO_STATE_PLAYING ||
1247 radio_state == MM_RADIO_STATE_SCANNING)
1250 if (radio_state == 0)
1255 case MMRADIO_COMMAND_UNREALIZE:
1257 if (radio_state == MM_RADIO_STATE_NULL)
1260 /* we can call unrealize at any higher state */
1264 case MMRADIO_COMMAND_START:
1266 if (radio_state == MM_RADIO_STATE_PLAYING)
1269 if (radio_state != MM_RADIO_STATE_READY)
1274 case MMRADIO_COMMAND_STOP:
1276 if (radio_state == MM_RADIO_STATE_READY)
1279 if (radio_state != MM_RADIO_STATE_PLAYING)
1284 case MMRADIO_COMMAND_START_SCAN:
1286 if (radio_state == MM_RADIO_STATE_SCANNING)
1289 if (radio_state == MM_RADIO_STATE_NULL)
1294 case MMRADIO_COMMAND_STOP_SCAN:
1296 if (radio_state == MM_RADIO_STATE_READY)
1299 if (radio_state != MM_RADIO_STATE_SCANNING)
1304 case MMRADIO_COMMAND_DESTROY:
1305 case MMRADIO_COMMAND_MUTE:
1306 case MMRADIO_COMMAND_UNMUTE:
1307 case MMRADIO_COMMAND_SET_FREQ:
1308 case MMRADIO_COMMAND_GET_FREQ:
1309 case MMRADIO_COMMAND_SET_REGION:
1310 case MMRADIO_COMMAND_SET_VOLUME:
1311 case MMRADIO_COMMAND_GET_VOLUME:
1313 /* we can do it at any state */
1317 case MMRADIO_COMMAND_SEEK:
1319 if (radio_state != MM_RADIO_STATE_PLAYING)
1324 case MMRADIO_COMMAND_GET_REGION:
1326 if (radio_state == MM_RADIO_STATE_NULL)
1332 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1336 MMRADIO_LOG_DEBUG("status OK");
1338 radio->cmd = command;
1340 MMRADIO_LOG_FLEAVE();
1342 return MM_ERROR_NONE;
1345 MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
1346 MMRADIO_LOG_FLEAVE();
1347 return MM_ERROR_RADIO_INVALID_STATE;
1350 MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
1351 MMRADIO_LOG_FLEAVE();
1352 return MM_ERROR_RADIO_NO_OP;
1356 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1358 MMMessageParamType msg = { 0, };
1359 int msg_type = MM_MESSAGE_UNKNOWN;
1361 MMRADIO_LOG_FENTER();
1364 MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
1368 if (radio->current_state == new_state && radio->pending_state == 0) {
1369 MMRADIO_LOG_WARNING("we are in same state");
1374 radio->old_state = radio->current_state;
1375 radio->current_state = new_state;
1377 /* fill message param */
1378 msg.union_type = MM_MSG_UNION_STATE;
1379 msg.state.previous = radio->old_state;
1380 msg.state.current = radio->current_state;
1382 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1383 /* post message to application */
1384 if (radio->sound_focus.by_focus_cb) {
1385 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1386 msg.state.code = radio->sound_focus.event_src;
1387 MMRADIO_POST_MSG(radio, msg_type, &msg);
1388 } else if (radio->resource_manager.by_rm_cb) {
1389 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1390 msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1391 MMRADIO_POST_MSG(radio, msg_type, &msg);
1393 msg_type = MM_MESSAGE_STATE_CHANGED;
1394 MMRADIO_POST_MSG(radio, msg_type, &msg);
1397 if (radio->resource_manager.by_rm_cb) {
1398 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1399 msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1400 MMRADIO_POST_MSG(radio, msg_type, &msg);
1402 msg_type = MM_MESSAGE_STATE_CHANGED;
1403 MMRADIO_POST_MSG(radio, msg_type, &msg);
1408 MMRADIO_LOG_FLEAVE();
1413 static int __mmradio_get_state(mm_radio_t *radio)
1415 MMRADIO_CHECK_INSTANCE(radio);
1417 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1418 radio->current_state, radio->old_state, radio->pending_state);
1420 return radio->current_state;
1423 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1424 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1425 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1426 const char *additional_info, void *user_data)
1428 mm_radio_t *radio = (mm_radio_t *)user_data;
1429 enum MMMessageInterruptedCode event_source;
1430 int result = MM_ERROR_NONE;
1431 int postMsg = false;
1433 MMRADIO_LOG_FENTER();
1434 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1435 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1437 mmradio_get_sound_focus_reason(focus_state, reason_for_change, FALSE, &event_source, &postMsg);
1438 radio->sound_focus.event_src = event_source;
1440 switch (focus_state) {
1441 case FOCUS_IS_RELEASED:{
1442 radio->sound_focus.cur_focus_type &= ~focus_type;
1443 radio->sound_focus.by_focus_cb = true;
1445 MMRADIO_CMD_LOCK(radio);
1446 result = _mmradio_stop(radio);
1448 MMRADIO_LOG_ERROR("failed to stop radio");
1449 MMRADIO_CMD_UNLOCK(radio);
1451 radio->sound_focus.by_focus_cb = false;
1453 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1457 case FOCUS_IS_ACQUIRED:{
1458 MMMessageParamType msg = { 0, };
1459 msg.union_type = MM_MSG_UNION_CODE;
1460 msg.code = event_source;
1462 radio->sound_focus.cur_focus_type |= focus_type;
1464 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1465 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1467 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1472 MMRADIO_LOG_DEBUG("Unknown focus_state");
1476 MMRADIO_LOG_FLEAVE();
1479 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1480 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1481 const char *additional_info, void *user_data)
1483 mm_radio_t *radio = (mm_radio_t *)user_data;
1484 enum MMMessageInterruptedCode event_source;
1485 int result = MM_ERROR_NONE;
1486 int postMsg = false;
1488 MMRADIO_LOG_FENTER();
1489 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1490 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1492 mmradio_get_sound_focus_reason(focus_state, reason_for_change, TRUE, &event_source, &postMsg);
1493 radio->sound_focus.event_src = event_source;
1495 switch (focus_state) {
1496 case FOCUS_IS_ACQUIRED: {
1497 radio->sound_focus.cur_focus_type &= ~focus_type;
1498 radio->sound_focus.by_focus_cb = true;
1500 MMRADIO_CMD_LOCK(radio);
1501 result = _mmradio_stop(radio);
1503 MMRADIO_LOG_ERROR("failed to stop radio");
1504 MMRADIO_CMD_UNLOCK(radio);
1506 radio->sound_focus.by_focus_cb = false;
1508 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1512 case FOCUS_IS_RELEASED: {
1513 MMMessageParamType msg = { 0, };
1514 msg.union_type = MM_MSG_UNION_CODE;
1515 msg.code = event_source;
1517 radio->sound_focus.cur_focus_type |= focus_type;
1519 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1520 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1522 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1527 MMRADIO_LOG_DEBUG("Unknown focus_state");
1531 MMRADIO_LOG_FLEAVE();
1535 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1537 mm_radio_t *radio = (mm_radio_t *)user_data;
1538 int ret = MM_ERROR_NONE;
1539 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1540 if (type == VOLUME_TYPE_MEDIA) {
1541 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1542 ret = __mmradio_set_media_volume(radio, volume);
1543 if (ret != MM_ERROR_NONE)
1544 MMRADIO_LOG_ERROR("__mmradio_set_media_volume error");
1549 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
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(type, MM_ERROR_INVALID_ARGUMENT);
1557 *type = radio->region_setting.country;
1559 MMRADIO_LOG_FLEAVE();
1560 return MM_ERROR_NONE;
1563 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1565 MMRADIO_LOG_FENTER();
1566 MMRADIO_CHECK_INSTANCE(radio);
1567 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1569 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1571 *min_freq = radio->region_setting.band_min;
1572 *max_freq = radio->region_setting.band_max;
1574 MMRADIO_LOG_FLEAVE();
1575 return MM_ERROR_NONE;
1578 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1580 MMRADIO_LOG_FENTER();
1581 MMRADIO_CHECK_INSTANCE(radio);
1582 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1584 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1586 *ch_spacing = radio->region_setting.channel_spacing;
1588 MMRADIO_LOG_FLEAVE();
1589 return MM_ERROR_NONE;
1592 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1594 int ret = MM_ERROR_NONE;
1596 MMRADIO_LOG_FENTER();
1598 MMRADIO_CHECK_INSTANCE(radio);
1599 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1601 MMRADIO_LOG_INFO("Setting %f volume", volume);
1603 MMRADIO_VOLUME_LOCK(radio);
1604 radio->local_volume = volume;
1605 MMRADIO_VOLUME_UNLOCK(radio);
1607 ret = radio_hal_set_volume(radio->hal_inf, volume);
1608 if (ret != MM_ERROR_NONE)
1609 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1611 MMRADIO_LOG_FLEAVE();
1616 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1618 int ret = MM_ERROR_NONE;
1620 MMRADIO_LOG_FENTER();
1622 MMRADIO_CHECK_INSTANCE(radio);
1623 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1625 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1627 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1628 if (ret != MM_ERROR_NONE) {
1629 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1634 MMRADIO_VOLUME_LOCK(radio);
1635 radio->local_volume = volume;
1636 *pVolume = (float)radio->local_volume;
1637 MMRADIO_VOLUME_UNLOCK(radio);
1639 MMRADIO_LOG_FLEAVE();
1644 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1646 int ret = MM_ERROR_NONE;
1648 MMRADIO_LOG_FENTER();
1650 MMRADIO_CHECK_INSTANCE(radio);
1651 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1653 MMRADIO_LOG_INFO("Setting %d volume", level);
1655 MMRADIO_VOLUME_LOCK(radio);
1656 radio->media_volume = level;
1657 MMRADIO_VOLUME_UNLOCK(radio);
1659 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1660 if (ret != MM_ERROR_NONE)
1661 MMRADIO_LOG_ERROR("radio_hal_set_media_volume error");
1663 MMRADIO_LOG_FLEAVE();