#define VOLUME_TYPE_LEN 64
-mm_sound_device_list_t *g_device_list;
+static mm_sound_device_list_t g_device_list;
+static pthread_mutex_t g_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
-static int _check_for_valid_mask (int flags)
+static int _check_for_valid_mask(int flags)
{
int ret = MM_ERROR_NONE;
bool at_least_cond = false;
} else {
ret = MM_ERROR_INVALID_ARGUMENT;
}
- if (!at_least_cond) {
+
+ if (!at_least_cond)
ret = MM_ERROR_INVALID_ARGUMENT;
- }
- if (ret) {
- debug_error("flags[0x%x] is not valid\n", flags);
- }
+
+ if (ret)
+ debug_error("flags[0x%x] is not valid", flags);
+
return ret;
}
-static int __convert_device_type_to_enum (char *device_type, mm_sound_device_type_e *device_type_enum)
+static int __convert_device_type_to_enum(char *device_type, mm_sound_device_type_e *device_type_enum)
{
int ret = MM_ERROR_NONE;
- if (!device_type || !device_type_enum) {
+ if (!device_type || !device_type_enum)
return MM_ERROR_INVALID_ARGUMENT;
- }
if (!strncmp(device_type, "builtin-speaker", VOLUME_TYPE_LEN)) {
*device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
*device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_MIC;
} else if (!strncmp(device_type, "audio-jack", VOLUME_TYPE_LEN)) {
*device_type_enum = MM_SOUND_DEVICE_TYPE_AUDIOJACK;
- } else if (!strncmp(device_type, "bt", VOLUME_TYPE_LEN)) {
- *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH;
+ } else if (!strncmp(device_type, "bt-a2dp", VOLUME_TYPE_LEN)) {
+ *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH_A2DP;
+ } else if (!strncmp(device_type, "bt-sco", VOLUME_TYPE_LEN)) {
+ *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH_SCO;
} else if (!strncmp(device_type, "hdmi", VOLUME_TYPE_LEN)) {
*device_type_enum = MM_SOUND_DEVICE_TYPE_HDMI;
} else if (!strncmp(device_type, "forwarding", VOLUME_TYPE_LEN)) {
*device_type_enum = MM_SOUND_DEVICE_TYPE_MIRRORING;
} else if (!strncmp(device_type, "usb-audio", VOLUME_TYPE_LEN)) {
*device_type_enum = MM_SOUND_DEVICE_TYPE_USB_AUDIO;
+ } else if (!strncmp(device_type, "network", VOLUME_TYPE_LEN)) {
+ *device_type_enum = MM_SOUND_DEVICE_TYPE_NETWORK;
} else {
ret = MM_ERROR_INVALID_ARGUMENT;
debug_error("not supported device_type(%s), err(0x%08x)", device_type, ret);
return MM_ERROR_INVALID_ARGUMENT;
debug_log("free device list %p", device_list_t);
- g_list_free_full(device_list_t->list, g_free);
+ g_list_free_full(g_list_first(device_list_t->list), g_free);
g_free(device_list_t);
return MM_ERROR_NONE;
}
EXPORT_API
-int mm_sound_add_device_connected_callback(mm_sound_device_flags_e flags, mm_sound_device_connected_cb func, void *user_data, unsigned int *subs_id)
+int mm_sound_add_device_connected_callback(int flags, mm_sound_device_connected_cb func, void *user_data, unsigned int *id)
{
int ret = MM_ERROR_NONE;
- if (func == NULL || subs_id == NULL) {
- debug_error("argument is not valid\n");
+ if (func == NULL || id == NULL) {
+ debug_error("argument is not valid");
return MM_ERROR_INVALID_ARGUMENT;
}
ret = _check_for_valid_mask(flags);
if (ret == MM_ERROR_NONE) {
- ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, subs_id);
- if (ret < 0) {
- debug_error("Could not add device connected callback, ret = %x\n", ret);
- }
+ ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, id);
+ if (ret < 0)
+ debug_error("Could not add device connected callback, ret = %x", ret);
}
return ret;
}
EXPORT_API
-int mm_sound_remove_device_connected_callback(unsigned int subs_id)
+int mm_sound_remove_device_connected_callback(unsigned int id)
{
int ret = MM_ERROR_NONE;
- ret = mm_sound_client_remove_device_connected_callback(subs_id);
- if (ret < 0) {
- debug_error("Could not remove device connected callback, ret = %x\n", ret);
+ ret = mm_sound_client_remove_device_connected_callback(id);
+ if (ret < 0)
+ debug_error("Could not remove device connected callback, ret = %x", ret);
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_add_device_information_changed_callback(int flags, mm_sound_device_info_changed_cb func, void *user_data, unsigned int *id)
+{
+ int ret = MM_ERROR_NONE;
+
+ if (func == NULL || id == NULL) {
+ debug_error("argument is not valid");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ ret = _check_for_valid_mask(flags);
+ if (ret == MM_ERROR_NONE) {
+ ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, id);
+ if (ret < 0)
+ debug_error("Could not add device information changed callback, ret = %x", ret);
}
return ret;
}
EXPORT_API
-int mm_sound_add_device_information_changed_callback(mm_sound_device_flags_e flags, mm_sound_device_info_changed_cb func, void *user_data, unsigned int *subs_id)
+int mm_sound_remove_device_information_changed_callback(unsigned int id)
+{
+ int ret = MM_ERROR_NONE;
+
+ ret = mm_sound_client_remove_device_info_changed_callback(id);
+ if (ret < 0)
+ debug_error("Could not remove device information changed callback, ret = %x", ret);
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_add_device_state_changed_callback(int flags, mm_sound_device_state_changed_cb func, void *user_data, unsigned int *id)
{
int ret = MM_ERROR_NONE;
- if (func == NULL || subs_id == NULL) {
- debug_error("argument is not valid\n");
+ if (func == NULL || id == NULL) {
+ debug_error("argument is not valid");
return MM_ERROR_INVALID_ARGUMENT;
}
ret = _check_for_valid_mask(flags);
if (ret == MM_ERROR_NONE) {
- ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, subs_id);
+ ret = mm_sound_client_add_device_state_changed_callback(flags, func, user_data, id);
+ if (ret < 0)
+ debug_error("Could not add device state changed callback, ret = %x", ret);
+ }
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_remove_device_state_changed_callback(unsigned int id)
+{
+ int ret = MM_ERROR_NONE;
+
+ ret = mm_sound_client_remove_device_state_changed_callback(id);
+ if (ret < 0)
+ debug_error("Could not remove device state changed callback, ret = %x", ret);
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_add_device_running_changed_callback(int flags, mm_sound_device_running_changed_cb func, void *user_data, unsigned int *id)
+{
+ int ret = MM_ERROR_NONE;
+
+ if (func == NULL || id == NULL) {
+ debug_error("argument is not valid");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ ret = _check_for_valid_mask(flags);
+ if (ret == MM_ERROR_NONE) {
+ ret = mm_sound_client_add_device_running_changed_callback(flags, func, user_data, id);
if (ret < 0) {
- debug_error("Could not add device information changed callback, ret = %x\n", ret);
+ debug_error("Could not add device running changed callback, ret = %x", ret);
}
}
}
EXPORT_API
-int mm_sound_remove_device_information_changed_callback(unsigned int subs_id)
+int mm_sound_remove_device_running_changed_callback(unsigned int id)
{
int ret = MM_ERROR_NONE;
- ret = mm_sound_client_remove_device_info_changed_callback(subs_id);
+ ret = mm_sound_client_remove_device_running_changed_callback(id);
if (ret < 0) {
- debug_error("Could not remove device information changed callback, ret = %x\n", ret);
+ debug_error("Could not remove device running changed callback, ret = %x", ret);
}
return ret;
{
int ret = MM_ERROR_NONE;
- if (!device_list) {
+ if (!device_list)
return MM_ERROR_INVALID_ARGUMENT;
- }
+
ret = _check_for_valid_mask(flags);
if (ret != MM_ERROR_NONE) {
debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
return ret;
}
- /* free previously allocated list */
- if (g_device_list != NULL)
- __free_device_list(g_device_list);
+ pthread_mutex_lock(&g_thread_mutex);
- if (!(g_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
- debug_error("[Client] Allocate device list failed");
- return MM_ERROR_SOUND_INTERNAL;
+ if (g_device_list.list != NULL) {
+ g_list_free_full(g_device_list.list, g_free);
+ g_device_list.list = NULL;
}
- g_device_list->is_new_device_list = true;
+ g_device_list.is_new_device_list = true;
- ret = mm_sound_client_get_current_connected_device_list(flags, g_device_list);
+ ret = mm_sound_client_get_current_connected_device_list(flags, &g_device_list);
if (ret < 0) {
- debug_error("Could not get current connected device list, ret = %x\n", ret);
- g_free(g_device_list);
- g_device_list = NULL;
+ debug_error("Could not get current connected device list, ret = %x", ret);
+ g_device_list.list = NULL;
} else {
- *device_list = g_device_list;
+ *device_list = &g_device_list;
}
+ pthread_mutex_unlock(&g_thread_mutex);
+
return ret;
}
int ret = MM_ERROR_NONE;
mm_sound_device_list_t *_device_list;
- if (!device_list) {
+ if (!device_list)
return MM_ERROR_INVALID_ARGUMENT;
- }
+
ret = _check_for_valid_mask(flags);
if (ret != MM_ERROR_NONE) {
debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
}
if (!(_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
- debug_error("[Client] Allocate device list failed");
+ debug_error("Allocate device list failed");
return MM_ERROR_SOUND_INTERNAL;
}
ret = mm_sound_client_get_current_connected_device_list(flags, _device_list);
if (ret < 0) {
- debug_error("Could not get current connected device list, ret = %x\n", ret);
+ debug_error("Could not get current connected device list, ret = %x", ret);
g_free(_device_list);
} else {
*device_list = _device_list;
}
EXPORT_API
-int mm_sound_get_next_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
+int mm_sound_free_device(MMSoundDevice_t device_h)
+{
+ if (device_h == NULL)
+ return MM_ERROR_INVALID_ARGUMENT;
+
+ g_free(device_h);
+
+ return MM_ERROR_NONE;
+}
+
+EXPORT_API
+int mm_sound_get_device_by_id(int device_id, MMSoundDevice_t *device_h)
+{
+ int ret = MM_ERROR_NONE;
+ mm_sound_device_t *device = NULL;
+
+ if (device_id < 1 || device_h == NULL)
+ return MM_ERROR_INVALID_ARGUMENT;
+
+ ret = mm_sound_client_get_device_by_id(device_id, &device);
+ if (ret < 0)
+ debug_error("Could not get device by id, ret = %x", ret);
+ else
+ *device_h = device;
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_get_next_device(MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
{
int ret = MM_ERROR_NONE;
mm_sound_device_list_t *device_list_t = NULL;
GList *node = NULL;
- if (!device_list || !device) {
+
+ if (!device_list || !device)
return MM_ERROR_INVALID_ARGUMENT;
- }
+
device_list_t = (mm_sound_device_list_t*) device_list;
- if (device_list_t->is_new_device_list) {
+ if (device_list_t->is_new_device_list)
node = g_list_first(device_list_t->list);
- } else {
+ else
node = g_list_next(device_list_t->list);
- }
+
if (!node) {
ret = MM_ERROR_SOUND_NO_DATA;
} else {
- if (device_list_t->is_new_device_list) {
+ if (device_list_t->is_new_device_list)
device_list_t->is_new_device_list = false;
- } else {
+ else
device_list_t->list = node;
- }
+
*device = (mm_sound_device_t*)node->data;
- debug_log("next device[0x%x]\n", *device);
+ debug_log("next device[%p]", *device);
}
return ret;
}
EXPORT_API
-int mm_sound_get_prev_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
+int mm_sound_get_prev_device(MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
{
int ret = MM_ERROR_NONE;
mm_sound_device_list_t *device_list_t = NULL;
GList *node = NULL;
- if (!device_list || !device) {
+
+ if (!device_list || !device)
return MM_ERROR_INVALID_ARGUMENT;
- }
+
device_list_t = (mm_sound_device_list_t*) device_list;
node = g_list_previous(device_list_t->list);
if (!node) {
ret = MM_ERROR_SOUND_NO_DATA;
- debug_error("Could not get previous device, ret = %x\n", ret);
+ debug_error("Could not get previous device, ret = %x", ret);
} else {
device_list_t->list = node;
*device = (mm_sound_device_t*)node->data;
- debug_log("previous device[0x%x]\n", *device);
+ debug_log("previous device[%p]", *device);
}
return ret;
}
int mm_sound_get_device_type(MMSoundDevice_t device_h, mm_sound_device_type_e *type)
{
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
- if(!device || !type) {
- debug_error("invalid argument\n");
+ if (!device || !type) {
+ debug_error("invalid argument");
return MM_ERROR_INVALID_ARGUMENT;
}
__convert_device_type_to_enum(device->type, type);
- debug_log("device_handle:0x%x, type:%d\n", device, *type);
+ debug_log("device_handle:%p, type:%d", device, *type);
return MM_ERROR_NONE;
}
int mm_sound_get_device_io_direction(MMSoundDevice_t device_h, mm_sound_device_io_direction_e *io_direction)
{
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
- if(!device) {
- debug_error("invalid handle\n");
+ if (!device) {
+ debug_error("invalid handle");
return MM_ERROR_INVALID_ARGUMENT;
}
*io_direction = device->io_direction;
- debug_log("device_handle:0x%x, io_direction:%d (1:IN,2:OUT,3:INOUT)\n", device, *io_direction);
+ debug_log("device_handle:%p, io_direction:%d (1:IN,2:OUT,3:INOUT)", device, *io_direction);
return MM_ERROR_NONE;
}
int mm_sound_get_device_id(MMSoundDevice_t device_h, int *id)
{
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
- if(!device) {
- debug_error("invalid handle\n");
+ if (!device) {
+ debug_error("invalid handle");
return MM_ERROR_INVALID_ARGUMENT;
}
*id = device->id;
- debug_log("device_handle:0x%x, id:%d\n", device, *id);
+ debug_log("device_handle:%p, id:%d", device, *id);
return MM_ERROR_NONE;
}
int mm_sound_get_device_state(MMSoundDevice_t device_h, mm_sound_device_state_e *state)
{
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
- if(!device) {
- debug_error("invalid handle\n");
+ if (!device) {
+ debug_error("invalid handle");
return MM_ERROR_INVALID_ARGUMENT;
}
*state = device->state;
- debug_log("device_handle:0x%x, state:%d (0:INACTIVATED,1:ACTIVATED)\n", device, *state);
+ debug_log("device_handle:%p, state:%d (0:INACTIVATED,1:ACTIVATED)", device, *state);
return MM_ERROR_NONE;
}
int mm_sound_get_device_name(MMSoundDevice_t device_h, char **name)
{
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
- if(!device) {
- debug_error("invalid handle\n");
+ if (!device) {
+ debug_error("invalid handle");
return MM_ERROR_INVALID_ARGUMENT;
}
*name = device->name;
- debug_log("device_handle:0x%x, name:%s\n", device, *name);
+ debug_log("device_handle:%p, name:%s", device, *name);
return MM_ERROR_NONE;
}
EXPORT_API
-int mm_sound_get_device_bt_avail_mode(MMSoundDevice_t device_h, int *avail_mode)
+int mm_sound_get_device_vendor_id(MMSoundDevice_t device_h, int *vendor_id)
{
- mm_sound_device_type_e type;
mm_sound_device_t *device = (mm_sound_device_t*)device_h;
+ if (!device) {
+ debug_error("invalid handle");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ *vendor_id = device->vendor_id;
+ debug_log("device_handle:%p, vendor id:%04x", device, *vendor_id);
+
+ return MM_ERROR_NONE;
+}
- if (!device || !avail_mode) {
- debug_error("invalid argument\n");
+EXPORT_API
+int mm_sound_get_device_product_id(MMSoundDevice_t device_h, int *product_id)
+{
+ mm_sound_device_t *device = (mm_sound_device_t*)device_h;
+ if (!device) {
+ debug_error("invalid handle");
return MM_ERROR_INVALID_ARGUMENT;
}
+ *product_id = device->product_id;
+ debug_log("device_handle:%p, product id:%04x", device, *product_id);
+
+ return MM_ERROR_NONE;
+}
- __convert_device_type_to_enum(device->type, &type);
- if (type != MM_SOUND_DEVICE_TYPE_BLUETOOTH) {
- debug_error("invalid device type(%s)\n", device->type);
+EXPORT_API
+int mm_sound_is_stream_on_device(int stream_id, MMSoundDevice_t device_h, bool *is_on)
+{
+ int ret = MM_ERROR_NONE;
+ int i;
+ mm_sound_device_t *device = (mm_sound_device_t*)device_h;
+ bool _is_on = false;
+
+ if (!device || !is_on) {
+ debug_error("invalid argument");
return MM_ERROR_INVALID_ARGUMENT;
}
- *avail_mode = device->avail_mode;
- debug_log("device_handle:0x%p, avail mode:%d\n", device, *avail_mode);
+ if (device->stream_num >= 0) {
+ debug_log("device_handle has stream id");
+ for (i = 0; i < device->stream_num; i++) {
+ if (device->stream_id[i] == stream_id) {
+ _is_on = true;
+ break;
+ }
+ }
+ } else {
+ debug_log("device_handle dosn't have stream id");
+ /* No information about stream in client-side, should ask to server-side */
+ if ((ret = mm_sound_client_is_stream_on_device(stream_id, device->id, &_is_on)) < 0) {
+ debug_error("Failed to query is stream on");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+ }
- return MM_ERROR_NONE;
+ debug_log("device(%d) %s stream(%d)", device->id, _is_on ? "has" : "doesn't have", stream_id);
+ *is_on = _is_on;
+
+ return ret;
+}
+
+EXPORT_API
+int mm_sound_is_stream_on_device_by_id(int stream_id, int device_id, bool *is_on)
+{
+ int ret = MM_ERROR_NONE;
+ bool _is_on = false;
+
+ if (!is_on) {
+ debug_error("invalid argument");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ if ((ret = mm_sound_client_is_stream_on_device(stream_id, device_id, &_is_on)) < 0) {
+ debug_error("Failed to query is stream on");
+ return MM_ERROR_SOUND_INTERNAL;
+ }
+
+ debug_log("device(%d) %s stream(%d)", device_id, _is_on ? "has" : "doesn't have", stream_id);
+ *is_on = _is_on;
+
+ return ret;
}
+EXPORT_API
+int mm_sound_is_device_running(MMSoundDevice_t device_h, bool *is_running)
+{
+ mm_sound_device_t *device = (mm_sound_device_t*)device_h;
+ if (!device || !is_running) {
+ debug_error("invalid argument");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ *is_running = device->is_running;
+ debug_log("device_handle:0x%p, running:%d", device, *is_running);
+
+ return MM_ERROR_NONE;
+}