Code sync
[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.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.tizenopensource.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 "util.h"
32
33 #define TASKMGR_PKG_NAME "org.tizen.taskmgr"
34 #define CAMERA_PKG_NAME "org.tizen.camera-app"
35 #define CALLLOG_PKG_NAME "org.tizen.calllog"
36 #define SEARCH_PKG_NAME "org.tizen.smartsearch"
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         _D("Launch TASKMGR");
66
67         key_info.long_press = NULL;
68
69         if (aul_open_app(TASKMGR_PKG_NAME) < 0)
70                 _E("Failed to launch the taskmgr");
71
72         return ECORE_CALLBACK_CANCEL;
73 }
74
75
76
77 static Eina_Bool _launch_home_screen(void *data)
78 {
79         char *package;
80         int ret;
81
82         syspopup_destroy_all();
83         key_info.single_timer = NULL;
84
85         package = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
86         if (package) {
87                 ret = aul_open_app(package);
88                 if (ret < 0) {
89                         _E("cannot launch package %s(err:%d)", package, ret);
90
91                         if (-1 == ret) { // -1 : AUL returns '-1' when there is no package name in DB.
92                                 ret = aul_open_app(HOME_SCREEN_PKG_NAME);
93                                 if (ret < 0) {
94                                         _E("Failed to open a default home, %s(err:%d)", HOME_SCREEN_PKG_NAME, ret);
95                                 }
96                         }
97                 }
98
99                 free(package);
100         } else {
101                 ret = aul_open_app(HOME_SCREEN_PKG_NAME);
102                 if (ret < 0) _E("Cannot open default home");
103         }
104
105         if (ret > 0) {
106                 if (-1 == sysconf_set_mempolicy_bypid(ret, OOM_IGNORE)) {
107                         _E("Cannot set the memory policy for Home-screen(%d)", ret);
108                 } else {
109                         _E("Set the memory policy for Home-screen(%d)", ret);
110                 }
111         }
112
113         return ECORE_CALLBACK_CANCEL;
114 }
115
116
117
118 inline static void _launch_svoice(void)
119 {
120         _D("Launch smartsearch");
121         if (aul_open_app(SEARCH_PKG_NAME) < 0)
122                 _E("Cannot open Smart-search");
123
124         return;
125 }
126
127
128
129 inline static int _release_home_key(void)
130 {
131         retv_if(NULL == key_info.long_press, EXIT_SUCCESS);
132         ecore_timer_del(key_info.long_press);
133         key_info.long_press = NULL;
134
135         if (NULL == key_info.single_timer) {
136                 key_info.single_timer = ecore_timer_add(0.3, _launch_home_screen, NULL);
137                 return EXIT_SUCCESS;
138         }
139         ecore_timer_del(key_info.single_timer);
140         key_info.single_timer = NULL;
141
142         syspopup_destroy_all();
143         _launch_svoice();
144
145         return EXIT_SUCCESS;
146 }
147
148
149
150 inline static void _release_multimedia_key(const char *value)
151 {
152         bundle *b;
153         int ret;
154
155         _D("Multimedia key is released with %s", value);
156         ret_if(NULL == value);
157
158         b = bundle_create();
159         if (!b) {
160                 _E("Cannot create bundle");
161                 return;
162         }
163
164         bundle_add(b, "multimedia_key", value);
165         ret = aul_launch_app(MUSIC_PLAYER_PKG_NAME, b);
166         bundle_free(b);
167
168         if (ret < 0)
169                 _E("Failed to launch the running apps, ret : %d", ret);
170 }
171
172
173
174 static Eina_Bool _key_release_cb(void *data, int type, void *event)
175 {
176         Evas_Event_Key_Up *ev = event;
177         int val = -1;
178
179         _D("Released");
180
181         if (!ev) {
182                 _D("Invalid event object");
183                 return ECORE_CALLBACK_RENEW;
184         }
185
186         if (!strcmp(ev->keyname, KEY_END)) {
187         } else if (!strcmp(ev->keyname, KEY_CONFIG)) {
188         } else if (!strcmp(ev->keyname, KEY_SEND)) {
189         } else if (!strcmp(ev->keyname, KEY_HOME)) {
190
191                 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
192                         _D("Cannot get VCONFKEY_IDLE_LOCK_STATE");
193                 }
194                 if (val == VCONFKEY_IDLE_LOCK) {
195                         _D("lock state, ignore home key..!!");
196                         return ECORE_CALLBACK_RENEW;
197                 }
198
199                 if (EINA_TRUE == key_info.cancel) {
200                         _D("Cancel key is activated");
201                         if (key_info.long_press) {
202                                 ecore_timer_del(key_info.long_press);
203                                 key_info.long_press = NULL;
204                         }
205
206                         if (key_info.single_timer) {
207                                 ecore_timer_del(key_info.single_timer);
208                                 key_info.single_timer = NULL;
209                         }
210
211                         return ECORE_CALLBACK_RENEW;
212                 }
213
214                 _release_home_key();
215         } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
216         } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
217                 _D("CANCEL Key is released");
218                 key_info.cancel = EINA_FALSE;
219         } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
220                 _release_multimedia_key("KEY_PLAYCD");
221         }
222
223         return ECORE_CALLBACK_RENEW;
224 }
225
226
227
228 static Eina_Bool _key_press_cb(void *data, int type, void *event)
229 {
230         Evas_Event_Key_Down *ev = event;
231         int val = -1;
232
233         _D("Pressed");
234
235         if (!ev) {
236                 _D("Invalid event object");
237                 return ECORE_CALLBACK_RENEW;
238         }
239
240         if (!strcmp(ev->keyname, KEY_SEND)) {
241                 _D("Launch calllog");
242                 if (aul_open_app(CALLLOG_PKG_NAME) < 0)
243                         _E("Failed to launch %s", CALLLOG_PKG_NAME);
244         } else if(!strcmp(ev->keyname, KEY_CONFIG)) {
245                 _D("Launch camera");
246                 if (aul_open_app(CAMERA_PKG_NAME) < 0)
247                         _E("Failed to launch %s", CAMERA_PKG_NAME);
248         } else if (!strcmp(ev->keyname, KEY_HOME)) {
249                 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
250                         _D("Cannot get VCONFKEY_IDLE_LOCK_STATE");
251                 }
252                 if (val == VCONFKEY_IDLE_LOCK) {
253                         _D("lock state, ignore home key..!!");
254                         return ECORE_CALLBACK_RENEW;
255                 }
256                 if (key_info.long_press) {
257                         ecore_timer_del(key_info.long_press);
258                         key_info.long_press = NULL;
259                 }
260
261                 key_info.long_press = ecore_timer_add(0.5, _launch_taskmgr_cb, NULL);
262                 if (!key_info.long_press)
263                         _E("Failed to add timer for long press detection");
264         } else if (!strcmp(ev->keyname, KEY_CANCEL)) {
265                 _D("Cancel button is pressed");
266                 key_info.cancel = EINA_TRUE;
267         } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
268                 _D("Media key is pressed");
269         }
270
271         return ECORE_CALLBACK_RENEW;
272 }
273
274
275
276 void _media_key_event_cb(media_key_e key, media_key_event_e status, void *user_data)
277 {
278         _D("MEDIA KEY EVENT");
279         if (MEDIA_KEY_STATUS_PRESSED == status) return;
280
281         if (MEDIA_KEY_PAUSE == key) {
282                 _release_multimedia_key("KEY_PAUSECD");
283         } else if (MEDIA_KEY_PLAY == key) {
284                 _release_multimedia_key("KEY_PLAYCD");
285         }
286 }
287
288
289
290 void create_key_window(void)
291 {
292         key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
293         if (!key_info.win) {
294                 _D("Failed to create hidden window");
295                 return;
296         }
297         ecore_x_event_mask_unset(key_info.win, ECORE_X_EVENT_MASK_NONE);
298         ecore_x_icccm_title_set(key_info.win, "menudaemon,key,receiver");
299         ecore_x_netwm_name_set(key_info.win, "menudaemon,key,receiver");
300         ecore_x_netwm_pid_set(key_info.win, getpid());
301
302         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_HOME, SHARED_GRAB);
303         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN, SHARED_GRAB);
304         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP, SHARED_GRAB);
305         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG, SHARED_GRAB);
306         utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA, SHARED_GRAB);
307
308         key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
309         if (!key_info.key_up)
310                 _D("Failed to register a key up event handler");
311
312         key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
313         if (!key_info.key_down)
314                 _D("Failed to register a key down event handler");
315
316         media_key_reserve(_media_key_event_cb, NULL);
317 }
318
319
320
321 void destroy_key_window(void)
322 {
323         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_HOME);
324         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN);
325         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP);
326         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG);
327         utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA);
328
329         if (key_info.key_up) {
330                 ecore_event_handler_del(key_info.key_up);
331                 key_info.key_up = NULL;
332         }
333
334         if (key_info.key_down) {
335                 ecore_event_handler_del(key_info.key_down);
336                 key_info.key_down = NULL;
337         }
338
339         ecore_x_window_delete_request_send(key_info.win);
340         key_info.win = 0x0;
341
342         media_key_release();
343 }
344
345
346
347 // End of a file