[mobile] Fix logic to launch menu-screen at 64bit binary
[apps/native/starter.git] / src / mobile / lock_pwd_simple.c
1 /*
2  * Copyright (c) 2000 - 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 #include <Elementary.h>
18 #include <app_control.h>
19 #include <bundle.h>
20 #include <aul.h>
21 #include <security-manager.h>
22 #include <vconf.h>
23
24 #include "lock_mgr.h"
25 #include "util.h"
26 #include "status.h"
27 #include "lock_pwd_util.h"
28 #include "lock_pwd_simple.h"
29 #include "lock_pwd_control_panel.h"
30
31 #define DOT_TIME 1.5
32 #define CORRECT_TIME 0.2
33
34 static struct _s_lock_pwd_simple {
35         Evas_Object *pwd_simple_layout;
36         Ecore_Timer *timer_dot;
37
38         Eina_Bool is_blocked;
39
40         char pwd_simple[MAX_PASSWORD_NUM +1];
41         int pwd_simple_length;
42
43         Ecore_Timer *timer_correct;
44         Ecore_Timer *timer_pin;
45         int pin_time_remain;
46 } s_lock_pwd_simple = {
47         .pwd_simple_layout = NULL,
48         .timer_dot = NULL,
49
50         .is_blocked = EINA_FALSE,
51
52         .pwd_simple = { 0, },
53         .pwd_simple_length = 0,
54
55         .timer_correct = NULL,
56         .timer_pin = NULL,
57         .pin_time_remain = PASSWORD_BLOCK_SECONDS,
58 };
59
60
61
62 Eina_Bool lock_pwd_simple_is_blocked_get(void)
63 {
64         return s_lock_pwd_simple.is_blocked;
65 }
66
67
68
69
70 static void _pwd_simple_layout_title_set(const char *title)
71 {
72         ret_if(!s_lock_pwd_simple.pwd_simple_layout);
73         ret_if(!title);
74         elm_object_part_text_set(s_lock_pwd_simple.pwd_simple_layout, "title", title);
75 }
76
77
78
79 static void _pwd_simple_backspace(int length)
80 {
81         char buf[BUF_SIZE_32] = { 0, };
82         ret_if(!s_lock_pwd_simple.pwd_simple_layout);
83
84         snprintf(buf, sizeof(buf), "dot_hide%d", length);
85         elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, buf, "keyboard");
86         if (s_lock_pwd_simple.timer_dot) {
87                 ecore_timer_del(s_lock_pwd_simple.timer_dot);
88                 s_lock_pwd_simple.timer_dot = NULL;
89         }
90 }
91
92
93
94 static Eina_Bool _hide_dot_cb(void *data)
95 {
96         char buf[BUF_SIZE_32] = { 0, };
97         retv_if(!s_lock_pwd_simple.pwd_simple_layout, ECORE_CALLBACK_CANCEL);
98
99         snprintf(buf, sizeof(buf), "dot_show%d", (int)data);
100         elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, buf, "keyboard");
101         s_lock_pwd_simple.timer_dot = NULL;
102
103         return ECORE_CALLBACK_CANCEL;
104 }
105
106
107
108 static void _pwd_simple_input(int length, const char *text)
109 {
110         char part_buf[BUF_SIZE_32] = { 0, };
111         char signal_buf[BUF_SIZE_32] = { 0, };
112         ret_if(!s_lock_pwd_simple.pwd_simple_layout);
113
114         lock_mgr_sound_play(LOCK_SOUND_BTN_KEY);
115
116         snprintf(part_buf, sizeof(part_buf), "panel%d", length);
117         elm_object_part_text_set(s_lock_pwd_simple.pwd_simple_layout, part_buf, text);
118
119         snprintf(signal_buf, sizeof(signal_buf), "input_show%d", length);
120         elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, signal_buf, "keyboard");
121
122         if (length > 0) {
123                 snprintf(signal_buf, sizeof(signal_buf), "dot_show%d", length-1);
124                 elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, signal_buf, "keyboard");
125         }
126
127         if (s_lock_pwd_simple.timer_dot) {
128                 ecore_timer_del(s_lock_pwd_simple.timer_dot);
129                 s_lock_pwd_simple.timer_dot = NULL;
130         }
131
132         if (length < MAX_PASSWORD_NUM-1) {
133                 s_lock_pwd_simple.timer_dot = ecore_timer_add(DOT_TIME, _hide_dot_cb, (void *)length);
134         }
135 }
136
137
138
139 static void _pwd_simple_keypad_process(void *data, Evas_Object *obj, const char *emission, const char *source)
140 {
141         _D("%s", __func__);
142
143         if (s_lock_pwd_simple.is_blocked) {
144                 _E("blocked");
145                 lock_mgr_sound_play(LOCK_SOUND_BTN_KEY);
146                 return;
147         }
148
149         if (!strncmp("Backspace", source, strlen("Backspace"))) {
150                 _E("Backspace");
151                 lock_mgr_sound_play(LOCK_SOUND_BTN_KEY);
152                 ret_if(s_lock_pwd_simple.pwd_simple_length <= 0);
153                 _pwd_simple_backspace(--s_lock_pwd_simple.pwd_simple_length);
154         } else {
155                 if (s_lock_pwd_simple.pwd_simple_length >= MAX_PASSWORD_NUM) {
156                         _E("Too long");
157                         return;
158                 } else {
159                         s_lock_pwd_simple.pwd_simple[s_lock_pwd_simple.pwd_simple_length] = *source;
160                         _pwd_simple_input(s_lock_pwd_simple.pwd_simple_length++, source);
161                 }
162         }
163
164         if (s_lock_pwd_simple.pwd_simple_length == MAX_PASSWORD_NUM) {
165                 lock_pwd_event_e pwd_event = lock_pwd_verification_verify(s_lock_pwd_simple.pwd_simple);
166                 lock_pwd_simple_event(pwd_event);
167         }
168 }
169
170
171
172 Evas_Object *lock_pwd_simple_layout_create(void *data)
173 {
174         Evas_Object *parent = NULL;
175         Evas_Object *pwd_simple_layout = NULL;
176         Evas_Object *pwd_control_panel = NULL;
177
178         lock_pwd_verification_policy_create();
179
180         parent = (Evas_Object *)data;
181         retv_if(!parent, NULL);
182
183         pwd_simple_layout = elm_layout_add(parent);
184         goto_if(!pwd_simple_layout, ERROR);
185         s_lock_pwd_simple.pwd_simple_layout = pwd_simple_layout;
186
187         if (!elm_layout_file_set(pwd_simple_layout, LOCK_PWD_EDJE_FILE, "lock-simple-password")) {
188                 _E("Failed to set edje file : %s", LOCK_PWD_EDJE_FILE);
189                 goto ERROR;
190         }
191
192         evas_object_size_hint_weight_set(pwd_simple_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
193         evas_object_size_hint_align_set(pwd_simple_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
194         evas_object_show(pwd_simple_layout);
195
196         elm_object_signal_callback_add(pwd_simple_layout, "keypad_down_clicked", "*", _pwd_simple_keypad_process, NULL);
197         _pwd_simple_layout_title_set(_("IDS_COM_BODY_ENTER_PIN"));
198
199         /* create control panel */
200         pwd_control_panel = lock_pwd_control_panel_create(pwd_simple_layout);
201         if (!pwd_control_panel) {
202                 _E("Failed to create password control panel");
203         } else {
204                 elm_object_part_content_set(pwd_simple_layout, "control_panel", pwd_control_panel);
205         }
206
207         return pwd_simple_layout;
208
209 ERROR:
210         _E("Failed to create simple password layout");
211
212         if (pwd_simple_layout) {
213                 evas_object_del(pwd_simple_layout);
214                 s_lock_pwd_simple.pwd_simple_layout = NULL;
215         }
216
217         return NULL;
218 }
219
220
221
222 void lock_pwd_simple_layout_del(void)
223 {
224         if (s_lock_pwd_simple.pwd_simple_layout) {
225                 evas_object_del(s_lock_pwd_simple.pwd_simple_layout);
226                 s_lock_pwd_simple.pwd_simple_layout = NULL;
227         }
228
229         if (s_lock_pwd_simple.timer_dot) {
230                 ecore_timer_del(s_lock_pwd_simple.timer_dot);
231                 s_lock_pwd_simple.timer_dot = NULL;
232         }
233
234         if (s_lock_pwd_simple.timer_pin) {
235                 ecore_timer_del(s_lock_pwd_simple.timer_pin);
236                 s_lock_pwd_simple.timer_pin = NULL;
237         }
238 }
239
240
241
242 void lock_pwd_simple_entry_clear(void)
243 {
244         int i = 0;
245         char buf[BUF_SIZE_32] = { 0, };
246
247         ret_if(!s_lock_pwd_simple.pwd_simple_layout);
248
249         if (s_lock_pwd_simple.timer_dot) {
250                 ecore_timer_del(s_lock_pwd_simple.timer_dot);
251                 s_lock_pwd_simple.timer_dot = NULL;
252         }
253
254         for (i = 0; i <= 3; i++) {
255                 snprintf(buf, sizeof(buf), "dot_hide%d", i);
256                 elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, buf, "keyboard");
257         }
258         s_lock_pwd_simple.pwd_simple_length = 0;
259 }
260
261
262
263 static Eina_Bool _pwd_simple_entry_clear(void *data)
264 {
265         lock_pwd_simple_entry_clear();
266         return ECORE_CALLBACK_CANCEL;
267 }
268
269
270
271 static void _pwd_simple_event_incorrect(lock_pwd_event_e event)
272 {
273         char temp_str[BUF_SIZE_256] = { 0, };
274         char temp_left[BUF_SIZE_256] = { 0, };
275         int remain_attempt = 0;
276
277         remain_attempt = lock_pwd_verification_remain_attempt_get();
278         _D("remain_attempt(%d)", remain_attempt);
279
280         if (remain_attempt == 1) {
281                 strncpy(temp_left, _("IDS_IDLE_BODY_1_ATTEMPT_LEFT"), sizeof(temp_left));
282                 temp_left[sizeof(temp_left) - 1] = '\0';
283         } else {
284                 snprintf(temp_left, sizeof(temp_left), _("IDS_IDLE_BODY_PD_ATTEMPTS_LEFT"), remain_attempt);
285         }
286         snprintf(temp_str, sizeof(temp_str), "%s<br>%s", _("IDS_COM_BODY_INCORRECT_PIN"), temp_left);
287         _pwd_simple_layout_title_set(temp_str);
288
289         ecore_timer_add(0.1, _pwd_simple_entry_clear, NULL);
290
291         lock_pwd_verification_popup_create(event);
292 }
293
294
295
296 static Eina_Bool _pwd_correct_timer_cb(void *data)
297 {
298         lock_pwd_util_win_hide();
299         lock_pwd_simple_entry_clear();
300         _pwd_simple_layout_title_set(_("IDS_COM_BODY_ENTER_PIN"));
301
302         lock_mgr_idle_lock_state_set(VCONFKEY_IDLE_UNLOCK);
303         lock_mgr_sound_play(LOCK_SOUND_UNLOCK);
304
305         s_lock_pwd_simple.timer_correct = NULL;
306
307         return ECORE_CALLBACK_CANCEL;
308 }
309
310
311
312 static void _pwd_simple_event_correct(lock_pwd_event_e event)
313 {
314         if (s_lock_pwd_simple.timer_correct) {
315                 ecore_timer_del(s_lock_pwd_simple.timer_correct);
316         }
317
318         s_lock_pwd_simple.timer_correct = ecore_timer_add(CORRECT_TIME, _pwd_correct_timer_cb, NULL);
319         if(!s_lock_pwd_simple.timer_correct) {
320                 _E("Failed to add tiemr for correct password event");
321         }
322 }
323
324
325
326 static void _pwd_simple_lock_time_init(void)
327 {
328         if (vconf_set_str(VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR, "") < 0) {
329                 _E("Failed to set vconfkey : %s", VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR);
330         }
331 }
332
333
334
335 static void _pwd_simple_lock_time_save(void)
336 {
337         time_t cur_time = time(NULL);
338         char buf[64] = { 0, };
339         snprintf(buf, sizeof(buf), "%ld", cur_time);
340         if (vconf_set_str(VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR, buf) < 0) {
341                 _E("Failed to set vconfkey : %s", VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR);
342         }
343 }
344
345
346
347 static Eina_Bool _wrong_pwd_wait_timer_cb(void *data)
348 {
349         char try_again_buf[BUF_SIZE_256] = { 0, };
350         char incorrect_pass_buf[BUF_SIZE_256] = { 0, };
351
352         retv_if(!s_lock_pwd_simple.pwd_simple_layout, ECORE_CALLBACK_CANCEL);
353
354         snprintf(try_again_buf, sizeof(try_again_buf), _("IDS_LCKSCN_POP_TRY_AGAIN_IN_PD_SECONDS"), s_lock_pwd_simple.pin_time_remain);
355         snprintf(incorrect_pass_buf, sizeof(incorrect_pass_buf), "%s<br>%s", _("IDS_COM_BODY_INCORRECT_PIN"), try_again_buf);
356         _pwd_simple_layout_title_set(incorrect_pass_buf);
357
358         if (s_lock_pwd_simple.pin_time_remain == PASSWORD_BLOCK_SECONDS ||
359                         s_lock_pwd_simple.pin_time_remain > 0) {
360                 s_lock_pwd_simple.pin_time_remain--;
361                 return ECORE_CALLBACK_RENEW;
362         } else {
363                 lock_pwd_simple_view_init();
364
365                 int lcd_state = lock_mgr_lcd_state_get();
366                 if (lcd_state == LCD_STATE_OFF) {
367                         if (!lock_mgr_lockscreen_launch()) {
368                                 _E("Failed to launch lockscreen");
369                         }
370                 }
371         }
372
373         return ECORE_CALLBACK_CANCEL;
374 }
375
376
377
378 static void _pwd_simple_event_input_block(lock_pwd_event_e event)
379 {
380         _D("%s", __func__);
381
382         int block_sec = PASSWORD_BLOCK_SECONDS;
383         char try_again_buf[200] = { 0, };
384         char incorrect_pass_buf[200] = { 0, };
385
386         ret_if(!s_lock_pwd_simple.pwd_simple_layout);
387
388         _pwd_simple_lock_time_save();
389
390         snprintf(try_again_buf, sizeof(try_again_buf), _("IDS_LCKSCN_POP_TRY_AGAIN_IN_PD_SECONDS"), block_sec);
391         snprintf(incorrect_pass_buf, sizeof(incorrect_pass_buf), "%s<br>%s", _("IDS_COM_BODY_INCORRECT_PIN"), try_again_buf);
392         _pwd_simple_layout_title_set(incorrect_pass_buf);
393
394         s_lock_pwd_simple.is_blocked = EINA_TRUE;
395
396         if (s_lock_pwd_simple.timer_pin) {
397                 ecore_timer_del(s_lock_pwd_simple.timer_pin);
398                 s_lock_pwd_simple.timer_pin = NULL;
399         }
400
401         s_lock_pwd_simple.timer_pin = ecore_timer_add(1.0, _wrong_pwd_wait_timer_cb, NULL);
402
403         ecore_timer_add(0.1, _pwd_simple_entry_clear, NULL);
404
405         lock_pwd_verification_popup_create(event);
406
407         lock_pwd_control_panel_cancel_btn_enable_set(EINA_FALSE);
408 }
409
410
411
412 void lock_pwd_simple_event(lock_pwd_event_e event)
413 {
414         switch(event) {
415         case PWD_EVENT_CORRECT:
416                 _pwd_simple_event_correct(event);
417                 break;
418         case PWD_EVENT_INCORRECT_WARNING:
419         case PWD_EVENT_INCORRECT:
420                 _pwd_simple_event_incorrect(event);
421                 break;
422         case PWD_EVENT_INPUT_BLOCK_WARNING:
423         case PWD_EVENT_INPUT_BLOCK:
424                 _pwd_simple_event_input_block(event);
425                 break;
426         case PWD_EVENT_EMPTY:
427                 break;
428         case PWD_EVENT_OVER:
429                 break;
430         default:
431                 break;
432         }
433 }
434
435 void lock_pwd_simple_view_init(void)
436 {
437         _D("initialize simpel password values");
438         s_lock_pwd_simple.pin_time_remain = PASSWORD_BLOCK_SECONDS;
439
440         _pwd_simple_layout_title_set(_("IDS_COM_BODY_ENTER_PIN"));
441         elm_object_signal_emit(s_lock_pwd_simple.pwd_simple_layout, "show_title", "title");
442         s_lock_pwd_simple.is_blocked = EINA_FALSE;
443
444         lock_pwd_simple_entry_clear();
445
446         _pwd_simple_lock_time_init();
447
448         lock_pwd_control_panel_cancel_btn_enable_set(EINA_TRUE);
449 }