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");
557 /* check previous acquired focus */
558 if (radio->sound_focus.watch_id > 0) {
559 char *stream_type = NULL;
560 char *ext_info = NULL;
563 ret = mm_sound_get_stream_type_of_acquired_focus(FOCUS_FOR_BOTH, &stream_type, &option, &ext_info);
564 if (ret == MM_ERROR_NONE) {
565 MMRADIO_LOG_DEBUG("Focus is acquired by stream_type[%s], option[%d], ext_info[%s]",
566 stream_type, option, ext_info);
567 if (!strcmp(stream_type, "alarm") || !strcmp(stream_type, "ringtone-voip") ||
568 !strcmp(stream_type, "ringtone-call") || !strcmp(stream_type, "voip") ||
569 !strcmp(stream_type, "call-voice") || !strcmp(stream_type, "call-video")) {
570 MMRADIO_LOG_DEBUG("Blcoked by session policy, focus_acquired_by[%s]", stream_type);
573 return MM_ERROR_POLICY_BLOCKED;
581 if (!radio->is_ready) {
582 ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO);
583 if (ret != MM_ERROR_NONE) {
584 MMRADIO_LOG_ERROR("resource manager prepare fail");
585 return MM_ERROR_RADIO_INTERNAL;
587 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
588 if (ret != MM_ERROR_NONE) {
589 MMRADIO_LOG_ERROR("failed to acquire resource manager");
590 mmradio_resource_manager_unprepare(&radio->resource_manager);
593 ret = radio_hal_prepare(radio->hal_inf);
594 if (ret == MM_ERROR_NOT_SUPPORT_API) {
595 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
596 } else if (ret != MM_ERROR_NONE) {
597 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
601 ret = radio_hal_open(radio->hal_inf);
602 if (ret == MM_ERROR_NOT_SUPPORT_API) {
603 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
604 } else if (ret != MM_ERROR_NONE) {
605 MMRADIO_LOG_ERROR("radio_hal_init error");
608 radio->is_ready = TRUE;
610 MMRADIO_LOG_DEBUG("radio prepared and opened");
613 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
614 if (ret != MM_ERROR_NONE)
615 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
617 ret = __mmradio_set_media_volume(radio, volume);
618 if (ret != MM_ERROR_NONE) {
619 MMRADIO_LOG_ERROR("failed to media volume");
623 ret = radio_hal_start(radio->hal_inf);
624 if (ret == MM_ERROR_NOT_SUPPORT_API) {
625 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
627 MMRADIO_LOG_ERROR("failed to radio_hal_start");
631 /* set stored frequency */
632 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
634 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency");
638 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
639 ret = sound_manager_start_virtual_stream(radio->vstream);
641 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream");
646 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
648 MMRADIO_LOG_FLEAVE();
650 return MM_ERROR_NONE;
652 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
654 sound_manager_stop_virtual_stream(radio->vstream);
657 radio_hal_close(radio->hal_inf);
659 radio_hal_unprepare(radio->hal_inf);
660 radio->is_ready = FALSE;
664 int _mmradio_stop(mm_radio_t *radio)
666 int ret = MM_ERROR_NONE;
667 mm_radio_resource_state_e resource_state = MM_RADIO_RESOURCE_STATE_NONE;
669 MMRADIO_LOG_FENTER();
671 MMRADIO_CHECK_INSTANCE(radio);
672 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
674 radio->seek_unmute = FALSE;
675 /*cancel if any seek*/
676 _mmradio_seek_cancel(radio);
677 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
678 ret = sound_manager_stop_virtual_stream(radio->vstream);
679 if (ret != MM_ERROR_NONE) {
680 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
685 ret = radio_hal_stop(radio->hal_inf);
686 if (ret == MM_ERROR_NOT_SUPPORT_API) {
687 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
689 MMRADIO_LOG_ERROR("failed to radio_hal_stop");
693 /* close radio device here !!!! */
694 ret = radio_hal_close(radio->hal_inf);
695 if (ret == MM_ERROR_NOT_SUPPORT_API) {
696 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
697 } else if (ret != MM_ERROR_NONE) {
698 MMRADIO_LOG_ERROR("radio_hal_close_device error");
702 ret = radio_hal_unprepare(radio->hal_inf);
703 if (ret == MM_ERROR_NOT_SUPPORT_API) {
704 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
705 } else if (ret != MM_ERROR_NONE) {
706 MMRADIO_LOG_ERROR("radio_hal_close_device error");
710 radio->is_ready = FALSE;
712 if (!radio->resource_manager.by_rm_cb && /* is being released */
713 mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
714 if (resource_state == MM_RADIO_RESOURCE_STATE_ACQUIRED) {
715 ret = mmradio_resource_manager_release(&radio->resource_manager);
716 if (ret != MM_ERROR_NONE) {
717 MMRADIO_LOG_ERROR("failed to release resource, ret(0x%x)", ret);
723 if (mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
724 if (resource_state == MM_RADIO_RESOURCE_STATE_PREPARED) {
725 ret = mmradio_resource_manager_unprepare(&radio->resource_manager);
726 if (ret != MM_ERROR_NONE)
727 MMRADIO_LOG_ERROR("resource manager unprepare fail");
731 #ifdef TIZEN_FEATURE_SOUND_FOCUS
732 if (radio->sound_focus.handle > 0) {
733 ret = mmradio_release_sound_focus(&radio->sound_focus);
735 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed");
740 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
742 MMRADIO_LOG_FLEAVE();
744 return MM_ERROR_NONE;
747 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
749 int ret = MM_ERROR_NONE;
751 MMRADIO_LOG_FENTER();
753 MMRADIO_CHECK_INSTANCE(radio);
754 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
756 if (radio->is_seeking) {
757 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
758 return MM_ERROR_RADIO_INTERNAL;
761 radio->seek_unmute = FALSE;
762 radio->is_seeking = TRUE;
763 radio->seek_cancel = FALSE;
765 if (!radio->is_muted) {
766 ret = radio_hal_mute(radio->hal_inf);
767 if (ret == MM_ERROR_NOT_SUPPORT_API) {
768 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
770 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
773 radio->seek_unmute = TRUE;
776 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
777 radio->seek_direction = direction;
779 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
782 MMRADIO_LOG_DEBUG("failed create thread");
783 radio->is_seeking = FALSE;
784 radio->seek_cancel = TRUE;
785 if (radio->seek_unmute) {
786 ret = radio_hal_mute(radio->hal_inf);
787 if (ret == MM_ERROR_NOT_SUPPORT_API) {
788 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
790 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
791 radio->seek_unmute = FALSE;
795 return MM_ERROR_RADIO_INTERNAL;
798 MMRADIO_LOG_FLEAVE();
800 return MM_ERROR_NONE;
803 void _mmradio_seek_cancel(mm_radio_t *radio)
805 int ret = MM_ERROR_NONE;
806 char str_error[READ_MAX_BUFFER_SIZE];
807 MMRADIO_LOG_FENTER();
809 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
811 /*cancel any outstanding seek request*/
812 radio->seek_cancel = TRUE;
813 if (radio->seek_thread) {
814 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
815 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
816 if (ret == EBUSY) { /* it was already locked by other */
817 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
818 } else if (ret == 0) {
819 MMRADIO_LOG_INFO("trylock is successful. unlock now");
820 pthread_mutex_unlock(&radio->seek_cancel_mutex);
822 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
824 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
825 pthread_join(radio->seek_thread, NULL);
826 MMRADIO_LOG_DEBUG("done");
827 radio->is_seeking = FALSE;
828 radio->seek_thread = 0;
830 MMRADIO_LOG_FLEAVE();
834 int _mmradio_start_scan(mm_radio_t *radio)
836 int ret = MM_ERROR_NONE;
838 MMRADIO_LOG_FENTER();
840 MMRADIO_CHECK_INSTANCE(radio);
841 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
845 radio->stop_scan = false;
847 if (!radio->is_ready) {
848 ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO);
849 if (ret != MM_ERROR_NONE) {
850 MMRADIO_LOG_ERROR("resource manager prepare fail");
851 return MM_ERROR_RADIO_INTERNAL;
853 ret = mmradio_resource_manager_acquire(&radio->resource_manager);
854 if (ret != MM_ERROR_NONE) {
855 MMRADIO_LOG_ERROR("failed to acquire resource manager");
856 mmradio_resource_manager_unprepare(&radio->resource_manager);
860 ret = radio_hal_prepare(radio->hal_inf);
861 if (ret == MM_ERROR_NOT_SUPPORT_API) {
862 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
863 } else if (ret != MM_ERROR_NONE) {
864 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
868 ret = radio_hal_open(radio->hal_inf);
869 if (ret == MM_ERROR_NOT_SUPPORT_API) {
870 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
871 } else if (ret != MM_ERROR_NONE) {
872 MMRADIO_LOG_ERROR("radio_hal_init error");
873 MMRADIO_LOG_FLEAVE();
876 radio->is_ready = TRUE;
878 MMRADIO_LOG_DEBUG("radio prepared and opened");
881 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
883 if (scan_tr_id != 0) {
884 MMRADIO_LOG_ERROR("failed to create thread : scan");
885 return MM_ERROR_RADIO_NOT_INITIALIZED;
888 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
890 MMRADIO_LOG_FLEAVE();
892 return MM_ERROR_NONE;
895 int _mmradio_stop_scan(mm_radio_t *radio)
898 char str_error[READ_MAX_BUFFER_SIZE];
899 MMRADIO_LOG_FENTER();
901 MMRADIO_CHECK_INSTANCE(radio);
902 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
904 radio->stop_scan = true;
906 if (radio->scan_thread > 0) {
907 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
908 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
909 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
910 if (ret == EBUSY) { /* it was already locked by other */
911 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
912 } else if (ret == 0) {
913 MMRADIO_LOG_INFO("trylock is successful. unlock now");
914 pthread_mutex_unlock(&radio->seek_cancel_mutex);
916 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
918 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
919 pthread_join(radio->scan_thread, NULL);
920 radio->scan_thread = 0;
923 MMRADIO_LOG_FLEAVE();
925 return MM_ERROR_NONE;
928 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
930 int ret = MM_ERROR_NONE;
931 int32_t strength = 0;
932 MMRADIO_LOG_FENTER();
933 MMRADIO_CHECK_INSTANCE(radio);
935 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
937 /* just return stored frequency if radio device is not ready */
938 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
939 if (ret == MM_ERROR_NOT_SUPPORT_API) {
940 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
941 } else if (ret != MM_ERROR_NONE) {
942 MMRADIO_LOG_ERROR("radio_hal_get_signal_strength error");
944 MMRADIO_LOG_FLEAVE();
947 *value = (int)strength;
948 MMRADIO_LOG_FLEAVE();
949 return MM_ERROR_NONE;
952 void __mmradio_scan_thread(mm_radio_t *radio)
954 int ret = MM_ERROR_NONE;
956 mm_radio_resource_state_e resource_state = MM_RADIO_RESOURCE_STATE_NONE;
958 MMRADIO_LOG_FENTER();
959 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
961 ret = radio_hal_mute(radio->hal_inf);
963 if (ret == MM_ERROR_NOT_SUPPORT_API) {
964 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
965 } else if (ret != MM_ERROR_NONE) {
966 MMRADIO_LOG_ERROR("radio_hal_mute error");
969 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
971 if (ret != MM_ERROR_NONE)
974 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
975 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
977 while (!radio->stop_scan) {
979 MMMessageParamType param = { 0, };
981 MMRADIO_LOG_DEBUG("scanning....");
983 pthread_mutex_lock(&radio->seek_cancel_mutex);
985 if (radio->stop_scan) {
986 MMRADIO_LOG_INFO("scan was canceled");
987 pthread_mutex_unlock(&radio->seek_cancel_mutex);
991 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
993 pthread_mutex_unlock(&radio->seek_cancel_mutex);
995 if (ret != MM_ERROR_NONE) {
996 MMRADIO_LOG_ERROR("radio scanning error");
1000 /* now we can get new frequency from radio device */
1001 if (radio->stop_scan)
1004 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1005 if (ret != MM_ERROR_NONE) {
1006 MMRADIO_LOG_ERROR("failed to get current frequency");
1008 if (freq <= prev_freq) {
1009 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
1013 prev_freq = param.radio_scan.frequency = (int)freq;
1014 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
1016 /* drop if max freq is scanned */
1017 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
1018 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
1022 if (radio->stop_scan) {
1023 /* doesn't need to post */
1027 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
1031 if (radio->old_state == MM_RADIO_STATE_READY) {
1032 MMRADIO_LOG_DEBUG("old state is ready");
1033 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
1034 MMRADIO_LOG_DEBUG("old state is playing");
1035 ret = radio_hal_unmute(radio->hal_inf);
1036 if (ret == MM_ERROR_NOT_SUPPORT_API) {
1037 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
1038 } else if (ret != MM_ERROR_NONE) {
1039 MMRADIO_LOG_ERROR("radio_hal_unmute error");
1042 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
1043 if (ret == MM_ERROR_NOT_SUPPORT_API) {
1044 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
1045 } else if (ret != MM_ERROR_NONE) {
1046 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
1053 radio->scan_thread = 0;
1055 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
1056 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
1058 /* close radio device here !!!! */
1059 ret = radio_hal_close(radio->hal_inf);
1060 if (ret == MM_ERROR_NOT_SUPPORT_API)
1061 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
1062 else if (ret != MM_ERROR_NONE)
1063 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1065 ret = radio_hal_unprepare(radio->hal_inf);
1066 if (ret == MM_ERROR_NOT_SUPPORT_API)
1067 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
1068 else if (ret != MM_ERROR_NONE)
1069 MMRADIO_LOG_ERROR("radio_hal_close_device error");
1071 radio->is_ready = FALSE;
1073 if (!radio->resource_manager.by_rm_cb && /* is being released */
1074 mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
1075 if (resource_state == MM_RADIO_RESOURCE_STATE_ACQUIRED) {
1076 ret = mmradio_resource_manager_release(&radio->resource_manager);
1077 if (ret != MM_ERROR_NONE)
1078 MMRADIO_LOG_ERROR("failed to release resource, ret(0x%x)", ret);
1082 if (mmradio_resource_manager_get_state(&radio->resource_manager, &resource_state) == MM_ERROR_NONE) {
1083 if (resource_state == MM_RADIO_RESOURCE_STATE_PREPARED) {
1084 ret = mmradio_resource_manager_unprepare(&radio->resource_manager);
1085 if (ret != MM_ERROR_NONE)
1086 MMRADIO_LOG_ERROR("resource manager unprepare fail");
1090 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
1093 if (!radio->stop_scan)
1094 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
1096 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
1098 MMRADIO_LOG_FLEAVE();
1105 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1107 MMRADIO_LOG_FENTER();
1109 MMRADIO_CHECK_INSTANCE(radio);
1111 if (freq >= radio->region_setting.band_max
1112 || freq <= radio->region_setting.band_min)
1115 MMRADIO_LOG_FLEAVE();
1120 void __mmradio_seek_thread(mm_radio_t *radio)
1122 int ret = MM_ERROR_NONE;
1124 MMMessageParamType param = {0, };
1126 MMRADIO_LOG_FENTER();
1127 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1129 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1131 MMRADIO_LOG_DEBUG("seeking....");
1133 if (!radio->seek_cancel) {
1135 MMRADIO_LOG_DEBUG("try to seek ");
1136 pthread_mutex_lock(&radio->seek_cancel_mutex);
1137 MMRADIO_LOG_DEBUG("seek start");
1139 if (radio->seek_cancel) {
1140 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1141 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1145 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1146 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1148 MMRADIO_LOG_ERROR("radio_hal_seek failed");
1152 /* now we can get new frequency from radio device */
1153 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1155 MMRADIO_LOG_ERROR("failed to get current frequency");
1159 MMRADIO_LOG_DEBUG("found frequency");
1161 /* if same freq is found, ignore it and search next one. */
1162 if (freq == radio->prev_seek_freq) {
1163 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1167 /* check if it's limit freq or not */
1168 if (__is_tunable_frequency(radio, freq)) {
1169 /* now tune to new frequency */
1170 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1172 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1175 radio->freq = (int)freq;
1176 MMRADIO_LOG_WARNING("setting frequency : [%d]", radio->freq);
1179 if (radio->seek_unmute) {
1180 /* now turn on radio
1181 * In the case of limit freq, tuner should be unmuted.
1182 * Otherwise, sound can't output even though application set new frequency.
1184 ret = radio_hal_unmute(radio->hal_inf);
1186 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1189 radio->seek_unmute = FALSE;
1192 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1193 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1194 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1197 radio->seek_thread = 0;
1198 radio->is_seeking = FALSE;
1200 MMRADIO_LOG_FLEAVE();
1207 if (radio->seek_unmute) {
1208 /* now turn on radio
1209 * In the case of limit freq, tuner should be unmuted.
1210 * Otherwise, sound can't output even though application set new frequency.
1212 ret = radio_hal_unmute(radio->hal_inf);
1214 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1215 radio->seek_unmute = FALSE;
1217 /* freq -1 means it's failed to seek */
1218 param.radio_scan.frequency = -1;
1219 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1220 radio->is_seeking = FALSE;
1221 radio->seek_thread = 0;
1226 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1228 MMRADIO_CHECK_INSTANCE(radio);
1230 MMRADIO_LOG_FENTER();
1232 if (!radio->msg_cb) {
1233 MMRADIO_LOG_WARNING("failed to post a message");
1237 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1239 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1241 MMRADIO_LOG_FLEAVE();
1246 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1248 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1250 MMRADIO_LOG_FENTER();
1252 MMRADIO_CHECK_INSTANCE(radio);
1254 radio_state = __mmradio_get_state(radio);
1256 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1259 case MMRADIO_COMMAND_CREATE:
1261 if (radio_state != 0)
1266 case MMRADIO_COMMAND_REALIZE:
1268 if (radio_state == MM_RADIO_STATE_READY ||
1269 radio_state == MM_RADIO_STATE_PLAYING ||
1270 radio_state == MM_RADIO_STATE_SCANNING)
1273 if (radio_state == 0)
1278 case MMRADIO_COMMAND_UNREALIZE:
1280 if (radio_state == MM_RADIO_STATE_NULL)
1283 /* we can call unrealize at any higher state */
1287 case MMRADIO_COMMAND_START:
1289 if (radio_state == MM_RADIO_STATE_PLAYING)
1292 if (radio_state != MM_RADIO_STATE_READY)
1297 case MMRADIO_COMMAND_STOP:
1299 if (radio_state == MM_RADIO_STATE_READY)
1302 if (radio_state != MM_RADIO_STATE_PLAYING)
1307 case MMRADIO_COMMAND_START_SCAN:
1309 if (radio_state == MM_RADIO_STATE_SCANNING)
1312 if (radio_state == MM_RADIO_STATE_NULL)
1317 case MMRADIO_COMMAND_STOP_SCAN:
1319 if (radio_state == MM_RADIO_STATE_READY)
1322 if (radio_state != MM_RADIO_STATE_SCANNING)
1327 case MMRADIO_COMMAND_DESTROY:
1328 case MMRADIO_COMMAND_MUTE:
1329 case MMRADIO_COMMAND_UNMUTE:
1330 case MMRADIO_COMMAND_SET_FREQ:
1331 case MMRADIO_COMMAND_GET_FREQ:
1332 case MMRADIO_COMMAND_SET_REGION:
1333 case MMRADIO_COMMAND_SET_VOLUME:
1334 case MMRADIO_COMMAND_GET_VOLUME:
1336 /* we can do it at any state */
1340 case MMRADIO_COMMAND_SEEK:
1342 if (radio_state != MM_RADIO_STATE_PLAYING)
1347 case MMRADIO_COMMAND_GET_REGION:
1349 if (radio_state == MM_RADIO_STATE_NULL)
1355 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1359 MMRADIO_LOG_DEBUG("status OK");
1361 radio->cmd = command;
1363 MMRADIO_LOG_FLEAVE();
1365 return MM_ERROR_NONE;
1368 MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
1369 MMRADIO_LOG_FLEAVE();
1370 return MM_ERROR_RADIO_INVALID_STATE;
1373 MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
1374 MMRADIO_LOG_FLEAVE();
1375 return MM_ERROR_RADIO_NO_OP;
1379 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1381 MMMessageParamType msg = { 0, };
1382 int msg_type = MM_MESSAGE_UNKNOWN;
1384 MMRADIO_LOG_FENTER();
1387 MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
1391 if (radio->current_state == new_state && radio->pending_state == 0) {
1392 MMRADIO_LOG_WARNING("we are in same state");
1397 radio->old_state = radio->current_state;
1398 radio->current_state = new_state;
1400 /* fill message param */
1401 msg.union_type = MM_MSG_UNION_STATE;
1402 msg.state.previous = radio->old_state;
1403 msg.state.current = radio->current_state;
1405 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1406 /* post message to application */
1407 if (radio->sound_focus.by_focus_cb) {
1408 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1409 msg.state.code = radio->sound_focus.event_src;
1410 MMRADIO_POST_MSG(radio, msg_type, &msg);
1411 } else if (radio->resource_manager.by_rm_cb) {
1412 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1413 msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1414 MMRADIO_POST_MSG(radio, msg_type, &msg);
1416 msg_type = MM_MESSAGE_STATE_CHANGED;
1417 MMRADIO_POST_MSG(radio, msg_type, &msg);
1420 if (radio->resource_manager.by_rm_cb) {
1421 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1422 msg.state.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT;
1423 MMRADIO_POST_MSG(radio, msg_type, &msg);
1425 msg_type = MM_MESSAGE_STATE_CHANGED;
1426 MMRADIO_POST_MSG(radio, msg_type, &msg);
1431 MMRADIO_LOG_FLEAVE();
1436 static int __mmradio_get_state(mm_radio_t *radio)
1438 MMRADIO_CHECK_INSTANCE(radio);
1440 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1441 radio->current_state, radio->old_state, radio->pending_state);
1443 return radio->current_state;
1446 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1447 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1448 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1449 const char *additional_info, void *user_data)
1451 mm_radio_t *radio = (mm_radio_t *)user_data;
1452 enum MMMessageInterruptedCode event_source;
1453 int result = MM_ERROR_NONE;
1454 int postMsg = false;
1456 MMRADIO_LOG_FENTER();
1457 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1458 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1460 mmradio_get_sound_focus_reason(focus_state, reason_for_change, FALSE, &event_source, &postMsg);
1461 radio->sound_focus.event_src = event_source;
1463 switch (focus_state) {
1464 case FOCUS_IS_RELEASED:{
1465 radio->sound_focus.cur_focus_type &= ~focus_type;
1466 radio->sound_focus.by_focus_cb = true;
1468 MMRADIO_CMD_LOCK(radio);
1469 result = _mmradio_stop(radio);
1471 MMRADIO_LOG_ERROR("failed to stop radio");
1472 MMRADIO_CMD_UNLOCK(radio);
1474 radio->sound_focus.by_focus_cb = false;
1476 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1480 case FOCUS_IS_ACQUIRED:{
1481 MMMessageParamType msg = { 0, };
1482 msg.union_type = MM_MSG_UNION_CODE;
1483 msg.code = event_source;
1485 radio->sound_focus.cur_focus_type |= focus_type;
1487 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1488 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1490 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1495 MMRADIO_LOG_DEBUG("Unknown focus_state");
1499 MMRADIO_LOG_FLEAVE();
1502 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1503 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1504 const char *additional_info, void *user_data)
1506 mm_radio_t *radio = (mm_radio_t *)user_data;
1507 enum MMMessageInterruptedCode event_source;
1508 int result = MM_ERROR_NONE;
1509 int postMsg = false;
1511 MMRADIO_LOG_FENTER();
1512 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1513 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1515 mmradio_get_sound_focus_reason(focus_state, reason_for_change, TRUE, &event_source, &postMsg);
1516 radio->sound_focus.event_src = event_source;
1518 switch (focus_state) {
1519 case FOCUS_IS_ACQUIRED: {
1520 radio->sound_focus.cur_focus_type &= ~focus_type;
1521 radio->sound_focus.by_focus_cb = true;
1523 MMRADIO_CMD_LOCK(radio);
1524 result = _mmradio_stop(radio);
1526 MMRADIO_LOG_ERROR("failed to stop radio");
1527 MMRADIO_CMD_UNLOCK(radio);
1529 radio->sound_focus.by_focus_cb = false;
1531 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1535 case FOCUS_IS_RELEASED: {
1536 MMMessageParamType msg = { 0, };
1537 msg.union_type = MM_MSG_UNION_CODE;
1538 msg.code = event_source;
1540 radio->sound_focus.cur_focus_type |= focus_type;
1542 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1543 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1545 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1550 MMRADIO_LOG_DEBUG("Unknown focus_state");
1554 MMRADIO_LOG_FLEAVE();
1558 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1560 mm_radio_t *radio = (mm_radio_t *)user_data;
1561 int ret = MM_ERROR_NONE;
1562 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1563 if (type == VOLUME_TYPE_MEDIA) {
1564 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1565 ret = __mmradio_set_media_volume(radio, volume);
1566 if (ret != MM_ERROR_NONE)
1567 MMRADIO_LOG_ERROR("__mmradio_set_media_volume error");
1572 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1574 MMRADIO_LOG_FENTER();
1575 MMRADIO_CHECK_INSTANCE(radio);
1576 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1578 return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT);
1580 *type = radio->region_setting.country;
1582 MMRADIO_LOG_FLEAVE();
1583 return MM_ERROR_NONE;
1586 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1588 MMRADIO_LOG_FENTER();
1589 MMRADIO_CHECK_INSTANCE(radio);
1590 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1592 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1594 *min_freq = radio->region_setting.band_min;
1595 *max_freq = radio->region_setting.band_max;
1597 MMRADIO_LOG_FLEAVE();
1598 return MM_ERROR_NONE;
1601 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1603 MMRADIO_LOG_FENTER();
1604 MMRADIO_CHECK_INSTANCE(radio);
1605 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1607 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1609 *ch_spacing = radio->region_setting.channel_spacing;
1611 MMRADIO_LOG_FLEAVE();
1612 return MM_ERROR_NONE;
1615 int _mmradio_set_volume(mm_radio_t *radio, float volume)
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 %f volume", volume);
1626 MMRADIO_VOLUME_LOCK(radio);
1627 radio->local_volume = volume;
1628 MMRADIO_VOLUME_UNLOCK(radio);
1630 ret = radio_hal_set_volume(radio->hal_inf, volume);
1631 if (ret != MM_ERROR_NONE)
1632 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1634 MMRADIO_LOG_FLEAVE();
1639 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1641 int ret = MM_ERROR_NONE;
1643 MMRADIO_LOG_FENTER();
1645 MMRADIO_CHECK_INSTANCE(radio);
1646 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1648 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1650 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1651 if (ret != MM_ERROR_NONE) {
1652 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1657 MMRADIO_VOLUME_LOCK(radio);
1658 radio->local_volume = volume;
1659 *pVolume = (float)radio->local_volume;
1660 MMRADIO_VOLUME_UNLOCK(radio);
1662 MMRADIO_LOG_FLEAVE();
1667 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1669 int ret = MM_ERROR_NONE;
1671 MMRADIO_LOG_FENTER();
1673 MMRADIO_CHECK_INSTANCE(radio);
1674 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1676 MMRADIO_LOG_INFO("Setting %d volume", level);
1678 MMRADIO_VOLUME_LOCK(radio);
1679 radio->media_volume = level;
1680 MMRADIO_VOLUME_UNLOCK(radio);
1682 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1683 if (ret != MM_ERROR_NONE)
1684 MMRADIO_LOG_ERROR("radio_hal_set_media_volume error");
1686 MMRADIO_LOG_FLEAVE();