Modify flora license version.
[platform/core/messaging/msg-service.git] / msg_helper / MsgSoundPlayer.cpp
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://floralicense.org/license/
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <pthread.h>
18
19 #include "MsgDebug.h"
20 #include "MsgCppTypes.h"
21 #include "MsgSettingTypes.h"
22 #include "MsgGconfWrapper.h"
23 #include "MsgUtilFile.h"
24 #include "MsgHelper.h"
25
26 #include <mm_error.h>
27 #include <mm_player.h>
28 #include <mm_session_private.h>
29 #include <mm_sound.h>
30 #include <feedback.h>
31
32 extern void worker_done();
33
34 /*==================================================================================================
35                                      VARIABLES
36 ==================================================================================================*/
37 static MMHandleType hPlayerHandle = 0;
38 static bool bPlaying = false;
39 static bool bVibrating = false;
40
41 pthread_mutex_t muMmPlay = PTHREAD_MUTEX_INITIALIZER;
42 pthread_cond_t cvMmPlay = PTHREAD_COND_INITIALIZER;
43
44 /*==================================================================================================
45                                      FUNCTION IMPLEMENTATION
46 ==================================================================================================*/
47
48 static gboolean MsgStopAndExit(void* data)
49 {
50         MsgSoundPlayStop();
51         if(!bPlaying && !bVibrating)
52                 worker_done();
53
54         return FALSE;
55 }
56
57 static gboolean MsgUninitAndExit(void* data)
58 {
59         MsgSoundPlayUninit();
60         if(!bPlaying && !bVibrating)
61                 worker_done();
62
63         return FALSE;
64 }
65
66 static gboolean MsgSoundMelodyTimeout(gpointer data)
67 {
68         MSG_BEGIN();
69
70         MsgSoundPlayStop();
71         if(!bPlaying && !bVibrating)
72                 worker_done();
73
74         MSG_END();
75
76         return FALSE;
77 }
78
79 static int MsgSoundPlayCallback(int message, void *param, void *user_param)
80 {
81         switch (message)
82         {
83                 case MM_MESSAGE_ERROR:
84                         MSG_DEBUG("ERROR is happened.");
85                         g_idle_add (MsgUninitAndExit, NULL);
86                         break;
87                 case MM_MESSAGE_BEGIN_OF_STREAM:
88                         MSG_DEBUG("Play is started.");
89                         break;
90                 case MM_MESSAGE_END_OF_STREAM:
91                 case MM_MESSAGE_STATE_INTERRUPTED:
92                         MSG_DEBUG("EOS or Interrupted.");
93                         g_idle_add (MsgStopAndExit, NULL);
94                         break;
95                 default:
96                         MSG_DEBUG("message = %d", message);
97                         break;
98         }
99
100         return 1;
101 }
102
103
104 void* MsgPlayThread(void *data)
105 {
106         MSG_BEGIN();
107
108         bool bSoundOn = false;
109         bool bVibrationOn = false;
110         int callStatus = 0;
111         /* 0 - off, 1 - sound, 2 - vibration */
112         int alertOnCall = 0;
113
114         bool isEmergency = false;
115
116         if (data)
117                 isEmergency = (bool)data;
118
119         char *msg_tone_file_path = NULL;
120         AutoPtr<char> buf(&msg_tone_file_path);
121
122         msg_tone_file_path = new char[MAX_SOUND_FILE_LEN];
123
124         if (isEmergency) {
125         } else {
126                 char *tmpFileFath = NULL;
127
128                 tmpFileFath = MsgSettingGetString(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
129
130                 if (tmpFileFath == NULL || MsgGetFileSize(tmpFileFath) < 1) {
131                         strncpy(msg_tone_file_path, DEFAULT_FILE, MAX_SOUND_FILE_LEN-1);
132                 } else {
133                         strncpy(msg_tone_file_path, tmpFileFath, MAX_SOUND_FILE_LEN-1);
134                         free(tmpFileFath);
135                         tmpFileFath = NULL;
136                 }
137         }
138
139         MSG_DEBUG("Emergency=[%d], Sound File [%s]", isEmergency, msg_tone_file_path);
140
141         MsgSettingGetBool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &bSoundOn);
142         MsgSettingGetBool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &bVibrationOn);
143
144         int err = MM_ERROR_NONE;
145
146         if (isEmergency)
147                 err = mm_session_init(MM_SESSION_TYPE_EMERGENCY);
148         else
149                 err = mm_session_init(MM_SESSION_TYPE_NOTIFY);
150
151         if(err != MM_ERROR_NONE)
152                 MSG_DEBUG("MM Session Init Failed");
153         else
154                 MSG_DEBUG("MM Session Init Success : %d", err);
155
156         hPlayerHandle = 0;
157
158         err = mm_player_create(&hPlayerHandle);
159
160         if (err != MM_ERROR_NONE) {
161                 MSG_DEBUG("creating the player handle failed");
162                 return NULL;
163         }
164
165         /* Setting the call back function msg_callback */
166         mm_player_set_message_callback(hPlayerHandle, MsgSoundPlayCallback, (void *)hPlayerHandle);
167
168         callStatus = MsgSettingGetInt(VCONFKEY_CALL_STATE);
169         MSG_DEBUG("Call Status = %d", callStatus);
170
171         if (callStatus > VCONFKEY_CALL_OFF && callStatus < VCONFKEY_CALL_STATE_MAX) {
172                 alertOnCall = MsgSettingGetInt(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT);
173                 MSG_DEBUG("Alert On Call = %d", alertOnCall);
174
175                 if (alertOnCall == 0) {
176                         MSG_DEBUG("Call is active & Alert on Call - Off");
177                 } else if (alertOnCall == 1) {
178                         MSG_DEBUG("Call is active & Alert on Call - Sound");
179
180                         if (bSoundOn)
181                                 MsgSoundPlayDtmf();
182                 } else if (alertOnCall == 2) {
183                         MSG_DEBUG("Call is active & Alert on Call - Vibration");
184
185                         if (bVibrationOn)
186                                 MsgSoundPlayVibration(true);
187                 }
188         } else{
189                 MSG_DEBUG("Call is not active");
190
191                 if (bVibrationOn) {
192                         MSG_DEBUG("Play vibration.");
193                         MsgSoundPlayVibration(false);
194                 }
195
196                 if (bSoundOn) {
197                         MSG_DEBUG("Play sound.");
198                         MsgSoundPlayMelody(msg_tone_file_path, false);
199                 }
200         }
201
202         err = mm_session_finish();
203
204         if (err != MM_ERROR_NONE)
205                 MSG_DEBUG("MM Session Finish Failed");
206         else
207                 MSG_DEBUG("MM Session Finish Success : %d", err);
208
209         if(!bPlaying && !bVibrating)
210                 worker_done();
211
212         MSG_END();
213
214         return NULL;
215 }
216
217
218 msg_error_t MsgSoundPlayUninit()
219 {
220         MSG_BEGIN();
221
222         int err = MM_ERROR_NONE;
223
224         /* Uninitializing the player module */
225         err = mm_player_unrealize(hPlayerHandle);
226
227         /* Destroying the player handle */
228         err = mm_player_destroy(hPlayerHandle);
229
230         pthread_mutex_lock(&muMmPlay);
231
232         bPlaying = false;
233
234         pthread_mutex_unlock(&muMmPlay);
235
236         pthread_cond_signal(&cvMmPlay);
237
238         hPlayerHandle = 0;
239
240         MSG_END();
241
242         return MSG_SUCCESS;
243 }
244
245
246 void MsgSoundPlayStart(bool isEmergency)
247 {
248         MSG_BEGIN();
249
250         pthread_mutex_lock(&muMmPlay);
251
252         if (bPlaying == true) {
253                 MSG_DEBUG("Ringtone is Playing...");
254                 pthread_mutex_unlock(&muMmPlay);
255                 return;
256         }
257
258         pthread_mutex_unlock(&muMmPlay);
259
260         pthread_t tid;
261
262         if (pthread_create(&tid, NULL, &MsgPlayThread, (void*)isEmergency) == 0) {
263                 MSG_DEBUG("Ring alert thread created = %d", tid);
264         } else {
265                 MSG_DEBUG("Creating Thread was failed");
266                 return;
267         }
268
269         MSG_END();
270 }
271
272
273 void MsgSoundPlayStop()
274 {
275         MSG_BEGIN();
276
277         pthread_mutex_lock(&muMmPlay);
278
279         if (bPlaying == false) {
280                 MSG_DEBUG("Ringtone is Not Playing...");
281                 pthread_mutex_unlock(&muMmPlay);
282                 return;
283         }
284
285         pthread_mutex_unlock(&muMmPlay);
286
287         /* Stop playing media contents */
288         MSG_DEBUG("Before mm_player_stop, %p", hPlayerHandle);
289
290         int err = mm_player_stop(hPlayerHandle);
291
292         MSG_DEBUG("After mm_player_stop");
293
294         if (err != MM_ERROR_NONE) {
295                 MSG_DEBUG("stopping the player handle failed");
296         }
297
298         MsgSoundPlayUninit();
299
300         MSG_END();
301 }
302
303
304 int MsgSoundPlayMelody(char *pMsgToneFilePath, bool bIncreasing)
305 {
306         int err = MM_ERROR_NONE;
307
308         /* Setting fade in/out, Volume */
309         err = mm_player_set_attribute(hPlayerHandle, NULL, "sound_volume_type", MM_SOUND_VOLUME_TYPE_NOTIFICATION,
310                                                                                                         "profile_uri", pMsgToneFilePath, strlen(pMsgToneFilePath),
311                                                                                                         "sound_priority", 2, NULL);
312
313         if (err != MM_ERROR_NONE) {
314                 MSG_DEBUG("error setting the profile attr");
315                 return err;
316         }
317
318         err = mm_player_realize(hPlayerHandle);
319
320         if (err != MM_ERROR_NONE) {
321                 MSG_DEBUG("mm_player_realize() error : [%d]", err);
322                 return err;
323         }
324
325         /* Add Timer to stop playing after 5 sec. */
326         int g_contact_timer = -1;
327         g_contact_timer = g_timeout_add(5500, (GSourceFunc)MsgSoundMelodyTimeout, NULL);
328
329         err = mm_player_start(hPlayerHandle);
330
331         if (err != MM_ERROR_NONE) {
332                 MSG_DEBUG("mm_player_start, FAIL [%x]", err);
333                 bPlaying = false;
334
335                 return err;
336         }
337
338         bPlaying = true;
339
340         pthread_mutex_lock(&muMmPlay);
341
342         while (bPlaying)
343         {
344                 MSG_DEBUG("Ring Alert Playing");
345                 pthread_cond_wait(&cvMmPlay, &muMmPlay);
346         }
347
348         pthread_mutex_unlock(&muMmPlay);
349
350         MSG_DEBUG("Ring Alert Idle");
351
352         return err;
353 }
354
355
356 void MsgSoundPlayVibration(bool isOnCall)
357 {
358         MSG_BEGIN();
359
360         int ret = 0;
361
362         ret = feedback_initialize();
363
364         if (ret != FEEDBACK_ERROR_NONE) {
365                 MSG_DEBUG("Fail to feedback_initialize : [%d]", ret);
366                 return;
367         }
368
369         if (isOnCall)
370                 ret = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_MESSAGE_ON_CALL);
371         else
372                 ret = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_MESSAGE);
373
374         if (ret != FEEDBACK_ERROR_NONE)
375                 MSG_DEBUG("Fail to feedback_play_type");
376
377         ret = feedback_deinitialize();
378
379         if (ret != FEEDBACK_ERROR_NONE) {
380                 MSG_DEBUG("Fail to feedback_deinitialize : [%d]", ret);
381                 return;
382         }
383
384         MSG_END();
385 }
386
387 void MsgSoundPlayDtmf()
388 {
389         MSG_BEGIN();
390
391         int ret = 0;
392         int hToneHandle = 0;
393
394         ret = mm_sound_play_tone(MM_SOUND_TONE_PROP_BEEP2, VOLUME_TYPE_SYSTEM, 1.0, 300, &hToneHandle);
395
396         if(ret < 0) {
397                 MSG_DEBUG("play tone failed\n");
398         } else {
399                 MSG_DEBUG("play tone success\n");
400         }
401
402         MSG_END();
403 }
404
405
406 int MsgSoundGetUnreadMsgCnt()
407 {
408         int unreadCnt = 0;
409
410         /*  Get SMS Count */
411         unreadCnt = MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_SMS_STATE);
412
413         /*  Get MMS Count */
414         unreadCnt += MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_MMS_STATE);
415
416         MSG_DEBUG("unread count : [%d]", unreadCnt);
417
418         return unreadCnt;
419 }