Name: pulseaudio-modules-tizen
Summary: Pulseaudio modules for Tizen
-Version: 5.0.109
+Version: 5.0.110
Release: 0
Group: Multimedia/Audio
License: LGPL-2.1+
return PA_HOOK_OK;
}
-
-
-static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object *pdevice, pa_device_manager *dm) {
- pa_tz_device *device;
- uint32_t idx = 0;
-
- pa_assert(c);
- pa_object_assert_ref(pdevice);
- pa_assert(dm);
-
- if (pa_sink_isinstance(pdevice)) {
- pa_sink *s = PA_SINK(pdevice);
- pa_sink_state_t state = pa_sink_get_state(s);
- pa_log_debug("=========== Sink(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state);
- if (s->use_internal_codec && state == PA_SINK_SUSPENDED) {
- PA_IDXSET_FOREACH(device, dm->device_list, idx) {
- if (pa_tz_device_is_use_internal_codec(device) && pa_tz_device_is_all_suspended(device))
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED);
- }
- } else {
- if ((device = pa_device_manager_get_device_with_sink(s))) {
- if (state == PA_SINK_RUNNING)
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_ACTIVATED);
- else if (state == PA_SINK_SUSPENDED)
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
- } else if (pa_source_isinstance(pdevice)) {
- pa_source *s = PA_SOURCE(pdevice);
- pa_source_state_t state = pa_source_get_state(s);
- pa_log_debug("=========== Source(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state);
- if (s->use_internal_codec && state == PA_SOURCE_SUSPENDED) {
- PA_IDXSET_FOREACH(device, dm->device_list, idx) {
- if (pa_tz_device_is_use_internal_codec(device) && pa_tz_device_is_all_suspended(device))
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED);
- }
- } else {
- if ((device = pa_device_manager_get_device_with_source(s))) {
- if (state == PA_SOURCE_RUNNING)
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_ACTIVATED);
- else if (state == PA_SOURCE_SUSPENDED)
- pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
- }
- pa_log_debug("========= sink_source_state_changed_hook_cb END =====");
-
- return PA_HOOK_OK;
-}
-
/*
Build params for load sink or source, and load it.
*/
type = pa_tz_device_get_type(device);
name = pa_tz_device_get_name(device);
device_id = (dbus_int32_t) pa_tz_device_get_id(device);
- state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+ state = pa_tz_device_get_state(device);
simple_device_dump(PA_LOG_INFO, description, device_id, type, name, direction, state);
if (state_mask == DEVICE_STATE_FLAGS || state_mask == 0)
return true;
- state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+ state = pa_tz_device_get_state(device);
if ((state_mask & DEVICE_STATE_DEACTIVATED_FLAG) && (state == DM_DEVICE_STATE_DEACTIVATED))
return true;
DBusMessage *reply = NULL;
DBusMessageIter msg_iter, array_iter, device_iter;
pa_tz_device *device;
- dm_device_state_t compound_state;
+ dm_device_state_t state;
uint32_t device_idx;
dbus_int32_t device_id, direction;
int mask;
pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiis)", &array_iter));
PA_IDXSET_FOREACH(device, dm->device_list, device_idx) {
- compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+ state = pa_tz_device_get_state(device);
direction = pa_tz_device_get_direction(device);
type = pa_tz_device_get_type(device);
name = pa_tz_device_get_name(device);
if (device_is_match_with_mask(device, mask)) {
device_id = (dbus_int32_t)pa_tz_device_get_id(device);
- simple_device_dump(PA_LOG_INFO, "[MATCH]", device_id, type, name, direction, compound_state);
+ simple_device_dump(PA_LOG_INFO, "[MATCH]", device_id, type, name, direction, state);
pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter));
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction);
- dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state);
+ dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter));
} else {
- simple_device_dump(PA_LOG_INFO, "[UNMATCH]", device_id, type, name, direction, compound_state);
+ simple_device_dump(PA_LOG_INFO, "[UNMATCH]", device_id, type, name, direction, state);
}
}
if ((device = _device_list_get_device_with_id(manager, device_id))) {
pa_assert_se((reply = dbus_message_new_method_return(msg)));
- state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+ state = pa_tz_device_get_state(device);
if (state == DM_DEVICE_STATE_ACTIVATED) {
stream_id_set = pa_tz_device_get_stream_list(device);
PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) {
dbus_init(dm);
dm->sink_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, dm);
- dm->sink_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm);
dm->sink_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, dm);
dm->source_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) source_put_hook_callback, dm);
- dm->source_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm);
dm->source_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_unlink_hook_callback, dm);
dm->comm = pa_communicator_get(dm->core);
dm->comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED),
}
}
-/* The state of a device using internal audio codec is handled here.
- * Regarding the state of an external device, it is handled in device-manager.c */
-static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) {
- dm_device_direction_t direction;
-
- pa_assert(device);
-
- direction = pa_tz_device_get_direction(device);
- if (IS_AVAILABLE_DIRECTION(stream_type, direction))
- if (pa_tz_device_is_use_internal_codec(device))
- pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state);
-}
-
/* threre is only one sco connected device */
static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) {
pa_idxset *device_list;
* 2. Update the state of devices.
* 3. Call HAL API to apply the routing setting. */
static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_data_for_route *data, struct userdata *u) {
- uint32_t i = 0;
uint32_t idx = 0;
uint32_t d_idx = 0;
uint32_t s_idx = 0;
stream_route_type_t route_type;
const char *device_type = NULL;
pa_tz_device *device = NULL;
- pa_tz_device *_device = NULL;
pa_tz_device *latest_device = NULL;
const char *dm_device_type = NULL;
- dm_device_state_t dm_device_state = DM_DEVICE_STATE_DEACTIVATED;
dm_device_direction_t dm_device_direction = DM_DEVICE_DIRECTION_NONE;
io_direction_t hal_direction;
void *s = NULL;
/* update BT SCO: close */
update_bt_sco_state(u->device_manager, false);
- /* get current connected devices */
- conn_devices = pa_device_manager_get_device_list(u->device_manager);
- /* set device state to deactivate */
- PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
- dm_device_type = pa_tz_device_get_type(device);
- dm_device_state = pa_tz_device_get_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type));
- dm_device_direction = pa_tz_device_get_direction(device);
- if (dm_device_state == DM_DEVICE_STATE_ACTIVATED && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) {
- pa_log_info("[ROUTE][RESET] found a matched device and set state to DE-ACTIVATED: type[%s], direction[0x%x]",
- dm_device_type, dm_device_direction);
- set_device_state_if_using_internal_codec(device, data->stream_type, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
route_info.role = "reset";
route_info.num_of_devices = 1;
route_info.device_infos = pa_xmalloc0(sizeof(hal_device_info)*route_info.num_of_devices);
route_info.device_infos[route_info.num_of_devices-1].id = dm_device_id;
pa_log_info(" ** found a matched device and set state to ACTIVATED: type[%-16s], direction[0x%x], id[%u]",
route_info.device_infos[route_info.num_of_devices-1].type, hal_direction, dm_device_id);
- /* set device state to activated */
- set_device_state_if_using_internal_codec(device, data->stream_type, DM_DEVICE_STATE_ACTIVATED);
} else
pa_log_debug(" -- it does not use internal audio codec, skip it");
break;
continue;
if (data->route_type == STREAM_ROUTE_TYPE_AUTO) {
- /* check if this device uses internal codec */
- use_internal_codec = pa_tz_device_is_use_internal_codec(device);
- if (use_internal_codec) {
- /* set other device's state to be deactivated */
- PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) {
- if (device == _device)
- continue;
- set_device_state_if_using_internal_codec(_device, data->stream_type, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
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
route_info.device_infos[route_info.num_of_devices-1].id = dm_device_id;
pa_log_info(" ** found a matched device and set state to ACTIVATED: type[%-16s], direction[0x%x], id[%u]",
route_info.device_infos[route_info.num_of_devices-1].type, hal_direction, dm_device_id);
- /* set device state to activated */
- set_device_state_if_using_internal_codec(latest_device, data->stream_type, DM_DEVICE_STATE_ACTIVATED);
-
- /* set other device's state to be deactivated */
- PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
- if (latest_device == device)
- continue;
- set_device_state_if_using_internal_codec(device, data->stream_type, DM_DEVICE_STATE_DEACTIVATED);
- }
} else
pa_log_debug(" -- it does not use internal audio codec, skip it");
}
}
- if (data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL && route_info.num_of_devices) {
- /* set other device's state to be deactivated */
- PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) {
- bool need_to_deactive = true;
- dm_device_id = pa_tz_device_get_id(_device);
- for (i = 0; i < route_info.num_of_devices; i++) {
- if (dm_device_id == route_info.device_infos[i].id) {
- need_to_deactive = false;
- break;
- }
- }
- if (need_to_deactive)
- set_device_state_if_using_internal_codec(_device, data->stream_type, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
-
} else if (data->route_type == STREAM_ROUTE_TYPE_MANUAL && data->idx_manual_devices && data->idx_avail_devices) {
PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) {
pa_log_info("[ROUTE][MANUAL] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type);
route_info.device_infos[route_info.num_of_devices-1].id = *device_id;
pa_log_info(" ** found a matched device and set state to be ACTIVATED: type[%-16s], direction[0x%x], id[%u]",
route_info.device_infos[route_info.num_of_devices-1].type, dm_device_direction, *device_id);
- /* set device state to be activated */
- set_device_state_if_using_internal_codec(device, data->stream_type, DM_DEVICE_STATE_ACTIVATED);
} else
pa_log_debug(" -- it does not use internal audio codec, skip it");
}
pa_idxset *mirroring_streams;
cur_max_priority_stream cur_highest_priority;
stream_restrictions restrictions;
+ bool on_call;
pa_hook_slot
*sink_input_new_slot,
#define IS_AVAILABLE_DIRECTION(stream_type, device_direction) \
((stream_type == STREAM_SINK_INPUT) ? (device_direction & DM_DEVICE_DIRECTION_OUT) : (device_direction & DM_DEVICE_DIRECTION_IN))
+#define GET_DIRECTION(stream) \
+ ((pa_sink_input_isinstance(stream)) ? DM_DEVICE_DIRECTION_OUT : DM_DEVICE_DIRECTION_IN)
static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata);
static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata);
dbus_message_unref(reply);
}
+
+static stream_parent* get_stream_parent(pa_object *stream, pa_stream_manager *m) {
+ pa_proplist *prop;
+ const char *parent_id;
+ uint32_t parent_id_u;
+
+ pa_assert(stream);
+ pa_assert(m);
+
+ if (pa_sink_input_isinstance(stream))
+ prop = PA_SINK_INPUT(stream)->proplist;
+ else
+ prop = PA_SOURCE_OUTPUT(stream)->proplist;
+
+ if ((parent_id = pa_proplist_gets(prop, PA_PROP_MEDIA_PARENT_ID)) == NULL) {
+ pa_log_warn("No parent for this stream");
+ return NULL;
+ }
+
+ if (pa_atou(parent_id, &parent_id_u) < 0) {
+ pa_log_warn("Invalid parent id '%s'", parent_id);
+ return NULL;
+ }
+
+ return pa_hashmap_get(m->stream_parents, (const void*)parent_id_u);
+}
+
+static pa_idxset* get_route_devices(pa_object *stream, pa_stream_manager *m) {
+ stream_parent *sp;
+
+ pa_assert(stream);
+ pa_assert(m);
+
+ if ((sp = get_stream_parent(stream, m)) == NULL) {
+ pa_log_error("No stream parent for this stream");
+ return NULL;
+ }
+
+ if (pa_sink_input_isinstance(stream))
+ return sp->idx_route_out_devices;
+ else
+ return sp->idx_route_in_devices;
+}
+
+static pa_idxset* get_avail_device_types(const char *stream_role, dm_device_direction_t direction, pa_stream_manager *m) {
+ stream_info *si;
+
+ pa_assert(stream_role);
+ pa_assert(m);
+
+ if (!(si = pa_hashmap_get(m->stream_infos, stream_role))) {
+ pa_log_warn("not supported role[%s]", stream_role);
+ return NULL;
+ }
+
+ if (direction == DM_DEVICE_DIRECTION_IN)
+ return si->idx_avail_in_devices;
+ else
+ return si->idx_avail_out_devices;
+}
+
+static void activate_device_only(pa_tz_device *device, pa_stream_manager *m) {
+ pa_idxset *device_list;
+ pa_tz_device *device_iter;
+ uint32_t device_idx, id, others_id;
+ dm_device_direction_t direction, others_direction;
+ dm_device_state_t others_state;
+ char *device_type;
+
+ pa_assert(device);
+ pa_assert(m);
+
+ direction = pa_tz_device_get_direction(device);
+ id = pa_tz_device_get_id(device);
+ device_type = pa_tz_device_get_type(device);
+
+ pa_log_info("activate device(%s/%u)", device_type, id);
+
+ pa_tz_device_set_state(device, DM_DEVICE_STATE_ACTIVATED);
+
+ /* deactivate others */
+ device_list = pa_device_manager_get_device_list(m->dm);
+ PA_IDXSET_FOREACH(device_iter, device_list, device_idx) {
+ if (device_iter != device) {
+ others_state = pa_tz_device_get_state(device_iter);
+ if (others_state == DM_DEVICE_STATE_DEACTIVATED)
+ continue;
+ others_direction = pa_tz_device_get_direction(device_iter);
+ others_id = pa_tz_device_get_id(device_iter);
+ if (direction & others_direction) {
+ pa_log_debug("device(%u) is deactivated by device(%u)", others_id, id);
+ pa_tz_device_set_state(device_iter, DM_DEVICE_STATE_DEACTIVATED);
+ }
+ }
+ }
+
+ return ;
+}
+
+static pa_tz_device* get_media_last_device(dm_device_direction_t direction, pa_stream_manager *m) {
+ char *device_type;
+ pa_tz_device *next_device, *latest_device = NULL;
+ pa_usec_t creation_time = 0;
+ pa_usec_t latest_creation_time = 0;
+ dm_device_direction_t direction2;
+ pa_idxset *avail_device_types;
+ uint32_t idx, id;
+
+ /* Only can get playback or capture device one by one */
+ if (direction == DM_DEVICE_DIRECTION_BOTH)
+ return NULL;
+
+ avail_device_types = get_avail_device_types(STREAM_ROLE_MEDIA, direction, m);
+
+ PA_IDXSET_FOREACH(device_type, avail_device_types, idx) {
+ if ((next_device = pa_device_manager_get_device(m->dm, device_type))) {
+ creation_time = pa_tz_device_get_creation_time(next_device);
+ direction2 = pa_tz_device_get_direction(next_device);
+ if ((direction & direction2) == 0)
+ continue;
+ if (!latest_device || (latest_creation_time <= creation_time)) {
+ latest_device = next_device;
+ latest_creation_time = creation_time;
+ }
+ }
+ }
+
+ if (latest_device) {
+ id = pa_tz_device_get_id(latest_device);
+ device_type = pa_tz_device_get_type(latest_device);
+ pa_log_info("last %s-device to activate : (%s/%u)", direction == DM_DEVICE_DIRECTION_IN ? "in" : "out", device_type, id);
+ } else {
+ pa_log_info("no %s-device", direction == DM_DEVICE_DIRECTION_IN ? "in" : "out");
+ }
+
+ return latest_device;
+}
+
+/* select device which of type is in avail_device_types, and highest priority in
+ * route_device */
+static pa_tz_device* select_device_from_avail_device_types(pa_idxset *avail_device_types,
+ pa_idxset *route_devices, pa_stream_manager *m) {
+ char *device_type;
+ uint32_t route_device_idx, device_type_idx;
+ uint32_t *route_device_id;
+ pa_tz_device *device, *candidate = NULL;
+
+ if (avail_device_types == NULL)
+ return NULL;
+ if (route_devices == NULL)
+ return NULL;
+
+ PA_IDXSET_FOREACH(device_type, avail_device_types, device_type_idx) {
+ PA_IDXSET_FOREACH(route_device_id, route_devices, route_device_idx) {
+ pa_log_warn("device id for call : %u", *route_device_id);
+ device = pa_device_manager_get_device_by_id(m->dm, *route_device_id);
+ if (device) {
+ pa_log_info("Found higher priority device(%u)", *route_device_id);
+ candidate = device;
+ }
+ }
+ }
+
+ return candidate;
+}
+
+static int change_active_route_for_call(pa_object *stream, bool stream_start, pa_stream_manager *m) {
+ pa_tz_device *device;
+ pa_idxset *avail_device_types, *route_devices;
+
+ pa_assert(stream);
+ pa_assert(m);
+ pa_assert(m->stream_parents);
+
+ pa_log_info("Call virtual stream %s, change active device", stream_start ? "start" : "change");
+
+ avail_device_types = get_avail_device_types(STREAM_ROLE_CALL_VOICE, GET_DIRECTION(stream), m);
+ if (!avail_device_types) {
+ pa_log_error("No avail device typs for call");
+ return -1;
+ }
+ route_devices = get_route_devices(stream, m);
+ if (!route_devices) {
+ pa_log_error("No route devices for this stream");
+ return -1;
+ }
+
+ device = select_device_from_avail_device_types(avail_device_types, route_devices, m);
+ if (!device) {
+ pa_log_error("Failed to select device to activate on call state");
+ return -1;
+ }
+ activate_device_only(device, m);
+
+ return 0;
+}
+
+static void set_media_active_device(pa_stream_manager *m) {
+ pa_tz_device *device;
+
+ pa_assert(m);
+
+ pa_log_info("set media active device");
+
+ device = get_media_last_device(DM_DEVICE_DIRECTION_IN, m);
+ if (device)
+ activate_device_only(device, m);
+ else
+ pa_log_info("There is no in-device");
+
+ device = get_media_last_device(DM_DEVICE_DIRECTION_OUT, m);
+ if (device)
+ activate_device_only(device, m);
+ else
+ pa_log_info("There is no out-device");
+}
+
+static void set_initial_active_device(pa_stream_manager *m) {
+ pa_assert(m);
+
+ set_media_active_device(m);
+}
+
static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *msg, void *userdata) {
uint32_t id = 0;
int i = 0;
}
} else if (m->cur_highest_priority.source_output) {
if (pa_idxset_get_by_data(sp->idx_source_outputs, m->cur_highest_priority.source_output, NULL)) {
+ const char *stream_role;
pa_log_debug(" -- cur_highest_priority.source_output->index[%u] belongs to this parent id[%u], do notify for the route change",
(m->cur_highest_priority.source_output)->index, id);
do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, m->cur_highest_priority.source_output);
+ stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) && m->on_call) {
+ pa_log_info("set active device for new call route device");
+ change_active_route_for_call(PA_OBJECT(m->cur_highest_priority.source_output), false, m);
+ }
}
}
} else {
}
} else if (m->cur_highest_priority.sink_input) {
if (pa_idxset_get_by_data(sp->idx_sink_inputs, m->cur_highest_priority.sink_input, NULL)) {
+ const char *stream_role;
pa_log_debug(" -- cur_highest_priority.sink_input->index[%u] belongs to this parent id[%u], do notify for the route change",
(m->cur_highest_priority.sink_input)->index, id);
do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input);
+ stream_role = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) && m->on_call) {
+ pa_log_info("set active device for new call route device");
+ change_active_route_for_call(PA_OBJECT(m->cur_highest_priority.sink_input), false, m);
+ }
}
}
} else {
}
static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) {
+ const char *stream_role;
+
pa_core_assert_ref(core);
pa_sink_input_assert_ref(i);
pa_log_debug("start sink_input_put_cb, i(%p, index:%u)", i, i->index);
process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_ADD_PARENT_ID, false);
+ stream_role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+ change_active_route_for_call(PA_OBJECT(i), true, m);
+ m->on_call = true;
+ }
return PA_HOOK_OK;
}
static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) {
+ const char *stream_role;
pa_core_assert_ref(core);
pa_sink_input_assert_ref(i);
pa_log_debug("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index);
+ stream_role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+ m->on_call = false;
+ set_media_active_device(m);
+ }
remove_sink_input_from_muted_streams(m, i);
process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_REMOVE_PARENT_ID, false);
process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
}
static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *o, pa_stream_manager *m) {
+ const char *stream_role;
pa_core_assert_ref(core);
pa_source_output_assert_ref(o);
update_mirroring_streams(m, o, true);
process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_ADD_PARENT_ID, false);
+ stream_role = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+ change_active_route_for_call(PA_OBJECT(o), true, m);
+ m->on_call = true;
+ }
return PA_HOOK_OK;
}
static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output *o, pa_stream_manager *m) {
+ const char *stream_role;
pa_core_assert_ref(core);
pa_source_output_assert_ref(o);
pa_log_info("start source_output_unlink_cb, o(%p, index:%u)", o, o->index);
+ stream_role = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_ROLE);
+ if (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE)) {
+ m->on_call = false;
+ set_media_active_device(m);
+ }
update_mirroring_streams(m, o, false);
process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false);
process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_REMOVE_PARENT_ID, false);
}
}
-/* The state of a device using internal audio codec is handled here.
- * Regarding the state of an external device, those is handled in device-manager.c */
-static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) {
- bool use_internal_codec = false;
-
- pa_assert(device);
-
- if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device)))
- pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state);
-}
-
static void update_sink_or_source_as_device_change(stream_route_type_t stream_route_type, pa_idxset *streams,
stream_type_t stream_type, pa_tz_device *device, bool is_connected, pa_stream_manager *m) {
#define MAX_CACHED_LEN 128
const char *cur_device_type = NULL;
const char *new_device_type = NULL;
pa_tz_device *next_device = NULL;
- pa_tz_device *_device = NULL;
stream_route_type_t route_type;
pa_sink *sink = NULL;
pa_sink *next_sink = NULL;
pa_log_debug("no need to move for stream(%p, idx:%u)", s, (stream_type == STREAM_SINK_INPUT ?
((pa_sink_input*)s)->index : ((pa_source_output*)s)->index));
if (available) {
- /* update activated device */
- pa_proplist_sets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, device_type);
- if ((_device = pa_device_manager_get_device(m->dm, device_type)))
- set_device_state_if_using_internal_codec(_device, stream_type, DM_DEVICE_STATE_ACTIVATED);
cached_prev_dev_list[cnt++].device_type = cur_device_type;
/* trigger to update routing path */
process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, use_internal_codec);
new_device_type = pa_tz_device_get_type(next_device);
/* update activated device */
pa_proplist_sets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, new_device_type);
- set_device_state_if_using_internal_codec(next_device, stream_type, DM_DEVICE_STATE_ACTIVATED);
cached_prev_dev_list[cnt++].device_type = device_type;
/* trigger to update routing path if the next device uses internal audio codec */
if (next_sink->use_internal_codec)
new_device_type = pa_tz_device_get_type(next_device);
/* update activated device */
pa_proplist_sets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, new_device_type);
- set_device_state_if_using_internal_codec(next_device, stream_type, DM_DEVICE_STATE_ACTIVATED);
cached_prev_dev_list[cnt++].device_type = device_type;
/* trigger to update routing path if the next device uses internal audio codec */
if (next_source->use_internal_codec)
}
}
}
- /* if there's no activated device marked in previous device list, set it to be deactivated */
- for (cnt = 0; cached_prev_dev_list[cnt].device_type; cnt++) {
- if (cached_prev_dev_list[cnt].count == 0) {
- if ((_device = pa_device_manager_get_device(m->dm, cached_prev_dev_list[cnt].device_type)))
- set_device_state_if_using_internal_codec(_device, stream_type, DM_DEVICE_STATE_DEACTIVATED);
- }
- }
}
} else if (stream_route_type == STREAM_ROUTE_TYPE_MANUAL_EXT) {
}
}
+ if (m->on_call) {
+ pa_log_info("This is on_call state, do nothing about active device");
+ } else {
+ pa_log_info("This is not on_call state, figure out to change active device");
+ set_media_active_device(m);
+ }
+
return PA_HOOK_OK;
}
m->comm.comm_hook_event_fully_handled_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_EVENT_FULLY_HANDLED),
PA_HOOK_EARLY + 10, (pa_hook_cb_t)event_fully_handled_hook_cb, m);
+ set_initial_active_device(m);
+
return m;
fail:
#define BT_CVSD_CODEC_ID 1 // narrow-band
#define BT_MSBC_CODEC_ID 2 // wide-band
-#define COMPOUND_STATE(d) (((pa_tz_device*)d)->playback_state | ((pa_tz_device*)d)->capture_state)
-
struct pa_intset {
int values[MAX_INTSET_NUM];
uint32_t write_index;
pa_strbuf_printf(buf, " Name : %s\n", device->name);
pa_strbuf_printf(buf, " System ID : %s\n", device->system_id);
pa_strbuf_printf(buf, " Direction : %s\n", device_direction_to_string(device->direction));
- pa_strbuf_printf(buf, " Is activated : %s\n", pa_yes_no(COMPOUND_STATE(device) == DM_DEVICE_STATE_ACTIVATED));
+ pa_strbuf_printf(buf, " Is activated : %s\n", pa_yes_no(device->state == DM_DEVICE_STATE_ACTIVATED));
pa_strbuf_printf(buf, " Internal : %s\n", pa_yes_no(device->use_internal_codec));
if (device_type_is_equal(device->type, DEVICE_TYPE_BT_SCO))
pa_strbuf_printf(buf, " SCO opened : %s\n", pa_yes_no(device->sco_opened));
return source;
}
-static void device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state) {
- dm_device_state_t prev_state, new_state;
+static void device_set_state(pa_tz_device *device, dm_device_state_t new_state) {
pa_assert(device);
- prev_state = COMPOUND_STATE(device);
- pa_log_debug("previous playback_state : %d, capture_state : %d => state %d", device->playback_state, device->capture_state, prev_state);
- if (direction & DM_DEVICE_DIRECTION_IN)
- device->capture_state = state;
- if (direction & DM_DEVICE_DIRECTION_OUT)
- device->playback_state = state;
- new_state = COMPOUND_STATE(device);
- pa_log_debug("new playback_state : %d, capture_state : %d => state %d", device->playback_state, device->capture_state, new_state);
-
- if (prev_state != new_state) {
+ if (device->state != new_state) {
+ pa_log_debug("change state %d -> %d", device->state, new_state);
+ device->state = new_state;
notify_device_state_changed(device, new_state);
pa_tz_device_dump_info(device, PA_LOG_DEBUG);
+ } else {
+ pa_log_debug("same state, not change it");
}
}
-static dm_device_state_t device_get_state(pa_tz_device *device, dm_device_direction_t direction) {
+static dm_device_state_t device_get_state(pa_tz_device *device) {
pa_assert(device);
-
- if (direction == DM_DEVICE_DIRECTION_BOTH)
- return COMPOUND_STATE(device);
- else if (direction == DM_DEVICE_DIRECTION_OUT)
- return device->playback_state;
- else if (direction == DM_DEVICE_DIRECTION_IN)
- return device->capture_state;
- else
- return DM_DEVICE_STATE_DEACTIVATED;
+ return device->state;
}
static int device_remove_sink_with_role(pa_tz_device *device, const char *role) {
device->playback_devices = data->playback_pcms;
device->capture_devices = data->capture_pcms;
device->direction = data->direction;
- device->playback_state = DM_DEVICE_STATE_DEACTIVATED;
- device->capture_state = DM_DEVICE_STATE_DEACTIVATED;
+ device->state = DM_DEVICE_STATE_DEACTIVATED;
device->creation_time = pa_rtclock_now();
device->use_internal_codec = data->use_internal_codec;
device->sco_opened = false;
/* TODO : Change param dm_device_state_t to bool or pa_tz_device_state_t,
* Because this state represent pa_tz_device's own state */
-void pa_tz_device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state) {
+void pa_tz_device_set_state(pa_tz_device *device, dm_device_state_t state) {
pa_assert(device);
- pa_log_info("device set state, device(%u) type(%s) direction(%s) -> %d",
- device->id, device->type, device_direction_to_string(direction), state);
- device_set_state(device, direction, state);
+ pa_log_info("device set state, device(%u) type(%s) -> %d",
+ device->id, device->type, state);
+ device_set_state(device, state);
}
-dm_device_state_t pa_tz_device_get_state(pa_tz_device *device, dm_device_direction_t direction) {
+dm_device_state_t pa_tz_device_get_state(pa_tz_device *device) {
pa_assert(device);
- return device_get_state(device, direction);
+ return device_get_state(device);
}
uint32_t pa_tz_device_get_id(pa_tz_device *device) {
/* Set by stream-manager
* If this is changed, will be notifacted */
- dm_device_state_t playback_state;
- dm_device_state_t capture_state;
+ dm_device_state_t state;
/* Can get proper sink/source in hashmaps with key(=device_role) */
pa_hashmap *playback_devices;
/* Exported API for other modules */
pa_sink* pa_tz_device_get_sink(pa_tz_device *device, const char *role);
pa_source* pa_tz_device_get_source(pa_tz_device *device, const char *role);
-void pa_tz_device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state);
-dm_device_state_t pa_tz_device_get_state(pa_tz_device *device, dm_device_direction_t direction);
+void pa_tz_device_set_state(pa_tz_device *device, dm_device_state_t state);
+dm_device_state_t pa_tz_device_get_state(pa_tz_device *device);
uint32_t pa_tz_device_get_id(pa_tz_device *device);
char* pa_tz_device_get_type(pa_tz_device *device);
char* pa_tz_device_get_name(pa_tz_device *device);