Remove unused include statement
[platform/core/multimedia/libmm-sound.git] / server / plugin / keytone / mm_sound_plugin_run_key_tone.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 <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <semaphore.h>
26 #include <mm_error.h>
27 #include <mm_debug.h>
28 #include <mm_source.h>
29 #include <mm_sound.h>
30
31 #include <fcntl.h>
32 #include <errno.h>
33
34 #include "../../include/mm_sound_plugin_run.h"
35 #include "../../include/mm_sound_plugin_codec.h"
36 #include "../../../include/mm_sound_utils.h"
37 #include "../../../include/mm_sound_common.h"
38
39 #define DEFAULT_TIMEOUT_MSEC_IN_USEC (600*1000)
40 #define ENV_KEYTONE_TIMEOUT "KEYTONE_TIMEOUT"
41
42 #define MAX_BUFFER_SIZE 1920
43 #define KEYTONE_PATH "/tmp/keytone"             /* Keytone pipe path, this is the pipe for pulseaudio module-sound-player */
44 #define KEYTONE_GROUP   6526                    /* Keytone group : assigned by security */
45 #define FILE_FULL_PATH 1024                             /* File path lenth */
46 #define ROLE_NAME_LEN 64                                /* Role name length */
47 #define VOLUME_GAIN_TYPE_LEN 64         /* Volume gain type length */
48 #define AUDIO_CHANNEL 1
49 #define AUDIO_SAMPLERATE 44100
50 #define DURATION_CRITERIA 11000          /* write once or not       */
51
52 #define SUPPORT_DBUS_KEYTONE
53 #ifdef SUPPORT_DBUS_KEYTONE
54 #include <gio/gio.h>
55
56 #include <vconf.h>
57
58 #define BUS_NAME       "org.tizen.system.deviced"
59 #define OBJECT_PATH    "/Org/Tizen/System/DeviceD/Key"
60 #define INTERFACE_NAME "org.tizen.system.deviced.Key"
61 #define SIGNAL_NAME    "ChangeHardkey"
62
63 #define DBUS_HW_KEYTONE "/usr/share/sounds/sound-server/Tizen_HW_Touch.ogg"
64
65 #endif /* SUPPORT_DBUS_KEYTONE */
66
67 typedef struct
68 {
69         pthread_mutex_t sw_lock;
70         pthread_cond_t sw_cond;
71         int handle;
72
73         int period;
74         int volume_config;
75         int state;
76         void *src;
77 } keytone_info_t;
78
79 typedef struct
80 {
81         char filename[FILE_FULL_PATH];
82         int volume_config;
83 } ipc_type;
84
85 typedef struct
86 {
87         mmsound_codec_info_t *info;
88         MMSourceType *source;
89 } buf_param_t;
90
91 static int (*g_thread_pool_func)(void*, void (*)(void*)) = NULL;
92
93 static int stop_flag = 0;
94
95 #ifdef SUPPORT_DBUS_KEYTONE
96 #define AUDIO_VOLUME_CONFIG_TYPE(vol) (vol & 0x00FF)
97 #define AUDIO_VOLUME_CONFIG_GAIN(vol) (vol & 0xFF00)
98 typedef struct ipc_data {
99         char filename[FILE_FULL_PATH];
100         char role[ROLE_NAME_LEN];
101         char volume_gain_type[VOLUME_GAIN_TYPE_LEN];
102 }ipc_t;
103
104 GDBusConnection *conn;
105 guint sig_id;
106
107 static const char* _convert_volume_type_to_role(int volume_type)
108 {
109         debug_warning ("volume_type(%d)", volume_type);
110         switch(volume_type) {
111         case VOLUME_TYPE_SYSTEM:
112                 return "system";
113         case VOLUME_TYPE_NOTIFICATION:
114                 return "notification";
115         case VOLUME_TYPE_ALARM:
116                 return "alarm";
117         case VOLUME_TYPE_RINGTONE:
118                 return "ringtone";
119         case VOLUME_TYPE_CALL:
120                 return "call";
121         case VOLUME_TYPE_VOIP:
122                 return "voip";
123         case VOLUME_TYPE_VOICE:
124                 return "voice";
125         default:
126                 return NULL;
127         }
128 }
129
130 static const char* _convert_volume_gain_type_to_string(int volume_gain_type)
131 {
132         debug_warning ("volume_gain_type(0x%x)", volume_gain_type);
133         switch(volume_gain_type) {
134         case VOLUME_GAIN_DEFAULT:
135                 return NULL;
136         case VOLUME_GAIN_DIALER:
137                 return "dialer";
138         case VOLUME_GAIN_TOUCH:
139                 return "touch";
140         case VOLUME_GAIN_AF:
141                 return "af";
142         case VOLUME_GAIN_SHUTTER1:
143                 return "shutter1";
144         case VOLUME_GAIN_SHUTTER2:
145                 return "shutter2";
146         case VOLUME_GAIN_CAMCORDING:
147                 return "camcording";
148         case VOLUME_GAIN_MIDI:
149                 return "midi";
150         case VOLUME_GAIN_BOOTING:
151                 return "booting";
152         case VOLUME_GAIN_VIDEO:
153                 return "video";
154         case VOLUME_GAIN_TTS:
155                 return "tts";
156         default:
157                 return NULL;
158         }
159 }
160
161 static int _play_keytone(const char *filename, int volume_config)
162 {
163         int err = -1;
164         int fd = -1;
165         ipc_t data = {{0,},{0,},{0,}};
166         int ret = MM_ERROR_NONE;
167         const char *role = NULL;
168         const char *vol_gain_type = NULL;
169
170         debug_msg("filepath=[%s], volume_config=[0x%x]\n", filename, volume_config);
171
172         if (!filename)
173                 return MM_ERROR_SOUND_INVALID_FILE;
174
175         /* Open PIPE */
176         if ((fd = open(KEYTONE_PATH, O_WRONLY | O_NONBLOCK)) != -1) {
177                 /* convert volume type to role */
178                 role = _convert_volume_type_to_role(AUDIO_VOLUME_CONFIG_TYPE(volume_config));
179                 if (role) {
180                         MMSOUND_STRNCPY(data.role, role, ROLE_NAME_LEN);
181                         vol_gain_type = _convert_volume_gain_type_to_string(AUDIO_VOLUME_CONFIG_GAIN(volume_config));
182                         if (vol_gain_type)
183                                 MMSOUND_STRNCPY(data.volume_gain_type, vol_gain_type, VOLUME_GAIN_TYPE_LEN);
184                 }
185                 MMSOUND_STRNCPY(data.filename, filename, FILE_FULL_PATH);
186
187                 /* Write to PIPE */
188                 if ((err = write(fd, &data, sizeof(ipc_t))) < 0) {
189                         char str_error[256];
190                         strerror_r(errno, str_error, sizeof(str_error));
191                         debug_error("Fail to write data: %s\n", str_error);
192                         ret = MM_ERROR_SOUND_INTERNAL;
193                 }
194                 /* Close PIPE */
195                 close(fd);
196         } else {
197                 debug_error("Fail to open pipe\n");
198                 ret = MM_ERROR_SOUND_FILE_NOT_FOUND;
199         }
200
201         return ret;
202 }
203
204 static bool _is_mute_sound ()
205 {
206         int setting_sound_status = true;
207         int setting_touch_sound = true;
208
209         /* 1. Check if recording is in progress */
210         if (mm_sound_util_is_recording()) {
211                 debug_log ("During Recording....MUTE!!!");
212                 return true;
213         }
214
215         /* 2. Check both SoundStatus & TouchSound vconf key for mute case */
216         vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &setting_sound_status);
217         vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &setting_touch_sound);
218
219         return !(setting_sound_status & setting_touch_sound);
220 }
221
222 static void _on_changed_receive(GDBusConnection *conn,
223                                                            const gchar *sender_name,
224                                                            const gchar *object_path,
225                                                            const gchar *interface_name,
226                                                            const gchar *signal_name,
227                                                            GVariant *parameters,
228                                                            gpointer user_data)
229 {
230         debug_msg ("sender : %s, object : %s, interface : %s, signal : %s",
231                         sender_name, object_path, interface_name, signal_name);
232
233         if (_is_mute_sound ()) {
234                 debug_log ("Skip playing keytone due to mute sound mode");
235         } else {
236                 /* request to play to pulseaudio module-sound-player */
237                 _play_keytone (DBUS_HW_KEYTONE, VOLUME_TYPE_SYSTEM | VOLUME_GAIN_TOUCH);
238         }
239 }
240
241 static int _init_dbus_keytone ()
242 {
243         GError *err = NULL;
244
245         debug_fenter ();
246
247         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
248         if (!conn && err) {
249                 debug_error ("g_bus_get_sync() error (%s) ", err->message);
250                 g_error_free (err);
251                 goto error;
252         }
253
254         sig_id = g_dbus_connection_signal_subscribe(conn,
255                         NULL, INTERFACE_NAME, SIGNAL_NAME, OBJECT_PATH, NULL, 0,
256                         _on_changed_receive, NULL, NULL);
257         if (sig_id == 0) {
258                 debug_error ("g_dbus_connection_signal_subscribe() error (%d)", sig_id);
259                 goto sig_error;
260         }
261
262         debug_fleave ();
263         return 0;
264
265 sig_error:
266         g_dbus_connection_signal_unsubscribe(conn, sig_id);
267         g_object_unref(conn);
268
269 error:
270         return -1;
271 }
272
273 static void _deinit_dbus_keytone ()
274 {
275         debug_fenter ();
276         g_dbus_connection_signal_unsubscribe(conn, sig_id);
277         g_object_unref(conn);
278         debug_fleave ();
279 }
280 #endif /* SUPPORT_DBUS_KEYTONE */
281
282 static int MMSoundPlugRunKeytoneControlRun(void)
283 {
284         debug_enter("\n");
285         /* While loop is always on */
286         stop_flag = MMSOUND_TRUE;
287
288 #ifdef SUPPORT_DBUS_KEYTONE
289         /* We receive the signal for HW back key here temporarily */
290         /* It'll be moved to some other place soon */
291         _init_dbus_keytone();
292 #endif /* SUPPORT_DBUS_KEYTONE */
293
294         while (stop_flag) {
295                 usleep(100000);
296         }
297
298         debug_leave("\n");
299
300         return MM_ERROR_NONE;
301 }
302
303 static int MMSoundPlugRunKeytoneControlStop(void)
304 {
305         stop_flag = MMSOUND_FALSE; /* No impl. Don`t stop */
306
307 #ifdef SUPPORT_DBUS_KEYTONE
308         _deinit_dbus_keytone();
309 #endif /* SUPPORT_DBUS_KEYTONE */
310
311         return MM_ERROR_NONE;
312 }
313
314 static int MMSoundPlugRunKeytoneSetThreadPool(int (*func)(void*, void (*)(void*)))
315 {
316         debug_enter("(func : %p)\n", func);
317         g_thread_pool_func = func;
318         debug_leave("\n");
319         return MM_ERROR_NONE;
320 }
321
322 EXPORT_API
323 int MMSoundPlugRunGetInterface(mmsound_run_interface_t *intf)
324 {
325         debug_enter("\n");
326         intf->run = MMSoundPlugRunKeytoneControlRun;
327         intf->stop = MMSoundPlugRunKeytoneControlStop;
328         intf->SetThreadPool = MMSoundPlugRunKeytoneSetThreadPool;
329         debug_leave("\n");
330
331         return MM_ERROR_NONE;
332 }
333
334 EXPORT_API
335 int MMSoundGetPluginType(void)
336 {
337         debug_enter("\n");
338         debug_leave("\n");
339         return MM_SOUND_PLUGIN_TYPE_RUN;
340 }