diff options
author | Gilbok Lee <gilbok.lee@samsung.com> | 2017-04-10 13:17:41 +0900 |
---|---|---|
committer | Gilbok Lee <gilbok.lee@samsung.com> | 2017-04-10 16:41:05 +0900 |
commit | 42e03880d935d628608776e138915c23cbe6f780 (patch) | |
tree | 56b06b55da1d627e79a7c7611fb29986870c59ab | |
parent | 3bc8e303ae07b3d3c9933495b86f6d7ebc0c875c (diff) | |
download | libmm-radio-42e03880d935d628608776e138915c23cbe6f780.tar.gz libmm-radio-42e03880d935d628608776e138915c23cbe6f780.tar.bz2 libmm-radio-42e03880d935d628608776e138915c23cbe6f780.zip |
Added implementation of interruption by resource managersubmit/tizen/20170420.053325accepted/tizen/unified/20170420.154835
1. Add cmd rock during _mm_radio_stop()
[Version] 0.2.25
[Profile] Mobile, Wearable
[Issue Type] Add featuresBrief
Change-Id: I720bbed4681ac7f8c870164d08413d35db3b54ea
-rwxr-xr-x | configure.ac | 8 | ||||
-rwxr-xr-x | packaging/libmm-radio.spec | 4 | ||||
-rwxr-xr-x | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/include/mm_radio_priv_hal.h | 3 | ||||
-rw-r--r-- | src/include/mm_radio_resource.h | 81 | ||||
-rw-r--r-- | src/mm_radio_priv_emulator.c | 4 | ||||
-rw-r--r-- | src/mm_radio_priv_hal.c | 71 | ||||
-rw-r--r-- | src/mm_radio_resource.c | 525 | ||||
-rw-r--r-- | src/mm_radio_sound_focus.c | 2 |
9 files changed, 702 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac index c41fa8c..d61edb8 100755 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,14 @@ PKG_CHECK_MODULES(MMCOMMON, mm-common) AC_SUBST(MMCOMMON_CFLAGS) AC_SUBST(MMCOMMON_LIBS) +PKG_CHECK_MODULES(MURPHY_RESOURCE, murphy-resource) +AC_SUBST(MURPHY_RESOURCE_CFLAGS) +AC_SUBST(MURPHY_RESOURCE_LIBS) + +PKG_CHECK_MODULES(MURPHY_GLIB, murphy-glib) +AC_SUBST(MURPHY_GLIB_CFLAGS) +AC_SUBST(MURPHY_GLIB_LIBS) + AC_ARG_ENABLE(emulator, AC_HELP_STRING([--enable-emulator], [using emulator interface]), [ case "${enableval}" in diff --git a/packaging/libmm-radio.spec b/packaging/libmm-radio.spec index d51df59..b2a5727 100755 --- a/packaging/libmm-radio.spec +++ b/packaging/libmm-radio.spec @@ -1,6 +1,6 @@ Name: libmm-radio Summary: Multimedia Framework Radio Library -Version: 0.2.24 +Version: 0.2.25 Release: 0 Group: System/Libraries License: Apache-2.0 @@ -17,6 +17,8 @@ BuildRequires: pkgconfig(capi-media-sound-manager) BuildRequires: pkgconfig(gstreamer-1.0) BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) %endif +BuildRequires: pkgconfig(murphy-resource) +BuildRequires: pkgconfig(murphy-glib) %description Description: Multimedia Framework Radio Library diff --git a/src/Makefile.am b/src/Makefile.am index 1b67d95..18ce7ce 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,15 +3,21 @@ lib_LTLIBRARIES = libmmfradio.la includelibmmfradiodir = $(includedir)/mmf includelibmmfradio_HEADERS = include/mm_radio.h -libmmfradio_la_SOURCES = mm_radio.c +libmmfradio_la_SOURCES = mm_radio.c \ + mm_radio_resource.c libmmfradio_la_CFLAGS = -I. -I./include \ $(GTHREAD_CFLAGS) \ $(MMCOMMON_CFLAGS) \ + $(MURPHY_RESOURCE_CFLAGS) \ + $(MURPHY_GLIB_CFLAGS) \ -DMMF_LOG_OWNER=0x200000 -DMMF_DEBUG_PREFIX=\"MM-RADIO\" libmmfradio_la_LIBADD = $(GTHREAD_LIBS) \ - $(MMCOMMON_LIBS) + $(MMCOMMON_LIBS) \ + $(MURPHY_RESOURCE_LIBS) \ + $(MURPHY_GLIB_LIBS) + if ENABLE_EMULATOR libmmfradio_la_SOURCES += mm_radio_priv_emulator.c diff --git a/src/include/mm_radio_priv_hal.h b/src/include/mm_radio_priv_hal.h index 72e2ef3..67bcf82 100644 --- a/src/include/mm_radio_priv_hal.h +++ b/src/include/mm_radio_priv_hal.h @@ -42,6 +42,7 @@ #include <media/sound_manager_internal.h> #endif +#include "mm_radio_resource.h" #include "mm_radio.h" #include "mm_radio_utils.h" #include "radio_hal_interface.h" @@ -193,6 +194,8 @@ typedef struct { mm_radio_hal_interface *hal_inf; + mm_radio_resource_manager resource_manager; + } mm_radio_t; /*=========================================================================================== diff --git a/src/include/mm_radio_resource.h b/src/include/mm_radio_resource.h new file mode 100644 index 0000000..85006ba --- /dev/null +++ b/src/include/mm_radio_resource.h @@ -0,0 +1,81 @@ +/* + * mm_radio_resource.h + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Heechul Jeon <heechul.jeon@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __MM_RADIO_RESOURCE_H__ +#define __MM_RADIO_RESOURCE_H__ + +#include <murphy/plugins/resource-native/libmurphy-resource/resource-api.h> +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define __MMRADIO_RESOURCE_WAIT_TIME 3 + +#define MMRADIO_GET_RESOURCE_LOCK(rm) (&((mm_radio_resource_manager *)rm)->lock) +#define MMRADIO_RESOURCE_LOCK(rm) (g_mutex_lock(MMRADIO_GET_RESOURCE_LOCK(rm))) +#define MMRADIO_RESOURCE_UNLOCK(rm) (g_mutex_unlock(MMRADIO_GET_RESOURCE_LOCK(rm))) + +#define MMRADIO_GET_RESOURCE_COND(rm) (&((mm_radio_resource_manager *)rm)->cond) +#define MMRADIO_RESOURCE_WAIT(rm) g_cond_wait(MMRADIO_GET_RESOURCE_COND(rm), MMRADIO_GET_RESOURCE_LOCK(rm) +#define MMRADIO_RESOURCE_WAIT_UNTIL(rm, end_time) \ + g_cond_wait_until(MMRADIO_GET_RESOURCE_COND(rm), MMRADIO_GET_RESOURCE_LOCK(rm), end_time) +#define MMRADIO_RESOURCE_SIGNAL(rm) g_cond_signal(MMRADIO_GET_RESOURCE_COND(rm)); + + +typedef enum { + MM_RADIO_RESOURCE_TYPE_RADIO, + MM_RADIO_RESOURCE_MAX +} mm_radio_resource_type_e; + +typedef enum { + MM_RADIO_RESOURCE_STATE_NONE, + MM_RADIO_RESOURCE_STATE_INITIALIZED, + MM_RADIO_RESOURCE_STATE_PREPARED, + MM_RADIO_RESOURCE_STATE_ACQUIRED, + MM_RADIO_RESOURCE_STATE_MAX, +} mm_radio_resource_state_e; + +typedef struct { + mrp_mainloop_t *mloop; + mrp_res_context_t *context; + mrp_res_resource_set_t *rset; + mm_radio_resource_state_e state; + GCond cond; + GMutex lock; + void *user_data; + bool is_connected; + bool by_rm_cb; +} mm_radio_resource_manager; + +int mmradio_resource_manager_init(mm_radio_resource_manager *resource_manager, void *user_data); +int mmradio_resource_manager_deinit(mm_radio_resource_manager *resource_manager); +int mmradio_resource_manager_prepare(mm_radio_resource_manager *resource_manager, mm_radio_resource_type_e resource_type); +int mmradio_resource_manager_unprepare(mm_radio_resource_manager *resource_manager); +int mmradio_resource_manager_acquire(mm_radio_resource_manager *resource_manager); +int mmradio_resource_manager_release(mm_radio_resource_manager *resource_manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __MM_RADIO_RESOURCE_H__ */ diff --git a/src/mm_radio_priv_emulator.c b/src/mm_radio_priv_emulator.c index 9219214..b2ceed4 100644 --- a/src/mm_radio_priv_emulator.c +++ b/src/mm_radio_priv_emulator.c @@ -1295,9 +1295,11 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type, radio->sound_focus.cur_focus_type &= ~focus_type; radio->sound_focus.by_focus_cb = true; + MMRADIO_CMD_LOCK(radio); result = _mmradio_stop(radio); if (result) MMRADIO_LOG_ERROR("failed to stop radio\n"); + MMRADIO_CMD_UNLOCK(radio); radio->sound_focus.by_focus_cb = false; @@ -1347,9 +1349,11 @@ static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_t radio->sound_focus.cur_focus_type &= ~focus_type; radio->sound_focus.by_focus_cb = true; + MMRADIO_CMD_LOCK(radio); result = _mmradio_stop(radio); if (result) MMRADIO_LOG_ERROR("failed to stop radio\n"); + MMRADIO_CMD_UNLOCK(radio); radio->sound_focus.by_focus_cb = false; diff --git a/src/mm_radio_priv_hal.c b/src/mm_radio_priv_hal.c index f13b632..f4a92e9 100644 --- a/src/mm_radio_priv_hal.c +++ b/src/mm_radio_priv_hal.c @@ -209,6 +209,13 @@ int _mmradio_create_radio(mm_radio_t *radio) MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); + /* initialize resource manager */ + ret = mmradio_resource_manager_init(&radio->resource_manager, radio); + if (ret) { + MMRADIO_LOG_ERROR("failed to initialize resource manager\n"); + return MM_ERROR_RADIO_INTERNAL; + } + #ifdef TIZEN_FEATURE_SOUND_FOCUS ret = mmradio_sound_focus_register(&radio->sound_focus, (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb, @@ -263,6 +270,12 @@ int _mmradio_realize(mm_radio_t *radio) ret = _mmradio_apply_region(radio, region, update); + ret = mmradio_resource_manager_prepare(&radio->resource_manager, MM_RADIO_RESOURCE_TYPE_RADIO); + if (ret != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("resource manager prepare fail"); + return MM_ERROR_RADIO_INTERNAL; + } + #ifdef TIZEN_FEATURE_SOUND_VSTREAM ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info); if (ret != MM_ERROR_NONE) { @@ -332,6 +345,10 @@ int _mmradio_unrealize(mm_radio_t *radio) sound_manager_destroy_virtual_stream(radio->vstream); sound_manager_destroy_stream_information(radio->stream_info); #endif + mmradio_resource_manager_unprepare(&radio->resource_manager); + if (ret != MM_ERROR_NONE) + MMRADIO_LOG_ERROR("resource manager unprepare fail"); + pthread_mutex_destroy(&radio->seek_cancel_mutex); MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL); @@ -375,6 +392,13 @@ int _mmradio_destroy(mm_radio_t *radio) return MM_ERROR_RADIO_INTERNAL; } #endif + + ret = mmradio_resource_manager_deinit(&radio->resource_manager); + if (ret) { + MMRADIO_LOG_ERROR("failed to initialize resource manager\n"); + return MM_ERROR_RADIO_INTERNAL; + } + MMRADIO_LOG_FLEAVE(); return MM_ERROR_NONE; @@ -541,6 +565,11 @@ int _mmradio_start(mm_radio_t *radio) #endif if (!radio->is_ready) { + ret = mmradio_resource_manager_acquire(&radio->resource_manager); + if (ret != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("failed to acquire resource manager"); + return ret; + } ret = radio_hal_prepare(radio->hal_inf); if (ret == MM_ERROR_NOT_SUPPORT_API) { MMRADIO_LOG_WARNING("radio_hal_prepare is not supported"); @@ -659,6 +688,12 @@ int _mmradio_stop(mm_radio_t *radio) radio->is_ready = FALSE; + ret = mmradio_resource_manager_release(&radio->resource_manager); + if (ret != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("failed to release resource"); + return ret; + } + #ifdef TIZEN_FEATURE_SOUND_FOCUS if (radio->sound_focus.handle > 0) { ret = mmradio_release_sound_focus(&radio->sound_focus); @@ -776,6 +811,12 @@ int _mmradio_start_scan(mm_radio_t *radio) radio->stop_scan = false; if (!radio->is_ready) { + ret = mmradio_resource_manager_acquire(&radio->resource_manager); + if (ret != MM_ERROR_NONE) { + MMRADIO_LOG_ERROR("failed to acquire resource manager"); + return ret; + } + ret = radio_hal_prepare(radio->hal_inf); if (ret == MM_ERROR_NOT_SUPPORT_API) { MMRADIO_LOG_WARNING("radio_hal_prepare is not supported"); @@ -847,7 +888,7 @@ int _mmradio_stop_scan(mm_radio_t *radio) int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value) { int ret = MM_ERROR_NONE; - uint32_t strength = 0; + int32_t strength = 0; MMRADIO_LOG_FENTER(); MMRADIO_CHECK_INSTANCE(radio); @@ -988,6 +1029,10 @@ FINISHED_ERR: radio->is_ready = FALSE; + ret = mmradio_resource_manager_release(&radio->resource_manager); + if (ret != MM_ERROR_NONE) + MMRADIO_LOG_ERROR("failed to release resource"); + MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY); } @@ -1073,6 +1118,8 @@ void __mmradio_seek_thread(mm_radio_t *radio) MMRADIO_LOG_ERROR("failed to tune to new frequency"); goto SEEK_FAILED; } + radio->freq = (int)freq; + MMRADIO_LOG_WARNING("setting frequency : [%d]", radio->freq); } if (radio->seek_unmute) { @@ -1117,6 +1164,7 @@ SEEK_FAILED: param.radio_scan.frequency = -1; MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m); radio->is_seeking = FALSE; + radio->seek_thread = 0; pthread_exit(NULL); return; } @@ -1306,13 +1354,26 @@ static bool __mmradio_set_state(mm_radio_t *radio, int new_state) msg.union_type = MM_MSG_UNION_CODE; msg.code = radio->sound_focus.event_src; MMRADIO_POST_MSG(radio, msg_type, &msg); + } else if (radio->resource_manager.by_rm_cb) { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT; + MMRADIO_POST_MSG(radio, msg_type, &msg); } else { msg_type = MM_MESSAGE_STATE_CHANGED; MMRADIO_POST_MSG(radio, msg_type, &msg); } #else - msg_type = MM_MESSAGE_STATE_CHANGED; - MMRADIO_POST_MSG(radio, msg_type, &msg); + if (radio->resource_manager.by_rm_cb) { + msg_type = MM_MESSAGE_STATE_INTERRUPTED; + msg.union_type = MM_MSG_UNION_CODE; + msg.code = MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } else { + msg_type = MM_MESSAGE_STATE_CHANGED; + MMRADIO_POST_MSG(radio, msg_type, &msg); + } + #endif MMRADIO_LOG_FLEAVE(); @@ -1352,9 +1413,11 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type, radio->sound_focus.cur_focus_type &= ~focus_type; radio->sound_focus.by_focus_cb = true; + MMRADIO_CMD_LOCK(radio); result = _mmradio_stop(radio); if (result) MMRADIO_LOG_ERROR("failed to stop radio"); + MMRADIO_CMD_UNLOCK(radio); radio->sound_focus.by_focus_cb = false; @@ -1405,9 +1468,11 @@ static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_t radio->sound_focus.cur_focus_type &= ~focus_type; radio->sound_focus.by_focus_cb = true; + MMRADIO_CMD_LOCK(radio); result = _mmradio_stop(radio); if (result) MMRADIO_LOG_ERROR("failed to stop radio"); + MMRADIO_CMD_UNLOCK(radio); radio->sound_focus.by_focus_cb = false; diff --git a/src/mm_radio_resource.c b/src/mm_radio_resource.c new file mode 100644 index 0000000..0e53030 --- /dev/null +++ b/src/mm_radio_resource.c @@ -0,0 +1,525 @@ +/* + * mm_radio_resource.c + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "mm_radio_utils.h" +#include "mm_radio_priv_hal.h" +#include "mm_radio_resource.h" +#include <murphy/common/glib-glue.h> + +#define MMRADIO_RESOURCE_TIMEOUT 5 +#define MRP_APP_CLASS_FOR_RADIO "media" +#define MRP_RESOURCE_TYPE_MANDATORY TRUE +#define MRP_RESOURCE_TYPE_EXCLUSIVE FALSE + +const char* mm_radio_resource_str[MM_RADIO_RESOURCE_MAX] = { + "radio" +}; + +#define MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(x_radio_resource_manager) \ +do { \ + if (!x_radio_resource_manager) { \ + MMRADIO_LOG_ERROR("no resource manager instance"); \ + return MM_ERROR_INVALID_ARGUMENT; \ + } \ +} while (0); + +#define MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(x_radio_resource_manager) \ +do { \ + if (!x_radio_resource_manager) { \ + MMRADIO_LOG_ERROR("no resource manager instance"); \ + return MM_ERROR_INVALID_ARGUMENT; \ + } else { \ + if (!x_radio_resource_manager->is_connected) { \ + MMRADIO_LOG_ERROR("not connected to resource server yet"); \ + return MM_ERROR_RESOURCE_NOT_INITIALIZED; \ + } \ + } \ +} while (0); + +static char *_mmrdio_resource_state_to_str(mrp_res_resource_state_t st) +{ + char *state = "unknown"; + switch (st) { + case MRP_RES_RESOURCE_ACQUIRED: + state = "acquired"; + break; + case MRP_RES_RESOURCE_LOST: + state = "lost"; + break; + case MRP_RES_RESOURCE_AVAILABLE: + state = "available"; + break; + case MRP_RES_RESOURCE_PENDING: + state = "pending"; + break; + case MRP_RES_RESOURCE_ABOUT_TO_LOOSE: + state = "about to loose"; + break; + } + return state; +} + +static void __mmradio_resource_state_callback(mrp_res_context_t *context, mrp_res_error_t err, void *user_data) +{ + + int i = 0; + const mrp_res_resource_set_t *rset; + mrp_res_resource_t *resource; + mm_radio_t *radio = NULL; + + MMRADIO_LOG_FENTER(); + + if (user_data == NULL) { + MMRADIO_LOG_ERROR(" - user data is null\n"); + return; + } + radio = (mm_radio_t *)user_data; + if (err != MRP_RES_ERROR_NONE) { + MMRADIO_LOG_ERROR(" - error message received from Murphy, for the radio(%p), err(0x%x)\n", radio, err); + return; + } + + switch (context->state) { + case MRP_RES_CONNECTED: + MMRADIO_LOG_DEBUG(" - connected to Murphy\n"); + if ((rset = mrp_res_list_resources(context)) != NULL) { + mrp_res_string_array_t *resource_names; + resource_names = mrp_res_list_resource_names(rset); + if (!resource_names) { + MMRADIO_LOG_ERROR(" - no resources available\n"); + return; + } + for (i = 0; i < resource_names->num_strings; i++) { + resource = mrp_res_get_resource_by_name(rset, resource_names->strings[i]); + if (resource) + MMRADIO_LOG_DEBUG(" - available resource: %s", resource->name); + } + mrp_res_free_string_array(resource_names); + } + radio->resource_manager.is_connected = true; + break; + case MRP_RES_DISCONNECTED: + MMRADIO_LOG_DEBUG(" - disconnected from Murphy\n"); + if (radio->resource_manager.rset) { + mrp_res_delete_resource_set(radio->resource_manager.rset); + radio->resource_manager.rset = NULL; + } + mrp_res_destroy(radio->resource_manager.context); + radio->resource_manager.context = NULL; + radio->resource_manager.is_connected = false; + break; + } + + MMRADIO_LOG_FLEAVE(); +} + +static void __mmradio_rset_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data) +{ + int i = 0; + mm_radio_t *radio = (mm_radio_t *)user_data; + mrp_res_resource_t *res; + + MMRADIO_LOG_FENTER(); + + MMRADIO_RESOURCE_LOCK(&radio->resource_manager); + + if (!mrp_res_equal_resource_set(rs, radio->resource_manager.rset)) { + MMRADIO_LOG_WARNING("- resource set(%p) is not same as this radio handle's(%p)", rs, radio->resource_manager.rset); + MMRADIO_RESOURCE_UNLOCK(&radio->resource_manager); + return; + } + + MMRADIO_LOG_DEBUG(" - resource set state of radio(%p) is changed to [%s]\n", + radio, _mmrdio_resource_state_to_str(rs->state)); + for (i = 0; i < MM_RADIO_RESOURCE_MAX; i++) { + res = mrp_res_get_resource_by_name(rs, mm_radio_resource_str[i]); + if (res == NULL) + MMRADIO_LOG_WARNING(" -- %s not present in resource set\n", mm_radio_resource_str[i]); + else + MMRADIO_LOG_DEBUG(" -- resource name [%s] -> [%s]'\n", res->name, + _mmrdio_resource_state_to_str(res->state)); + } + + mrp_res_delete_resource_set(radio->resource_manager.rset); + radio->resource_manager.rset = mrp_res_copy_resource_set(rs); + + if (rs->state == MRP_RES_RESOURCE_ACQUIRED) { + MMRADIO_LOG_DEBUG(" - resource set is acquired"); + radio->resource_manager.state = MM_RADIO_RESOURCE_STATE_ACQUIRED; + MMRADIO_RESOURCE_SIGNAL(&radio->resource_manager); + } else if ((radio->resource_manager.state >= MM_RADIO_RESOURCE_STATE_ACQUIRED) && + (rs->state == MRP_RES_RESOURCE_AVAILABLE)) { + MMRADIO_LOG_DEBUG(" - resource set is released"); + radio->resource_manager.state = MM_RADIO_RESOURCE_STATE_PREPARED; + MMRADIO_RESOURCE_SIGNAL(&radio->resource_manager); + + /* mm radio was unrealized by resource conflict. */ + if (radio->resource_manager.by_rm_cb == true) { + MMRADIO_LOG_DEBUG(" - delete resource set "); + if (radio->resource_manager.rset) { + mrp_res_delete_resource_set(radio->resource_manager.rset); + radio->resource_manager.rset = NULL; + } + radio->resource_manager.state = MM_RADIO_RESOURCE_STATE_INITIALIZED; + radio->resource_manager.by_rm_cb = false; + } + } + + MMRADIO_RESOURCE_UNLOCK(&radio->resource_manager); + + MMRADIO_LOG_FLEAVE(); +} + +static void __mmradio_mrp_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data) +{ + int i = 0; + int result = MM_ERROR_NONE; + mm_radio_t *radio = NULL; + mrp_res_resource_t *res; + gboolean resource_released = FALSE; + + MMRADIO_LOG_FENTER(); + + if (user_data == NULL) { + MMRADIO_LOG_ERROR("- user_data is null\n"); + return; + } + + radio = (mm_radio_t *)user_data; + + if (!mrp_res_equal_resource_set(rs, radio->resource_manager.rset)) { + MMRADIO_LOG_WARNING("- resource set(%p) is not same as this radio handle's(%p)", rs, radio->resource_manager.rset); + return; + } + + MMRADIO_LOG_DEBUG(" - resource set state of radio(%p) is changed to [%s]\n", radio, + _mmrdio_resource_state_to_str(rs->state)); + for (i = 0; i < MM_RADIO_RESOURCE_MAX; i++) { + res = mrp_res_get_resource_by_name(rs, mm_radio_resource_str[i]); + if (res == NULL) { + MMRADIO_LOG_WARNING(" -- %s not present in resource set\n", mm_radio_resource_str[i]); + } else { + MMRADIO_LOG_DEBUG(" -- resource name [%s] -> [%s]'\n", res->name, + _mmrdio_resource_state_to_str(res->state)); + if (res->state == MRP_RES_RESOURCE_ABOUT_TO_LOOSE) + resource_released = TRUE; + } + } + + if (resource_released) { + MMRADIO_LOG_DEBUG("radio resource conflict so, resource will be freed by _mmradio_stop"); + + radio->resource_manager.by_rm_cb = true; + + MMRADIO_CMD_LOCK(radio); + result = _mmradio_stop(radio); + if (result != MM_ERROR_NONE) + MMRADIO_LOG_ERROR("failed to stop radio"); + MMRADIO_CMD_UNLOCK(radio); + + radio->resource_manager.by_rm_cb = false; + + } else { + MMRADIO_LOG_WARNING("could not find videobin"); + } + + MMRADIO_LOG_FLEAVE(); + + return; + +} + +static int _mmradio_create_rset(mm_radio_resource_manager *resource_manager) +{ + if (resource_manager->rset) { + MMRADIO_LOG_ERROR(" - resource set was already created\n"); + return MM_ERROR_RESOURCE_INVALID_STATE; + } + + resource_manager->rset = mrp_res_create_resource_set(resource_manager->context, + MRP_APP_CLASS_FOR_RADIO, __mmradio_rset_state_callback, + (void*)resource_manager->user_data); + if (resource_manager->rset == NULL) { + MMRADIO_LOG_ERROR(" - could not create resource set\n"); + return MM_ERROR_RESOURCE_INTERNAL; + } + + if (!mrp_res_set_autorelease(TRUE, resource_manager->rset)) + MMRADIO_LOG_WARNING(" - could not set autorelease flag!\n"); + + return MM_ERROR_NONE; +} + +static int _mmradio_include_resource(mm_radio_resource_manager *resource_manager, const char *resource_name) +{ + mrp_res_resource_t *resource = NULL; + resource = mrp_res_create_resource(resource_manager->rset, + resource_name, + MRP_RESOURCE_TYPE_MANDATORY, + MRP_RESOURCE_TYPE_EXCLUSIVE); + if (resource == NULL) { + MMRADIO_LOG_ERROR(" - could not include resource[%s]\n", resource_name); + return MM_ERROR_RESOURCE_INTERNAL; + } + + MMRADIO_LOG_DEBUG(" - include resource[%s]\n", resource_name); + + return MM_ERROR_NONE; +} + +static int _mmradio_set_resource_release_cb(mm_radio_resource_manager *resource_manager) +{ + int ret = MM_ERROR_NONE; + bool mrp_ret = false; + MMRADIO_LOG_FENTER(); + + if (resource_manager->rset) { + mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmradio_mrp_resource_release_cb, resource_manager->user_data); + if (!mrp_ret) { + MMRADIO_LOG_ERROR(" - could not set release callback\n"); + ret = MM_ERROR_RESOURCE_INTERNAL; + } + } else { + MMRADIO_LOG_ERROR(" - resource set is null\n"); + ret = MM_ERROR_RESOURCE_INVALID_STATE; + } + MMRADIO_LOG_FLEAVE(); + return ret; +} + + +int mmradio_resource_manager_init(mm_radio_resource_manager *resource_manager, void *user_data) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + + GMainContext *mrp_ctx = g_main_context_new(); + if (!mrp_ctx) { + MMRADIO_LOG_ERROR("- could not create main context for resource manager"); + return MM_ERROR_RESOURCE_INTERNAL; + } + + GMainLoop *mrp_loop = g_main_loop_new(mrp_ctx, TRUE); + g_main_context_unref(mrp_ctx); + if (!mrp_loop) { + MMRADIO_LOG_ERROR("- could not create glib mainloop for resource manager"); + return MM_ERROR_RESOURCE_INTERNAL; + } + + resource_manager->mloop = mrp_mainloop_glib_get(mrp_loop); + g_main_loop_unref(mrp_loop); + + if (resource_manager->mloop) { + resource_manager->context = mrp_res_create(resource_manager->mloop, __mmradio_resource_state_callback, user_data); + if (resource_manager->context == NULL) { + MMRADIO_LOG_ERROR(" - could not get context for resource manager\n"); + mrp_mainloop_destroy(resource_manager->mloop); + resource_manager->mloop = NULL; + return MM_ERROR_RESOURCE_INTERNAL; + } + resource_manager->user_data = user_data; + } else { + MMRADIO_LOG_ERROR("- could not get mainloop for resource manager\n"); + return MM_ERROR_RESOURCE_INTERNAL; + } + + resource_manager->state = MM_RADIO_RESOURCE_STATE_INITIALIZED; + g_mutex_init(&resource_manager->lock); + g_cond_init(&resource_manager->cond); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; + +} + + +int mmradio_resource_manager_prepare(mm_radio_resource_manager *resource_manager, mm_radio_resource_type_e resource_type) +{ + int ret = MM_ERROR_NONE; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager); + + if (!resource_manager->rset) + ret = _mmradio_create_rset(resource_manager); + + if (ret == MM_ERROR_NONE) { + switch (resource_type) { + case MM_RADIO_RESOURCE_TYPE_RADIO: + ret = _mmradio_include_resource(resource_manager, mm_radio_resource_str[MM_RADIO_RESOURCE_TYPE_RADIO]); + break; + default: + MMRADIO_LOG_WARNING("resource type(%d) is worng", resource_type); + break; + } + } + + resource_manager->state = MM_RADIO_RESOURCE_STATE_PREPARED; + + MMRADIO_LOG_FLEAVE(); + + return ret; + +} + +int mmradio_resource_manager_unprepare(mm_radio_resource_manager *resource_manager) +{ + int ret = MM_ERROR_NONE; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager); + + if (resource_manager->rset == NULL) { + MMRADIO_LOG_ERROR("- could not unprepare for resource_manager, mmradio_resource_manager_unprepare() first\n"); + ret = MM_ERROR_RESOURCE_INVALID_STATE; + } else { + MMRADIO_RESOURCE_LOCK(resource_manager); + mrp_res_delete_resource_set(resource_manager->rset); + resource_manager->rset = NULL; + MMRADIO_RESOURCE_UNLOCK(resource_manager); + } + + resource_manager->state = MM_RADIO_RESOURCE_STATE_INITIALIZED; + + MMRADIO_LOG_FLEAVE(); + + return ret; + +} + +int mmradio_resource_manager_acquire(mm_radio_resource_manager *resource_manager) +{ + int ret = MM_ERROR_NONE; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager); + + if (resource_manager->rset == NULL) { + MMRADIO_LOG_ERROR("- could not acquire resource, resource set is null\n"); + ret = MM_ERROR_RESOURCE_INVALID_STATE; + } else { + ret = _mmradio_set_resource_release_cb(resource_manager); + if (ret) { + MMRADIO_LOG_ERROR("- could not set resource release cb, ret(0x%x)\n", ret); + ret = MM_ERROR_RESOURCE_INTERNAL; + } else { + MMRADIO_RESOURCE_LOCK(resource_manager); + + ret = mrp_res_acquire_resource_set(resource_manager->rset); + if (ret) { + MMRADIO_LOG_ERROR("- could not acquire resource, ret(%d)\n", ret); + ret = MM_ERROR_RESOURCE_INTERNAL; + } else { + gint64 end_time = g_get_monotonic_time() + MMRADIO_RESOURCE_TIMEOUT * G_TIME_SPAN_SECOND; + + MMRADIO_LOG_DEBUG("- acquire resource waiting..%p till %lld\n", resource_manager, end_time); + + if (!MMRADIO_RESOURCE_WAIT_UNTIL(resource_manager, end_time)) { + MMRADIO_LOG_ERROR("- could not acquire resource\n"); + ret = MM_ERROR_RESOURCE_INTERNAL; + } else { + MMRADIO_LOG_DEBUG("- resources are acquired\n"); + } + + } + MMRADIO_RESOURCE_UNLOCK(resource_manager); + } + } + + MMRADIO_LOG_FLEAVE(); + + return ret; + +} + +int mmradio_resource_manager_release(mm_radio_resource_manager *resource_manager) +{ + int ret = MM_ERROR_NONE; + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager); + + if (resource_manager->rset == NULL) { + MMRADIO_LOG_ERROR("- could not release resource, resource set is null\n"); + ret = MM_ERROR_RESOURCE_INVALID_STATE; + } else { + if (resource_manager->rset->state != MRP_RES_RESOURCE_ACQUIRED) { + MMRADIO_LOG_ERROR("- could not release resource, resource set state is [%s]\n", + _mmrdio_resource_state_to_str(resource_manager->rset->state)); + ret = MM_ERROR_RESOURCE_INVALID_STATE; + } else { + MMRADIO_RESOURCE_LOCK(resource_manager); + ret = mrp_res_release_resource_set(resource_manager->rset); + if (ret) { + MMRADIO_LOG_ERROR("- could not release resource, ret(%d)\n", ret); + ret = MM_ERROR_RESOURCE_INTERNAL; + } else { + gint64 end_time = g_get_monotonic_time() + MMRADIO_RESOURCE_TIMEOUT * G_TIME_SPAN_SECOND; + + MMRADIO_LOG_DEBUG("- release resource waiting..%p till %lld\n", resource_manager, end_time); + + if (!MMRADIO_RESOURCE_WAIT_UNTIL(resource_manager, end_time)) + MMRADIO_LOG_WARNING("- could not release resource in time\n"); + else + MMRADIO_LOG_DEBUG("- resources are released\n"); + } + MMRADIO_RESOURCE_UNLOCK(resource_manager); + } + } + + MMRADIO_LOG_FLEAVE(); + + return ret; +} + +int mmradio_resource_manager_deinit(mm_radio_resource_manager *resource_manager) +{ + MMRADIO_LOG_FENTER(); + MMRADIO_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager); + MMRADIO_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager); + + if (resource_manager->rset) { + if (resource_manager->rset->state == MRP_RES_RESOURCE_ACQUIRED) { + if (mrp_res_release_resource_set(resource_manager->rset)) + MMRADIO_LOG_ERROR("- could not release resource\n"); + } + mrp_res_delete_resource_set(resource_manager->rset); + resource_manager->rset = NULL; + } + + if (resource_manager->context) { + mrp_res_destroy(resource_manager->context); + resource_manager->context = NULL; + } + + if (resource_manager->mloop) { + mrp_mainloop_quit(resource_manager->mloop, 0); + mrp_mainloop_destroy(resource_manager->mloop); + resource_manager->mloop = NULL; + } + + resource_manager->state = MM_RADIO_RESOURCE_STATE_NONE; + g_mutex_clear(&resource_manager->lock); + g_cond_clear(&resource_manager->cond); + + MMRADIO_LOG_FLEAVE(); + + return MM_ERROR_NONE; +} diff --git a/src/mm_radio_sound_focus.c b/src/mm_radio_sound_focus.c index 0eff66e..e4b70b2 100644 --- a/src/mm_radio_sound_focus.c +++ b/src/mm_radio_sound_focus.c @@ -51,9 +51,11 @@ static void _mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connect radio->sound_focus.by_focus_cb = true; radio->sound_focus.event_src = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG; + MMRADIO_CMD_LOCK(radio); result = _mmradio_stop(radio); if (result != MM_ERROR_NONE) MMRADIO_LOG_ERROR("failed to stop radio"); + MMRADIO_CMD_UNLOCK(radio); radio->sound_focus.by_focus_cb = false; } |