Change keygrab logic : add ecore timer -> check global added & keymap update flags
[apps/native/starter.git] / src / mobile / hw_key.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 #ifdef HAVE_X11
18
19 #include <app.h>
20 #include <bundle.h>
21 #include <Elementary.h>
22 #include <Ecore_X.h>
23 #include <Ecore_Input.h>
24 #include <dd-deviced.h>
25 #include <syspopup_caller.h>
26 #include <utilX.h>
27 #include <vconf.h>
28 #include <system/media_key.h>
29 #include <aul.h>
30 #include <feedback.h>
31 #include <system_settings.h>
32
33 #include "hw_key.h"
34 #include "home_mgr.h"
35 #include "util.h"
36 #include "dbus_util.h"
37 #include "lock_mgr.h"
38 #include "status.h"
39 #include "process_mgr.h"
40
41 #define APPID_CAMERA "org.tizen.camera-app"
42 #define APPID_CALLLOG "org.tizen.calllog"
43 #define APPID_MUSIC_PLAYER "org.tizen.music-player"
44 #define APPID_TASKMGR "org.tizen.task-mgr"
45 #define APPID_BROWSER "org.tizen.browser"
46 #define APPID_EMAIL "org.tizen.email"
47 #define APPID_DIALER "org.tizen.phone"
48
49 #define STR_ATOM_XKEY_COMPOSITION "_XKEY_COMPOSITION"
50 #define STR_ATOM_KEYROUTER_NOTIWINDOW "_KEYROUTER_NOTIWINDOW"
51
52 #define LONG_PRESS_TIMER_SEC 0.4
53 #define HOMEKEY_TIMER_SEC 0.2
54 #define CANCEL_KEY_TIMER_SEC 0.3
55
56 static struct {
57         Ecore_X_Window win;
58         Ecore_Event_Handler *key_up;
59         Ecore_Event_Handler *key_down;
60         Ecore_Timer *home_long_press_timer;
61         Ecore_Timer *home_multi_press_timer;
62         Eina_Bool cancel;
63         Ecore_X_Window keyrouter_notiwindow;
64         int homekey_count;
65 } key_info = {
66         .win = 0x0,
67         .key_up = NULL,
68         .key_down = NULL,
69         .home_long_press_timer = NULL,
70         .home_multi_press_timer = NULL,
71         .cancel = EINA_FALSE,
72         .keyrouter_notiwindow = 0x0,
73         .homekey_count = 0,
74 };
75
76
77
78 static void _after_launch_taskmgr(int pid)
79 {
80         if(0 < pid) {
81                 if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
82                         _E("failed to send oom dbus signal");
83                 }
84         }
85 }
86
87
88
89 static Eina_Bool _launch_taskmgr_cb(void* data)
90 {
91         int val = -1;
92
93         _D("Launch TASKMGR");
94
95         key_info.home_long_press_timer = NULL;
96
97         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
98                 _E("Cannot get VCONFKEY for lock state");
99         } else if (VCONFKEY_IDLE_LOCK == val) {
100                 _E("lock state, ignore home key long press..!!");
101                 return ECORE_CALLBACK_CANCEL;
102         }
103
104         process_mgr_must_launch(APPID_TASKMGR, NULL, NULL, NULL, _after_launch_taskmgr);
105
106         return ECORE_CALLBACK_CANCEL;
107 }
108
109
110
111 static void _release_multimedia_key(const char *value)
112 {
113         ret_if(NULL == value);
114         _D("Multimedia key is released with %s", value);
115         process_mgr_must_launch(APPID_MUSIC_PLAYER, "multimedia_key", value, NULL, NULL);
116 }
117
118
119
120 #define HOME_OP_KEY "__HOME_OP__"
121 #define HOME_OP_VAL_LAUNCH_BY_HOME_KEY "__LAUNCH_BY_HOME_KEY__"
122 static Eina_Bool _launch_by_home_key(void *data)
123 {
124         if (status_passive_get()->idle_lock_state > VCONFKEY_IDLE_UNLOCK) {
125                 return ECORE_CALLBACK_CANCEL;
126         }
127
128         home_mgr_open_home(NULL, HOME_OP_KEY, HOME_OP_VAL_LAUNCH_BY_HOME_KEY);
129
130         return ECORE_CALLBACK_CANCEL;
131 }
132
133
134
135 static Eina_Bool _home_multi_press_timer_cb(void *data)
136 {
137         _W("homekey count[%d]", key_info.homekey_count);
138
139         key_info.home_multi_press_timer = NULL;
140
141         if (0 == key_info.homekey_count % 2) {
142                 key_info.homekey_count = 0;
143                 return ECORE_CALLBACK_CANCEL;
144         } else if(key_info.homekey_count >= 3) {
145                 key_info.homekey_count = 0;
146                 return ECORE_CALLBACK_CANCEL;
147         }
148
149         /* Single homekey operation */
150         key_info.homekey_count = 0;
151         _launch_by_home_key(data);
152
153         return ECORE_CALLBACK_CANCEL;
154
155 }
156
157
158
159 #define SERVICE_OPERATION_POPUP_SEARCH "http://samsung.com/appcontrol/operation/search"
160 #define SEARCH_PKG_NAME "org.tizen.sfinder"
161 static int _launch_search(void)
162 {
163         app_control_h app_control;
164         int ret = APP_CONTROL_ERROR_NONE;
165
166         app_control_create(&app_control);
167         app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
168         app_control_set_app_id(app_control, SEARCH_PKG_NAME);
169
170         ret = app_control_send_launch_request(app_control, NULL, NULL);
171
172         if(ret != APP_CONTROL_ERROR_NONE) {
173                 _E("Cannot launch search!! err[%d]", ret);
174         }
175
176         app_control_destroy(app_control);
177         return ret;
178 }
179
180
181
182 static void _cancel_key_events(void)
183 {
184         key_info.homekey_count = 0;
185
186         if (key_info.home_long_press_timer) {
187                 ecore_timer_del(key_info.home_long_press_timer);
188                 key_info.home_long_press_timer = NULL;
189         }
190
191         if(key_info.home_multi_press_timer) {
192                 ecore_timer_del(key_info.home_multi_press_timer);
193                 key_info.home_multi_press_timer = NULL;
194         }
195 }
196
197
198
199 static Eina_Bool _key_release_cb(void *data, int type, void *event)
200 {
201         Evas_Event_Key_Up *ev = event;
202
203         retv_if(!ev, ECORE_CALLBACK_RENEW);
204         retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
205
206         _D("_key_release_cb : %s Released", ev->keyname);
207
208         /* Priority 1 : Cancel event */
209         if (!strcmp(ev->keyname, KEY_CANCEL)) {
210                 _D("CANCEL Key is released");
211                 key_info.cancel = EINA_FALSE;
212                 return ECORE_CALLBACK_RENEW;
213         }
214
215         if (EINA_TRUE == key_info.cancel) {
216                 _D("CANCEL is on");
217                 return ECORE_CALLBACK_RENEW;
218         }
219
220         /* Priority 2 : Execute before checking the lock status */
221         if (!strcmp(ev->keyname, KEY_MEDIA)) {
222                 _release_multimedia_key("KEY_PLAYCD");
223                 return ECORE_CALLBACK_RENEW;
224         }
225
226         /* Priority 3 : Check the lock status */
227         if ((status_passive_get()->idle_lock_state  == VCONFKEY_IDLE_LOCK)
228                 && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
229                 _D("phone lock state, ignore home key.");
230                 return ECORE_CALLBACK_RENEW;
231         }
232
233         /* Priority 4 : These keys are only activated after checking the lock state */
234         if (!strcmp(ev->keyname, KEY_END)) {
235         } else if (!strcmp(ev->keyname, KEY_CONFIG)) {
236         } else if (!strcmp(ev->keyname, KEY_SEND)) {
237         } else if (!strcmp(ev->keyname, KEY_HOME)) {
238                 _W("Home Key is released");
239
240                 syspopup_destroy_all();
241
242                 if(key_info.home_multi_press_timer) {
243                         _D("delete homekey timer");
244                         ecore_timer_del(key_info.home_multi_press_timer);
245                         key_info.home_multi_press_timer = NULL;
246                 }
247
248                 if (key_info.home_long_press_timer) {
249                         ecore_timer_del(key_info.home_long_press_timer);
250                         key_info.home_long_press_timer = NULL;
251                 } else {
252                         key_info.homekey_count = 0;
253                         return ECORE_CALLBACK_RENEW;
254                 }
255
256                 key_info.home_multi_press_timer = ecore_timer_add(HOMEKEY_TIMER_SEC, _home_multi_press_timer_cb, NULL);
257                 if (!key_info.home_multi_press_timer) {
258                         _E("Critical! cannot add a timer for home multi press");
259                 }
260                 return ECORE_CALLBACK_RENEW;
261         } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
262         } else if (!strcmp(ev->keyname, KEY_APPS)) {
263                 _D("App tray key is released");
264         } else if (!strcmp(ev->keyname, KEY_TASKSWITCH)) {
265                 _D("Task switch key is released");
266                 _launch_taskmgr_cb(NULL);
267         } else if (!strcmp(ev->keyname, KEY_WEBPAGE)) {
268                 _D("Web page key is released");
269                 process_mgr_must_open(APPID_BROWSER, NULL, NULL);
270         } else if (!strcmp(ev->keyname, KEY_MAIL)) {
271                 _D("Mail key is released");
272                 process_mgr_must_open(APPID_EMAIL, NULL, NULL);
273         } else if (!strcmp(ev->keyname, KEY_CONNECT)) {
274                 _D("Connect key is released");
275                 process_mgr_must_open(APPID_DIALER, NULL, NULL);
276         } else if (!strcmp(ev->keyname, KEY_SEARCH)) {
277                 _D("Search key is released");
278                 if (_launch_search() < 0) {
279                         _E("Failed to launch the search");
280                 }
281         } else if (!strcmp(ev->keyname, KEY_VOICE)) {
282                 _D("Voice key is released");
283         }
284
285         return ECORE_CALLBACK_RENEW;
286 }
287
288
289
290 static Eina_Bool _key_press_cb(void *data, int type, void *event)
291 {
292         Evas_Event_Key_Down *ev = event;
293
294         retv_if(!ev, ECORE_CALLBACK_RENEW);
295         retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
296
297         _D("_key_press_cb : %s Pressed", ev->keyname);
298
299         /* Priority 1 : Cancel */
300         /* every reserved events have to be canceld when cancel key is pressed */
301         if (!strcmp(ev->keyname, KEY_CANCEL)) {
302                 _D("Cancel button is pressed");
303                 key_info.cancel = EINA_TRUE;
304                 _cancel_key_events();
305                 return ECORE_CALLBACK_RENEW;
306         }
307
308         if (EINA_TRUE == key_info.cancel) {
309                 _D("CANCEL is on");
310                 return ECORE_CALLBACK_RENEW;
311         }
312
313         /* Priority 2 : Check the lock status */
314         if ((status_passive_get()->idle_lock_state == VCONFKEY_IDLE_LOCK)
315                 && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
316                 _D("phone lock state, ignore key events.");
317                 _cancel_key_events();
318                 return ECORE_CALLBACK_RENEW;
319         }
320
321         /* Priority 3 : other keys */
322         if (!strcmp(ev->keyname, KEY_SEND)) {
323                 _D("Launch calllog");
324                 process_mgr_must_open(APPID_CALLLOG, NULL, NULL);
325         } else if(!strcmp(ev->keyname, KEY_CONFIG)) {
326                 _D("Launch camera");
327                 process_mgr_must_open(APPID_CAMERA, NULL, NULL);
328         } else if (!strcmp(ev->keyname, KEY_HOME)) {
329                 _W("Home Key is pressed");
330                 if (key_info.home_long_press_timer) {
331                         ecore_timer_del(key_info.home_long_press_timer);
332                         key_info.home_long_press_timer = NULL;
333                 }
334
335                 key_info.homekey_count++;
336                 _W("homekey count : %d", key_info.homekey_count);
337
338                 if(key_info.home_multi_press_timer) {
339                         ecore_timer_del(key_info.home_multi_press_timer);
340                         key_info.home_multi_press_timer = NULL;
341                         _D("delete homekey timer");
342                 }
343
344                 _D("create long press timer");
345                 key_info.home_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _launch_taskmgr_cb, NULL);
346                 if (!key_info.home_long_press_timer) {
347                         _E("Failed to add timer for long press detection");
348                 }
349         } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
350                 _D("Media key is pressed");
351         } else if (!strcmp(ev->keyname, KEY_APPS)) {
352                 _D("App tray key is pressed");
353         } else if (!strcmp(ev->keyname, KEY_TASKSWITCH)) {
354                 _D("Task switch key is pressed");
355         } else if (!strcmp(ev->keyname, KEY_WEBPAGE)) {
356                 _D("Web page key is pressed");
357         } else if (!strcmp(ev->keyname, KEY_MAIL)) {
358                 _D("Mail key is pressed");
359         } else if (!strcmp(ev->keyname, KEY_SEARCH)) {
360                 _D("Search key is pressed");
361         } else if (!strcmp(ev->keyname, KEY_VOICE)) {
362                 _D("Voice key is pressed");
363         } else if (!strcmp(ev->keyname, KEY_CONNECT)) {
364                 _D("Connect key is pressed");
365         }
366
367         return ECORE_CALLBACK_RENEW;
368 }
369
370
371
372 void _media_key_event_cb(media_key_e key, media_key_event_e status, void *user_data)
373 {
374         _D("MEDIA KEY EVENT : %d", key);
375         if (MEDIA_KEY_STATUS_PRESSED == status) return;
376
377         switch (key) {
378         case MEDIA_KEY_PAUSE:
379                 _release_multimedia_key("KEY_PAUSECD");
380                 break;
381         case MEDIA_KEY_PLAY:
382                 _release_multimedia_key("KEY_PLAYCD");
383                 break;
384         case MEDIA_KEY_PLAYPAUSE:
385                 _release_multimedia_key("KEY_PLAYPAUSECD");
386                 break;
387         default:
388                 _E("cannot reach here, key[%d]", key);
389                 break;
390         }
391 }
392
393
394
395 void hw_key_create_window(void)
396 {
397         int ret;
398         Ecore_X_Atom atomNotiWindow;
399         Ecore_X_Window keyrouter_notiwindow;
400
401         key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
402         if (!key_info.win) {
403                 _D("Failed to create hidden window");
404                 return;
405         }
406         ecore_x_event_mask_unset(key_info.win, ECORE_X_EVENT_MASK_NONE);
407         ecore_x_icccm_title_set(key_info.win, "menudaemon,key,receiver");
408         ecore_x_netwm_name_set(key_info.win, "menudaemon,key,receiver");
409         ecore_x_netwm_pid_set(key_info.win, getpid());
410
411         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_HOME, SHARED_GRAB);
412         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN, SHARED_GRAB);
413         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP, SHARED_GRAB);
414         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG, SHARED_GRAB);
415         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA, SHARED_GRAB);
416         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_APPS, SHARED_GRAB);
417         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_TASKSWITCH, SHARED_GRAB);
418         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_WEBPAGE, SHARED_GRAB);
419         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MAIL, SHARED_GRAB);
420         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_SEARCH, SHARED_GRAB);
421         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOICE, SHARED_GRAB);
422         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONNECT, SHARED_GRAB);
423         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_POWER, SHARED_GRAB);
424
425         key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
426         if (!key_info.key_up)
427                 _E("Failed to register a key up event handler");
428
429         key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
430         if (!key_info.key_down)
431                 _E("Failed to register a key down event handler");
432
433         /* Get notifwindow */
434         atomNotiWindow = ecore_x_atom_get(STR_ATOM_KEYROUTER_NOTIWINDOW);
435         ret = ecore_x_window_prop_window_get(ecore_x_window_root_first_get(), atomNotiWindow, &keyrouter_notiwindow, 1);
436         if (ret > 0) {
437                 _D("Succeed to get keyrouter notiwindow ! ret = %d (win=0x%x)\n"
438                                 , ret, keyrouter_notiwindow);
439                 ecore_x_window_sniff(keyrouter_notiwindow);
440                 key_info.keyrouter_notiwindow = keyrouter_notiwindow;
441         } else {
442                 _E("Failed to get keyrouter notiwindow! ret = %d, atomNotiWindow = 0x%x, keyrouter_notiwindow = 0x%x"
443                                 , ret, atomNotiWindow, keyrouter_notiwindow);
444         }
445
446         media_key_reserve(_media_key_event_cb, NULL);
447 }
448
449
450
451 void hw_key_destroy_window(void)
452 {
453         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_HOME);
454         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN);
455         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP);
456         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG);
457         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA);
458         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_APPS);
459         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_TASKSWITCH);
460         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_WEBPAGE);
461         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MAIL);
462         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_SEARCH);
463         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOICE);
464         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONNECT);
465
466         if (key_info.key_up) {
467                 ecore_event_handler_del(key_info.key_up);
468                 key_info.key_up = NULL;
469         }
470
471         if (key_info.key_down) {
472                 ecore_event_handler_del(key_info.key_down);
473                 key_info.key_down = NULL;
474         }
475
476         ecore_x_window_delete_request_send(key_info.win);
477         key_info.win = 0x0;
478
479         media_key_release();
480 }
481
482 #elif HAVE_WAYLAND
483
484 #include <app.h>
485 #include <bundle.h>
486 #include <Elementary.h>
487 #include <Ecore.h>
488 #include <Ecore_Wayland.h>
489 #include <Ecore_Input.h>
490 #include <dd-deviced.h>
491 #include <syspopup_caller.h>
492 #include <vconf.h>
493 #include <system/media_key.h>
494 #include <aul.h>
495 #include <feedback.h>
496 #include <system_settings.h>
497
498 #include "hw_key.h"
499 #include "home_mgr.h"
500 #include "util.h"
501 #include "dbus_util.h"
502 #include "lock_mgr.h"
503 #include "status.h"
504 #include "process_mgr.h"
505
506 #define APPID_CAMERA "org.tizen.camera-app"
507 #define APPID_CALLLOG "org.tizen.calllog"
508 #define APPID_MUSIC_PLAYER "org.tizen.music-player"
509 #define APPID_TASKMGR "org.tizen.task-mgr"
510 #define APPID_BROWSER "org.tizen.browser"
511 #define APPID_EMAIL "org.tizen.email"
512 #define APPID_DIALER "org.tizen.phone"
513
514 #define STR_ATOM_KEYROUTER_NOTIWINDOW "_KEYROUTER_NOTIWINDOW"
515
516 #define LONG_PRESS_TIMER_SEC 0.4
517 #define HOMEKEY_TIMER_SEC 0.2
518 #define CANCEL_KEY_TIMER_SEC 0.3
519
520
521 const char *key_name[KEY_NAME_MAX] = {
522         "XF86AudioRaiseVolume",
523         "XF86AudioLowerVolume",
524         "XF86PowerOff",
525         "XF86Menu",
526         "XF86Home",
527         "XF86Back",
528         "XF86Camera",
529         "XF86Camera_Full",
530         "XF86Search",
531         "XF86AudioPlay",
532         "XF86AudioPause",
533         "XF86AudioStop",
534         "XF86AudioNext",
535         "XF86AudioPrev",
536         "XF86AudioRewind",
537         "XF86AudioForward",
538         "XF86AudioMedia",
539         "XF86AudioPlayPause",
540         "XF86AudioMute",
541         "XF86AudioRecord",
542         "Cancel",
543         "XF86SoftKBD",
544         "XF86QuickPanel",
545         "XF86TaskPane",
546         "XF86HomePage",
547         "XF86WWW",
548         "XF86Mail",
549         "XF86ScreenSaver",
550         "XF86MonBrightnessDown",
551         "XF86MonBrightnessUp",
552         "XF86Voice",
553         "Hangul",
554         "XF86Apps",
555         "XF86Call",
556         "XF86Game",
557         "XF86VoiceWakeUp_LPSD",
558         "XF86VoiceWakeUp",
559 };
560
561
562 static struct {
563         Ecore_Event_Handler *key_up;
564         Ecore_Event_Handler *key_down;
565         Ecore_Event_Handler *global_added;
566         Ecore_Event_Handler *keymap_update;
567         Ecore_Timer *home_long_press_timer;
568         Ecore_Timer *home_multi_press_timer;
569         Eina_Bool cancel;
570         Eina_Bool keymap_update_flag;
571         Eina_Bool global_added_flag;
572         int homekey_count;
573 } key_info = {
574         .key_up = NULL,
575         .key_down = NULL,
576         .global_added = NULL,
577         .keymap_update = NULL,
578         .home_long_press_timer = NULL,
579         .home_multi_press_timer = NULL,
580         .cancel = EINA_FALSE,
581         .keymap_update_flag = EINA_FALSE,
582         .global_added_flag = EINA_FALSE,
583         .homekey_count = 0,
584 };
585
586
587
588 static void _destroy_precondition_handlers_for_keygrab(void);
589
590
591
592 static void _cancel_key_events(void)
593 {
594         key_info.homekey_count = 0;
595
596         if (key_info.home_long_press_timer) {
597                 ecore_timer_del(key_info.home_long_press_timer);
598                 key_info.home_long_press_timer = NULL;
599         }
600
601         if(key_info.home_multi_press_timer) {
602                 ecore_timer_del(key_info.home_multi_press_timer);
603                 key_info.home_multi_press_timer = NULL;
604         }
605 }
606
607
608
609 #define SERVICE_OPERATION_POPUP_SEARCH "http://samsung.com/appcontrol/operation/search"
610 #define SEARCH_PKG_NAME "org.tizen.sfinder"
611 static int _launch_search(void)
612 {
613         app_control_h app_control;
614         int ret = APP_CONTROL_ERROR_NONE;
615
616         app_control_create(&app_control);
617         app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
618         app_control_set_app_id(app_control, SEARCH_PKG_NAME);
619
620         ret = app_control_send_launch_request(app_control, NULL, NULL);
621
622         if(ret != APP_CONTROL_ERROR_NONE) {
623                 _E("Cannot launch search!! err[%d]", ret);
624         }
625
626         app_control_destroy(app_control);
627         return ret;
628 }
629
630
631
632 static void _after_launch_taskmgr(int pid)
633 {
634         if(0 < pid) {
635                 if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
636                         _E("failed to send oom dbus signal");
637                 }
638         }
639 }
640
641
642
643 static Eina_Bool _launch_taskmgr_cb(void* data)
644 {
645         int val = -1;
646
647         _D("Launch TASKMGR");
648
649         key_info.home_long_press_timer = NULL;
650
651         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
652                 _E("Cannot get VCONFKEY for lock state");
653         } else if (VCONFKEY_IDLE_LOCK == val) {
654                 _E("lock state, ignore home key long press..!!");
655                 return ECORE_CALLBACK_CANCEL;
656         }
657
658         process_mgr_must_launch(APPID_TASKMGR, NULL, NULL, NULL, _after_launch_taskmgr);
659
660         return ECORE_CALLBACK_CANCEL;
661 }
662
663
664
665 #define HOME_OP_KEY "__HOME_OP__"
666 #define HOME_OP_VAL_LAUNCH_BY_HOME_KEY "__LAUNCH_BY_HOME_KEY__"
667 static Eina_Bool _launch_by_home_key(void *data)
668 {
669         if (status_passive_get()->idle_lock_state > VCONFKEY_IDLE_UNLOCK) {
670                 return ECORE_CALLBACK_CANCEL;
671         }
672
673         home_mgr_open_home(NULL, HOME_OP_KEY, HOME_OP_VAL_LAUNCH_BY_HOME_KEY);
674
675         return ECORE_CALLBACK_CANCEL;
676 }
677
678
679
680 static Eina_Bool _home_multi_press_timer_cb(void *data)
681 {
682         _W("homekey count[%d]", key_info.homekey_count);
683
684         key_info.home_multi_press_timer = NULL;
685
686         if (0 == key_info.homekey_count % 2) {
687                 key_info.homekey_count = 0;
688                 return ECORE_CALLBACK_CANCEL;
689         } else if(key_info.homekey_count >= 3) {
690                 key_info.homekey_count = 0;
691                 return ECORE_CALLBACK_CANCEL;
692         }
693
694         /* Single homekey operation */
695         key_info.homekey_count = 0;
696         _launch_by_home_key(data);
697
698         return ECORE_CALLBACK_CANCEL;
699
700 }
701
702
703
704 static void _release_multimedia_key(const char *value)
705 {
706         ret_if(NULL == value);
707         _D("Multimedia key is released with %s", value);
708         process_mgr_must_launch(APPID_MUSIC_PLAYER, "multimedia_key", value, NULL, NULL);
709 }
710
711
712
713 static Eina_Bool _key_release_cb(void *data, int type, void *event)
714 {
715         Evas_Event_Key_Up *ev = event;
716
717         retv_if(!ev, ECORE_CALLBACK_RENEW);
718         retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
719
720         _D("_key_release_cb : %s Released", ev->keyname);
721
722         /* Priority 1 : Cancel event */
723         if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
724                 _D("CANCEL Key is released");
725                 key_info.cancel = EINA_FALSE;
726                 return ECORE_CALLBACK_RENEW;
727         }
728
729         if (EINA_TRUE == key_info.cancel) {
730                 _D("CANCEL is on");
731                 return ECORE_CALLBACK_RENEW;
732         }
733
734         /* Priority 2 : Execute before checking the lock status */
735         if (!strcmp(ev->keyname, key_name[KEY_MEDIA])) {
736                 _release_multimedia_key("KEY_PLAYCD");
737                 return ECORE_CALLBACK_RENEW;
738         }
739
740         /* Priority 3 : Check the lock status */
741         if ((status_passive_get()->idle_lock_state  == VCONFKEY_IDLE_LOCK)
742                 && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
743                         _D("phone lock state, ignore home key.");
744                 return ECORE_CALLBACK_RENEW;
745         }
746
747         /* Priority 4 : These keys are only activated after checking the lock state */
748 #if 0
749         if (!strcmp(ev->keyname, key_name[KEY_END])) {
750         } else
751 #endif
752         if (!strcmp(ev->keyname, key_name[KEY_CONFIG])) {
753         //} else if (!strcmp(ev->keyname, key_name[KEY_SEND])) {
754         } else if (!strcmp(ev->keyname, key_name[KEY_HOME])) {
755                 _W("Home Key is released");
756
757                 syspopup_destroy_all();
758
759                 if(key_info.home_multi_press_timer) {
760                         _D("delete homekey timer");
761                         ecore_timer_del(key_info.home_multi_press_timer);
762                         key_info.home_multi_press_timer = NULL;
763                 }
764
765                 if (key_info.home_long_press_timer) {
766                         ecore_timer_del(key_info.home_long_press_timer);
767                         key_info.home_long_press_timer = NULL;
768                 } else {
769                         key_info.homekey_count = 0;
770                         return ECORE_CALLBACK_RENEW;
771                 }
772
773                 key_info.home_multi_press_timer = ecore_timer_add(HOMEKEY_TIMER_SEC, _home_multi_press_timer_cb, NULL);
774                 if (!key_info.home_multi_press_timer) {
775                         _E("Critical! cannot add a timer for home multi press");
776                 }
777                 return ECORE_CALLBACK_RENEW;
778         //} else if (!strcmp(ev->keyname, key_name[KEY_PAUSE])) {
779         } else if (!strcmp(ev->keyname, key_name[KEY_APPS])) {
780                 _D("App tray key is released");
781         } else if (!strcmp(ev->keyname, key_name[KEY_TASKSWITCH])) {
782                 _D("Task switch key is released");
783                 _launch_taskmgr_cb(NULL);
784         } else if (!strcmp(ev->keyname, key_name[KEY_WEBPAGE])) {
785                 _D("Web page key is released");
786                 process_mgr_must_open(APPID_BROWSER, NULL, NULL);
787         } else if (!strcmp(ev->keyname, key_name[KEY_MAIL])) {
788                 _D("Mail key is released");
789                 process_mgr_must_open(APPID_EMAIL, NULL, NULL);
790         } else if (!strcmp(ev->keyname, key_name[KEY_CONNECT])) {
791                 _D("Connect key is released");
792                 process_mgr_must_open(APPID_DIALER, NULL, NULL);
793         } else if (!strcmp(ev->keyname, key_name[KEY_SEARCH])) {
794                 _D("Search key is released");
795                 if (_launch_search() < 0) {
796                         _E("Failed to launch the search");
797                 }
798         } else if (!strcmp(ev->keyname, key_name[KEY_VOICE])) {
799                 _D("Voice key is released");
800         }
801
802         return ECORE_CALLBACK_RENEW;
803 }
804
805
806
807 static Eina_Bool _key_press_cb(void *data, int type, void *event)
808 {
809         Evas_Event_Key_Down *ev = event;
810
811         retv_if(!ev, ECORE_CALLBACK_RENEW);
812         retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
813
814         _D("_key_press_cb : %s Pressed", ev->keyname);
815
816         /* Priority 1 : Cancel */
817         /*              every reserved events have to be canceld when cancel key is pressed */
818         if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
819                 _D("Cancel button is pressed");
820                 key_info.cancel = EINA_TRUE;
821                 _cancel_key_events();
822                 return ECORE_CALLBACK_RENEW;
823         }
824
825         if (EINA_TRUE == key_info.cancel) {
826                 _D("CANCEL is on");
827                 return ECORE_CALLBACK_RENEW;
828         }
829
830         /* Priority 2 : Check the lock status */
831         if ((status_passive_get()->idle_lock_state == VCONFKEY_IDLE_LOCK)
832                 && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
833                 _D("phone lock state, ignore key events.");
834                 _cancel_key_events();
835                 return ECORE_CALLBACK_RENEW;
836         }
837
838         /* Priority 3 : other keys */
839 #if 0
840         if (!strcmp(ev->keyname, key_name[KEY_SEND])) {
841                 _D("Launch calllog");
842                 process_mgr_must_open(APPID_CALLLOG, NULL, NULL);
843         } else
844 #endif
845         if(!strcmp(ev->keyname, key_name[KEY_CONFIG])) {
846                 _D("Launch camera");
847                 process_mgr_must_open(APPID_CAMERA, NULL, NULL);
848         } else if (!strcmp(ev->keyname, key_name[KEY_HOME])) {
849                 _W("Home Key is pressed");
850                 if (key_info.home_long_press_timer) {
851                         ecore_timer_del(key_info.home_long_press_timer);
852                         key_info.home_long_press_timer = NULL;
853                 }
854
855                 key_info.homekey_count++;
856                 _W("homekey count : %d", key_info.homekey_count);
857
858                 if(key_info.home_multi_press_timer) {
859                         ecore_timer_del(key_info.home_multi_press_timer);
860                         key_info.home_multi_press_timer = NULL;
861                         _D("delete homekey timer");
862                 }
863
864                 _D("create long press timer");
865                 key_info.home_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _launch_taskmgr_cb, NULL);
866                 if (!key_info.home_long_press_timer) {
867                         _E("Failed to add timer for long press detection");
868                 }
869         } else if (!strcmp(ev->keyname, key_name[KEY_MEDIA])) {
870                 _D("Media key is pressed");
871         } else if (!strcmp(ev->keyname, key_name[KEY_APPS])) {
872                 _D("App tray key is pressed");
873         } else if (!strcmp(ev->keyname, key_name[KEY_TASKSWITCH])) {
874                 _D("Task switch key is pressed");
875         } else if (!strcmp(ev->keyname, key_name[KEY_WEBPAGE])) {
876                 _D("Web page key is pressed");
877         } else if (!strcmp(ev->keyname, key_name[KEY_MAIL])) {
878                 _D("Mail key is pressed");
879         } else if (!strcmp(ev->keyname, key_name[KEY_SEARCH])) {
880                 _D("Search key is pressed");
881         } else if (!strcmp(ev->keyname, key_name[KEY_VOICE])) {
882                 _D("Voice key is pressed");
883         } else if (!strcmp(ev->keyname, key_name[KEY_CONNECT])) {
884                 _D("Connect key is pressed");
885         }
886
887         return ECORE_CALLBACK_RENEW;
888 }
889
890
891
892 static void _set_keygrab(void)
893 {
894         int i = 0;
895         int ret = 0;
896
897         if (key_info.keymap_update_flag != EINA_TRUE || key_info.global_added_flag != EINA_TRUE) {
898                 _E("keygrab is not ready");
899                 return;
900         }
901
902         _destroy_precondition_handlers_for_keygrab();
903
904         for (i = 0; i < KEY_NAME_MAX; i++) {
905                 ret = ecore_wl_window_keygrab_set(NULL, key_name[i], 0, 0, 0, ECORE_WL_WINDOW_KEYGRAB_SHARED);
906                 _D("key grab : %s / ret : %d", key_name[i], ret);
907         }
908
909         key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
910         if (!key_info.key_up) {
911                 _E("Failed to register a key up event handler");
912         }
913
914         key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
915         if (!key_info.key_down) {
916                 _E("Failed to register a key down event handler");
917         }
918 }
919
920
921
922 static void _unset_keygrab(void)
923 {
924         int i = 0;
925
926         if (key_info.keymap_update_flag == EINA_TRUE && key_info.global_added_flag == EINA_TRUE) {
927                 for (i = 0; i < KEY_NAME_MAX; i++) {
928                         ecore_wl_window_keygrab_unset(NULL, key_name[i], 0, 0);
929                 }
930
931                 key_info.keymap_update_flag = EINA_FALSE;
932                 key_info.global_added_flag = EINA_FALSE;
933         }
934 }
935
936
937
938 static Eina_Bool _global_added_cb(void *data, int type, void *event)
939 {
940         Ecore_Wl_Event_Global *ev = NULL;
941
942         ev = (Ecore_Wl_Event_Global *) event;
943         if (!ev) {
944                 _E("Failed to get global added event");
945                 return ECORE_CALLBACK_CANCEL;
946         }
947
948         if (ev->interface && !strncmp(ev->interface, "tizen_keyrouter", strlen(ev->interface))) {
949                 key_info.global_added_flag = EINA_TRUE;
950                 _set_keygrab();
951         }
952
953         return ECORE_CALLBACK_PASS_ON;
954 }
955
956
957
958 static Eina_Bool _keymap_update_cb(void *data, int type, void *event)
959 {
960         Ecore_Wl_Event_Keymap_Update *ev = NULL;
961         Ecore_Wl_Input *input = NULL;
962         struct xkb_keymap *keymap = NULL;
963
964         ev = (Ecore_Wl_Event_Keymap_Update *) event;
965         if (!ev) {
966                 _E("Failed to get keymap event");
967                 return ECORE_CALLBACK_CANCEL;
968         }
969
970         input = ecore_wl_input_get();
971         if (!input) {
972                 _E("Failed to get wl input");
973                 return ECORE_CALLBACK_CANCEL;
974         }
975
976         keymap = ecore_wl_input_keymap_get(input);
977         if (ev->keymap && keymap) {
978                 key_info.keymap_update_flag = EINA_TRUE;
979                 _set_keygrab();
980         }
981
982         return ECORE_CALLBACK_PASS_ON;
983 }
984
985
986
987 static void _create_precondition_handlers_for_keygrab(void)
988 {
989         key_info.global_added = ecore_event_handler_add(ECORE_WL_EVENT_GLOBAL_ADDED, _global_added_cb, NULL);
990         if (!key_info.global_added) {
991                 _E("Failed to add handler for global added");
992         }
993
994         key_info.keymap_update = ecore_event_handler_add(ECORE_WL_EVENT_KEYMAP_UPDATE, _keymap_update_cb, NULL);
995         if (!key_info.keymap_update) {
996                 _E("Failed to add handler for keymap update");
997         }
998 }
999
1000
1001
1002 static void _destroy_precondition_handlers_for_keygrab(void)
1003 {
1004         if (key_info.global_added) {
1005                 ecore_event_handler_del(key_info.global_added);
1006                 key_info.global_added = NULL;
1007         }
1008
1009         if (key_info.keymap_update) {
1010                 ecore_event_handler_del(key_info.keymap_update);
1011                 key_info.keymap_update = NULL;
1012         }
1013 }
1014
1015
1016
1017 void hw_key_create_window(void)
1018 {
1019         _create_precondition_handlers_for_keygrab();
1020 }
1021
1022
1023
1024 void hw_key_destroy_window(void)
1025 {
1026         if (key_info.key_up) {
1027                 ecore_event_handler_del(key_info.key_up);
1028                 key_info.key_up = NULL;
1029         }
1030
1031         if (key_info.key_down) {
1032                 ecore_event_handler_del(key_info.key_down);
1033                 key_info.key_down = NULL;
1034         }
1035
1036         _destroy_precondition_handlers_for_keygrab();
1037         _unset_keygrab();
1038 }
1039
1040 #endif
1041
1042 // End of a file