[Other]Tizen 2.0 branch
[apps/core/preloaded/lockscreen.git] / src / simple-password.c
1 /*\r
2  * Copyright 2012  Samsung Electronics Co., Ltd\r
3  *\r
4  * Licensed under the Flora License, Version 1.0 (the License);\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *  http://www.tizenopensource.org/license\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an AS IS BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 #include <vconf.h>\r
18 \r
19 #include "lockscreen.h"\r
20 #include "util.h"\r
21 #include "log.h"\r
22 #include "password-verification.h"\r
23 \r
24 #define MAX_PASSWORD_NUM 4\r
25 #define PASSWORD_ATTEMPTS_MAX_NUM  5\r
26 #define VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT   VCONFKEY_SETAPPL_PREFIX"/phone_lock_attempts_left"\r
27 #define VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR       VCONFKEY_SETAPPL_PREFIX"/phone_lock_timestamp"\r
28 #define PASSWORD_TIMESTAMP_STR_LENGTH 512\r
29 #define PASSWORD_BLOCK_SECONDS        30\r
30 \r
31 static char simple_password[MAX_PASSWORD_NUM + 1] = {0};\r
32 static int simple_password_length = 0;\r
33 static Evas_Coord simple_pw_down_y = 0;\r
34 \r
35 static void __simple_password_password_show(struct appdata *ad)\r
36 {\r
37         char buf1[50] = {0};\r
38         char buf2[50] = {0};\r
39         int i = 1;\r
40 \r
41         for(i = 1; i <= simple_password_length; i++){\r
42                 snprintf(buf1, sizeof(buf1), "show,password%d", i);\r
43                 snprintf(buf2, sizeof(buf2), "password%d", i);\r
44                 edje_object_signal_emit(_EDJ(ad->ly_simple_password), buf1, buf2);\r
45         }\r
46         for(i = MAX_PASSWORD_NUM; i > simple_password_length; i--){\r
47                 snprintf(buf1, sizeof(buf1), "hide,password%d", i);\r
48                 snprintf(buf2, sizeof(buf2), "password%d", i);\r
49                 edje_object_signal_emit(_EDJ(ad->ly_simple_password), buf1, buf2);\r
50         }\r
51 }\r
52 \r
53 static void __simple_password_keypad_process(void *data, Evas_Object *obj, const char *emission, const char *source)\r
54 {\r
55         struct appdata *ad = data;\r
56 \r
57         LOCK_SCREEN_TRACE_DBG("source = %s", source);\r
58         if (strcmp("SOS", source) == 0) {\r
59         } else if (strcmp("Backspace", source) == 0) {\r
60                 if(simple_password_length <= 0){\r
61                         simple_password[0] = '\0';\r
62                         return;\r
63                 }\r
64                 simple_password_length--;\r
65                 simple_password[simple_password_length] = '\0';\r
66         } else {\r
67                 if(ad->is_disabled){\r
68                         return;\r
69                 }\r
70                 if(simple_password_length >= MAX_PASSWORD_NUM){\r
71                         return;\r
72                 }else {\r
73                         simple_password[simple_password_length] = *source;\r
74                         simple_password_length++;\r
75                 }\r
76 \r
77                 if(simple_password_length == MAX_PASSWORD_NUM){\r
78                         password_verification_verify(ad->h_password_policy, simple_password);\r
79                 }\r
80         }\r
81 \r
82         LOCK_SCREEN_TRACE_DBG("simple_password = %s, simple_password_length = %d", simple_password, simple_password_length);\r
83         __simple_password_password_show(ad);\r
84 }\r
85 \r
86 static void __simple_password_layout_destroy(void *data, Evas_Object *obj, const char *emission, const char *source)\r
87 {\r
88         struct appdata *ad = data;\r
89         int i = 0;\r
90         LOCK_SCREEN_TRACE_DBG("__simple_password_layout_destroy");\r
91 \r
92         for(i = 0; i <= MAX_PASSWORD_NUM; i++){\r
93                 simple_password[i] = 0;\r
94         }\r
95         simple_password_length = 0;\r
96         if (ad->password_timer) {\r
97                 ecore_timer_del(ad->password_timer);\r
98                 ad->password_timer = NULL;\r
99         }\r
100         if(ad->ly_simple_password){\r
101                 evas_object_del(ad->ly_simple_password);\r
102                 ad->ly_simple_password = NULL;\r
103         }\r
104         password_verification_policy_destroy(ad->h_password_policy);\r
105         lockscreen_info_show(ad);\r
106 }\r
107 \r
108 static void __simple_password_mouse_down_cb(void *data, Evas * evas, Evas_Object * obj,\r
109                             void *event_info)\r
110 {\r
111         Evas_Event_Mouse_Down *ei = event_info;\r
112 \r
113         simple_pw_down_y = ei->output.y;\r
114 \r
115         LOCK_SCREEN_TRACE_DBG("simple_pw_down_y = %d", simple_pw_down_y);\r
116 }\r
117 \r
118 static void __simple_password_mouse_up_cb(void *data, Evas * evas, Evas_Object * obj,\r
119                           void *event_info)\r
120 {\r
121         struct appdata *ad = data;\r
122         Evas_Event_Mouse_Down *ei = event_info;\r
123 \r
124         Evas_Coord pos_up_y = ei->output.y;\r
125 \r
126         if((pos_up_y - simple_pw_down_y) > _X(300)){\r
127                 edje_object_signal_emit(_EDJ(ad->ly_simple_password), "hide,numberkeyboard", "sw.keypad.number");\r
128                 edje_object_signal_callback_add(_EDJ(ad->ly_simple_password), "hide,simplepw", "event", __simple_password_layout_destroy, ad);\r
129         }\r
130 }\r
131 \r
132 static void __simple_password_mouse_move_cb(void *data, Evas * evas, Evas_Object * obj,\r
133                             void *event_info)\r
134 {\r
135         LOCK_SCREEN_TRACE_DBG("__simple_password_mouse_move_cb");\r
136 }\r
137 \r
138 void __simple_password_check_result(void *data)\r
139 {\r
140         struct appdata *ad = (struct appdata *) data;\r
141 \r
142         int value = -1;\r
143 \r
144         vconf_get_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT, &value);\r
145         value--;\r
146 \r
147         if (value > 0 && value <= PASSWORD_ATTEMPTS_MAX_NUM) {\r
148                 char temp_str[200] = {0};\r
149                 char temp_left[50] = {0};\r
150 \r
151                 vconf_set_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT,\r
152                               value);\r
153                 if(value == 1)\r
154                 {\r
155                         snprintf(temp_left, sizeof(temp_left), _L("1 attempt left."));\r
156                 }\r
157                 else\r
158                 {\r
159                         snprintf(temp_left, sizeof(temp_left), _L("%d attempts left."), value);\r
160                 }\r
161                 snprintf(temp_str, sizeof(temp_str), "%s, %s", _L("Wrong password"), temp_left);\r
162                 edje_object_part_text_set(_EDJ(ad->ly_simple_password), "txt.result", temp_str);\r
163         } else if (value == 0) {\r
164                 time_t cur_time = time(NULL);\r
165                 char cur_timestamp[64] = {0};\r
166                 char temp_str[512] = {0};\r
167 \r
168                 snprintf(cur_timestamp, sizeof(cur_timestamp), "%ld", cur_time);\r
169                 vconf_set_str(VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR, cur_timestamp);\r
170                 vconf_set_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT, value);\r
171                 ad->block_seconds = PASSWORD_BLOCK_SECONDS;\r
172 \r
173                 snprintf(temp_str, sizeof(temp_str), _L("Input password again after %d seconds."), ad->block_seconds);\r
174                 edje_object_part_text_set(_EDJ(ad->ly_simple_password), "txt.result", temp_str);\r
175         }\r
176 }\r
177 \r
178 static void __simple_password_check_result_cb (const char *event, void *data)\r
179 {\r
180         __simple_password_check_result(data);\r
181 }\r
182 \r
183 static void __simple_password_results_update(void *data)\r
184 {\r
185         int value = -1;\r
186         int ret = 0;\r
187 \r
188         struct appdata *ad = (struct appdata *) data;\r
189 \r
190         if (ad == NULL) {\r
191                 return;\r
192         }\r
193         LOCK_SCREEN_TRACE_DBG("%s", __FUNCTION__);\r
194 \r
195         ret =\r
196             vconf_get_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT,\r
197                           &value);\r
198 \r
199         if (ret != 0) {\r
200                 return;\r
201         }\r
202 \r
203         if (value == 0) {\r
204                 char timestamp_str[512] = {0};\r
205                 char *temp = NULL;\r
206                 int length = 0;\r
207                 int temp_length = 0;\r
208                 temp = vconf_get_str(VCONFKEY_SETAPPL_PASSWORD_TIMESTAMP_STR);\r
209                 temp_length = strlen(temp);\r
210                 length = (temp_length <= PASSWORD_TIMESTAMP_STR_LENGTH) ? temp_length : PASSWORD_TIMESTAMP_STR_LENGTH;\r
211                 strncpy(timestamp_str, temp, length);\r
212                 timestamp_str[length] = '\0';\r
213                 if ((strcmp(timestamp_str, "") != 0)\r
214                     || (strlen(timestamp_str) != 0)) {\r
215                         time_t cur_time = time(NULL);\r
216                         time_t last_lock_time;\r
217                         sscanf(timestamp_str, "%ld", &last_lock_time);\r
218 \r
219                         if ((cur_time - last_lock_time) < PASSWORD_BLOCK_SECONDS) {\r
220                                 ad->block_seconds = PASSWORD_BLOCK_SECONDS - (cur_time - last_lock_time);\r
221                                 LOCK_SCREEN_TRACE_DBG("ad->block_seconds = %d", ad->block_seconds);\r
222                                 ad->is_disabled = EINA_TRUE;\r
223                                 char temp_str[512] = {0};\r
224                                 snprintf(temp_str, sizeof(temp_str), _L("Input password again after %d seconds."), ad->block_seconds);\r
225                                 edje_object_part_text_set(_EDJ(ad->ly_simple_password), "txt.result", temp_str);\r
226                         } else {\r
227                                 ad->is_disabled = EINA_FALSE;\r
228                                 vconf_set_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT, PASSWORD_ATTEMPTS_MAX_NUM);\r
229                         }\r
230                 }\r
231         }\r
232 }\r
233 \r
234 static Eina_Bool __simple_password_results_update_cb(void *data)\r
235 {\r
236         __simple_password_results_update(data);\r
237         return EINA_TRUE;\r
238 }\r
239 \r
240 static void __simple_password_check_vconf_value(void *data)\r
241 {\r
242         int phone_lock_value = -1;\r
243         struct appdata *ad = (struct appdata *) data;\r
244 \r
245         if (ad == NULL) {\r
246                 return;\r
247         }\r
248         LOCK_SCREEN_TRACE_DBG("%s", __FUNCTION__);\r
249 \r
250         vconf_get_int(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT, &phone_lock_value);\r
251 \r
252         if (phone_lock_value == 0) {\r
253                 if (ad->password_timer) {\r
254                         return;\r
255                 }\r
256                 ad->password_timer = ecore_timer_add(1, (Ecore_Task_Cb)__simple_password_results_update_cb, ad);\r
257         } else {\r
258                 if (ad->password_timer) {\r
259                         ecore_timer_del(ad->password_timer);\r
260                         ad->password_timer = NULL;\r
261                 }\r
262                 ad->is_disabled = EINA_FALSE;\r
263         }\r
264 }\r
265 \r
266 static void __simple_password_check_vconf_value_cb(keynode_t * key, void *data)\r
267 {\r
268         __simple_password_check_vconf_value(data);\r
269 }\r
270 \r
271 void simple_password_layout_create(void *data)\r
272 {\r
273         struct appdata *ad = (struct appdata *)data;\r
274         if(ad == NULL){\r
275                 return;\r
276         }\r
277 \r
278         Evas_Object *keypad_layout = NULL;\r
279 \r
280         ad->h_password_policy = password_verification_policy_create();\r
281         password_verification_callback_set(ad->h_password_policy, __simple_password_check_result_cb, ad);\r
282         lockscreen_info_hide(ad);\r
283         ad->ly_simple_password = elm_layout_add(ad->ly_main);\r
284         elm_layout_file_set(ad->ly_simple_password, EDJEFILE, "lock-simple-password");\r
285         elm_object_part_content_set(ad->ly_main, "sw.phone-lock", ad->ly_simple_password);\r
286         edje_object_part_text_set(_EDJ(ad->ly_simple_password), "txt.title", _S("IDS_COM_BODY_ENTER_PASSWORD"));\r
287 \r
288         keypad_layout = elm_layout_add(ad->ly_simple_password);\r
289         elm_layout_file_set(keypad_layout, EDJEFILE, "lock-keypad-number");\r
290         elm_object_part_content_set(ad->ly_simple_password, "sw.keypad.number", keypad_layout);\r
291         edje_object_signal_emit(_EDJ(ad->ly_simple_password), "show,numberkeyboard", "sw.keypad.number");\r
292         edje_object_signal_callback_add(_EDJ(keypad_layout), "keypad_down_clicked", "*", __simple_password_keypad_process, ad);\r
293         evas_object_event_callback_add(ad->ly_simple_password, EVAS_CALLBACK_MOUSE_DOWN, __simple_password_mouse_down_cb, ad);\r
294         evas_object_event_callback_add(ad->ly_simple_password, EVAS_CALLBACK_MOUSE_MOVE, __simple_password_mouse_move_cb, ad);\r
295         evas_object_event_callback_add(ad->ly_simple_password, EVAS_CALLBACK_MOUSE_UP, __simple_password_mouse_up_cb, ad);\r
296         evas_object_show(keypad_layout);\r
297         vconf_notify_key_changed(VCONFKEY_SETAPPL_PASSWORD_ATTEMPTS_LEFT_INT, __simple_password_check_vconf_value_cb, ad);\r
298         __simple_password_check_vconf_value(ad);\r
299 }\r