Move out dbus unrelated logic code from client_dbus.c
[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 bool g_is_new_device_list = true;
36
37 static int _check_for_valid_mask (mm_sound_device_flags_e flags)
38 {
39         int ret = MM_ERROR_NONE;
40         bool at_least_cond = false;
41
42         if (flags > 0 && flags <= MM_SOUND_DEVICE_ALL_FLAG) {
43                 if (flags & MM_SOUND_DEVICE_IO_DIRECTION_IN_FLAG)
44                         at_least_cond = true;
45                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_OUT_FLAG))
46                         at_least_cond = true;
47                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_IO_DIRECTION_BOTH_FLAG))
48                         at_least_cond = true;
49                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_INTERNAL_FLAG))
50                         at_least_cond = true;
51                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG))
52                         at_least_cond = true;
53                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_DEACTIVATED_FLAG))
54                         at_least_cond = true;
55                 if (!at_least_cond && (flags & MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG))
56                         at_least_cond = true;
57         } else {
58                 ret = MM_ERROR_INVALID_ARGUMENT;
59         }
60         if (!at_least_cond) {
61                 ret = MM_ERROR_INVALID_ARGUMENT;
62         }
63         if (ret) {
64                 debug_error("flags[0x%x] is not valid\n", flags);
65         }
66         return ret;
67 }
68
69 static int __convert_device_type_to_enum (char *device_type, mm_sound_device_type_e *device_type_enum)
70 {
71         int ret = MM_ERROR_NONE;
72
73         if (!device_type || !device_type_enum) {
74                 return MM_ERROR_INVALID_ARGUMENT;
75         }
76
77         if (!strncmp(device_type, "builtin-speaker", VOLUME_TYPE_LEN)) {
78                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_SPEAKER;
79         } else if (!strncmp(device_type, "builtin-receiver", VOLUME_TYPE_LEN)) {
80                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_RECEIVER;
81         } else if (!strncmp(device_type, "builtin-mic", VOLUME_TYPE_LEN)) {
82                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BUILTIN_MIC;
83         } else if (!strncmp(device_type, "audio-jack", VOLUME_TYPE_LEN)) {
84                 *device_type_enum = MM_SOUND_DEVICE_TYPE_AUDIOJACK;
85         } else if (!strncmp(device_type, "bt", VOLUME_TYPE_LEN)) {
86                 *device_type_enum = MM_SOUND_DEVICE_TYPE_BLUETOOTH;
87         } else if (!strncmp(device_type, "hdmi", VOLUME_TYPE_LEN)) {
88                 *device_type_enum = MM_SOUND_DEVICE_TYPE_HDMI;
89         } else if (!strncmp(device_type, "forwarding", VOLUME_TYPE_LEN)) {
90                 *device_type_enum = MM_SOUND_DEVICE_TYPE_MIRRORING;
91         } else if (!strncmp(device_type, "usb-audio", VOLUME_TYPE_LEN)) {
92                 *device_type_enum = MM_SOUND_DEVICE_TYPE_USB_AUDIO;
93         } else {
94                 ret = MM_ERROR_INVALID_ARGUMENT;
95                 debug_error("not supported device_type(%s), err(0x%08x)", device_type, ret);
96         }
97
98         return ret;
99 }
100
101 EXPORT_API
102 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)
103 {
104         int ret = MM_ERROR_NONE;
105
106         if (func == NULL || subs_id == NULL) {
107                 debug_error("argument is not valid\n");
108                 return MM_ERROR_INVALID_ARGUMENT;
109         }
110         ret = _check_for_valid_mask(flags);
111         if (ret == MM_ERROR_NONE) {
112                 ret = mm_sound_client_add_device_connected_callback(flags, func, user_data, subs_id);
113                 if (ret < 0) {
114                         debug_error("Could not add device connected callback, ret = %x\n", ret);
115                 }
116         }
117
118         return ret;
119 }
120
121 EXPORT_API
122 int mm_sound_remove_device_connected_callback(unsigned int subs_id)
123 {
124         int ret = MM_ERROR_NONE;
125
126         ret = mm_sound_client_remove_device_connected_callback(subs_id);
127         if (ret < 0) {
128                 debug_error("Could not remove device connected callback, ret = %x\n", ret);
129         }
130
131         return ret;
132 }
133
134 EXPORT_API
135 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)
136 {
137         int ret = MM_ERROR_NONE;
138
139         if (func == NULL || subs_id == NULL) {
140                 debug_error("argument is not valid\n");
141                 return MM_ERROR_INVALID_ARGUMENT;
142         }
143         ret = _check_for_valid_mask(flags);
144         if (ret == MM_ERROR_NONE) {
145                 ret = mm_sound_client_add_device_info_changed_callback(flags, func, user_data, subs_id);
146                 if (ret < 0) {
147                         debug_error("Could not add device information changed callback, ret = %x\n", ret);
148                 }
149         }
150
151         return ret;
152 }
153
154 EXPORT_API
155 int mm_sound_remove_device_information_changed_callback(unsigned int subs_id)
156 {
157         int ret = MM_ERROR_NONE;
158
159         ret = mm_sound_client_remove_device_info_changed_callback(subs_id);
160         if (ret < 0) {
161                 debug_error("Could not remove device information changed callback, ret = %x\n", ret);
162         }
163
164         return ret;
165 }
166
167 EXPORT_API
168 int mm_sound_get_current_device_list(mm_sound_device_flags_e flags, MMSoundDeviceList_t *device_list)
169 {
170         int ret = MM_ERROR_NONE;
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                 ret = mm_sound_client_get_current_connected_device_list(flags, (mm_sound_device_list_t**)device_list);
178                 if (ret < 0) {
179                         debug_error("Could not get current connected device list, ret = %x\n", ret);
180                 } else {
181                         g_is_new_device_list = true;
182                 }
183         }
184
185         return ret;
186 }
187
188 EXPORT_API
189 int mm_sound_get_next_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
190 {
191         int ret = MM_ERROR_NONE;
192         mm_sound_device_list_t *device_list_t = NULL;
193         GList *node = NULL;
194         if (!device_list || !device) {
195                 return MM_ERROR_INVALID_ARGUMENT;
196         }
197         device_list_t = (mm_sound_device_list_t*) device_list;
198         if (g_is_new_device_list) {
199                 node = g_list_first(device_list_t->list);
200         } else {
201                 node = g_list_next(device_list_t->list);
202         }
203         if (!node) {
204                 ret = MM_ERROR_SOUND_NO_DATA;
205         } else {
206                 if (g_is_new_device_list) {
207                         g_is_new_device_list = false;
208                 } else {
209                         device_list_t->list = node;
210                 }
211                 *device = (mm_sound_device_t*)node->data;
212                 debug_log("next device[0x%x]\n", *device);
213         }
214         return ret;
215 }
216
217 EXPORT_API
218 int mm_sound_get_prev_device (MMSoundDeviceList_t device_list, MMSoundDevice_t *device)
219 {
220         int ret = MM_ERROR_NONE;
221         mm_sound_device_list_t *device_list_t = NULL;
222         GList *node = NULL;
223         if (!device_list || !device) {
224                 return MM_ERROR_INVALID_ARGUMENT;
225         }
226         device_list_t = (mm_sound_device_list_t*) device_list;
227         node = g_list_previous(device_list_t->list);
228         if (!node) {
229                 ret = MM_ERROR_SOUND_NO_DATA;
230                 debug_error("Could not get previous device, ret = %x\n", ret);
231         } else {
232                 device_list_t->list = node;
233                 *device = (mm_sound_device_t*)node->data;
234                 debug_log("previous device[0x%x]\n", *device);
235         }
236         return ret;
237 }
238
239 EXPORT_API
240 int mm_sound_get_device_type(MMSoundDevice_t device_h, mm_sound_device_type_e *type)
241 {
242         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
243         if(!device || !type) {
244                 debug_error("invalid argument\n");
245                 return MM_ERROR_INVALID_ARGUMENT;
246         }
247         __convert_device_type_to_enum(device->type, type);
248         debug_log("device_handle:0x%x, type:%d\n", device, *type);
249
250         return MM_ERROR_NONE;
251 }
252
253 EXPORT_API
254 int mm_sound_get_device_io_direction(MMSoundDevice_t device_h, mm_sound_device_io_direction_e *io_direction)
255 {
256         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
257         if(!device) {
258                 debug_error("invalid handle\n");
259                 return MM_ERROR_INVALID_ARGUMENT;
260         }
261         *io_direction = device->io_direction;
262         debug_log("device_handle:0x%x, io_direction:%d (1:IN,2:OUT,3:INOUT)\n", device, *io_direction);
263
264         return MM_ERROR_NONE;
265 }
266
267 EXPORT_API
268 int mm_sound_get_device_id(MMSoundDevice_t device_h, int *id)
269 {
270         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
271         if(!device) {
272                 debug_error("invalid handle\n");
273                 return MM_ERROR_INVALID_ARGUMENT;
274         }
275         *id = device->id;
276         debug_log("device_handle:0x%x, id:%d\n", device, *id);
277
278         return MM_ERROR_NONE;
279 }
280
281 EXPORT_API
282 int mm_sound_get_device_state(MMSoundDevice_t device_h, mm_sound_device_state_e *state)
283 {
284         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
285         if(!device) {
286                 debug_error("invalid handle\n");
287                 return MM_ERROR_INVALID_ARGUMENT;
288         }
289         *state = device->state;
290         debug_log("device_handle:0x%x, state:%d (0:INACTIVATED,1:ACTIVATED)\n", device, *state);
291
292         return MM_ERROR_NONE;
293 }
294
295 EXPORT_API
296 int mm_sound_get_device_name(MMSoundDevice_t device_h, char **name)
297 {
298         mm_sound_device_t *device = (mm_sound_device_t*)device_h;
299         if(!device) {
300                 debug_error("invalid handle\n");
301                 return MM_ERROR_INVALID_ARGUMENT;
302         }
303         *name = device->name;
304         debug_log("device_handle:0x%x, name:%s\n", device, *name);
305
306         return MM_ERROR_NONE;
307 }
308