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