Tizen release 1.0
[pkgs/p/phone-lock.git] / phone-lock-main / src / phone-lock.c
1 /*
2  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved 
3  *
4  * This file is part of <phone-lock>
5  * Written by <Seungtaek Chung> <seungtaek.chung@samsung.com>, <Mi-Ju Lee> <miju52.lee@samsung.com>, <Xi Zhichan> <zhichan.xi@samsung.com>
6  *
7  * PROPRIETARY/CONFIDENTIAL
8  *
9  * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").
10  * You shall not disclose such Confidential Information and shall use it only in accordance
11  * with the terms of the license agreement you entered into with SAMSUNG ELECTRONICS.
12  * SAMSUNG make no representations or warranties about the suitability of the software,
13  * either express or implied, including but not limited to the implied warranties of merchantability,
14  * fitness for a particular purpose, or non-infringement.
15  * SAMSUNG shall not be liable for any damages suffered by licensee as a result of using,
16  * modifying or distributing this software or its derivatives.
17  *
18  */
19
20 #include <stdio.h>
21 #include <appcore-efl.h>
22 #include <Ecore_X.h>
23 #include <vconf.h>
24 #include <utilX.h>
25 #include <ui-gadget.h>
26
27 #include "phone-lock.h"
28 #include "phone-lock-util.h"
29 #include "phone-lock-string.h"
30 #include "phone-lock-ui.h"
31
32 #define MENUSCREEN_PKG_NAME "db/menuscreen/pkgname"
33
34 struct state {
35         int (*_do) (struct appdata * ad);
36 };
37
38 static int do_ST_FIRST(struct appdata *ad);
39 static int do_ST_PHONE(struct appdata *ad);
40 static int do_ST_EXIT(struct appdata *ad);
41
42 static Eina_Bool _phone_lock_do_state(void *data);
43 static int _phone_lock_get_locked_status(void);
44 static void _phone_lock_set_unlock_state(struct appdata *ad);
45 static void _phone_lock_set_lock_state(struct appdata *ad);
46 static void _phone_lock_vconf_call_state_changed_cb(keynode_t * node,
47                                                     void *data);
48 static void _phone_lock_register_vconf(struct appdata *ad);
49 static void _phone_lock_unregister_vconf(struct appdata *ad);
50 static void _phone_lock_grab_key(Evas_Object * win);
51 static void _phone_lock_ungrab_key(Evas_Object * win);
52 static void _phone_lock_focus_out_cb(void *data, Evas_Object * obj,
53                                      void *event_info);
54 static int _phone_lock_low_battery_cb(void *data);
55
56 static struct state states[_ST_MAX] = {
57         {do_ST_FIRST,},
58         {do_ST_PHONE,},
59         {do_ST_EXIT,},
60 };
61
62 static inline void trans(struct appdata *ad, int state)
63 {
64         _DBG("trans state %d --> state %d", ad->state, state);
65         ad->state = state;
66
67 }
68
69 static int do_ST_FIRST(struct appdata *ad)
70 {
71         _DBG("%s", __func__);
72
73         trans(ad, _ST_PHONE);
74
75         return ECORE_CALLBACK_RENEW;
76 }
77
78 static int do_ST_PHONE(struct appdata *ad)
79 {
80         int r;
81
82         _DBG("%s", __func__);
83
84         r = _phone_lock_get_locked_status();
85         _DBG("r = %d, ad->running_status = %d, ad->window_status = %d, %s", r,
86              ad->running_status, ad->window_status, __func__);
87
88         if (r) {
89                 if (ad->running_status == 1 && ad->window_status == 0) {
90                         _phone_lock_set_lock_state(ad);
91                         phone_lock_show_alpha_ug(ad);
92                         trans(ad, _ST_EXIT);
93                         r = ECORE_CALLBACK_CANCEL;
94                 }
95         }
96         return r;
97 }
98
99 static int do_ST_EXIT(struct appdata *ad)
100 {
101         _DBG("%s", __func__);
102
103         elm_exit();
104         return ECORE_CALLBACK_CANCEL;
105 }
106
107 static Eina_Bool _phone_lock_do_state(void *data)
108 {
109         int r;
110         struct appdata *ad = data;
111
112         _DBG("%s, ad->state:%d", __func__, ad->state);
113
114         if (ad->state < _ST_FIRST || ad->state >= _ST_MAX) {
115                 _ERR("Unknown state: %d", ad->state);
116                 trans(ad, _ST_EXIT);
117                 r = ECORE_CALLBACK_RENEW;
118         } else
119                 r = states[ad->state]._do(ad);
120
121         if (r == ECORE_CALLBACK_CANCEL)
122                 ad->idler = NULL;
123
124         return r;
125 }
126
127 static int _phone_lock_get_locked_status(void)
128 {
129         int r;
130         int locked;
131
132         r = vconf_get_bool(VCONFKEY_SETAPPL_STATE_POWER_ON_LOCK_BOOL, &locked);
133         if (r) {
134                 _ERR("Get phone lock value error\n");
135                 locked = 0;
136         }
137
138         _DBG("phone_locked status: %d", locked);
139
140         return locked;
141 }
142
143 static void _phone_lock_set_unlock_state(struct appdata *ad)
144 {
145         if (ad->running_status > 0)
146                 vconf_set_int(VCONFKEY_PWLOCK_STATE,
147                               VCONFKEY_PWLOCK_RUNNING_UNLOCK);
148         else
149                 vconf_set_int(VCONFKEY_PWLOCK_STATE,
150                               VCONFKEY_PWLOCK_BOOTING_UNLOCK);
151 }
152
153 static void _phone_lock_set_lock_state(struct appdata *ad)
154 {
155         if (ad->running_status > 0)
156                 vconf_set_int(VCONFKEY_PWLOCK_STATE,
157                               VCONFKEY_PWLOCK_RUNNING_LOCK);
158         else
159                 vconf_set_int(VCONFKEY_PWLOCK_STATE,
160                               VCONFKEY_PWLOCK_BOOTING_LOCK);
161 }
162
163 static void _phone_lock_vconf_call_state_changed_cb(keynode_t * node,
164                                                     void *data)
165 {
166         int api_ret = 0;
167         int vconf_val = 0;
168         struct appdata *ad = data;
169
170         _DBG("%s", __func__);
171
172         api_ret = vconf_get_int(VCONFKEY_CALL_STATE, &vconf_val);
173         if (api_ret != 0) {
174                 _DBG("fail to get vconf key %s value", VCONFKEY_CALL_STATE);
175         } else {
176                 if (vconf_val == VCONFKEY_CALL_OFF) {
177                         _DBG("call off state..");
178                         phone_lock_set_win_prop(ad,
179                                                 ECORE_X_WINDOW_TYPE_NOTIFICATION);
180                 } else {
181                         _DBG("call on state..");
182                         phone_lock_set_win_prop(ad, ECORE_X_WINDOW_TYPE_NORMAL);
183                 }
184         }
185         return;
186 }
187
188 static void _phone_lock_register_vconf(struct appdata *ad)
189 {
190         _DBG("%s", __func__);
191         if (vconf_notify_key_changed
192             (VCONFKEY_CALL_STATE, _phone_lock_vconf_call_state_changed_cb,
193              ad) != 0) {
194                 _DBG("Fail to register");
195         }
196 }
197
198 static void _phone_lock_unregister_vconf(struct appdata *ad)
199 {
200         _DBG("%s", __func__);
201         if (vconf_ignore_key_changed
202             (VCONFKEY_CALL_STATE,
203              _phone_lock_vconf_call_state_changed_cb) != 0) {
204                 _DBG("Fail to unregister");
205         }
206 }
207
208 static void _phone_lock_grab_key(Evas_Object * win)
209 {
210         Ecore_X_Window w;
211
212         w = elm_win_xwindow_get(win);
213
214         utilx_grab_key(ecore_x_display_get(), w, KEY_SELECT, EXCLUSIVE_GRAB);
215         utilx_grab_key(ecore_x_display_get(), w, KEY_CAMERA, TOP_POSITION_GRAB);
216 }
217
218 static void _phone_lock_ungrab_key(Evas_Object * win)
219 {
220         Ecore_X_Window w;
221
222         w = elm_win_xwindow_get(win);
223
224         utilx_ungrab_key(ecore_x_display_get(), w, KEY_SELECT);
225         utilx_ungrab_key(ecore_x_display_get(), w, KEY_CAMERA);
226 }
227
228 static void _phone_lock_focus_out_cb(void *data, Evas_Object * obj,
229                                     void *event_info)
230 {
231         int pid = 0;
232         char buf[128];
233         Ecore_X_Window x_win_focused;
234         struct appdata *ad = data;
235
236         _DBG("%s", __func__);
237
238         x_win_focused = ecore_x_window_focus_get();
239         ecore_x_netwm_pid_get(x_win_focused, &pid);
240         if (aul_app_get_pkgname_bypid(pid, buf, sizeof(buf)) < 0) {
241                 _DBG("no such pkg by pid %d\n", pid);
242         } else {
243                 char *pkg_str;
244                 _DBG("created pkgname = %s, pid = %d\n", buf, pid);
245                 pkg_str = vconf_get_str(MENUSCREEN_PKG_NAME);
246                 if ((pkg_str != NULL)
247                     && !strncmp(pkg_str, buf, strlen(pkg_str))) {
248                         _DBG("%s is on the phone lock.!!\n", pkg_str);
249                         elm_win_raise(ad->win);
250                         free(pkg_str);
251                         pkg_str = NULL;
252                 } else
253                     if (!strncmp("org.tizen.live-magazine", buf, strlen(buf)))
254                 {
255                         _DBG("%s is on the phone lock.!!\n", buf);
256                         elm_win_raise(ad->win);
257                 }
258         }
259
260 }
261
262 static int _phone_lock_low_battery_cb(void *data)
263 {
264         _ERR("System battry goes low");
265         return 0;
266 }
267
268 static int _phone_lock_app_create(void *data)
269 {
270         struct appdata *ad = data;
271
272         _DBG("%s", __func__);
273
274         ad->win = phone_lock_create_win(PACKAGE);
275         if (ad->win == NULL) {
276                 _ERR("Create win error");
277                 return -1;
278         }
279
280         ecore_imf_init();
281         _phone_lock_grab_key(ad->win);
282         _phone_lock_register_vconf(ad);
283         phone_lock_set_win_prop(ad, ECORE_X_WINDOW_TYPE_NOTIFICATION);
284         evas_object_smart_callback_add(ad->win, "focus,out",
285                                        _phone_lock_focus_out_cb, ad);
286         appcore_set_i18n(PACKAGE, LOCALEDIR);
287         appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY,
288                                    _phone_lock_low_battery_cb, ad);
289
290         ad->state = _ST_FIRST;
291
292         return 0;
293 }
294
295 static int _phone_lock_app_terminate(void *data)
296 {
297         struct appdata *ad = data;
298
299         if (!ad) {
300                 return -1;
301         }
302         _DBG("\n ===============> %s\n", __func__);
303
304         _phone_lock_set_unlock_state(ad);
305         _phone_lock_unregister_vconf(ad);
306         _phone_lock_ungrab_key(ad->win);
307         ecore_imf_shutdown();
308
309         if (ad->idler) {
310                 ecore_idler_del(ad->idler);
311                 ad->idler = NULL;
312         }
313         if (ad->win) {
314                 evas_object_del(ad->win);
315                 ad->win = NULL;
316         }
317         _DBG("\n ===============> %s end!\n", __func__);
318         return 0;
319 }
320
321 static int _phone_lock_app_reset(bundle * b, void *data)
322 {
323         struct appdata *ad = data;
324
325         _DBG("%s", __func__);
326         char *svcname = NULL;
327
328         if(ad->state != _ST_FIRST) {
329                 if (ad->win)
330                         elm_win_activate(ad->win);
331                 return 0;
332         }
333
334         svcname = (char *)bundle_get_val(b, "pwlock_type");
335
336         if (svcname != NULL) {
337                 if (!strcmp(svcname, "running_lock")) {
338                         _DBG("%s : running_lock", __func__);
339                         ad->running_status = 1;
340                 } else if (!strcmp(svcname, "booting_lock")) {
341                         _DBG("%s : booting_lock", __func__);
342                         ad->running_status = 0;
343                 }
344         }
345
346         svcname = (char *)bundle_get_val(b, "window_type");
347
348         if (svcname != NULL) {
349                 if (!strcmp(svcname, "normal")) {
350                         _DBG("%s : running_lock", __func__);
351                         ad->window_status = 1;
352                 } else if (!strcmp(svcname, "alpha")) {
353                         _DBG("%s : booting_lock", __func__);
354                         ad->window_status = 0;
355                 }
356         }
357
358         phone_lock_do_state(ad);
359
360         if (ad->win)
361                 elm_win_activate(ad->win);
362
363         return 0;
364 }
365
366 void phone_lock_do_state(struct appdata *ad)
367 {
368         _DBG("%s", __func__);
369         if (ad->idler == NULL)
370                 ad->idler = ecore_idler_add(_phone_lock_do_state, ad);
371 }
372
373 void phone_lock_set_win_prop(struct appdata *ad, int type)
374 {
375         Ecore_X_Window w;
376
377         w = elm_win_xwindow_get(ad->win);
378
379         if (type == ECORE_X_WINDOW_TYPE_NORMAL) {
380                 ecore_x_netwm_window_type_set(w, ECORE_X_WINDOW_TYPE_NORMAL);
381                 ad->win_type = ECORE_X_WINDOW_TYPE_NORMAL;
382         } else if (type == ECORE_X_WINDOW_TYPE_NOTIFICATION) {
383                 ecore_x_netwm_window_type_set(w,
384                                               ECORE_X_WINDOW_TYPE_NOTIFICATION);
385                 utilx_set_system_notification_level(ecore_x_display_get(), w,
386                                                     UTILX_NOTIFICATION_LEVEL_NORMAL);
387                 ad->win_type = ECORE_X_WINDOW_TYPE_NOTIFICATION;
388         }
389 }
390
391 int main(int argc, char *argv[])
392 {
393         struct appdata ad;
394         struct appcore_ops ops = {
395                 .create = _phone_lock_app_create,
396                 .terminate = _phone_lock_app_terminate,
397                 .reset = _phone_lock_app_reset,
398         };
399
400         memset(&ad, 0x0, sizeof(struct appdata));
401
402         _DBG("\n\n========= phone lock is started..!! ===========\n");
403
404         ops.data = &ad;
405
406         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
407 }