" <interface name=\"" DBUS_INTERFACE_DEVICE_MANAGER "\">\n" \
" <method name=\"GetConnectedDeviceList\">\n" \
" <arg name=\"mask_flags\" direction=\"in\" type=\"i\"/>\n" \
- " <arg name=\"ConnectedDeviceList\" direction=\"out\" type=\"a(iiiis)\"/>\n" \
+ " <arg name=\"ConnectedDeviceList\" direction=\"out\" type=\"a(isiiis)\"/>\n" \
" </method>\n" \
" <method name='GetBTA2DPStatus'>" \
" <arg type='b' name='is_bt_on' direction='out'/>" \
DEVICE_STATE_FLAGS = 0xF000, /**< Flag for device state */
} device_flags_type_t;
+typedef enum dm_device_bt_mode_type {
+ DM_DEVICE_BT_MODE_MEDIA = 0x1,
+ DM_DEVICE_BT_MODE_VOICE = 0x2
+} dm_device_bt_mode_t;
+
+typedef enum dm_device_changed_into_type {
+ DM_DEVICE_CHANGED_INFO_STATE,
+ DM_DEVICE_CHANGED_INFO_IO_DIRECTION,
+ DM_DEVICE_CHANGED_INFO_BT_AVAIL_MODE,
+ DM_DEVICE_CHANGED_INFO_MAX
+} dm_device_changed_info_t;
+
/*
Structure to save parsed information about device-file.
pa_core *core;
pa_hook_slot *sink_put_hook_slot, *sink_state_changed_slot, *sink_unlink_hook_slot;
pa_hook_slot *source_put_hook_slot, *source_state_changed_slot, *source_unlink_hook_slot;
- pa_hook_slot *comm_hook_device_connection_changed_slot, *comm_hook_device_info_changed_slot;
+ pa_hook_slot *comm_hook_device_connection_changed_slot, *comm_hook_device_profile_changed_slot;
+ pa_hook_slot *comm_hook_device_state_changed_slot;
pa_communicator *comm;
/*
.receive_cb = handle_test_device_status_change},
};
-/*** Defines for signal send ***/
-
-enum signal_index {
- SIGNAL_DEVICE_CONNECTED,
- SIGNAL_DEVICE_INFO_CHANGED,
- SIGNAL_MAX
-};
-
#endif
static void type_info_free_func(struct device_type_info *type_info) {
-static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *pdevice, pa_device_manager *dm) {
+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;
bool use_internal_codec = false;
uint32_t idx = 0;
}
}
}
- pa_log_debug("========= device_state_changed_hook_cb END =====");
+ pa_log_debug("========= sink_source_state_changed_hook_cb END =====");
return PA_HOOK_OK;
}
dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm);
}
+static int _get_avail_mode(pa_tz_device *device) {
+ int avail_mode = 0;
+ char *type;
+
+ pa_assert(device);
+
+ type = pa_tz_device_get_type(device);
+ if (pa_streq(type, DEVICE_TYPE_BT) == false) {
+ pa_log_debug("Not BT device");
+ return 0;
+ }
+
+ if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_SCO))
+ avail_mode |= DM_DEVICE_BT_MODE_VOICE;
+ if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_A2DP))
+ avail_mode |= DM_DEVICE_BT_MODE_MEDIA;
+
+ return avail_mode;
+}
static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) {
DBusMessage *signal_msg;
DBusMessageIter msg_iter, device_iter;
dbus_bool_t _connected = connected;
dm_device_state_t compound_state;
- dbus_int32_t device_id, direction;
+ dbus_int32_t device_id, direction, avail_mode;
char *type, *name;
pa_assert(device);
pa_assert(dm);
- pa_log_info("Send following device %s signal", connected ? "Connected" : "Disconnected");
+ pa_log_info("Send device %s signal, event_id(%u) device(%u)",
+ connected ? "Connected" : "Disconnected", event_id, device->id);
pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected"));
dbus_message_iter_init_append(signal_msg, &msg_iter);
direction = (dbus_int32_t) pa_tz_device_get_direction(device);
type = pa_tz_device_get_type(device);
name = pa_tz_device_get_name(device);
+ avail_mode = _get_avail_mode(device);
device_id = (dbus_int32_t) pa_tz_device_get_id(device);
compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
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, &avail_mode);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter));
dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected);
DBusMessage *signal_msg;
DBusMessageIter msg_iter, device_iter;
dm_device_state_t compound_state;
- dbus_int32_t device_id, direction;
+ dbus_int32_t device_id, direction, avail_mode;
char *type, *name;
pa_assert(device);
pa_assert(dm);
- pa_log_debug("Send following device info changed signal");
+ pa_log_debug("Send device info changed signal, event_id(%u) device(%u) changed_type(%d)",
+ event_id, device->id, changed_type);
pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged"));
dbus_message_iter_init_append(signal_msg, &msg_iter);
name = pa_tz_device_get_name(device);
device_id = (dbus_int32_t) pa_tz_device_get_id(device);
compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
+ avail_mode = (dbus_int32_t) _get_avail_mode(device);
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, &avail_mode);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter));
dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type);
pa_tz_device *device;
dm_device_state_t compound_state;
uint32_t device_idx;
- dbus_int32_t device_id, direction;
+ dbus_int32_t device_id, direction, avail_mode;
int mask_flags;
char *type, *name;
DBUS_TYPE_INVALID));
dbus_message_iter_init_append(reply, &msg_iter);
- pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiis)", &array_iter));
+ pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiiis)", &array_iter));
PA_IDXSET_FOREACH(device, dm->device_list, device_idx) {
compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH);
direction = pa_tz_device_get_direction(device);
type = pa_tz_device_get_type(device);
name = pa_tz_device_get_name(device);
+ avail_mode = _get_avail_mode(device);
if (device_item_match_for_mask(device, mask_flags, dm)) {
device_id = (dbus_int32_t)pa_tz_device_get_id(device);
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_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, &avail_mode);
dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name);
pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter));
}
return -1;
}
-static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *data, pa_device_manager *dm) {
+static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_device_manager *dm) {
send_device_connected_signal(data->event_id, data->device, data->is_connected, dm);
return PA_HOOK_OK;
}
-static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *data, pa_device_manager *dm) {
- send_device_info_changed_signal(data->event_id, data->device, data->changed_info, dm);
+static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *data, pa_device_manager *dm) {
+ if (data->changed == PA_TZ_DEVICE_PROFILE_ADDED || data->changed == PA_TZ_DEVICE_PROFILE_REMOVED)
+ send_device_info_changed_signal(data->event_id, data->device, DM_DEVICE_CHANGED_INFO_BT_AVAIL_MODE, dm);
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_state_changed *data, pa_device_manager *dm) {
+ send_device_info_changed_signal(data->event_id, data->device, DM_DEVICE_CHANGED_INFO_STATE, dm);
return PA_HOOK_OK;
}
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) device_state_changed_hook_cb, 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) device_state_changed_hook_cb, 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),
PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, dm);
- dm->comm_hook_device_info_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED),
- PA_HOOK_EARLY, (pa_hook_cb_t)device_info_changed_hook_cb, dm);
+ dm->comm_hook_device_profile_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED),
+ PA_HOOK_EARLY, (pa_hook_cb_t)device_profile_changed_hook_cb, dm);
+ dm->comm_hook_device_state_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED),
+ PA_HOOK_EARLY, (pa_hook_cb_t)device_state_changed_hook_cb, dm);
if (!(dm->type_infos = parse_device_type_infos())) {
pa_log_error("Parse device-type-map failed");
return NULL;
if (dm->comm_hook_device_connection_changed_slot)
pa_hook_slot_free(dm->comm_hook_device_connection_changed_slot);
- if (dm->comm_hook_device_info_changed_slot)
- pa_hook_slot_free(dm->comm_hook_device_info_changed_slot);
+ if (dm->comm_hook_device_profile_changed_slot)
+ pa_hook_slot_free(dm->comm_hook_device_profile_changed_slot);
+ if (dm->comm_hook_device_state_changed_slot)
+ pa_hook_slot_free(dm->comm_hook_device_state_changed_slot);
if (dm->sink_put_hook_slot)
pa_hook_slot_free(dm->sink_put_hook_slot);
if (dm->sink_state_changed_slot)
pa_hook_slot *comm_hook_select_proper_sink_or_source_slot;
pa_hook_slot *comm_hook_change_route_slot;
pa_hook_slot *comm_hook_device_connection_changed_slot;
- pa_hook_slot *comm_hook_device_info_changed_slot;
+ pa_hook_slot *comm_hook_device_profile_changed_slot;
pa_hook_slot *comm_hook_update_info_slot;
} communicator;
}
/* Reorganize routing when a device has been connected or disconnected */
-static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *conn, struct userdata *u) {
+static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *conn, struct userdata *u) {
uint32_t idx = 0;
pa_sink_input *s = NULL;
dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT;
}
/* Update connected device list when a device's information has been changed */
-static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *conn, struct userdata *u) {
+static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *conn, struct userdata *u) {
dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT;
int* ptr_in = NULL;
int* ptr_out = NULL;
device_direction = pa_tz_device_get_direction(conn->device);
- pa_log_info("[CONN] device_info_changed_hook_cb is called. conn(%p), changed_info(%d), device(%p), direction(0x%x)",
- conn, conn->changed_info, conn->device, device_direction);
+ pa_log_info("[CONN] device_profile_changed_hook_cb is called. conn(%p), changed(%d), device(%p), direction(0x%x)",
+ conn, conn->changed, conn->device, device_direction);
- if (conn->changed_info == DM_DEVICE_CHANGED_INFO_IO_DIRECTION)
+ if (conn->changed == PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED)
if (pa_streq(pa_tz_device_get_type(conn->device), DEVICE_TYPE_BT)) {
/* In case of the bluetooth, we do not maintain a ref. count of the bluetooth devices.
* Because bluetooth framework supports only one device simultaneously for audio profile. */
u->communicator.comm_hook_device_connection_changed_slot = pa_hook_connect(
pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED),
PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, u);
- u->communicator.comm_hook_device_info_changed_slot = pa_hook_connect(
- pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED),
- PA_HOOK_EARLY, (pa_hook_cb_t)device_info_changed_hook_cb, u);
+ u->communicator.comm_hook_device_profile_changed_slot = pa_hook_connect(
+ pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED),
+ PA_HOOK_EARLY, (pa_hook_cb_t)device_profile_changed_hook_cb, u);
u->communicator.comm_hook_update_info_slot = pa_hook_connect(
pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_UPDATE_INFORMATION),
PA_HOOK_EARLY, (pa_hook_cb_t)update_info_hook_cb, u);
pa_hook_slot_free(u->communicator.comm_hook_change_route_slot);
if (u->communicator.comm_hook_device_connection_changed_slot)
pa_hook_slot_free(u->communicator.comm_hook_device_connection_changed_slot);
- if (u->communicator.comm_hook_device_info_changed_slot)
- pa_hook_slot_free(u->communicator.comm_hook_device_info_changed_slot);
+ if (u->communicator.comm_hook_device_profile_changed_slot)
+ pa_hook_slot_free(u->communicator.comm_hook_device_profile_changed_slot);
if (u->communicator.comm_hook_update_info_slot)
pa_hook_slot_free(u->communicator.comm_hook_update_info_slot);
pa_communicator_unref(u->communicator.comm);
}
static void notify_device_connection_changed(pa_tz_device *device, bool connected) {
- pa_device_manager_hook_data_for_conn_changed hook_data;
- uint32_t event_id;
+ pa_tz_device_hook_data_for_conn_changed hook_data;
- event_id = _new_event_id();
-
- hook_data.event_id = event_id;
+ hook_data.event_id = _new_event_id();
hook_data.is_connected = connected;
hook_data.device = device;
- pa_log_info("Fire hook for device connection changed, device(%u) %s",
- device->id, connected ? "connected" : "disconnected");
+ pa_log_info("Fire hook for device connection changed, device(%s/%u) %s",
+ device->type, device->id, connected ? "connected" : "disconnected");
pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), &hook_data);
}
-static void notify_device_info_changed(pa_tz_device *device, dm_device_changed_info_t changed_type) {
- pa_device_manager_hook_data_for_info_changed hook_data;
- uint32_t event_id;
+static void notify_device_profile_changed(pa_tz_device *device, pa_tz_device_profile_changed_t changed_type) {
+ pa_tz_device_hook_data_for_profile_changed hook_data;
+ const char* changed_type_str[PA_TZ_DEVICE_PROFILE_CHANGED_MAX] =
+ {"Profile Added", "Profile Removed", "Active-profile Changed"};
+
+ hook_data.event_id = _new_event_id();
+ hook_data.changed = changed_type;
+ hook_data.device = device;
+
+ pa_log_info("Fire hook for device profile changed, device(%s/%u) %s",
+ device->type, device->id, changed_type_str[changed_type]);
+ pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED), &hook_data);
+}
- event_id = _new_event_id();
+static void notify_device_state_changed(pa_tz_device *device, dm_device_state_t state) {
+ pa_tz_device_hook_data_for_state_changed hook_data;
- hook_data.event_id = event_id;
- hook_data.changed_info = changed_type;
+ hook_data.event_id = _new_event_id();
+ hook_data.activated = (state == DM_DEVICE_STATE_ACTIVATED) ? true : false;
hook_data.device = device;
- pa_log_info("Fire hook for device info changed, device(%u) %s changed",
- device->id, changed_type == DM_DEVICE_CHANGED_INFO_STATE ? "state" : "direction");
- pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), &hook_data);
+ pa_log_info("Fire hook for device state changed, device(%s/%u) %s",
+ device->type, device->id, hook_data.activated ? "Activated" : "De-activated");
+ pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED), &hook_data);
}
/* pa_tz_device_new_data */
pa_log_debug("new playback_state : %d, capture_state : %d => state %d", profile->playback_state, profile->capture_state, new_state);
if (prev_state != new_state) {
- notify_device_info_changed(profile->device, DM_DEVICE_CHANGED_INFO_STATE);
+ notify_device_state_changed(profile->device, new_state);
pa_tz_device_dump_info(profile->device, PA_LOG_DEBUG);
}
}
/* Compare index only when check_idx is true */
if (noti_always || prev_active_idx != device->active_profile)
- notify_device_info_changed(device, DM_DEVICE_CHANGED_INFO_IO_DIRECTION);
+ notify_device_profile_changed(device, PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED);
return 0;
}
if (as_active)
_set_active_profile(device, pdata->profile, true);
+ notify_device_profile_changed(device, PA_TZ_DEVICE_PROFILE_ADDED);
pa_tz_device_dump_info(device, PA_LOG_INFO);
return 0;
/* change active profile if removed one was active */
if (device->active_profile == remove_idx)
_set_active_profile(device, NULL, true);
+ notify_device_profile_changed(device, PA_TZ_DEVICE_PROFILE_REMOVED);
pa_tz_device_dump_info(device, PA_LOG_INFO);
return 0;
} else {
return source;
}
+/* 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) {
pa_tz_profile *profile;