4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@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.
26 #include "email-debug-log.h"
27 #include "email-storage.h"
28 #include "email-core-utils.h"
29 #include "email-core-mailbox.h"
30 #include "email-core-sound.h"
31 #include "email-core-alarm.h"
32 #include "email-utilities.h"
34 #define TIMER 30000 // 30 seconds
35 #define HAPTIC_TEST_ITERATION 1
36 #define EMAIL_ALARM_REFERENCE_ID_FOR_ALERT_TONE -1
38 static MMHandleType email_mmhandle = 0;
39 static int setting_noti_status = 0;
41 static char *filename;
43 static pthread_mutex_t sound_mutex = PTHREAD_MUTEX_INITIALIZER;
44 static pthread_cond_t sound_condition = PTHREAD_COND_INITIALIZER;
45 static pthread_mutex_t mmhandle_mutex = PTHREAD_MUTEX_INITIALIZER;
46 static thread_t g_alert_thread;
48 void emcore_set_repetition_alarm(int repetition);
49 int emcore_sound_mp_player_stop();
50 bool emcore_sound_mp_player_destory();
51 void *start_alert_thread(void *arg);
53 bool emcore_set_mp_filepath(const char *key)
55 filename = vconf_get_str(key);
59 /* initialize the ringtone path */
60 if (vconf_set_str(VCONF_VIP_NOTI_RINGTONE_PATH, filename) != 0) {
61 EM_DEBUG_EXCEPTION("vconf_set_str failed");
68 int emcore_alert_sound_init()
70 int ret = MM_ERROR_NONE;
71 if ((ret = mm_session_init(MM_SESSION_TYPE_NOTIFY)) != MM_ERROR_NONE)
72 EM_DEBUG_EXCEPTION("mm_session_int failed");
77 int emcore_alert_sound_filepath_init()
79 filename = (char *)em_malloc(MAX_PATH);
80 if (filename == NULL) {
81 EM_DEBUG_EXCEPTION("Memory malloc error");
85 if (!emcore_set_mp_filepath(VCONFKEY_SETAPPL_NOTI_EMAIL_RINGTONE_PATH_STR)) {
86 /* TODO : Add code to set default ringtone path */
87 EM_DEBUG_EXCEPTION("emcore_set_mp_filepath failed.");
94 void emcore_global_noti_key_changed_cb(keynode_t *key_node, void *data)
96 EM_DEBUG_FUNC_BEGIN();
97 int err = EMAIL_ERROR_NONE;
99 switch (vconf_keynode_get_type(key_node)) {
101 if ((err = emcore_delete_alram_data_by_reference_id(EMAIL_ALARM_CLASS_NEW_MAIL_ALERT, EMAIL_ALARM_REFERENCE_ID_FOR_ALERT_TONE)) != EMAIL_ERROR_NONE) {
102 EM_DEBUG_EXCEPTION("emcore_delete_alram_data_by_reference_id failed [%d]", err);
104 emcore_set_repetition_alarm(vconf_keynode_get_int(key_node));
106 case VCONF_TYPE_STRING:
107 filename = vconf_keynode_get_str(key_node);
110 EM_DEBUG_EXCEPTION("Invalid key type");
117 void emcore_email_noti_key_changed_cb(keynode_t *key_node, void *data)
119 EM_DEBUG_FUNC_BEGIN();
120 int err = EMAIL_ERROR_NONE;
122 switch (vconf_keynode_get_type(key_node)) {
124 if ((err = emcore_delete_alram_data_by_reference_id(EMAIL_ALARM_CLASS_NEW_MAIL_ALERT, EMAIL_ALARM_REFERENCE_ID_FOR_ALERT_TONE)) != EMAIL_ERROR_NONE) {
125 EM_DEBUG_EXCEPTION("emcore_delete_alram_data_by_reference_id failed [%d]", err);
128 emcore_set_repetition_alarm(vconf_keynode_get_int(key_node));
130 case VCONF_TYPE_STRING:
131 filename = vconf_keynode_get_str(key_node);
134 EM_DEBUG_EXCEPTION("Invalid key type");
140 bool emcore_update_noti_status()
142 EM_DEBUG_FUNC_BEGIN();
145 /* Get the priority noti ticker */
146 if (vconf_get_bool(VCONF_VIP_NOTI_NOTIFICATION_TICKER, &ticker_noti) != 0) {
147 EM_DEBUG_EXCEPTION("vconf_get_bool failed");
151 EM_DEBUG_LOG("ticker_noti of vip : [%d]", ticker_noti);
153 if (ticker_noti <= 0) {
154 /* Get the Global noti ticker */
155 if (vconf_get_bool(VCONFKEY_SETAPPL_STATE_TICKER_NOTI_EMAIL_BOOL, &ticker_noti) != 0) {
156 EM_DEBUG_EXCEPTION("Not display the noti of email");
160 EM_DEBUG_LOG("ticker_noti of global : [%d]", ticker_noti);
163 EM_DEBUG_LOG("Not use the notification");
164 setting_noti_status = SETTING_NOTI_STATUS_OFF;
168 setting_noti_status = SETTING_NOTI_STATUS_GLOBAL;
170 setting_noti_status = SETTING_NOTI_STATUS_EMAIL;
177 void emcore_noti_status_changed_cb(keynode_t *key_node, void *data)
179 EM_DEBUG_FUNC_BEGIN();
180 if (!emcore_update_noti_status()) {
181 EM_DEBUG_EXCEPTION("emcore_update_noti_status failed");
187 bool emcore_noti_init(void *data)
189 EM_DEBUG_FUNC_BEGIN();
190 struct appdata *ap = data;
192 if (!emcore_update_noti_status()) {
193 EM_DEBUG_EXCEPTION("emcore_update_noti_status failed");
197 /* Noti callback registration */
198 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_EMAIL_ALERT_REP_TYPE_INT, emcore_global_noti_key_changed_cb, ap) < 0) {
199 EM_DEBUG_EXCEPTION("Register failed : alert type");
202 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_EMAIL_RINGTONE_PATH_STR, emcore_global_noti_key_changed_cb, ap) < 0) {
203 EM_DEBUG_EXCEPTION("Register failed : Ringtone path");
206 if (vconf_notify_key_changed(VCONF_VIP_NOTI_REP_TYPE, emcore_email_noti_key_changed_cb, ap) < 0) {
207 EM_DEBUG_EXCEPTION("Register failed : alert type");
210 if (vconf_notify_key_changed(VCONF_VIP_NOTI_RINGTONE_PATH, emcore_email_noti_key_changed_cb, ap) < 0) {
211 EM_DEBUG_EXCEPTION("Register failed : Ringtone path");
214 if (vconf_notify_key_changed(VCONF_VIP_NOTI_NOTIFICATION_TICKER, emcore_noti_status_changed_cb, ap) < 0) {
215 EM_DEBUG_EXCEPTION("Register failed : Ringtone path");
218 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_STATE_TICKER_NOTI_EMAIL_BOOL, emcore_noti_status_changed_cb, ap) < 0) {
219 EM_DEBUG_EXCEPTION("Register failed : Ringtone path");
226 int emcore_alert_init()
228 EM_DEBUG_FUNC_BEGIN();
232 if (!emcore_alert_sound_filepath_init()) {
233 EM_DEBUG_EXCEPTION("emcore_alert_sound_filepath_init failed");
237 if ((err = emcore_alert_sound_init()) != MM_ERROR_NONE) {
238 EM_DEBUG_EXCEPTION("emcore_alert_sound_init failed : [%d]", err);
242 if (!emcore_noti_init(NULL)) {
243 EM_DEBUG_EXCEPTION("emcore_noti_init failed");
251 int emcore_mp_player_state_cb(int message, void *param, void *user_param)
255 case MM_MESSAGE_ERROR:
256 EM_DEBUG_LOG("Error is happened.");
257 if (email_mmhandle) {
258 emcore_sound_mp_player_destory();
261 case MM_MESSAGE_BEGIN_OF_STREAM:
262 EM_DEBUG_LOG("Play is started.");
264 case MM_MESSAGE_END_OF_STREAM:
265 EM_DEBUG_LOG("End of stream.");
266 ENTER_CRITICAL_SECTION(mmhandle_mutex);
269 emcore_sound_mp_player_stop();
270 emcore_sound_mp_player_destory();
272 LEAVE_CRITICAL_SECTION(mmhandle_mutex);
275 EM_DEBUG_LOG("Message = %d", message);
281 bool emcore_sound_mp_player_create()
283 EM_DEBUG_FUNC_BEGIN();
286 if (email_mmhandle) {
287 EM_DEBUG_LOG("already create the handle");
291 if ((err = mm_player_create(&email_mmhandle)) != MM_ERROR_NONE) {
292 EM_DEBUG_EXCEPTION("mm_player create fail [%d]", err);
299 bool emcore_alert_create()
301 EM_DEBUG_FUNC_BEGIN();
304 /* Set the music file in alert */
305 if (!emcore_set_mp_filepath(VCONFKEY_SETAPPL_NOTI_EMAIL_RINGTONE_PATH_STR)) {
306 /* TODO : Add code to set default ringtone path */
307 EM_DEBUG_EXCEPTION("emcore_set_mp_filepath failed.");
315 bool emcore_alert_destory()
317 EM_DEBUG_FUNC_BEGIN();
319 /* Destroy the music player handle */
320 if (!emcore_sound_mp_player_destory()) {
321 EM_DEBUG_EXCEPTION("emcore_sound_mp_player_destory fail");
329 gboolean mp_player_timeout_cb(void *data)
331 EM_DEBUG_FUNC_BEGIN();
333 ENTER_CRITICAL_SECTION(mmhandle_mutex);
336 emcore_sound_mp_player_stop();
337 emcore_sound_mp_player_destory();
339 LEAVE_CRITICAL_SECTION(mmhandle_mutex);
345 bool emcore_vibration_start()
347 EM_DEBUG_FUNC_BEGIN();
349 int error = FEEDBACK_ERROR_NONE;
352 error = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
354 EM_DEBUG_EXCEPTION("vconf_get_int failed");
358 error = feedback_initialize();
359 if (error != FEEDBACK_ERROR_NONE) {
360 EM_DEBUG_EXCEPTION("feedback_initialize failed : [%d]", error);
364 if (call_state > VCONFKEY_CALL_OFF && call_state < VCONFKEY_CALL_STATE_MAX) {
365 error = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_EMAIL_ON_CALL);
367 error = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_EMAIL);
370 if (error != FEEDBACK_ERROR_NONE) {
371 EM_DEBUG_EXCEPTION("feedback_play failed : [%d]", error);
379 error = feedback_deinitialize();
380 if (error != FEEDBACK_ERROR_NONE) {
381 EM_DEBUG_EXCEPTION("feedback_deinitialize failed : [%d]", error);
388 int emcore_sound_mp_player_start(char *filepath)
390 EM_DEBUG_FUNC_BEGIN();
392 int err = MM_ERROR_NONE;
394 mm_player_set_message_callback(email_mmhandle, emcore_mp_player_state_cb, (void *)email_mmhandle);
396 EM_DEBUG_LOG("Before mm_player_set_attribute filepath = %s", filepath);
397 if ((err = mm_player_set_attribute(email_mmhandle, NULL, "sound_volume_type", MM_SOUND_VOLUME_TYPE_NOTIFICATION, "profile_uri", filepath, EM_SAFE_STRLEN(filepath), NULL)) != MM_ERROR_NONE)
399 EM_DEBUG_EXCEPTION("mm_player_set_attribute faile [ %d ] ", err);
403 EM_DEBUG_LOG("After mm_player_set_attribute");
405 if ((err = mm_player_realize(email_mmhandle)) != MM_ERROR_NONE)
407 EM_DEBUG_EXCEPTION("mm_player_realize fail [%d]", err);
411 if ((err = mm_player_start(email_mmhandle)) != MM_ERROR_NONE)
413 EM_DEBUG_EXCEPTION("mm_player_start fail [%d]", err);
417 if ((err = g_timeout_add(TIMER, (GSourceFunc)mp_player_timeout_cb, NULL) <= 0))
419 EM_DEBUG_EXCEPTION("g_timeout_add - Failed to start timer");
427 int emcore_sound_mp_player_stop()
429 EM_DEBUG_FUNC_BEGIN();
431 int err = MM_ERROR_NONE;
433 if ((err = mm_player_stop(email_mmhandle)) != MM_ERROR_NONE)
435 EM_DEBUG_EXCEPTION("mm_player_stop fail [%d]", err);
439 if ((err = mm_player_unrealize(email_mmhandle)) != MM_ERROR_NONE)
441 EM_DEBUG_EXCEPTION("mm_player_unrealize [%d]", err);
449 bool emcore_sound_mp_player_destory()
451 EM_DEBUG_FUNC_BEGIN();
453 int err = MM_ERROR_NONE;
455 if ((err = mm_player_destroy(email_mmhandle)) != MM_ERROR_NONE) {
456 EM_DEBUG_EXCEPTION("mm_player_destory [%d]", err);
466 int get_vconf_data(int key, int *return_value)
468 EM_DEBUG_FUNC_BEGIN();
469 int err = -1, value = 0;
473 case EMAIL_SOUND_STATUS:
474 err = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &value);
475 EM_DEBUG_LOG("EMAIL_SOUND_STATUS[%d]", value);
477 case EMAIL_VIBE_STATUS:
478 err = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &value);
479 EM_DEBUG_LOG("EMAIL_VIBRATION_STATUS[%d]", value);
481 case EMAIL_ALERT_REP_TYPE:
482 err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_EMAIL_ALERT_REP_TYPE_INT, &value);
483 EM_DEBUG_LOG("EMAIL_ALERT_REP_TYPE[%d]", value);
485 case EMAIL_ALERT_VOLUME:
486 err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_SOUND_VOLUME_INT, &value);
487 EM_DEBUG_LOG("EMAIL_ALERT_VOLUME[%d]", value);
489 case EMAIL_ALERT_VIBE_STENGTH:
490 err = vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &value);
491 EM_DEBUG_LOG("EMAIL_ALERT_VIBE_STENGTH[%d]", value);
495 EM_DEBUG_LOG("Uuknown request\n");
502 EM_DEBUG_LOG("Vconf_get_int failed\n");
506 *return_value = value;
511 int emcore_get_alert_type()
513 EM_DEBUG_FUNC_BEGIN();
514 int sound_status = 0, vibe_status = 0;
518 if (!(err = get_vconf_data(EMAIL_SOUND_STATUS, &sound_status))) {
519 EM_DEBUG_EXCEPTION("Don't get sound status");
523 if (!(err = get_vconf_data(EMAIL_VIBE_STATUS, &vibe_status)))
525 EM_DEBUG_EXCEPTION("Don't get vibration status");
529 if (sound_status && vibe_status)
530 alert_type = EMAIL_ALERT_TYPE_MELODY_AND_VIB;
531 else if (sound_status)
532 alert_type = EMAIL_ALERT_TYPE_MELODY;
533 else if (vibe_status)
534 alert_type = EMAIL_ALERT_TYPE_VIB;
536 alert_type = EMAIL_ALERT_TYPE_MUTE;
542 INTERNAL_FUNC int emcore_start_thread_for_alerting_new_mails(int *err_code)
544 EM_DEBUG_FUNC_BEGIN();
548 if (err_code != NULL)
549 *err_code = EMAIL_ERROR_NONE;
553 EM_DEBUG_EXCEPTION("Alert service is already running...");
554 if (err_code != NULL)
555 *err_code = EMAIL_ERROR_UNKNOWN;
560 THREAD_CREATE(g_alert_thread, start_alert_thread, NULL, thread_error);
561 if (thread_error != 0)
563 EM_DEBUG_EXCEPTION("Cannot create alert thread");
564 if (err_code != NULL)
565 *err_code = EMAIL_ERROR_SYSTEM_FAILURE;
570 if (err_code != NULL)
571 *err_code = EMAIL_ERROR_NONE;
576 int emcore_alarm_timeout_cb_for_alert(int timer_id, void *user_parm)
578 EM_DEBUG_FUNC_BEGIN();
580 int err = EMAIL_ERROR_NONE;
581 int total_unread_count = 0;
582 int total_mail_count = 0;
583 email_mailbox_t mailbox;
585 memset(&mailbox, 0x00, sizeof(email_mailbox_t));
587 mailbox.account_id = ALL_ACCOUNT;
588 mailbox.mailbox_name = NULL;
590 if (!emcore_get_mail_count(&mailbox, &total_mail_count, &total_unread_count, &err)) {
591 EM_DEBUG_EXCEPTION("emcore_get_mail_count failed - %d\n", err);
595 EM_DEBUG_LOG(">>>> total_unread_count : [%d]\n", total_unread_count);
597 if (total_unread_count) {
598 emcore_start_alert();
605 /* repetition_time in minutes */
606 static int emcore_set_alarm_for_alert(int alert_time_in_minute)
608 EM_DEBUG_FUNC_BEGIN();
610 int err = EMAIL_ERROR_NONE;
612 time_t trigger_at_time;
616 trigger_at_time = current_time + (alert_time_in_minute * 60);
618 if ((err = emcore_add_alarm(trigger_at_time, EMAIL_ALARM_CLASS_NEW_MAIL_ALERT, EMAIL_ALARM_REFERENCE_ID_FOR_ALERT_TONE, emcore_alarm_timeout_cb_for_alert, NULL)) != EMAIL_ERROR_NONE) {
619 EM_DEBUG_EXCEPTION("emcore_add_alarm failed [%d]", err);
625 EM_DEBUG_FUNC_END("err [%d]", err);
629 void emcore_set_repetition_alarm(int repetition)
631 EM_DEBUG_FUNC_BEGIN();
633 int repetition_time = 0;
635 switch (repetition) {
636 case EMAIL_GCONF_VALUE_REPEAT_NONE:
639 case EMAIL_GCONF_VALUE_REPEAT_2MINS:
642 case EMAIL_GCONF_VALUE_REPEAT_5MINS:
645 case EMAIL_GCONF_VALUE_REPEAT_10MINS:
646 repetition_time = 10;
649 EM_DEBUG_EXCEPTION("Invalid repetition time");
653 EM_DEBUG_LOG("repetition time is %d", repetition_time);
655 if (repetition_time > 0) {
656 emcore_set_alarm_for_alert(repetition_time);
662 void *start_alert_thread(void *arg)
664 EM_DEBUG_FUNC_BEGIN();
669 if (!emcore_alert_init())
671 EM_DEBUG_EXCEPTION("Error : emcore_alert_init failed");
676 if (!emcore_alert_create()) {
677 EM_DEBUG_EXCEPTION("Error : emcore_alert_create failed");
681 err = get_vconf_data(EMAIL_ALERT_REP_TYPE, &repetition);
682 emcore_set_repetition_alarm(repetition);
684 ENTER_CRITICAL_SECTION(sound_mutex);
685 SLEEP_CONDITION_VARIABLE(sound_condition , sound_mutex);
687 switch (emcore_get_alert_type())
689 case EMAIL_ALERT_TYPE_MELODY:
690 if (!emcore_sound_mp_player_create()) {
691 EM_DEBUG_LOG("emcore_sound_mp_player_create failed : [%d]", email_mmhandle);
694 emcore_sound_mp_player_start(filename);
696 case EMAIL_ALERT_TYPE_VIB:
697 emcore_vibration_start();
699 case EMAIL_ALERT_TYPE_MELODY_AND_VIB:
700 emcore_vibration_start();
701 if (!emcore_sound_mp_player_create()) {
702 EM_DEBUG_LOG("emcore_sound_mp_player_create failed : [%d]", email_mmhandle);
705 emcore_sound_mp_player_start(filename);
707 case EMAIL_ALERT_TYPE_MUTE:
708 EM_DEBUG_LOG("Alert type is mute!!");
711 EM_DEBUG_EXCEPTION("alert type is strange");
712 emcore_alert_destory();
715 LEAVE_CRITICAL_SECTION(sound_mutex);
716 EM_DEBUG_LOG("Start FINISH");
723 INTERNAL_FUNC void emcore_start_alert()
725 EM_DEBUG_FUNC_BEGIN("setting_noti_status : [%d]", setting_noti_status);
727 #ifdef __FEATURE_BLOCKING_MODE__
728 if (emcore_get_blocking_mode_status())
730 #endif /* __FEATURE_BLOCKING_MODE__ */
732 if (setting_noti_status == SETTING_NOTI_STATUS_OFF)
735 ENTER_CRITICAL_SECTION(sound_mutex);
736 WAKE_CONDITION_VARIABLE(sound_condition);
737 LEAVE_CRITICAL_SECTION(sound_mutex);