Apply smack rule.
[apps/native/starter.git] / src / hw_key.c
1  /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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
19 #include <ail.h>
20 #include <bundle.h>
21 #include <Elementary.h>
22 #include <Ecore_X.h>
23 #include <Ecore_Input.h>
24 #include <sysman.h>
25 #include <syspopup_caller.h>
26 #include <utilX.h>
27 #include <vconf.h>
28 #include <system/media_key.h>
29
30 #include "hw_key.h"
31 #include "menu_daemon.h"
32 #include "util.h"
33
34 #define TASKMGR_PKG_NAME "org.tizen.taskmgr"
35 #define CAMERA_PKG_NAME "org.tizen.camera-app"
36 #define CALLLOG_PKG_NAME "org.tizen.calllog"
37 #define MUSIC_PLAYER_PKG_NAME "org.tizen.music-player"
38
39
40
41 static struct {
42         Ecore_X_Window win;
43         Ecore_Event_Handler *key_up;
44         Ecore_Event_Handler *key_down;
45         Ecore_Timer *long_press;
46         Ecore_Timer *single_timer;
47         Ecore_Timer *volume_up_long_press;
48         Ecore_Timer *volume_down_long_press;
49         Eina_Bool cancel;
50 } key_info = {
51         .win = 0x0,
52         .key_up = NULL,
53         .key_down = NULL,
54         .long_press = NULL,
55         .single_timer = NULL,
56         .volume_up_long_press = NULL,
57         .volume_down_long_press = NULL,
58         .cancel = EINA_FALSE,
59 };
60
61
62
63 static Eina_Bool _launch_taskmgr_cb(void* data)
64 {
65         int val1 = -1;
66         int val2 = -1;
67         _D("Launch TASKMGR");
68
69         key_info.long_press = NULL;
70
71         if (vconf_get_int(VCONFKEY_PM_STATE, &val1) < 0) {
72                 _E("Cannot get VCONFKEY_PM_STATE");
73                 return ECORE_CALLBACK_CANCEL;
74         }
75         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val2) < 0) {
76                 _E("Cannot get VCONFKEY_IDLE_LOCK_STATE");
77                 return ECORE_CALLBACK_CANCEL;
78         }
79
80         if ((val1 == VCONFKEY_PM_STATE_NORMAL) && (val2 == VCONFKEY_IDLE_UNLOCK)) {
81                 _D("LCD ON, UNLOCK state => launch taskmgr");
82                 if (menu_daemon_open_app(TASKMGR_PKG_NAME) < 0)
83                         _E("Failed to launch the taskmgr");
84         } else {
85                 _D("Can't launch TASKMGR pm state : %d lock state : %d", val1, val2);
86         }
87
88         return ECORE_CALLBACK_CANCEL;
89 }
90
91
92
93 static Eina_Bool _launch_by_home_key(void *data)
94 {
95         key_info.single_timer = NULL;
96         syspopup_destroy_all();
97         menu_daemon_open_homescreen(NULL);
98         return ECORE_CALLBACK_CANCEL;
99 }
100
101
102
103 inline static int _release_home_key(void)
104 {
105         retv_if(NULL == key_info.long_press, EXIT_SUCCESS);
106         ecore_timer_del(key_info.long_press);
107         key_info.long_press = NULL;
108
109         if (NULL == key_info.single_timer) {
110                 key_info.single_timer = ecore_timer_add(0.3, _launch_by_home_key, NULL);
111                 return EXIT_SUCCESS;
112         }
113         ecore_timer_del(key_info.single_timer);
114         key_info.single_timer = NULL;
115
116         syspopup_destroy_all();
117
118         return EXIT_SUCCESS;
119 }
120
121
122
123 inline static void _release_multimedia_key(const char *value)
124 {
125         ret_if(NULL == value);
126
127         _D("Multimedia key is released with %s", value);
128
129         bundle *b;
130         b = bundle_create();
131         if (!b) {
132                 _E("Cannot create bundle");
133                 return;
134         }
135         bundle_add(b, "multimedia_key", value);
136
137         int ret;
138         ret = menu_daemon_launch_app(MUSIC_PLAYER_PKG_NAME, b);
139         if (ret < 0)
140                 _E("Failed to launch the running apps, ret : %d", ret);
141
142         bundle_free(b);
143 }
144
145
146
147 static Eina_Bool _key_release_cb(void *data, int type, void *event)
148 {
149         Evas_Event_Key_Up *ev = event;
150         int val = -1;
151
152         _D("Released");
153
154         if (!ev) {
155                 _D("Invalid event object");
156                 return ECORE_CALLBACK_RENEW;
157         }
158
159         if (!strcmp(ev->keyname, KEY_END)) {
160         } else if (!strcmp(ev->keyname, KEY_CONFIG)) {
161         } else if (!strcmp(ev->keyname, KEY_SEND)) {
162         } else if (!strcmp(ev->keyname, KEY_HOME)) {
163
164                 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
165                         _D("Cannot get VCONFKEY_IDLE_LOCK_STATE");
166                 }
167                 if (val == VCONFKEY_IDLE_LOCK) {
168                         _D("lock state, ignore home key..!!");
169                         return ECORE_CALLBACK_RENEW;
170                 }
171
172                 if (EINA_TRUE == key_info.cancel) {
173                         _D("Cancel key is activated");
174                         if (key_info.long_press) {
175                                 ecore_timer_del(key_info.long_press);
176                                 key_info.long_press = NULL;
177                         }
178
179                         if (key_info.single_timer) {
180                                 ecore_timer_del(key_info.single_timer);
181                                 key_info.single_timer = NULL;
182                         }
183
184                         return ECORE_CALLBACK_RENEW;
185                 }
186
187                 _release_home_key();
188         } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
189         } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
190                 _D("CANCEL Key is released");
191                 key_info.cancel = EINA_FALSE;
192         } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
193                 _release_multimedia_key("KEY_PLAYCD");
194         }
195
196         return ECORE_CALLBACK_RENEW;
197 }
198
199
200
201 static Eina_Bool _key_press_cb(void *data, int type, void *event)
202 {
203         Evas_Event_Key_Down *ev = event;
204         int val = -1;
205
206         _D("Pressed");
207
208         if (!ev) {
209                 _D("Invalid event object");
210                 return ECORE_CALLBACK_RENEW;
211         }
212
213         if (!strcmp(ev->keyname, KEY_SEND)) {
214                 _D("Launch calllog");
215                 if (menu_daemon_open_app(CALLLOG_PKG_NAME) < 0)
216                         _E("Failed to launch %s", CALLLOG_PKG_NAME);
217         } else if(!strcmp(ev->keyname, KEY_CONFIG)) {
218                 _D("Launch camera");
219                 if (menu_daemon_open_app(CAMERA_PKG_NAME) < 0)
220                         _E("Failed to launch %s", CAMERA_PKG_NAME);
221         } else if (!strcmp(ev->keyname, KEY_HOME)) {
222                 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
223                         _D("Cannot get VCONFKEY_IDLE_LOCK_STATE");
224                 }
225                 if (val == VCONFKEY_IDLE_LOCK) {
226                         _D("lock state, ignore home key..!!");
227                         return ECORE_CALLBACK_RENEW;
228                 }
229                 if (key_info.long_press) {
230                         ecore_timer_del(key_info.long_press);
231                         key_info.long_press = NULL;
232                 }
233
234                 key_info.long_press = ecore_timer_add(0.5, _launch_taskmgr_cb, NULL);
235                 if (!key_info.long_press)
236                         _E("Failed to add timer for long press detection");
237         } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
238                 _D("Cancel button is pressed");
239                 key_info.cancel = EINA_TRUE;
240         } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
241                 _D("Media key is pressed");
242         }
243
244         return ECORE_CALLBACK_RENEW;
245 }
246
247
248
249 void _media_key_event_cb(media_key_e key, media_key_event_e status, void *user_data)
250 {
251         _D("MEDIA KEY EVENT");
252         if (MEDIA_KEY_STATUS_PRESSED == status) return;
253
254         if (MEDIA_KEY_PAUSE == key) {
255                 _release_multimedia_key("KEY_PAUSECD");
256         } else if (MEDIA_KEY_PLAY == key) {
257                 _release_multimedia_key("KEY_PLAYCD");
258         }
259 }
260
261
262
263 void create_key_window(void)
264 {
265         key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
266         if (!key_info.win) {
267                 _D("Failed to create hidden window");
268                 return;
269         }
270         ecore_x_event_mask_unset(key_info.win, ECORE_X_EVENT_MASK_NONE);
271         ecore_x_icccm_title_set(key_info.win, "menudaemon,key,receiver");
272         ecore_x_netwm_name_set(key_info.win, "menudaemon,key,receiver");
273         ecore_x_netwm_pid_set(key_info.win, getpid());
274
275         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_HOME, SHARED_GRAB);
276         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN, SHARED_GRAB);
277         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP, SHARED_GRAB);
278         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG, SHARED_GRAB);
279         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA, SHARED_GRAB);
280
281         key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
282         if (!key_info.key_up)
283                 _D("Failed to register a key up event handler");
284
285         key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
286         if (!key_info.key_down)
287                 _D("Failed to register a key down event handler");
288
289         media_key_reserve(_media_key_event_cb, NULL);
290 }
291
292
293
294 void destroy_key_window(void)
295 {
296         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_HOME);
297         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN);
298         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP);
299         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG);
300         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA);
301
302         if (key_info.key_up) {
303                 ecore_event_handler_del(key_info.key_up);
304                 key_info.key_up = NULL;
305         }
306
307         if (key_info.key_down) {
308                 ecore_event_handler_del(key_info.key_down);
309                 key_info.key_down = NULL;
310         }
311
312         ecore_x_window_delete_request_send(key_info.win);
313         key_info.win = 0x0;
314
315         media_key_release();
316 }
317
318
319
320 // End of a file