4 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Sangchul Lee <sc11.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include "include/mm_sound.h"
28 #include "include/mm_sound_device.h"
29 #include "include/mm_sound_client.h"
31 #define VOLUME_TYPE_LEN 64
33 mm_sound_device_list_t *g_device_list;
35 static int _check_for_valid_mask (int flags)
37 int ret = MM_ERROR_NONE;
38 bool at_least_cond = false;
40 if (flags > 0 && flags <= MM_SOUND_DEVICE_ALL_FLAG) {
41 if (flags & MM_SOUND_DEVICE_IO_DIRECTION_IN_FLAG)
43 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG))
45 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG))
47 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_INTERNAL_FLAG))
49 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG))
51 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_DEACTIVATED_FLAG))
53 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG))
56 ret = MM_ERROR_INVALID_ARGUMENT;
59 ret = MM_ERROR_INVALID_ARGUMENT;
62 debug_error("flags[0x%x] is not valid\n", flags);
67 static int __convert_device_type_to_enum (char *device_type, mm_sound_device_type_e *device_type_enum)
69 int ret = MM_ERROR_NONE;
71 if (!device_type || !device_type_enum) {
72 return MM_ERROR_INVALID_ARGUMENT;
75 if (!strncmp(device_type, "builtin-speaker", VOLUME_TYPE_LEN)) {
76 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
77 } else if (!strncmp(device_type, "builtin-receiver", VOLUME_TYPE_LEN)) {
78 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER;
79 } else if (!strncmp(device_type, "builtin-mic", VOLUME_TYPE_LEN)) {
80 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_MIC;
81 } else if (!strncmp(device_type, "audio-jack", VOLUME_TYPE_LEN)) {
82 *device_type_enum = MM_SOUND_DEVICE_TYPE_AUDIOJACK;
83 } else if (!strncmp(device_type, "bt", VOLUME_TYPE_LEN)) {
84 *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH;
85 } else if (!strncmp(device_type, "hdmi", VOLUME_TYPE_LEN)) {
86 *device_type_enum = MM_SOUND_DEVICE_TYPE_HDMI;
87 } else if (!strncmp(device_type, "forwarding", VOLUME_TYPE_LEN)) {
88 *device_type_enum = MM_SOUND_DEVICE_TYPE_MIRRORING;
89 } else if (!strncmp(device_type, "usb-audio", VOLUME_TYPE_LEN)) {
90 *device_type_enum = MM_SOUND_DEVICE_TYPE_USB_AUDIO;
92 ret = MM_ERROR_INVALID_ARGUMENT;
93 debug_error("not supported device_type(%s), err(0x%08x)", device_type, ret);
99 static int __free_device_list(mm_sound_device_list_t *device_list_t)
102 return MM_ERROR_INVALID_ARGUMENT;
104 debug_log("free device list %p", device_list_t);
105 g_list_free_full(device_list_t->list, g_free);
106 g_free(device_list_t);
108 return MM_ERROR_NONE;
112 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)
114 int ret = MM_ERROR_NONE;
116 if (func == NULL || subs_id == NULL) {
117 debug_error("argument is not valid\n");
118 return MM_ERROR_INVALID_ARGUMENT;
120 ret = _check_for_valid_mask(flags);
121 if (ret == MM_ERROR_NONE) {
122 ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, subs_id);
124 debug_error("Could not add device connected callback, ret = %x\n", ret);
132 int mm_sound_remove_device_connected_callback(unsigned int subs_id)
134 int ret = MM_ERROR_NONE;
136 ret = mm_sound_client_remove_device_connected_callback(subs_id);
138 debug_error("Could not remove device connected callback, ret = %x\n", ret);
145 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)
147 int ret = MM_ERROR_NONE;
149 if (func == NULL || subs_id == NULL) {
150 debug_error("argument is not valid\n");
151 return MM_ERROR_INVALID_ARGUMENT;
153 ret = _check_for_valid_mask(flags);
154 if (ret == MM_ERROR_NONE) {
155 ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, subs_id);
157 debug_error("Could not add device information changed callback, ret = %x\n", ret);
165 int mm_sound_remove_device_information_changed_callback(unsigned int subs_id)
167 int ret = MM_ERROR_NONE;
169 ret = mm_sound_client_remove_device_info_changed_callback(subs_id);
171 debug_error("Could not remove device information changed callback, ret = %x\n", ret);
178 int mm_sound_get_current_device_list(mm_sound_device_flags_e flags, MMSoundDeviceList_t *device_list)
180 int ret = MM_ERROR_NONE;
183 return MM_ERROR_INVALID_ARGUMENT;
185 ret = _check_for_valid_mask(flags);
186 if (ret != MM_ERROR_NONE) {
187 debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
191 /* free previously allocated list */
192 if (g_device_list != NULL)
193 __free_device_list(g_device_list);
195 if (!(g_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
196 debug_error("[Client] Allocate device list failed");
197 return MM_ERROR_SOUND_INTERNAL;
200 g_device_list->is_new_device_list = true;
202 ret = mm_sound_client_get_current_connected_device_list(flags, g_device_list);
204 debug_error("Could not get current connected device list, ret = %x\n", ret);
205 g_free(g_device_list);
206 g_device_list = NULL;
208 *device_list = g_device_list;
215 int mm_sound_get_device_list(int flags, MMSoundDeviceList_t *device_list)
217 int ret = MM_ERROR_NONE;
218 mm_sound_device_list_t *_device_list;
221 return MM_ERROR_INVALID_ARGUMENT;
223 ret = _check_for_valid_mask(flags);
224 if (ret != MM_ERROR_NONE) {
225 debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
229 if (!(_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
230 debug_error("[Client] Allocate device list failed");
231 return MM_ERROR_SOUND_INTERNAL;
234 _device_list->is_new_device_list = true;
236 ret = mm_sound_client_get_current_connected_device_list(flags, _device_list);
238 debug_error("Could not get current connected device list, ret = %x\n", ret);
239 g_free(_device_list);
241 *device_list = _device_list;
248 int mm_sound_free_device_list(MMSoundDeviceList_t device_list)
250 return __free_device_list((mm_sound_device_list_t*) device_list);
254 int mm_sound_get_next_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
256 int ret = MM_ERROR_NONE;
257 mm_sound_device_list_t *device_list_t = NULL;
259 if (!device_list || !device) {
260 return MM_ERROR_INVALID_ARGUMENT;
262 device_list_t = (mm_sound_device_list_t*) device_list;
263 if (device_list_t->is_new_device_list) {
264 node = g_list_first(device_list_t->list);
266 node = g_list_next(device_list_t->list);
269 ret = MM_ERROR_SOUND_NO_DATA;
271 if (device_list_t->is_new_device_list) {
272 device_list_t->is_new_device_list = false;
274 device_list_t->list = node;
276 *device = (mm_sound_device_t*)node->data;
277 debug_log("next device[0x%x]\n", *device);
283 int mm_sound_get_prev_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
285 int ret = MM_ERROR_NONE;
286 mm_sound_device_list_t *device_list_t = NULL;
288 if (!device_list || !device) {
289 return MM_ERROR_INVALID_ARGUMENT;
291 device_list_t = (mm_sound_device_list_t*) device_list;
292 node = g_list_previous(device_list_t->list);
294 ret = MM_ERROR_SOUND_NO_DATA;
295 debug_error("Could not get previous device, ret = %x\n", ret);
297 device_list_t->list = node;
298 *device = (mm_sound_device_t*)node->data;
299 debug_log("previous device[0x%x]\n", *device);
305 int mm_sound_get_device_type(MMSoundDevice_t device_h, mm_sound_device_type_e *type)
307 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
308 if(!device || !type) {
309 debug_error("invalid argument\n");
310 return MM_ERROR_INVALID_ARGUMENT;
312 __convert_device_type_to_enum(device->type, type);
313 debug_log("device_handle:0x%x, type:%d\n", device, *type);
315 return MM_ERROR_NONE;
319 int mm_sound_get_device_io_direction(MMSoundDevice_t device_h, mm_sound_device_io_direction_e *io_direction)
321 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
323 debug_error("invalid handle\n");
324 return MM_ERROR_INVALID_ARGUMENT;
326 *io_direction = device->io_direction;
327 debug_log("device_handle:0x%x, io_direction:%d (1:IN,2:OUT,3:INOUT)\n", device, *io_direction);
329 return MM_ERROR_NONE;
333 int mm_sound_get_device_id(MMSoundDevice_t device_h, int *id)
335 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
337 debug_error("invalid handle\n");
338 return MM_ERROR_INVALID_ARGUMENT;
341 debug_log("device_handle:0x%x, id:%d\n", device, *id);
343 return MM_ERROR_NONE;
347 int mm_sound_get_device_state(MMSoundDevice_t device_h, mm_sound_device_state_e *state)
349 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
351 debug_error("invalid handle\n");
352 return MM_ERROR_INVALID_ARGUMENT;
354 *state = device->state;
355 debug_log("device_handle:0x%x, state:%d (0:INACTIVATED,1:ACTIVATED)\n", device, *state);
357 return MM_ERROR_NONE;
361 int mm_sound_get_device_name(MMSoundDevice_t device_h, char **name)
363 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
365 debug_error("invalid handle\n");
366 return MM_ERROR_INVALID_ARGUMENT;
368 *name = device->name;
369 debug_log("device_handle:0x%x, name:%s\n", device, *name);
371 return MM_ERROR_NONE;
375 int mm_sound_get_device_bt_avail_mode(MMSoundDevice_t device_h, int *avail_mode)
377 mm_sound_device_type_e type;
378 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
380 if (!device || !avail_mode) {
381 debug_error("invalid argument\n");
382 return MM_ERROR_INVALID_ARGUMENT;
385 __convert_device_type_to_enum(device->type, &type);
386 if (type != MM_SOUND_DEVICE_TYPE_BLUETOOTH) {
387 debug_error("invalid device type(%s)\n", device->type);
388 return MM_ERROR_INVALID_ARGUMENT;
391 *avail_mode = device->avail_mode;
392 debug_log("device_handle:0x%p, avail mode:%d\n", device, *avail_mode);
394 return MM_ERROR_NONE;