summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilbok Lee <gilbok.lee@samsung.com>2017-04-10 13:17:41 +0900
committerGilbok Lee <gilbok.lee@samsung.com>2017-04-10 16:41:05 +0900
commit42e03880d935d628608776e138915c23cbe6f780 (patch)
tree56b06b55da1d627e79a7c7611fb29986870c59ab
parent3bc8e303ae07b3d3c9933495b86f6d7ebc0c875c (diff)
downloadlibmm-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-xconfigure.ac8
-rwxr-xr-xpackaging/libmm-radio.spec4
-rwxr-xr-xsrc/Makefile.am10
-rw-r--r--src/include/mm_radio_priv_hal.h3
-rw-r--r--src/include/mm_radio_resource.h81
-rw-r--r--src/mm_radio_priv_emulator.c4
-rw-r--r--src/mm_radio_priv_hal.c71
-rw-r--r--src/mm_radio_resource.c525
-rw-r--r--src/mm_radio_sound_focus.c2
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, &param);
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;
}