Fix the issue in which poweroff popup is not terminated even if "OK" btn is clicked
[platform/core/system/system-popup.git] / poweroff-popup / src / poweroff.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 #include <stdio.h>
19 #include <appcore-efl.h>
20 #include <sensor.h>
21 #include <devman.h>
22 #include <devman_haptic.h>
23 #include <pmapi.h>
24 #include <sysman.h>
25 #include "poweroff.h"
26
27 #include <Ecore_X.h>
28 #include <Ecore_Input.h>
29 #include <utilX.h>
30
31 /* Time profiling support */
32 #ifdef ACCT_PROF
33 #include <sys/acct.h>
34 #endif /* ACCT_PROF */
35
36 #include <syspopup.h>
37 #include <vconf.h>
38
39 int create_and_show_basic_popup_min(struct appdata *ad);
40 void poweroff_response_yes_cb_min(void *data, Evas_Object * obj, void *event_info);
41 void poweroff_response_no_cb_min(void *data, Evas_Object * obj, void *event_info);
42
43
44 int myterm(bundle *b, void *data)
45 {
46         return 0;
47 }
48
49 int mytimeout(bundle *b, void *data)
50 {
51         return 0;
52 }
53
54 syspopup_handler handler = {
55         .def_term_fn = myterm,
56         .def_timeout_fn = mytimeout
57 };
58
59 static Eina_Bool exit_idler_cb(void *data)
60 {
61         elm_exit();
62         return ECORE_CALLBACK_CANCEL;
63 }
64
65 void popup_terminate(void)
66 {
67         if (ecore_idler_add(exit_idler_cb, NULL))
68                 return;
69
70         exit_idler_cb(NULL);
71 }
72
73 /* App Life cycle funtions */
74 static void win_del(void *data, Evas_Object * obj, void *event)
75 {
76         popup_terminate();
77 }
78
79 /* Quit  */
80 static void main_quit_cb(void *data, Evas_Object * obj, const char *emission,
81                          const char *source)
82 {
83         popup_terminate();
84 }
85
86 /* Update text font */
87 static void update_ts(Evas_Object * eo, struct text_part *tp, int size)
88 {
89         int i;
90
91         if (eo == NULL || tp == NULL || size < 0)
92                 return;
93
94         for (i = 0; i < size; i++) {
95                 if (tp[i].part && tp[i].msgid)
96                         edje_object_part_text_set(eo, tp[i].part,
97                                                   _(tp[i].msgid));
98         }
99 }
100
101 /* Language changed noti handler */
102 static int lang_changed(void *data)
103 {
104         struct appdata *ad = data;
105
106         if (ad->layout_main == NULL)
107                 return 0;
108
109         update_ts(elm_layout_edje_get(ad->layout_main), main_txt,
110                   sizeof(main_txt) / sizeof(main_txt[0]));
111         return 0;
112 }
113
114 /* Create main window */
115 static Evas_Object *create_win(const char *name)
116 {
117         Evas_Object *eo;
118         int w, h;
119
120         eo = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC);
121         if (eo) {
122                 elm_win_title_set(eo, name);
123                 elm_win_borderless_set(eo, EINA_TRUE);
124                 evas_object_smart_callback_add(eo, "delete,request", win_del, NULL);
125                 elm_win_alpha_set(eo, EINA_TRUE);
126                 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w,
127                                         &h);
128                 evas_object_resize(eo, w, h);
129         }
130
131         return eo;
132 }
133
134 /* Read from EDJ file */
135 static Evas_Object *load_edj(Evas_Object * parent, const char *file,
136                              const char *group)
137 {
138         Evas_Object *eo;
139         int r;
140
141         eo = elm_layout_add(parent);
142         if (eo) {
143                 r = elm_layout_file_set(eo, file, group);
144                 if (!r) {
145                         evas_object_del(eo);
146                         return NULL;
147                 }
148
149                 evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
150                                                  EVAS_HINT_EXPAND);
151         }
152
153         return eo;
154 }
155
156 /* Terminate noti handler */
157 static int app_terminate(void *data)
158 {
159         struct appdata *ad = data;
160
161         if (ad->layout_main)
162                 evas_object_del(ad->layout_main);
163
164         if (ad->win_main)
165                 evas_object_del(ad->win_main);
166
167         return 0;
168 }
169
170 /* Pause/background */
171 static int app_pause(void *data)
172 {
173         return 0;
174 }
175
176 /* Resume */
177 static int app_resume(void *data)
178 {
179         return 0;
180 }
181
182
183 /* Reset */
184 static int app_reset(bundle *b, void *data)
185 {
186         struct appdata *ad = data;
187
188         if (syspopup_has_popup(b)) {
189                 syspopup_reset(b);
190         } else {
191                 syspopup_create(b, &handler, ad->win_main, ad);
192                 evas_object_show(ad->win_main);
193
194                 /* Start Main UI */
195                 poweroff_start((void *)ad);
196         }
197
198         return 0;
199 }
200
201 /* Customized print */
202 void system_print(const char *format, ...)
203 {
204         /* Un-comment return to disable logs */
205
206         va_list args;
207         va_start(args, format);
208         vfprintf(stderr, format, args);
209         va_end(args);
210 }
211
212 /* Cleanup objects to avoid mem-leak */
213 void poweroff_cleanup(struct appdata *ad)
214 {
215         if (ad->popup_poweroff)
216                 evas_object_del(ad->popup_poweroff);
217         if (ad->layout_main)
218                 evas_object_del(ad->layout_main);
219 }
220
221 /* Background clicked noti */
222 static void bg_clicked_cb(void *data, Evas * e, Evas_Object * obj, void *event_info)
223 {
224         system_print("\n system-popup : In BG Noti \n");
225         fflush(stdout);
226         popup_terminate();
227 }
228
229 static void poweroff_popup_direct_cancel(keynode_t *key, void *data)
230 {
231         int val;
232         struct appdata *ad = data;
233         if ( vconf_get_int(VCONFKEY_PM_STATE, &val) == 0
234         && val == VCONFKEY_PM_STATE_LCDOFF ) {
235                 vconf_ignore_key_changed(VCONFKEY_PM_STATE,(void*)poweroff_popup_direct_cancel);
236                 if (ad != NULL)
237                         poweroff_cleanup(ad);
238                 popup_terminate();
239         }
240         else
241                 return;
242 }
243 void poweroff_response_yes_cb_min(void *data, Evas_Object * obj, void *event_info)
244 {
245         static int bPowerOff = 0;
246         if (1 == bPowerOff)
247                 return;
248         bPowerOff = 1;
249         system_print("System-popup : Switching off phone !! Bye Bye \n");
250         vconf_ignore_key_changed(VCONFKEY_PM_STATE,(void*)poweroff_popup_direct_cancel);
251         /* This will cleanup the memory */
252         if (data != NULL)
253                 poweroff_cleanup(data);
254
255         if (sysman_call_predef_action(PREDEF_POWEROFF, 0) == -1) {
256                 system_print("System-popup : failed to request poweroff to system_server \n");
257                 system("poweroff");
258         }
259 }
260
261 void poweroff_response_no_cb_min(void *data, Evas_Object * obj, void *event_info)
262 {
263         system_print("\nSystem-popup: Option is Wrong");
264         vconf_ignore_key_changed(VCONFKEY_PM_STATE,(void*)poweroff_popup_direct_cancel);
265         if(data != NULL)
266                 poweroff_cleanup(data);
267         popup_terminate();
268 }
269
270 int create_and_show_basic_popup_min(struct appdata *ad)
271 {
272         Evas_Object *btn1;
273         Evas_Object *btn2;
274
275         ad->popup_poweroff = elm_popup_add(ad->win_main);
276         if (ad->popup_poweroff == NULL) {
277                 system_print("\n System-popup : Add popup failed \n");
278                 return -1;
279         }
280
281         evas_object_size_hint_weight_set(ad->popup_poweroff, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
282         elm_object_style_set(ad->popup_poweroff, "transparent");
283         elm_object_text_set(ad->popup_poweroff, _("IDS_ST_BODY_POWER_OFF"));
284         elm_object_part_text_set(ad->popup_poweroff, "title,text", _("IDS_COM_BODY_SYSTEM_INFO_ABB"));
285
286         btn1 = elm_button_add(ad->popup_poweroff);
287         elm_object_text_set(btn1, _("IDS_COM_SK_CANCEL"));
288         elm_object_part_content_set(ad->popup_poweroff, "button1", btn1);
289         elm_object_style_set (btn1,"popup_button/default");
290         evas_object_smart_callback_add(btn1, "clicked", poweroff_response_no_cb_min, ad);
291         btn2 = elm_button_add(ad->popup_poweroff);
292         elm_object_text_set(btn2, _("IDS_COM_SK_OK"));
293         elm_object_part_content_set(ad->popup_poweroff, "button2", btn2);
294         elm_object_style_set (btn2,"popup_button/default");
295         evas_object_smart_callback_add(btn2, "clicked", poweroff_response_yes_cb_min, ad);
296
297         Ecore_X_Window xwin;
298         xwin = elm_win_xwindow_get(ad->popup_poweroff);
299         ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
300         utilx_grab_key(ecore_x_display_get(), xwin, KEY_SELECT, SHARED_GRAB);
301         evas_object_show(ad->popup_poweroff);
302         vconf_notify_key_changed(VCONFKEY_PM_STATE, poweroff_popup_direct_cancel, ad);
303
304         return 0;
305 }
306
307 static void bg_noti_cb(void *data)
308 {
309         ui_bgimg_reload((Evas_Object *) data);
310 }
311
312 /* Create indicator bar */
313 static int poweroff_create_indicator(struct appdata *ad)
314 {
315
316         elm_win_indicator_mode_set(ad->win_main, ELM_WIN_INDICATOR_HIDE);
317         return 0;
318 }
319
320 /* Play vibration */
321 static int poweroff_play_vibration()
322 {
323
324         int ret_val = 0;
325         int dev_handle = 0;
326         int mode = 0;
327
328         /* Open the haptic device */
329         dev_handle = device_haptic_open(DEV_IDX_0, mode);
330         if (dev_handle < 0)
331                 return -1;
332
333         /* Play a monotone pattern for 1s */
334         ret_val = device_haptic_play_monotone(dev_handle, 1000);
335         device_haptic_close(dev_handle);
336         if (ret_val < 0)
337                 return -1;
338
339         return 0;
340
341 }
342
343 /* Start UI */
344 int poweroff_start(void *data)
345 {
346         struct appdata *ad = data;
347         int ret_val = 0;
348
349         /* Create and show popup */
350         ret_val = create_and_show_basic_popup_min(ad);
351         if (ret_val != 0)
352                 return -1;
353
354         /* Change LCD brightness */
355         ret_val = pm_change_state(LCD_NORMAL);
356         if (ret_val != 0)
357                 return -1;
358
359         /* Play a vibration for 1 sec */
360         ret_val = poweroff_play_vibration();
361         if (ret_val == -1)
362                 system_print("\n Poweroff : Play vibration Failed \n");
363
364         return 0;
365 }
366
367 /* App init */
368 int app_create(void *data)
369 {
370
371         Evas_Object *win;
372         struct appdata *ad = data;
373
374         /* Create window (Reqd for sys-popup) */
375         win = create_win(PACKAGE);
376         if (win == NULL)
377                 return -1;
378
379         ad->win_main = win;
380
381         elm_theme_overlay_add(NULL,EDJ_NAME); 
382
383         return 0;
384 }
385
386 int main(int argc, char *argv[])
387 {
388         struct appdata ad;
389
390         /* App life cycle management */
391         struct appcore_ops ops = {
392                 .create = app_create,
393                 .terminate = app_terminate,
394                 .pause = app_pause,
395                 .resume = app_resume,
396                 .reset = app_reset,
397         };
398
399         memset(&ad, 0x0, sizeof(struct appdata));
400         ops.data = &ad;
401
402         /* Go into loop */
403         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
404 }