Let's start tizen audio 3.0
[platform/core/multimedia/libmm-sound.git] / common / mm_sound_utils.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@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 <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <glib.h>
30
31 #include <vconf.h>
32 #include <vconf-keys.h>
33 #include <mm_types.h>
34 #include <mm_error.h>
35 #include <mm_debug.h>
36 #include "../include/mm_sound_private.h"
37 #include "../include/mm_sound.h"
38 #include "../include/mm_sound_common.h"
39 #include "../include/mm_sound_utils.h"
40
41 static mm_sound_route g_valid_route[] = {
42                 MM_SOUND_ROUTE_OUT_SPEAKER, MM_SOUND_ROUTE_OUT_RECEIVER, MM_SOUND_ROUTE_OUT_WIRED_ACCESSORY, MM_SOUND_ROUTE_OUT_BLUETOOTH_SCO, MM_SOUND_ROUTE_OUT_BLUETOOTH_A2DP,
43                 MM_SOUND_ROUTE_OUT_DOCK, MM_SOUND_ROUTE_OUT_HDMI, MM_SOUND_ROUTE_OUT_MIRRORING, MM_SOUND_ROUTE_OUT_USB_AUDIO, MM_SOUND_ROUTE_OUT_MULTIMEDIA_DOCK,
44                 MM_SOUND_ROUTE_IN_MIC, MM_SOUND_ROUTE_IN_WIRED_ACCESSORY, MM_SOUND_ROUTE_IN_MIC_OUT_RECEIVER,
45                 MM_SOUND_ROUTE_IN_MIC_OUT_SPEAKER, MM_SOUND_ROUTE_IN_MIC_OUT_HEADPHONE,
46                 MM_SOUND_ROUTE_INOUT_HEADSET, MM_SOUND_ROUTE_INOUT_BLUETOOTH
47 };
48
49 #define MM_SOUND_DEFAULT_VOLUME_SYSTEM                  9
50 #define MM_SOUND_DEFAULT_VOLUME_NOTIFICATION    11
51 #define MM_SOUND_DEFAULT_VOLUME_ALARAM                  7
52 #define MM_SOUND_DEFAULT_VOLUME_RINGTONE                11
53 #define MM_SOUND_DEFAULT_VOLUME_MEDIA                   7
54 #define MM_SOUND_DEFAULT_VOLUME_CALL                    4
55 #define MM_SOUND_DEFAULT_VOLUME_VOIP                    4
56 #define MM_SOUND_DEFAULT_VOLUME_VOICE                   7
57 #define MM_SOUND_DEFAULT_VOLUME_ANDROID                 0
58
59 static char *g_volume_vconf[VOLUME_TYPE_MAX] = {
60         VCONF_KEY_VOLUME_TYPE_SYSTEM,           /* VOLUME_TYPE_SYSTEM */
61         VCONF_KEY_VOLUME_TYPE_NOTIFICATION,     /* VOLUME_TYPE_NOTIFICATION */
62         VCONF_KEY_VOLUME_TYPE_ALARM,            /* VOLUME_TYPE_ALARM */
63         VCONF_KEY_VOLUME_TYPE_RINGTONE,         /* VOLUME_TYPE_RINGTONE */
64         VCONF_KEY_VOLUME_TYPE_MEDIA,            /* VOLUME_TYPE_MEDIA */
65         VCONF_KEY_VOLUME_TYPE_CALL,                     /* VOLUME_TYPE_CALL */
66         VCONF_KEY_VOLUME_TYPE_VOIP,                     /* VOLUME_TYPE_VOIP */
67         VCONF_KEY_VOLUME_TYPE_VOICE,            /* VOLUME_TYPE_VOICE */
68         VCONF_KEY_VOLUME_TYPE_ANDROID           /* VOLUME_TYPE_FIXED */
69 };
70 static char *g_volume_str[VOLUME_TYPE_MAX] = {
71         "SYSTEM",
72         "NOTIFICATION",
73         "ALARM",
74         "RINGTONE",
75         "MEDIA",
76         "CALL",
77         "VOIP",
78         "VOICE",
79         "FIXED",
80 };
81
82 EXPORT_API
83 int mm_sound_util_get_valid_route_list(mm_sound_route **route_list)
84 {
85         *route_list = g_valid_route;
86
87         return (int)(sizeof(g_valid_route) / sizeof(mm_sound_route));
88 }
89
90 EXPORT_API
91 bool mm_sound_util_is_route_valid(mm_sound_route route)
92 {
93         mm_sound_route *route_list = 0;
94         int route_index = 0;
95         int route_list_count = 0;
96
97         route_list_count = mm_sound_util_get_valid_route_list(&route_list);
98         for (route_index = 0; route_index < route_list_count; route_index++) {
99                 if (route_list[route_index] == route)
100                         return 1;
101         }
102
103         return 0;
104 }
105
106 EXPORT_API
107 void mm_sound_util_get_devices_from_route(mm_sound_route route, mm_sound_device_in *device_in, mm_sound_device_out *device_out)
108 {
109         if (device_in && device_out) {
110                 *device_in = route & 0x00FF;
111                 *device_out = route & 0xFFF00;
112         }
113 }
114
115 EXPORT_API
116 int mm_sound_util_volume_add_callback(volume_type_t type, void *func, void* user_data)
117 {
118         if (vconf_notify_key_changed(g_volume_vconf[type], func, user_data)) {
119                 debug_error ("vconf_notify_key_changed failed..\n");
120                 return MM_ERROR_SOUND_INTERNAL;
121         }
122
123         return MM_ERROR_NONE;
124 }
125
126 EXPORT_API
127 int mm_sound_util_volume_remove_callback(volume_type_t type, void *func)
128 {
129         if (vconf_ignore_key_changed(g_volume_vconf[type], func)) {
130                 debug_error ("vconf_ignore_key_changed failed..\n");
131                 return MM_ERROR_SOUND_INTERNAL;
132         }
133
134         return MM_ERROR_NONE;
135 }
136
137 EXPORT_API
138 int mm_sound_util_volume_get_value_by_type(volume_type_t type, unsigned int *value)
139 {
140         int ret = MM_ERROR_NONE;
141         int vconf_value = 0;
142
143         /* Get volume value from VCONF */
144         if (vconf_get_int(g_volume_vconf[type], &vconf_value)) {
145                 debug_error ("vconf_get_int(%s) failed..\n", g_volume_vconf[type]);
146                 return MM_ERROR_SOUND_INTERNAL;
147         }
148
149         *value = vconf_value;
150         if (ret == MM_ERROR_NONE)
151                 debug_log("volume_get_value %s %d",  g_volume_str[type], *value);
152
153         return ret;
154 }
155
156 EXPORT_API
157 int mm_sound_util_volume_set_value_by_type(volume_type_t type, unsigned int value)
158 {
159         int ret = MM_ERROR_NONE;
160         int vconf_value = 0;
161
162         vconf_value = value;
163         debug_log("volume_set_value %s %d",  g_volume_str[type], value);
164
165         /* Set volume value to VCONF */
166         if ((ret = vconf_set_int(g_volume_vconf[type], vconf_value)) != 0) {
167                 debug_error ("vconf_set_int(%s) failed..ret[%d]\n", g_volume_vconf[type], ret);
168                 if (ret == -EPERM || ret == -EACCES)
169                         return MM_ERROR_SOUND_PERMISSION_DENIED;
170                 else
171                         return MM_ERROR_SOUND_INTERNAL;
172         }
173         return ret;
174 }
175
176 EXPORT_API
177 int mm_sound_util_get_earjack_type (int *type)
178 {
179         int earjack_status = 0;
180
181         if (type == NULL) {
182                 debug_error ("invalid parameter!!!");
183                 return MM_ERROR_INVALID_ARGUMENT;
184         }
185
186         /* Get actual vconf value */
187         vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status);
188         debug_msg ("[%s] get status=[%d]\n", VCONFKEY_SYSMAN_EARJACK, earjack_status);
189
190         *type = (earjack_status >= 0)? earjack_status : VCONFKEY_SYSMAN_EARJACK_REMOVED;
191
192         return MM_ERROR_NONE;
193 }
194
195 EXPORT_API
196 int mm_sound_util_get_dock_type (int *type)
197 {
198         int dock_status = 0;
199
200         if (type == NULL) {
201                 debug_error ("invalid parameter!!!");
202                 return MM_ERROR_INVALID_ARGUMENT;
203         }
204
205         /* Get actual vconf value */
206         vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &dock_status);
207         debug_msg ("[%s] get dock status=[%d]\n", VCONFKEY_SYSMAN_CRADLE_STATUS, dock_status);
208
209         *type = dock_status;
210
211         return MM_ERROR_NONE;
212 }
213
214 EXPORT_API
215 bool mm_sound_util_is_recording (void)
216 {
217         int capture_status = 0;
218         bool result = false;
219
220     /* FIXME */
221         return result;
222 }
223
224 EXPORT_API
225 bool mm_sound_util_is_mute_policy (void)
226 {
227         int setting_sound_status = true;
228
229         /* If sound is mute mode, force ringtone/notification path to headset */
230         vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &setting_sound_status);
231         debug_log ("[%s] setting_sound_status=%d\n", VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, setting_sound_status);
232
233         return !setting_sound_status;
234 }
235
236 EXPORT_API
237 bool mm_sound_util_is_process_alive(pid_t pid)
238 {
239         gchar *tmp = NULL;
240         int ret = -1;
241
242         if (pid > 999999 || pid < 2)
243                 return false;
244
245         if ((tmp = g_strdup_printf("/proc/%d", pid))) {
246                 ret = access(tmp, F_OK);
247                 g_free(tmp);
248         }
249
250         if (ret == -1) {
251                 if (errno == ENOENT) {
252                         debug_warning ("/proc/%d not exist", pid);
253                         return false;
254                 } else {
255                         debug_error ("/proc/%d access errno[%d]", pid, errno);
256
257                         /* FIXME: error occured but file exists */
258                         return true;
259                 }
260         }
261
262         return true;
263 }