fa5ca9f285d4c90a1e080119be2732fbc1f02f0d
[apps/home/quickpanel.git] / daemon / service / reminder.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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
18
19 #include <alarm.h>
20 #include <time.h>
21 #include <unistd.h>
22 #include <vconf.h>
23
24 #include "quickpanel-ui.h"
25 #include "common.h"
26 #include "media.h"
27 #include "noti.h"
28
29 #define REMINDER_MIN_INTERVAL 2
30
31 static struct info {
32         int alarm_id;
33 } s_info = {
34         .alarm_id = -1,
35 };
36
37 static void _feedback_sound_play(void)
38 {
39         int ret = 0;
40         noti_node_item *node = NULL;
41         notification_h noti;
42         int priv_id = 0;
43         const char *nsound_path = NULL;
44         notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
45         int is_play_default = 0;
46
47         // check first noti sound
48         node = quickpanel_noti_node_get_first_noti();
49         if (node)
50         {
51                 noti = node->noti;
52                 if (noti)
53                 {
54                         notification_get_id(noti, NULL, &priv_id);
55                         notification_get_sound(noti, &nsound_type, &nsound_path);
56                         SDBG("reminded notification sound type[%d] path[%s]", nsound_type, nsound_path);
57
58                         switch (nsound_type)
59                         {
60                         case NOTIFICATION_SOUND_TYPE_USER_DATA:
61                                 /*
62                                  *  if user data file isn't playable, play the default ringtone
63                                  */
64                                 if (nsound_path != NULL)
65                                 {
66                                         if (quickpanel_media_playable_check(nsound_path) == EINA_TRUE)
67                                         {
68                                                 ret = quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
69                                                 if (ret == PLAYER_ERROR_NONE)
70                                                 {
71                                                         quickpanel_player_id_set(priv_id);
72                                                 }
73                                                 else
74                                                 {
75                                                         ERR("failed to play notification sound[%d]", ret);
76                                                         is_play_default = 1;
77                                                 }
78                                         }
79                                 }
80                                 break;
81                         case NOTIFICATION_SOUND_TYPE_DEFAULT:
82                                 is_play_default = 1;
83                                 break;
84                         case NOTIFICATION_SOUND_TYPE_MAX:
85                         case NOTIFICATION_SOUND_TYPE_NONE:
86                                 break;
87                         }
88                 }
89         }
90
91         if (is_play_default)
92         {
93 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
94                 char *default_msg_tone = NULL;
95                 default_msg_tone = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
96                 SDBG("Reminded setting sound[%s]", default_msg_tone);
97
98                 if (default_msg_tone != NULL)
99                 {
100                         ret = quickpanel_player_play(SOUND_TYPE_NOTIFICATION, default_msg_tone);
101                         free(default_msg_tone);
102                         quickpanel_player_id_set(0);
103                         if (ret != PLAYER_ERROR_NONE)
104                         {
105                                 ERR("failed to play feedback sound");
106                         }
107                 }
108
109                 if (quickpanel_is_vib_enabled() == 1)
110                 {
111                         feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_MESSAGE);
112                 }
113 #else
114                 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
115 #endif
116         }
117 }
118
119 static int _reminder_interval_get(void) {
120         int key = 0;
121         int min = 0;
122         int ret = -1;
123
124         ret = vconf_get_int(VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT, &key);
125         retif(ret != 0, 0, "failed to get vconf VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT");
126
127         switch (key) {
128                 case 1:
129                         min = 2;
130                         break;
131                 case 2:
132                         min = 5;
133                         break;
134                 case 3:
135                         min = 10;
136                         break;
137         }
138
139         DBG("interval:%d", min);
140
141         return min;
142 }
143
144 static int _alarm_delete_cb(alarm_id_t id, void * user_param)
145 {
146         int ret = ALARMMGR_RESULT_SUCCESS;
147
148         ret = alarmmgr_remove_alarm(id);
149         if(ret != ALARMMGR_RESULT_SUCCESS) {
150                 ERR("alarmmgr_enum_alarm_ids() failed");
151         }
152
153         return 0;
154 }
155
156 static void _alarm_unset(void)
157 {
158         int ret = ALARMMGR_RESULT_SUCCESS;
159
160         if(s_info.alarm_id != -1){
161                 ERR("try to delete alarm_id(%d)", s_info.alarm_id);
162                 ret = alarmmgr_remove_alarm(s_info.alarm_id);
163                 if(ret != ALARMMGR_RESULT_SUCCESS) {
164                         ERR("alarmmgr_remove_alarm(%d) failed", s_info.alarm_id);
165                         ret = alarmmgr_enum_alarm_ids(_alarm_delete_cb, NULL);
166                         if(ret != ALARMMGR_RESULT_SUCCESS) {
167                                 ERR("alarmmgr_enum_alarm_ids() failed");
168                         }
169                 }
170                 s_info.alarm_id = -1;
171         }
172 }
173
174 static Eina_Bool _alarm_set_from_now(int min, void *data)
175 {
176         int ret = ALARMMGR_RESULT_SUCCESS;
177         time_t current_time;
178         struct tm current_tm;
179         alarm_entry_t *alarm_info = NULL;
180         alarm_id_t alarm_id;
181         alarm_date_t alarm_time;
182
183         /* delete before registering alarm ids */
184         _alarm_unset();
185
186         /* set alarm after sec */
187         time(&current_time);
188
189         DBG(" %s, after %d MIN alarm set", ctime(&current_time), min);
190         localtime_r(&current_time, &current_tm);
191
192         alarm_info = alarmmgr_create_alarm();
193         if(alarm_info == NULL) {
194                 ERR("alarmmgr_create_alarm() is failed\n");
195                 return EINA_FALSE;
196         }
197
198         alarm_time.year = 0;
199         alarm_time.month = 0;
200         alarm_time.day = 0;
201         alarm_time.hour = current_tm.tm_hour;
202         alarm_time.min = current_tm.tm_min + min;
203         alarm_time.sec = current_tm.tm_sec;
204
205         alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_ONCE, 0);
206         alarmmgr_set_time(alarm_info, alarm_time);
207         alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
208
209         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
210         if(ret != ALARMMGR_RESULT_SUCCESS) {
211                 ERR("alarmmgr_add_alarm_with_localtime() failed:%d", ret);
212                 alarmmgr_free_alarm(alarm_info) ;
213                 return EINA_FALSE;
214         }
215
216         DBG("alarm id(%d) is set", alarm_id);
217         s_info.alarm_id = alarm_id;
218         alarmmgr_free_alarm(alarm_info) ;
219
220         return EINA_TRUE;
221 }
222
223 static int _alarm_cb(alarm_id_t alarm_id, void *data)
224 {
225         DBG("");
226
227         int min = _reminder_interval_get();
228
229         if (min >= REMINDER_MIN_INTERVAL) {
230                 _alarm_set_from_now(min, data);
231         } else {
232                 _alarm_unset();
233         }
234
235         if (!quickpanel_is_opened()) {
236                 _feedback_sound_play();
237         } else {
238                 ERR("quickpanel is opened, skip remind sound");
239         }
240
241         return 1;
242 }
243
244 static void _alarm_setting_changed_cb(keynode_t *key, void* data) {
245         int min = _reminder_interval_get();
246
247         if (quickpanel_noti_get_count() <= 0) {
248                 _alarm_unset();
249         } else {
250                 if (min >= REMINDER_MIN_INTERVAL) {
251                         _alarm_set_from_now(min, data);
252                 } else {
253                         _alarm_unset();
254                 }
255         }
256 }
257
258 void quickpanel_reminder_init(void *data) {
259         DBG("");
260
261         int ret = 0;
262
263         ret = alarmmgr_init("org.tizen.quickpanel");
264         retif(ret < 0, , "alarmmgr_init() failed (%d)", ret);
265
266         ret = alarmmgr_set_cb(_alarm_cb, NULL);
267         retif(ret < 0, , "alarmmgr_init() failed (%d)", ret);
268
269         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT,
270                         _alarm_setting_changed_cb, data);
271         if (ret != 0) {
272                 ERR("failed to register a cb key:%s err:%d",
273                                 "VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT", ret);
274         }
275
276         s_info.alarm_id = -1;
277 }
278
279 void quickpanel_reminder_fini(void *data) {
280         DBG("");
281
282         int ret = 0;
283
284         _alarm_unset();
285
286         alarmmgr_fini();
287
288         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT, _alarm_setting_changed_cb);
289         if (ret != 0) {
290                 ERR("failed to unregister a cb key:%s err:%d", "VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT", ret);
291         }
292 }
293
294 void quickpanel_reminder_start(void *data) {
295         DBG("");
296
297         int min = _reminder_interval_get();
298
299         if (min >= REMINDER_MIN_INTERVAL) {
300                 _alarm_set_from_now(min, data);
301         }
302 }
303
304 void quickpanel_reminder_stop(void *data) {
305         DBG("");
306
307         _alarm_unset();
308 }