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
34 static int _check_for_valid_mask (mm_sound_device_flags_e flags)
36 int ret = MM_ERROR_NONE;
37 bool at_least_cond = false;
39 if (flags > 0 && flags <= MM_SOUND_DEVICE_ALL_FLAG) {
40 if (flags & MM_SOUND_DEVICE_IO_DIRECTION_IN_FLAG)
42 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG))
44 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG))
46 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_INTERNAL_FLAG))
48 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG))
50 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_DEACTIVATED_FLAG))
52 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG))
55 ret = MM_ERROR_INVALID_ARGUMENT;
58 ret = MM_ERROR_INVALID_ARGUMENT;
61 debug_error("flags[0x%x] is not valid\n", flags);
66 static int __convert_device_type_to_enum (char *device_type, mm_sound_device_type_e *device_type_enum)
68 int ret = MM_ERROR_NONE;
70 if (!device_type || !device_type_enum) {
71 return MM_ERROR_INVALID_ARGUMENT;
74 if (!strncmp(device_type, "builtin-speaker", VOLUME_TYPE_LEN)) {
75 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
76 } else if (!strncmp(device_type, "builtin-receiver", VOLUME_TYPE_LEN)) {
77 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER;
78 } else if (!strncmp(device_type, "builtin-mic", VOLUME_TYPE_LEN)) {
79 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_MIC;
80 } else if (!strncmp(device_type, "audio-jack", VOLUME_TYPE_LEN)) {
81 *device_type_enum = MM_SOUND_DEVICE_TYPE_AUDIOJACK;
82 } else if (!strncmp(device_type, "bt", VOLUME_TYPE_LEN)) {
83 *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH;
84 } else if (!strncmp(device_type, "hdmi", VOLUME_TYPE_LEN)) {
85 *device_type_enum = MM_SOUND_DEVICE_TYPE_HDMI;
86 } else if (!strncmp(device_type, "forwarding", VOLUME_TYPE_LEN)) {
87 *device_type_enum = MM_SOUND_DEVICE_TYPE_MIRRORING;
88 } else if (!strncmp(device_type, "usb-audio", VOLUME_TYPE_LEN)) {
89 *device_type_enum = MM_SOUND_DEVICE_TYPE_USB_AUDIO;
91 ret = MM_ERROR_INVALID_ARGUMENT;
92 debug_error("not supported device_type(%s), err(0x%08x)", device_type, ret);
99 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)
101 int ret = MM_ERROR_NONE;
103 if (func == NULL || subs_id == NULL) {
104 debug_error("argument is not valid\n");
105 return MM_ERROR_INVALID_ARGUMENT;
107 ret = _check_for_valid_mask(flags);
108 if (ret == MM_ERROR_NONE) {
109 ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, subs_id);
111 debug_error("Could not add device connected callback, ret = %x\n", ret);
119 int mm_sound_remove_device_connected_callback(unsigned int subs_id)
121 int ret = MM_ERROR_NONE;
123 ret = mm_sound_client_remove_device_connected_callback(subs_id);
125 debug_error("Could not remove device connected callback, ret = %x\n", ret);
132 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)
134 int ret = MM_ERROR_NONE;
136 if (func == NULL || subs_id == NULL) {
137 debug_error("argument is not valid\n");
138 return MM_ERROR_INVALID_ARGUMENT;
140 ret = _check_for_valid_mask(flags);
141 if (ret == MM_ERROR_NONE) {
142 ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, subs_id);
144 debug_error("Could not add device information changed callback, ret = %x\n", ret);
152 int mm_sound_remove_device_information_changed_callback(unsigned int subs_id)
154 int ret = MM_ERROR_NONE;
156 ret = mm_sound_client_remove_device_info_changed_callback(subs_id);
158 debug_error("Could not remove device information changed callback, ret = %x\n", ret);
165 int mm_sound_get_current_device_list(mm_sound_device_flags_e flags, MMSoundDeviceList_t *device_list)
167 int ret = MM_ERROR_NONE;
168 mm_sound_device_list_t *_device_list;
171 return MM_ERROR_INVALID_ARGUMENT;
173 ret = _check_for_valid_mask(flags);
174 if (ret != MM_ERROR_NONE) {
175 debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
179 if (!(_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
180 debug_error("[Client] Allocate device list failed");
181 return MM_ERROR_SOUND_INTERNAL;
184 _device_list->is_new_device_list = true;
186 ret = mm_sound_client_get_current_connected_device_list(flags, _device_list);
188 debug_error("Could not get current connected device list, ret = %x\n", ret);
189 g_free(_device_list);
191 *device_list = _device_list;
198 int mm_sound_free_device_list(MMSoundDeviceList_t device_list)
200 mm_sound_device_list_t *device_list_t = NULL;
203 return MM_ERROR_INVALID_ARGUMENT;
205 device_list_t = (mm_sound_device_list_t*) device_list;
206 g_list_free_full(device_list_t->list, g_free);
207 g_free(device_list_t);
209 return MM_ERROR_NONE;
213 int mm_sound_get_next_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
215 int ret = MM_ERROR_NONE;
216 mm_sound_device_list_t *device_list_t = NULL;
218 if (!device_list || !device) {
219 return MM_ERROR_INVALID_ARGUMENT;
221 device_list_t = (mm_sound_device_list_t*) device_list;
222 if (device_list_t->is_new_device_list) {
223 node = g_list_first(device_list_t->list);
225 node = g_list_next(device_list_t->list);
228 ret = MM_ERROR_SOUND_NO_DATA;
230 if (device_list_t->is_new_device_list) {
231 device_list_t->is_new_device_list = false;
233 device_list_t->list = node;
235 *device = (mm_sound_device_t*)node->data;
236 debug_log("next device[0x%x]\n", *device);
242 int mm_sound_get_prev_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
244 int ret = MM_ERROR_NONE;
245 mm_sound_device_list_t *device_list_t = NULL;
247 if (!device_list || !device) {
248 return MM_ERROR_INVALID_ARGUMENT;
250 device_list_t = (mm_sound_device_list_t*) device_list;
251 node = g_list_previous(device_list_t->list);
253 ret = MM_ERROR_SOUND_NO_DATA;
254 debug_error("Could not get previous device, ret = %x\n", ret);
256 device_list_t->list = node;
257 *device = (mm_sound_device_t*)node->data;
258 debug_log("previous device[0x%x]\n", *device);
264 int mm_sound_get_device_type(MMSoundDevice_t device_h, mm_sound_device_type_e *type)
266 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
267 if(!device || !type) {
268 debug_error("invalid argument\n");
269 return MM_ERROR_INVALID_ARGUMENT;
271 __convert_device_type_to_enum(device->type, type);
272 debug_log("device_handle:0x%x, type:%d\n", device, *type);
274 return MM_ERROR_NONE;
278 int mm_sound_get_device_io_direction(MMSoundDevice_t device_h, mm_sound_device_io_direction_e *io_direction)
280 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
282 debug_error("invalid handle\n");
283 return MM_ERROR_INVALID_ARGUMENT;
285 *io_direction = device->io_direction;
286 debug_log("device_handle:0x%x, io_direction:%d (1:IN,2:OUT,3:INOUT)\n", device, *io_direction);
288 return MM_ERROR_NONE;
292 int mm_sound_get_device_id(MMSoundDevice_t device_h, int *id)
294 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
296 debug_error("invalid handle\n");
297 return MM_ERROR_INVALID_ARGUMENT;
300 debug_log("device_handle:0x%x, id:%d\n", device, *id);
302 return MM_ERROR_NONE;
306 int mm_sound_get_device_state(MMSoundDevice_t device_h, mm_sound_device_state_e *state)
308 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
310 debug_error("invalid handle\n");
311 return MM_ERROR_INVALID_ARGUMENT;
313 *state = device->state;
314 debug_log("device_handle:0x%x, state:%d (0:INACTIVATED,1:ACTIVATED)\n", device, *state);
316 return MM_ERROR_NONE;
320 int mm_sound_get_device_name(MMSoundDevice_t device_h, char **name)
322 mm_sound_device_t *device = (mm_sound_device_t*)device_h;
324 debug_error("invalid handle\n");
325 return MM_ERROR_INVALID_ARGUMENT;
327 *name = device->name;
328 debug_log("device_handle:0x%x, name:%s\n", device, *name);
330 return MM_ERROR_NONE;