Change IPC for keysound to DBUS
[platform/core/multimedia/libmm-sound.git] / mm_sound_keysound.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 <stdlib.h>
23 #include <memory.h>
24 #include <unistd.h>
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29 #include <vconf.h>
30
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <gio/gio.h>
34
35 #include <mm_types.h>
36 #include <mm_error.h>
37 #include <mm_message.h>
38 #include <mm_debug.h>
39 #include <mm_sound.h>
40 #include <mm_sound_private.h>
41
42 #include "include/mm_sound_common.h"
43
44 #define PA_BUS_NAME                              "org.pulseaudio.Server"
45 #define PA_SOUND_PLAYER_OBJECT_PATH              "/org/pulseaudio/SoundPlayer"
46 #define PA_SOUND_PLAYER_INTERFACE                "org.pulseaudio.SoundPlayer"
47 #define PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY  "SimplePlay"
48
49 #define KEYTONE_PATH "/tmp/keytone"             /* Keytone pipe path */
50 #define FILE_FULL_PATH 1024                             /* File path length */
51 #define ROLE_NAME_LEN 64                                /* Role name length */
52 #define VOLUME_GAIN_TYPE_LEN 64         /* Volume gain type length */
53
54 #define AUDIO_VOLUME_CONFIG_TYPE(vol) (vol & 0x00FF)
55 #define AUDIO_VOLUME_CONFIG_GAIN(vol) (vol & 0xFF00)
56
57 typedef struct ipc_data {
58     char filename[FILE_FULL_PATH];
59     char role[ROLE_NAME_LEN];
60     char volume_gain_type[VOLUME_GAIN_TYPE_LEN];
61 }ipc_t;
62
63 typedef enum {
64         IPC_TYPE_PIPE,
65         IPC_TYPE_DBUS,
66 }ipc_type_t;
67
68 static int _mm_sound_play_keysound(const char *filename, int volume_config, ipc_type_t ipc_type);
69
70 static const char* convert_volume_type_to_role(int volume_type)
71 {
72         debug_warning ("volume_type(%d)", volume_type);
73         switch(volume_type) {
74         case VOLUME_TYPE_MEDIA:
75                 return "media";
76         case VOLUME_TYPE_SYSTEM:
77                 return "system";
78         case VOLUME_TYPE_NOTIFICATION:
79                 return "notification";
80         case VOLUME_TYPE_ALARM:
81                 return "alarm";
82         case VOLUME_TYPE_VOICE:
83                 return "voice";
84         default:
85                 debug_warning ("not supported type(%d), we change it SYSTEM type forcibly" );
86                 return "system";
87         }
88 }
89
90 static const char* convert_volume_gain_type_to_string(int volume_gain_type)
91 {
92         debug_warning ("volume_gain_type(0x%x)", volume_gain_type);
93         switch(volume_gain_type) {
94         case VOLUME_GAIN_DEFAULT:
95                 return NULL;
96         case VOLUME_GAIN_DIALER:
97                 return "dialer";
98         case VOLUME_GAIN_TOUCH:
99                 return "touch";
100         case VOLUME_GAIN_AF:
101                 return "af";
102         case VOLUME_GAIN_SHUTTER1:
103                 return "shutter1";
104         case VOLUME_GAIN_SHUTTER2:
105                 return "shutter2";
106         case VOLUME_GAIN_CAMCORDING:
107                 return "camcording";
108         case VOLUME_GAIN_MIDI:
109                 return "midi";
110         case VOLUME_GAIN_BOOTING:
111                 return "booting";
112         case VOLUME_GAIN_VIDEO:
113                 return "video";
114         case VOLUME_GAIN_TTS:
115                 return "tts";
116         default:
117                 return NULL;
118         }
119 }
120
121 EXPORT_API
122 int mm_sound_play_keysound(const char *filename, int volume_config)
123 {
124         return _mm_sound_play_keysound(filename, volume_config, IPC_TYPE_DBUS);
125 }
126
127 static int _mm_sound_play_keysound(const char *filename, int volume_config, ipc_type_t ipc_type)
128 {
129         int ret = MM_ERROR_NONE;
130         const char *role = NULL;
131         const char *vol_gain_type = NULL;
132
133         if (!filename)
134                 return MM_ERROR_SOUND_INVALID_FILE;
135
136         /* convert volume type to role/volume gain */
137         role = convert_volume_type_to_role(AUDIO_VOLUME_CONFIG_TYPE(volume_config));
138         if (role) {
139                 vol_gain_type = convert_volume_gain_type_to_string(AUDIO_VOLUME_CONFIG_GAIN(volume_config));
140         }
141
142         if (ipc_type == IPC_TYPE_PIPE) {
143                 int res = 0;
144                 int fd = -1;
145                 int size = 0;
146                 ipc_t data = {{0,},{0,},{0,}};
147
148                 /* Check whether file exists */
149                 fd = open(filename, O_RDONLY);
150                 if (fd == -1) {
151                         debug_error("file open failed with [%s][%d]\n", strerror(errno), errno);
152                         switch (errno) {
153                         case ENOENT:
154                                 return MM_ERROR_SOUND_FILE_NOT_FOUND;
155                         default:
156                                 return MM_ERROR_SOUND_INTERNAL;
157                         }
158                 }
159                 close(fd);
160                 fd = -1;
161
162                 /* Open PIPE */
163                 fd = open(KEYTONE_PATH, O_WRONLY | O_NONBLOCK);
164                 if (fd == -1) {
165                         debug_error("Fail to open pipe\n");
166                         return MM_ERROR_SOUND_FILE_NOT_FOUND;
167                 }
168
169                 /* convert volume type to role/volume gain */
170                 if (role) {
171                         MMSOUND_STRNCPY(data.role, role, ROLE_NAME_LEN);
172                 }
173                 if (vol_gain_type) {
174                         MMSOUND_STRNCPY(data.volume_gain_type, vol_gain_type, VOLUME_GAIN_TYPE_LEN);
175                 }
176
177                 MMSOUND_STRNCPY(data.filename, filename, FILE_FULL_PATH);
178
179                 debug_msg("filepath=[%s], role=[%s], volume_gain_type=[%s]\n", data.filename, data.role, data.volume_gain_type);
180                 size = sizeof(ipc_t);
181
182                 /* Write to PIPE */
183                 res = write(fd, &data, size);
184                 if (res < 0) {
185                         debug_error("Fail to write data: [%s][%d]\n", strerror(errno), errno);
186                         close(fd);
187                         ret = MM_ERROR_SOUND_INTERNAL;
188                 }
189                 /* Close PIPE */
190                 close(fd);
191
192         } else if (ipc_type == IPC_TYPE_DBUS) {
193                 GVariant *result = NULL;
194                 GDBusConnection *conn = NULL;
195                 GError *err = NULL;
196                 int idx = 0;
197
198                 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
199                 if (!conn && err) {
200                         debug_error("g_bus_get_sync() error (%s)", err->message);
201                         ret = MM_ERROR_SOUND_INTERNAL;
202                 } else {
203                         result = g_dbus_connection_call_sync (conn,
204                                                                         PA_BUS_NAME,
205                                                                         PA_SOUND_PLAYER_OBJECT_PATH,
206                                                                         PA_SOUND_PLAYER_INTERFACE,
207                                                                         PA_SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY,
208                                                                         g_variant_new ("(sss)", filename, role, vol_gain_type),
209                                                                         NULL,
210                                                                         G_DBUS_CALL_FLAGS_NONE,
211                                                                         2000,
212                                                                         NULL,
213                                                                         &err);
214                         if (!result && err) {
215                                 debug_error("g_dbus_connection_call_sync() for SIMPLE_PLAY error (%s)", err->message);
216                                 ret = MM_ERROR_SOUND_INTERNAL;
217                         } else {
218                                 g_variant_get(result, "(i)", &idx);
219                                 if (idx == -1) {
220                                         debug_error("SIMPLE_PLAY failure, filename(%s)/role(%s)/gain(%s)/stream idx(%d)", filename, role, vol_gain_type, idx);
221                                         ret = MM_ERROR_SOUND_INTERNAL;
222                                 } else {
223                                         debug_msg("SIMPLE_PLAY success, filename(%s)/role(%s)/gain(%s)/stream idx(%d)", filename, role, vol_gain_type, idx);
224                                 }
225                                 g_variant_unref(result);
226                         }
227                         g_object_unref(conn);
228                 }
229                 if (err) {
230                         g_error_free(err);
231                 }
232         }
233
234         return ret;
235 }