static pa_dbus_arg_info simple_play_args[] = { { "uri", "s", "in" },
{ "role", "s", "in" },
- { "volume_gain", "s", "in" } };
+ { "volume_gain", "s", "in" },
+ { "priority", "i", "in" } };
static pa_dbus_arg_info simple_stop_args[] = { { "uri", "s", "in" } };
static pa_dbus_arg_info sample_play_args[] = { { "sample_name", "s", "in" },
{ "role", "s", "in" },
" <arg name=\"uri\" direction=\"in\" type=\"s\"/>" \
" <arg name=\"role\" direction=\"in\" type=\"s\"/>" \
" <arg name=\"volume_gain\" direction=\"in\" type=\"s\"/>" \
+ " <arg name=\"priority\" direction=\"in\" type=\"i\"/>" \
" </method>" \
" <method name=\"SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP\">" \
" <arg name=\"uri\" direction=\"in\" type=\"s\"/>" \
#define RETRY_NUM 100
+#define NO_PRIORITY (-1)
+#define PA_PROP_MEDIA_SIMPLE_PRIORITY "media.simple.priority"
+
+enum priority_result {
+ PRIORITY_BLOCKED,
+ PRIORITY_PASS
+};
+
struct ipc_data {
char filename[FILE_FULL_PATH];
char role[ROLE_NAME_LEN];
char volume_gain_type[VOLUME_GAIN_TYPE_LEN];
char method[METHOD_LEN];
+ int priority;
};
#define KEYTONE_PREFIX "SIMPLE_PLAY"
#define KEYTONE_GROUP 6526 /* Keytone group : assigned by security */
#define DEFAULT_IPC_TYPE IPC_TYPE_PIPE
-static int _simple_play(struct userdata *u, const char *file_path, const char *role, const char *vol_gain_type) {
+static int _simple_play(struct userdata *u, const char *file_path, const char *role, const char *vol_gain_type, int priority) {
int ret = 0;
pa_proplist *p;
pa_proplist_sets(p, PA_PROP_MEDIA_ROLE, role);
if (vol_gain_type)
pa_proplist_sets(p, PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE, vol_gain_type);
- pa_log_debug("role[%s], volume_gain_type[%s]", role, vol_gain_type);
+ pa_proplist_setf(p, PA_PROP_MEDIA_SIMPLE_PRIORITY, "%d", priority);
+
+ pa_log_debug("role[%s], volume_gain_type[%s], priority[%d]", role, vol_gain_type, priority);
/* prepare scache */
scache_name = pa_sprintf_malloc("%s_%s", KEYTONE_PREFIX, file_path);
const char *volume_gain = NULL;
dbus_int32_t result = -1;
struct userdata *u = (struct userdata *)userdata;
+ dbus_int32_t priority = NO_PRIORITY;
pa_assert(conn);
pa_assert(msg);
DBUS_TYPE_STRING, &uri,
DBUS_TYPE_STRING, &role,
DBUS_TYPE_STRING, &volume_gain,
+ DBUS_TYPE_INT32, &priority,
DBUS_TYPE_INVALID));
- pa_log_info("uri[%s], role[%s], volume_gain[%s]", uri, role, volume_gain);
+ pa_log_info("uri[%s], role[%s], volume_gain[%s], priority[%d]", uri, role, volume_gain, priority);
if (uri) {
- result = _simple_play(u, uri, role, volume_gain);
+ result = _simple_play(u, uri, role, volume_gain, priority);
if (result != -1) {
int32_t *stream_idx = pa_xmalloc0(sizeof(int32_t));
*stream_idx = result;
#endif
}
+static bool _handle_priority(struct userdata *u, int priority) {
+ pa_sink_input *si = NULL;
+ uint32_t idx = 0;
+ int32_t si_priority = 0;
+ const char *priority_str = NULL;
+
+ pa_assert(u);
+
+ if (priority == NO_PRIORITY)
+ return PRIORITY_PASS;
+
+ PA_IDXSET_FOREACH(si, u->module->core->sink_inputs, idx) {
+ priority_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_SIMPLE_PRIORITY);
+ if (!priority_str) {
+ pa_log_info("sink-input : %u, no priority property", si->index);
+ continue;
+ }
+
+ if (pa_atoi(priority_str, &si_priority) < 0) {
+ pa_log_error("Invalid priority value %s", priority_str);
+ continue;
+ }
+
+ if (si_priority == NO_PRIORITY)
+ continue;
+
+ if (si_priority < priority) {
+ pa_log_info("requested(%d) will be blocked because of existence(%d)", priority, si_priority);
+ return PRIORITY_BLOCKED;
+ }
+
+ pa_log_info("kill sink-input : %u, priority(%d) > requested priority(%d)",
+ si->index, si_priority, priority);
+ pa_sink_input_kill(si);
+ }
+
+ return PRIORITY_PASS;
+}
+
static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
struct userdata *u = userdata;
struct ipc_data data;
}
if (read_sum == data_size) {
- pa_log_info("name(%s), role(%s), volume_gain_type(%s), method(%s)",
- data.filename, data.role, data.volume_gain_type, data.method);
-
- if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY, METHOD_LEN))
- _simple_play(u, data.filename, data.role, data.volume_gain_type);
- else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP, METHOD_LEN))
+ pa_log_info("name(%s), role(%s), volume_gain_type(%s), priority(%d), method(%s)",
+ data.filename, data.role, data.volume_gain_type, data.priority, data.method);
+
+ if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY, METHOD_LEN)) {
+ if (_handle_priority(u, data.priority) == PRIORITY_BLOCKED)
+ return;
+ _simple_play(u, data.filename, data.role, data.volume_gain_type, data.priority);
+ } else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP, METHOD_LEN)) {
_simple_stop(u, data.filename);
- else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL, METHOD_LEN))
+ } else if (pa_strneq(data.method, SOUND_PLAYER_METHOD_NAME_SIMPLE_STOP_ALL, METHOD_LEN)) {
_simple_stop_all(u);
- else
+ } else {
pa_log_error("Invalid method!!!");
+ }
} else {
pa_log_warn("Fail to read, retry_count(%d), read sum(%zu), err(%s)", retry_count, read_sum, pa_cstrerror(errno));
}