Fix SVACE defects / remove unused a2dp functions
[platform/core/multimedia/libmm-sound.git] / mm_sound_device.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Sangchul Lee <sc11.lee@samsung.com>
7  *
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
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <vconf.h>
26
27 #include <mm_debug.h>
28
29 #include "include/mm_sound.h"
30 #include "include/mm_sound_device.h"
31 #include "include/mm_sound_client.h"
32
33 #define VOLUME_TYPE_LEN 64
34
35
36 static int _check_for_valid_mask (mm_sound_device_flags_e flags)
37 {
38         int ret = MM_ERROR_NONE;
39         bool at_least_cond = false;
40
41         if (flags > 0 && flags <= MM_SOUND_DEVICE_ALL_FLAG) {
42                 if (flags & MM_SOUND_DEVICE_IO_DIRECTION_IN_FLAG)
43                         at_least_cond = true;
44                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG))
45                         at_least_cond = true;
46                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG))
47                         at_least_cond = true;
48                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_INTERNAL_FLAG))
49                         at_least_cond = true;
50                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG))
51                         at_least_cond = true;
52                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_DEACTIVATED_FLAG))
53                         at_least_cond = true;
54                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG))
55                         at_least_cond = true;
56         } else {
57                 ret = MM_ERROR_INVALID_ARGUMENT;
58         }
59         if (!at_least_cond) {
60                 ret = MM_ERROR_INVALID_ARGUMENT;
61         }
62         if (ret) {
63                 debug_error("flags[0x%x] is not valid\n", flags);
64         }
65         return ret;
66 }
67
68 static int __convert_device_type_to_enum (char *device_type, mm_sound_device_type_e *device_type_enum)
69 {
70         int ret = MM_ERROR_NONE;
71
72         if (!device_type || !device_type_enum) {
73                 return MM_ERROR_INVALID_ARGUMENT;
74         }
75
76         if (!strncmp(device_type, "builtin-speaker", VOLUME_TYPE_LEN)) {
77                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
78         } else if (!strncmp(device_type, "builtin-receiver", VOLUME_TYPE_LEN)) {
79                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER;
80         } else if (!strncmp(device_type, "builtin-mic", VOLUME_TYPE_LEN)) {
81                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_MIC;
82         } else if (!strncmp(device_type, "audio-jack", VOLUME_TYPE_LEN)) {
83                 *device_type_enum = MM_SOUND_DEVICE_TYPE_AUDIOJACK;
84         } else if (!strncmp(device_type, "bt", VOLUME_TYPE_LEN)) {
85                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH;
86         } else if (!strncmp(device_type, "hdmi", VOLUME_TYPE_LEN)) {
87                 *device_type_enum = MM_SOUND_DEVICE_TYPE_HDMI;
88         } else if (!strncmp(device_type, "forwarding", VOLUME_TYPE_LEN)) {
89                 *device_type_enum = MM_SOUND_DEVICE_TYPE_MIRRORING;
90         } else if (!strncmp(device_type, "usb-audio", VOLUME_TYPE_LEN)) {
91                 *device_type_enum = MM_SOUND_DEVICE_TYPE_USB_AUDIO;
92         } else {
93                 ret = MM_ERROR_INVALID_ARGUMENT;
94                 debug_error("not supported device_type(%s), err(0x%08x)", device_type, ret);
95         }
96
97         return ret;
98 }
99
100 EXPORT_API
101 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)
102 {
103         int ret = MM_ERROR_NONE;
104
105         if (func == NULL || subs_id == NULL) {
106                 debug_error("argument is not valid\n");
107                 return MM_ERROR_INVALID_ARGUMENT;
108         }
109         ret = _check_for_valid_mask(flags);
110         if (ret == MM_ERROR_NONE) {
111                 ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, subs_id);
112                 if (ret < 0) {
113                         debug_error("Could not add device connected callback, ret = %x\n", ret);
114                 }
115         }
116
117         return ret;
118 }
119
120 EXPORT_API
121 int mm_sound_remove_device_connected_callback(unsigned int subs_id)
122 {
123         int ret = MM_ERROR_NONE;
124
125         ret = mm_sound_client_remove_device_connected_callback(subs_id);
126         if (ret < 0) {
127                 debug_error("Could not remove device connected callback, ret = %x\n", ret);
128         }
129
130         return ret;
131 }
132
133 EXPORT_API
134 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)
135 {
136         int ret = MM_ERROR_NONE;
137
138         if (func == NULL || subs_id == NULL) {
139                 debug_error("argument is not valid\n");
140                 return MM_ERROR_INVALID_ARGUMENT;
141         }
142         ret = _check_for_valid_mask(flags);
143         if (ret == MM_ERROR_NONE) {
144                 ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, subs_id);
145                 if (ret < 0) {
146                         debug_error("Could not add device information changed callback, ret = %x\n", ret);
147                 }
148         }
149
150         return ret;
151 }
152
153 EXPORT_API
154 int mm_sound_remove_device_information_changed_callback(unsigned int subs_id)
155 {
156         int ret = MM_ERROR_NONE;
157
158         ret = mm_sound_client_remove_device_info_changed_callback(subs_id);
159         if (ret < 0) {
160                 debug_error("Could not remove device information changed callback, ret = %x\n", ret);
161         }
162
163         return ret;
164 }
165
166 EXPORT_API
167 int mm_sound_get_current_device_list(mm_sound_device_flags_e flags, MMSoundDeviceList_t *device_list)
168 {
169         int ret = MM_ERROR_NONE;
170         mm_sound_device_list_t *_device_list;
171
172         if (!device_list) {
173                 return MM_ERROR_INVALID_ARGUMENT;
174         }
175         ret = _check_for_valid_mask(flags);
176         if (ret != MM_ERROR_NONE) {
177                 debug_error("mask[0x%x] is invalid, ret=0x%x", flags, ret);
178                 return ret;
179         }
180
181         if (!(_device_list = g_malloc0(sizeof(mm_sound_device_list_t)))) {
182                 debug_error("[Client] Allocate device list failed");
183                 return MM_ERROR_SOUND_INTERNAL;
184         }
185
186         _device_list->is_new_device_list = true;
187
188         ret = mm_sound_client_get_current_connected_device_list(flags, _device_list);
189         if (ret < 0) {
190                 debug_error("Could not get current connected device list, ret = %x\n", ret);
191                 g_free(_device_list);
192         } else {
193                 *device_list = _device_list;
194         }
195
196         return ret;
197 }
198
199 EXPORT_API
200 int mm_sound_free_device_list(MMSoundDeviceList_t device_list)
201 {
202         mm_sound_device_list_t *device_list_t = NULL;
203
204         if (!device_list) {
205                 return MM_ERROR_INVALID_ARGUMENT;
206         }
207         device_list_t = (mm_sound_device_list_t*) device_list;
208         g_list_free_full(device_list_t->list, g_free);
209         g_free(device_list_t);
210
211         return MM_ERROR_NONE;
212 }
213
214 EXPORT_API
215 int mm_sound_get_next_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
216 {
217         int ret = MM_ERROR_NONE;
218         mm_sound_device_list_t *device_list_t = NULL;
219         GList *node = NULL;
220         if (!device_list || !device) {
221                 return MM_ERROR_INVALID_ARGUMENT;
222         }
223         device_list_t = (mm_sound_device_list_t*) device_list;
224         if (device_list_t->is_new_device_list) {
225                 node = g_list_first(device_list_t->list);
226         } else {
227                 node = g_list_next(device_list_t->list);
228         }
229         if (!node) {
230                 ret = MM_ERROR_SOUND_NO_DATA;
231         } else {
232                 if (device_list_t->is_new_device_list) {
233                         device_list_t->is_new_device_list = false;
234                 } else {
235                         device_list_t->list = node;
236                 }
237                 *device = (mm_sound_device_t*)node->data;
238                 debug_log("next device[0x%x]\n", *device);
239         }
240         return ret;
241 }
242
243 EXPORT_API
244 int mm_sound_get_prev_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
245 {
246         int ret = MM_ERROR_NONE;
247         mm_sound_device_list_t *device_list_t = NULL;
248         GList *node = NULL;
249         if (!device_list || !device) {
250                 return MM_ERROR_INVALID_ARGUMENT;
251         }
252         device_list_t = (mm_sound_device_list_t*) device_list;
253         node = g_list_previous(device_list_t->list);
254         if (!node) {
255                 ret = MM_ERROR_SOUND_NO_DATA;
256                 debug_error("Could not get previous device, ret = %x\n", ret);
257         } else {
258                 device_list_t->list = node;
259                 *device = (mm_sound_device_t*)node->data;
260                 debug_log("previous device[0x%x]\n", *device);
261         }
262         return ret;
263 }
264
265 EXPORT_API
266 int mm_sound_get_device_type(MMSoundDevice_t device_h, mm_sound_device_type_e *type)
267 {
268         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
269         if(!device || !type) {
270                 debug_error("invalid argument\n");
271                 return MM_ERROR_INVALID_ARGUMENT;
272         }
273         __convert_device_type_to_enum(device->type, type);
274         debug_log("device_handle:0x%x, type:%d\n", device, *type);
275
276         return MM_ERROR_NONE;
277 }
278
279 EXPORT_API
280 int mm_sound_get_device_io_direction(MMSoundDevice_t device_h, mm_sound_device_io_direction_e *io_direction)
281 {
282         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
283         if(!device) {
284                 debug_error("invalid handle\n");
285                 return MM_ERROR_INVALID_ARGUMENT;
286         }
287         *io_direction = device->io_direction;
288         debug_log("device_handle:0x%x, io_direction:%d (1:IN,2:OUT,3:INOUT)\n", device, *io_direction);
289
290         return MM_ERROR_NONE;
291 }
292
293 EXPORT_API
294 int mm_sound_get_device_id(MMSoundDevice_t device_h, int *id)
295 {
296         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
297         if(!device) {
298                 debug_error("invalid handle\n");
299                 return MM_ERROR_INVALID_ARGUMENT;
300         }
301         *id = device->id;
302         debug_log("device_handle:0x%x, id:%d\n", device, *id);
303
304         return MM_ERROR_NONE;
305 }
306
307 EXPORT_API
308 int mm_sound_get_device_state(MMSoundDevice_t device_h, mm_sound_device_state_e *state)
309 {
310         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
311         if(!device) {
312                 debug_error("invalid handle\n");
313                 return MM_ERROR_INVALID_ARGUMENT;
314         }
315         *state = device->state;
316         debug_log("device_handle:0x%x, state:%d (0:INACTIVATED,1:ACTIVATED)\n", device, *state);
317
318         return MM_ERROR_NONE;
319 }
320
321 EXPORT_API
322 int mm_sound_get_device_name(MMSoundDevice_t device_h, char **name)
323 {
324         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
325         if(!device) {
326                 debug_error("invalid handle\n");
327                 return MM_ERROR_INVALID_ARGUMENT;
328         }
329         *name = device->name;
330         debug_log("device_handle:0x%x, name:%s\n", device, *name);
331
332         return MM_ERROR_NONE;
333 }
334