tizenaudio-policy: Add support for the preferred device role of built-in devices 72/209472/2
authorSangchul Lee <sc11.lee@samsung.com>
Mon, 8 Jul 2019 05:54:18 +0000 (14:54 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Tue, 9 Jul 2019 00:50:30 +0000 (09:50 +0900)
[Version] 11.1.56
[Issue type] New feature

Change-Id: Icaabe87ceeb0336bde8f5487c1748d44e83f3c52
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/device-manager.c
src/module-tizenaudio-policy.c
src/stream-manager-priv.h
src/stream-manager.c
src/tizen-device-def.c
src/tizen-device-def.h
src/tizen-device.c

index 5e301ca..50cbbd6 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.55
+Version:          11.1.56
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index d569f98..e905437 100644 (file)
@@ -1686,6 +1686,7 @@ static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object
         if (!s->use_internal_codec && !pa_safe_streq(s->name, SINK_NAME_NULL))
             if ((device = pa_device_manager_get_device_with_sink(s)))
                 pa_tz_device_set_running_and_notify(device, (state == PA_SINK_RUNNING));
+
     } else if (pa_source_isinstance(pdevice)) {
         pa_source *s = PA_SOURCE(pdevice);
         pa_source_state_t state = pa_source_get_state(s);
@@ -1702,7 +1703,7 @@ static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object
 /*
     Build params for load sink or source, and load it.
 */
-static void* load_module(pa_core *c, bool is_sink, const char *device_string, const char *device_params) {
+static void* load_module(pa_core *c, bool is_sink, const char *device_string, const char *device_params, const char *device_role) {
     const char *module_name;
     pa_module *module;
     pa_sink *sink;
@@ -1745,14 +1746,18 @@ static void* load_module(pa_core *c, bool is_sink, const char *device_string, co
     if (is_sink) {
         PA_IDXSET_FOREACH(sink, c->sinks, device_idx) {
             if (sink->module == module) {
-                pa_log_info("sink loaded : %s %u", sink->name, sink->index);
+                pa_log_info("sink loaded : %s %u %s", sink->name, sink->index, pa_strnull(device_role));
+                if (device_role)
+                    pa_proplist_sets(sink->proplist, PA_PROP_DEVICE_ROLE, device_role);
                 return sink;
             }
         }
     } else {
         PA_IDXSET_FOREACH(source, c->sources, device_idx) {
             if (source->module == module) {
-                pa_log_info("source loaded : %s %u", source->name, source->index);
+                pa_log_info("source loaded : %s %u %s", source->name, source->index, pa_strnull(device_role));
+                if (device_role)
+                    pa_proplist_sets(source->proplist, PA_PROP_DEVICE_ROLE, device_role);
                 return source;
             }
         }
@@ -1798,6 +1803,8 @@ static int _load_type_devices(device_type_info *type_info, bool is_playback, pa_
     void *state;
     char *role;
     const char *device_string, *params;
+    bool first_one = true;
+    void *device;
 
     pa_assert(dm);
     pa_assert(type_info);
@@ -1833,8 +1840,18 @@ static int _load_type_devices(device_type_info *type_info, bool is_playback, pa_
             pa_log_error("Failed to get param for %s", device_string);
             continue;
         }
-        if (!(load_module(dm->core, is_playback, device_string, params))) {
+        if (!(device = load_module(dm->core, is_playback, device_string, params, role))) {
             pa_log_warn("load device failed %s %s", device_string, params);
+            continue;
+        }
+        if (first_one && !pa_streq(role, DEVICE_ROLE_NORMAL)) {
+            /* NOTE: If the first role is not NORMAL, handle it as external devices.
+             * Because it's not ready to pass this information to audio HAL for now. */
+            if (is_playback)
+                PA_SINK(device)->use_internal_codec = false;
+            else
+                PA_SOURCE(device)->use_internal_codec = false;
+            first_one = false;
         }
     }
 
@@ -1932,15 +1949,23 @@ void handle_device_connected(pa_device_manager *dm, const char *type, const char
         _load_forwarding_device(dm);
     } else {
         dm_device_direction_t direction;
+        bool use_internal_codec = true;
 
         direction = device_type_get_static_direction(type);
         if (direction != DM_DEVICE_DIRECTION_NONE) {
             pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL);
-            _fill_new_data_basic(&data, type, direction, true, dm);
-            if (direction & DM_DEVICE_DIRECTION_OUT)
+
+            if (direction & DM_DEVICE_DIRECTION_OUT) {
                 _fill_new_data_sinks(&data, type_info, dm);
-            if (direction & DM_DEVICE_DIRECTION_IN)
+                if (use_internal_codec && pa_hashmap_size(data.playback_pcms))
+                    use_internal_codec = (PA_SINK(pa_hashmap_first(data.playback_pcms)))->use_internal_codec;
+            }
+            if (direction & DM_DEVICE_DIRECTION_IN) {
                 _fill_new_data_sources(&data, type_info, dm);
+                if (use_internal_codec && pa_hashmap_size(data.capture_pcms))
+                    use_internal_codec = (PA_SOURCE(pa_hashmap_first(data.capture_pcms)))->use_internal_codec;
+            }
+            _fill_new_data_basic(&data, type, direction, use_internal_codec, dm);
 
             pa_tz_device_new(&data);
             pa_tz_device_new_data_done(&data);
@@ -2386,7 +2411,7 @@ static pa_sink* load_sink(pa_device_manager *dm, const char *type, const char *r
         goto fail;
     }
 
-    if ((sink = load_module(dm->core, true, device_string, params))) {
+    if ((sink = load_module(dm->core, true, device_string, params, role))) {
         pa_log_debug("loaded sink '%s' for '%s,%s' success", sink->name, type, role);
     } else {
         pa_log_warn("Cannot load playback device with '%s,%s'", device_string, params);
@@ -2477,7 +2502,7 @@ static pa_source* load_source(pa_device_manager *dm, const char *type, const cha
         goto fail;
     }
 
-    if ((source = load_module(dm->core, false, device_string, params))) {
+    if ((source = load_module(dm->core, false, device_string, params, role))) {
         pa_log_debug("loaded source '%s' for '%s,%s' success", source->name, type, role);
     } else {
         pa_log_warn("Cannot load capture device with '%s,%s'", device_string, params);
index 3c35d78..19602ff 100644 (file)
@@ -719,7 +719,12 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre
                             *(data->proper_source) = pa_tz_device_get_source(device, data->device_role);
 
                         if (data->route_type == STREAM_ROUTE_TYPE_AUTO) {
-                            pa_proplist_sets(GET_STREAM_NEW_PROPLIST(data->stream, data->stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, dm_device_type);
+                            if (data->origins_from_new_data)
+                                pa_proplist_sets(GET_STREAM_NEW_PROPLIST(data->stream, data->stream_type),
+                                                    PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, dm_device_type);
+                            else
+                                pa_proplist_sets(GET_STREAM_PROPLIST(data->stream, data->stream_type),
+                                                    PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, dm_device_type);
                             return PA_HOOK_OK;
                         }
                     }
@@ -762,7 +767,12 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre
                 else
                     *(data->proper_source) = pa_tz_device_get_source(latest_device, data->device_role);
 
-                pa_proplist_sets(GET_STREAM_NEW_PROPLIST(data->stream, data->stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, pa_tz_device_get_type(latest_device));
+                if (data->origins_from_new_data)
+                    pa_proplist_sets(GET_STREAM_NEW_PROPLIST(data->stream, data->stream_type),
+                                        PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, pa_tz_device_get_type(latest_device));
+                else
+                    pa_proplist_sets(GET_STREAM_PROPLIST(data->stream, data->stream_type),
+                                        PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, pa_tz_device_get_type(latest_device));
             }
         }
 
index 7c2aa36..a89b0c3 100644 (file)
@@ -185,6 +185,7 @@ typedef struct _stream_parent {
     pa_idxset *idx_route_out_devices;
     focus_acquired_status_t focus_status;
     stream_route_type_t route_type;
+    const char *preferred_device_role;
 } stream_parent;
 
 typedef struct _filter_info {
index c0bc99d..8894a2c 100644 (file)
@@ -1099,6 +1099,29 @@ static bool update_focus_status_of_stream(pa_stream_manager *m, void *stream, st
     return true;
 }
 
+static void update_preferred_device_role(pa_stream_manager *m, void *stream, stream_type_t type) {
+    const char *p_idx_str;
+    uint32_t parent_idx = 0;
+    stream_parent *sp = NULL;
+
+    pa_assert(m);
+    pa_assert(stream);
+
+    p_idx_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID);
+    if (!p_idx_str || pa_atou(p_idx_str, &parent_idx))
+        return;
+
+    if (!(sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx))) {
+        pa_log_error("could not find matching client for this parent_id(%u)", parent_idx);
+        return;
+    }
+
+    if (sp->preferred_device_role)
+        pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type),
+                        PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE,
+                        sp->preferred_device_role);
+}
+
 static bool update_stream_parent_info(pa_stream_manager *m, process_command_type_t command, stream_type_t type, void *stream) {
     const char *p_idx;
     uint32_t parent_idx;
@@ -1535,7 +1558,6 @@ ret_msg_t do_notify(pa_stream_manager *m, notify_command_type_t command, stream_
     pa_stream_manager_hook_data_for_route hook_call_route_data;
     hal_stream_connection_info stream_conn_info;
     hal_route_option route_option;
-    const char *role = NULL;
     void *s = NULL;
     const char *modifier_gain = NULL;
     ret_msg_t ret = RET_MSG_OK;
@@ -1553,7 +1575,10 @@ ret_msg_t do_notify(pa_stream_manager *m, notify_command_type_t command, stream_
             hook_call_select_data.stream_type = type;
             hook_call_select_data.origins_from_new_data = is_new_data;
             if (is_new_data) {
-                hook_call_select_data.stream_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_select_data.stream_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type),
+                                                                PA_PROP_MEDIA_ROLE);
+                hook_call_select_data.device_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type),
+                                                                PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
                 fill_device_info_to_hook_data(m, &hook_call_select_data, command, type, s, is_new_data);
                 hook_call_select_data.sample_spec = GET_STREAM_NEW_SAMPLE_SPEC(s, type);
                 if (type == STREAM_SINK_INPUT) {
@@ -1582,7 +1607,10 @@ ret_msg_t do_notify(pa_stream_manager *m, notify_command_type_t command, stream_
                     }
                 }
             } else {
-                hook_call_select_data.stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_select_data.stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type),
+                                                                PA_PROP_MEDIA_ROLE);
+                hook_call_select_data.device_role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type),
+                                                                PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
                 fill_device_info_to_hook_data(m, &hook_call_select_data, command, type, s, is_new_data);
                 hook_call_select_data.sample_spec = GET_STREAM_SAMPLE_SPEC(s, type);
                 if (type == STREAM_SINK_INPUT)
@@ -1590,7 +1618,8 @@ ret_msg_t do_notify(pa_stream_manager *m, notify_command_type_t command, stream_
                 else if (type == STREAM_SOURCE_OUTPUT)
                     hook_call_select_data.proper_source = &(((pa_source_output*)s)->source);
             }
-            CONVERT_TO_DEVICE_ROLE(hook_call_select_data.stream_role, hook_call_select_data.device_role);
+            if (hook_call_select_data.route_type == STREAM_ROUTE_TYPE_MANUAL)
+                CONVERT_TO_DEVICE_ROLE(hook_call_select_data.stream_role, hook_call_select_data.device_role);
             if (pa_hook_fire(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_SELECT_INIT_SINK_OR_SOURCE), &hook_call_select_data))
                 ret = RET_MSG_ERROR_INTERNAL;
 BREAK_WITH_FREE:
@@ -1605,7 +1634,8 @@ BREAK_WITH_FREE:
         if (s) {
             if (is_new_data) {
                 hook_call_route_data.origins_from_new_data = true;
-                role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_route_data.stream_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_route_data.device_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
                 hook_call_route_data.sample_spec = GET_STREAM_NEW_SAMPLE_SPEC(s, type);
                 if (type == STREAM_SINK_INPUT) {
                     hook_call_route_data.proper_sink = &(((pa_sink_input_new_data*)s)->sink);
@@ -1613,14 +1643,15 @@ BREAK_WITH_FREE:
                     hook_call_route_data.proper_source = &(((pa_source_output_new_data*)s)->source);
                 }
             } else {
-                role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_route_data.stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE);
+                hook_call_route_data.device_role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
                 hook_call_route_data.sample_spec = GET_STREAM_SAMPLE_SPEC(s, type);
                 hook_call_route_data.idx_streams = (type == STREAM_SINK_INPUT) ? ((pa_sink_input*)s)->sink->inputs :
                                                                                  ((pa_source_output*)s)->source->outputs;
             }
             hook_call_route_data.stream_type = type;
-            hook_call_route_data.stream_role = role;
-            CONVERT_TO_DEVICE_ROLE(hook_call_route_data.stream_role, hook_call_route_data.device_role);
+            if (hook_call_route_data.route_type == STREAM_ROUTE_TYPE_MANUAL)
+                CONVERT_TO_DEVICE_ROLE(hook_call_route_data.stream_role, hook_call_route_data.device_role);
             fill_device_info_to_hook_data(m, &hook_call_route_data, command, type, s, is_new_data);
             if (hook_call_route_data.route_type == STREAM_ROUTE_TYPE_MANUAL || hook_call_route_data.route_type == STREAM_ROUTE_TYPE_MANUAL_EXT) {
                 if (hook_call_route_data.idx_manual_devices && !pa_idxset_size(hook_call_route_data.idx_manual_devices)) {
@@ -1856,6 +1887,9 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea
             }
         }
 
+        /* update the preferred device role, it will affect only built-in devices. */
+        update_preferred_device_role(m, stream, type);
+
         /* check if it is a virtual stream */
         if (check_name_is_vstream(stream, type, is_new_data)) {
             pa_log_debug("skip notifying for selecting sink/source, rather set it to null sink/source");
@@ -1869,12 +1903,24 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea
         }
 
     } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED) {
+        const char *preferred_device_role;
+
         if (is_new_data) {
             role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
             route_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
+            preferred_device_role =  pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type),
+                                                                PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
         } else {
             role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
             route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE);
+            preferred_device_role =  pa_proplist_gets(GET_STREAM_PROPLIST(stream, type),
+                                                                PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
+        }
+
+        /* skip updating priority, focus status, the highest priority, ucm to HAL */
+        if (preferred_device_role) {
+            pa_log_debug("preferred device role[%s] is found, skip ROUTE_START", preferred_device_role);
+            goto skip_notifying_route_start;
         }
 
         /* skip roles */
@@ -1933,88 +1979,98 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea
             }
         }
 
+skip_notifying_route_start:
         if (!is_new_data)
             do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, type, false, stream);
 
     } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED) {
-        role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
-        if (role) {
-            /* unload forwarding device */
-            if (type == STREAM_SOURCE_OUTPUT && pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING))
-                update_forwarding_device(m, false);
+        const char *preferred_device_role;
 
-            /* skip roles */
-            if (check_role_to_skip(m, command, role)) {
-                result = PROCESS_STREAM_RESULT_SKIP;
-                goto finish;
-            }
+        if (!(role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE))) {
+            pa_log_warn("role is null, skip it");
+            goto finish;
+        }
 
-            /* skip route types */
-            if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
-                if (check_route_type_to_skip(command, route_type_str)) {
-                    result = PROCESS_STREAM_RESULT_SKIP;
-                    goto finish;
-                }
-            }
+        preferred_device_role =  pa_proplist_gets(GET_STREAM_PROPLIST(stream, type),
+                                                    PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
+        /* skip updating the highest priority, ucm to HAL */
+        if (preferred_device_role) {
+            pa_log_debug("preferred device role[%s] is found, skip ROUTE_END", preferred_device_role);
+            goto skip_notifying_route_end;
+        }
+
+        /* unload forwarding device */
+        if (type == STREAM_SOURCE_OUTPUT && pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING))
+            update_forwarding_device(m, false);
 
-            /* check if it has already been processed (unlink or state_changed_cb) */
-            if (pa_proplist_get(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&prior_priority, &size)) {
-                pa_log_debug("it has already been processed for PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, skip it..");
+        /* skip roles */
+        if (check_role_to_skip(m, command, role)) {
+            result = PROCESS_STREAM_RESULT_SKIP;
+            goto finish;
+        }
+
+        /* skip route types */
+        if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
+            if (check_route_type_to_skip(command, route_type_str)) {
                 result = PROCESS_STREAM_RESULT_SKIP;
                 goto finish;
             }
+        }
 
-            ret = update_the_highest_priority_stream(m, command, stream, type, role, is_new_data, &need_update);
-            if (ret == false) {
-                pa_log_error("could not update the highest priority stream");
-                result = PROCESS_STREAM_RESULT_STOP;
-                goto finish;
-            }
+        /* check if it has already been processed (unlink or state_changed_cb) */
+        if (pa_proplist_get(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&prior_priority, &size)) {
+            pa_log_debug("it has already been processed for PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, skip it..");
+            result = PROCESS_STREAM_RESULT_SKIP;
+            goto finish;
+        }
 
-            do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, type, false, stream);
+        ret = update_the_highest_priority_stream(m, command, stream, type, role, is_new_data, &need_update);
+        if (ret == false) {
+            pa_log_error("could not update the highest priority stream");
+            result = PROCESS_STREAM_RESULT_STOP;
+            goto finish;
+        }
 
-            /* need to skip if this stream does not belong to internal device */
-            /* if needed, notify to update */
-            if (need_update)
-                do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, false, NULL);
+skip_notifying_route_end:
+        do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, type, false, stream);
 
-        } else {
-            pa_log_warn("role is null, skip it");
-        }
+        /* need to skip if this stream does not belong to internal device */
+        /* if needed, notify to update */
+        if (need_update)
+            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, false, NULL);
 
     } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED) {
-        role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
-        if (role) {
-            /* skip roles */
-            if (check_role_to_skip(m, command, role)) {
-                result = PROCESS_STREAM_RESULT_SKIP;
-                goto finish;
-            }
+        if (!(role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE))) {
+            pa_log_warn("role is null, skip it");
+            goto finish;
+        }
 
-            /* skip route types */
-            if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
-                if (check_route_type_to_skip(command, route_type_str)) {
-                    result = PROCESS_STREAM_RESULT_SKIP;
-                    goto finish;
-                }
-            }
+        /* skip roles */
+        if (check_role_to_skip(m, command, role)) {
+            result = PROCESS_STREAM_RESULT_SKIP;
+            goto finish;
+        }
 
-            ret = update_the_highest_priority_stream(m, command, stream, type, role, is_new_data, &need_update);
-            if (ret == false) {
-                pa_log_error("could not update the highest priority stream");
-                result = PROCESS_STREAM_RESULT_STOP;
+        /* skip route types */
+        if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
+            if (check_route_type_to_skip(command, route_type_str)) {
+                result = PROCESS_STREAM_RESULT_SKIP;
                 goto finish;
             }
+        }
 
-            /* need to skip if this stream does not belong to internal device */
-            /* if needed, notify to update */
-            if (need_update)
-                do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, false, NULL);
-
-        } else {
-            pa_log_warn("role is null, skip it");
+        ret = update_the_highest_priority_stream(m, command, stream, type, role, is_new_data, &need_update);
+        if (ret == false) {
+            pa_log_error("could not update the highest priority stream");
+            result = PROCESS_STREAM_RESULT_STOP;
+            goto finish;
         }
 
+        /* need to skip if this stream does not belong to internal device */
+        /* if needed, notify to update */
+        if (need_update)
+            do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, false, NULL);
+
     } else if (command == PROCESS_COMMAND_UPDATE_VOLUME) {
         if (is_new_data) {
             si_volume_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE);
@@ -2053,45 +2109,46 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea
         }
 
     } else if (command == PROCESS_COMMAND_ADD_PARENT_ID || command == PROCESS_COMMAND_REMOVE_PARENT_ID) {
-        role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
-        if (role) {
-            /* skip roles */
-            if (check_role_to_skip(m, command, role)) {
+        if (!(role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE)))
+            goto finish;
+
+        /* skip roles */
+        if (check_role_to_skip(m, command, role)) {
+            result = PROCESS_STREAM_RESULT_SKIP;
+            goto finish;
+        }
+
+        /* skip route types */
+        if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
+            if (check_route_type_to_skip(command, route_type_str)) {
                 result = PROCESS_STREAM_RESULT_SKIP;
                 goto finish;
             }
+        }
 
-            /* skip route types */
-            if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) {
-                if (check_route_type_to_skip(command, route_type_str)) {
-                    result = PROCESS_STREAM_RESULT_SKIP;
-                    goto finish;
+        if (!IS_ROUTE_TYPE_FOR_EXTERNAL_DEV(route_type_str, route_type)) {
+            if (command == PROCESS_COMMAND_ADD_PARENT_ID) {
+                if (type == STREAM_SINK_INPUT && m->cur_highest_priority.need_to_update_si) {
+                    m->cur_highest_priority.sink_input = stream;
+                    m->cur_highest_priority.role_si = role;
+                    m->cur_highest_priority.need_to_update_si = false;
                 }
-            }
-
-            if (!IS_ROUTE_TYPE_FOR_EXTERNAL_DEV(route_type_str, route_type)) {
-                if (command == PROCESS_COMMAND_ADD_PARENT_ID) {
-                    if (type == STREAM_SINK_INPUT && m->cur_highest_priority.need_to_update_si) {
-                        m->cur_highest_priority.sink_input = stream;
-                        m->cur_highest_priority.role_si = role;
-                        m->cur_highest_priority.need_to_update_si = false;
-                    }
-                    if (type == STREAM_SOURCE_OUTPUT && m->cur_highest_priority.need_to_update_so) {
-                        m->cur_highest_priority.source_output = stream;
-                        m->cur_highest_priority.role_so = role;
-                        m->cur_highest_priority.need_to_update_so = false;
-                    }
-                    do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, type, false, stream);
+                if (type == STREAM_SOURCE_OUTPUT && m->cur_highest_priority.need_to_update_so) {
+                    m->cur_highest_priority.source_output = stream;
+                    m->cur_highest_priority.role_so = role;
+                    m->cur_highest_priority.need_to_update_so = false;
                 }
+                do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, type, false, stream);
             }
+        }
 
-            /* update parent stream info. */
-            ret = update_stream_parent_info(m, command, type, stream);
-            if (ret == false) {
-                pa_log_debug("could not update the parent information of this stream");
-                //return PROCESS_STREAM_RESULT_STOP;
-            }
+        /* update parent stream info. */
+        ret = update_stream_parent_info(m, command, type, stream);
+        if (ret == false) {
+            pa_log_debug("could not update the parent information of this stream");
+            //return PROCESS_STREAM_RESULT_STOP;
         }
+
     } else if (command == PROCESS_COMMAND_UPDATE_BUFFER_ATTR) {
         update_buffer_attribute(m, stream, type, is_new_data);
     } else if (command == PROCESS_COMMAND_APPLY_FILTER) {
index 5e58c27..164146c 100644 (file)
@@ -159,6 +159,12 @@ const char* device_direction_to_string(dm_device_direction_t direction) {
 bool device_role_is_valid(const char *device_role) {
     if (pa_safe_streq(device_role, DEVICE_ROLE_NORMAL))
         return true;
+    else if (pa_safe_streq(device_role, DEVICE_ROLE_SECOND))
+        return true;
+    else if (pa_safe_streq(device_role, DEVICE_ROLE_THIRD))
+        return true;
+    else if (pa_safe_streq(device_role, DEVICE_ROLE_FOURTH))
+        return true;
     else if (pa_safe_streq(device_role, DEVICE_ROLE_CALL_VOICE))
         return true;
     else if (pa_safe_streq(device_role, DEVICE_ROLE_CALL_VIDEO))
index df0e297..ed91400 100644 (file)
@@ -17,6 +17,9 @@
 #define DEVICE_TYPE_NONE                    "none"
 
 #define DEVICE_ROLE_NORMAL                  "normal"
+#define DEVICE_ROLE_SECOND                  "second"
+#define DEVICE_ROLE_THIRD                   "third"
+#define DEVICE_ROLE_FOURTH                  "fourth"
 #define DEVICE_ROLE_CALL_VOICE              "call-voice"
 #define DEVICE_ROLE_CALL_VIDEO              "call-video"
 #define DEVICE_ROLE_VOIP                    "voip"
index e2c0605..c1c1a83 100644 (file)
@@ -496,12 +496,10 @@ pa_tz_device* pa_tz_device_new(pa_tz_device_new_data *data) {
     device->is_running = false;
     device->specified_stream_role = pa_xstrdup("none");
 
-    if (device_type_is_use_external_card(device->type)) {
-        if ((sink = device_get_sink(device, NULL)))
-            sink->device_item = device;
-        if ((source = device_get_source(device, NULL)))
-            source->device_item = device;
-    }
+    if ((sink = device_get_sink(device, NULL)))
+        sink->device_item = device;
+    if ((source = device_get_source(device, NULL)))
+        source->device_item = device;
 
     pa_idxset_put(device->list, device, NULL);
     notify_device_connection_changed(device, true);