4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 #include <semaphore.h>
28 #include <mm_source.h>
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"
39 #define DEFAULT_TIMEOUT_MSEC_IN_USEC (600*1000)
40 #define ENV_KEYTONE_TIMEOUT "KEYTONE_TIMEOUT"
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 */
52 #define SUPPORT_DBUS_KEYTONE
53 #ifdef SUPPORT_DBUS_KEYTONE
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"
63 #define DBUS_HW_KEYTONE "/usr/share/sounds/sound-server/Tizen_HW_Touch.ogg"
65 #endif /* SUPPORT_DBUS_KEYTONE */
69 pthread_mutex_t sw_lock;
70 pthread_cond_t sw_cond;
81 char filename[FILE_FULL_PATH];
87 mmsound_codec_info_t *info;
91 static int (*g_thread_pool_func)(void*, void (*)(void*)) = NULL;
93 static int stop_flag = 0;
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];
104 GDBusConnection *conn;
107 static const char* _convert_volume_type_to_role(int volume_type)
109 debug_warning ("volume_type(%d)", volume_type);
110 switch(volume_type) {
111 case VOLUME_TYPE_SYSTEM:
113 case VOLUME_TYPE_NOTIFICATION:
114 return "notification";
115 case VOLUME_TYPE_ALARM:
117 case VOLUME_TYPE_RINGTONE:
119 case VOLUME_TYPE_CALL:
121 case VOLUME_TYPE_VOIP:
123 case VOLUME_TYPE_VOICE:
130 static const char* _convert_volume_gain_type_to_string(int volume_gain_type)
132 debug_warning ("volume_gain_type(0x%x)", volume_gain_type);
133 switch(volume_gain_type) {
134 case VOLUME_GAIN_DEFAULT:
136 case VOLUME_GAIN_DIALER:
138 case VOLUME_GAIN_TOUCH:
142 case VOLUME_GAIN_SHUTTER1:
144 case VOLUME_GAIN_SHUTTER2:
146 case VOLUME_GAIN_CAMCORDING:
148 case VOLUME_GAIN_MIDI:
150 case VOLUME_GAIN_BOOTING:
152 case VOLUME_GAIN_VIDEO:
154 case VOLUME_GAIN_TTS:
161 static int _play_keytone(const char *filename, int volume_config)
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;
170 debug_msg("filepath=[%s], volume_config=[0x%x]\n", filename, volume_config);
173 return MM_ERROR_SOUND_INVALID_FILE;
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));
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));
183 MMSOUND_STRNCPY(data.volume_gain_type, vol_gain_type, VOLUME_GAIN_TYPE_LEN);
185 MMSOUND_STRNCPY(data.filename, filename, FILE_FULL_PATH);
188 if ((err = write(fd, &data, sizeof(ipc_t))) < 0) {
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;
197 debug_error("Fail to open pipe\n");
198 ret = MM_ERROR_SOUND_FILE_NOT_FOUND;
204 static bool _is_mute_sound ()
206 int setting_sound_status = true;
207 int setting_touch_sound = true;
209 /* 1. Check if recording is in progress */
210 if (mm_sound_util_is_recording()) {
211 debug_log ("During Recording....MUTE!!!");
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);
219 return !(setting_sound_status & setting_touch_sound);
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,
230 debug_msg ("sender : %s, object : %s, interface : %s, signal : %s",
231 sender_name, object_path, interface_name, signal_name);
233 if (_is_mute_sound ()) {
234 debug_log ("Skip playing keytone due to mute sound mode");
236 /* request to play to pulseaudio module-sound-player */
237 _play_keytone (DBUS_HW_KEYTONE, VOLUME_TYPE_SYSTEM | VOLUME_GAIN_TOUCH);
241 static int _init_dbus_keytone ()
247 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
249 debug_error ("g_bus_get_sync() error (%s) ", err->message);
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);
258 debug_error ("g_dbus_connection_signal_subscribe() error (%d)", sig_id);
266 g_dbus_connection_signal_unsubscribe(conn, sig_id);
267 g_object_unref(conn);
273 static void _deinit_dbus_keytone ()
276 g_dbus_connection_signal_unsubscribe(conn, sig_id);
277 g_object_unref(conn);
280 #endif /* SUPPORT_DBUS_KEYTONE */
282 static int MMSoundPlugRunKeytoneControlRun(void)
285 /* While loop is always on */
286 stop_flag = MMSOUND_TRUE;
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 */
300 return MM_ERROR_NONE;
303 static int MMSoundPlugRunKeytoneControlStop(void)
305 stop_flag = MMSOUND_FALSE; /* No impl. Don`t stop */
307 #ifdef SUPPORT_DBUS_KEYTONE
308 _deinit_dbus_keytone();
309 #endif /* SUPPORT_DBUS_KEYTONE */
311 return MM_ERROR_NONE;
314 static int MMSoundPlugRunKeytoneSetThreadPool(int (*func)(void*, void (*)(void*)))
316 debug_enter("(func : %p)\n", func);
317 g_thread_pool_func = func;
319 return MM_ERROR_NONE;
323 int MMSoundPlugRunGetInterface(mmsound_run_interface_t *intf)
326 intf->run = MMSoundPlugRunKeytoneControlRun;
327 intf->stop = MMSoundPlugRunKeytoneControlStop;
328 intf->SetThreadPool = MMSoundPlugRunKeytoneSetThreadPool;
331 return MM_ERROR_NONE;
335 int MMSoundGetPluginType(void)
339 return MM_SOUND_PLUGIN_TYPE_RUN;