2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <Elementary.h>
19 #include <Ecore_Input.h>
20 #include <Ecore_Wl2.h>
22 #include <dd-display.h>
27 #include <pkgmgr-info.h>
32 #include "dbus_util.h"
34 #include "process_mgr.h"
36 #define LONG_PRESS_TIMER_SEC 0.7
37 #define POWERKEY_LCDOFF_TIMER_SEC 0.4
38 #define POWERKEY_TIMER_SEC 0.25
40 #define APP_CONTROL_OPERATION_MAIN_KEY "__APP_SVC_OP_TYPE__"
41 #define APP_CONTROL_OPERATION_MAIN_VALUE "http://tizen.org/appcontrol/operation/main"
43 #define USE_DBUS_POWEROFF 1
45 const char *key_name[KEY_NAME_MAX] = {
46 "XF86AudioRaiseVolume",
47 "XF86AudioLowerVolume",
74 "XF86MonBrightnessDown",
75 "XF86MonBrightnessUp",
81 "XF86VoiceWakeUp_LPSD",
86 Ecore_Event_Handler *key_up;
87 Ecore_Event_Handler *key_down;
88 Ecore_Timer *home_long_press_timer;
89 Ecore_Timer *home_multi_press_timer;
90 Ecore_Timer *keygrab_timer;
94 Ecore_Timer *power_long_press_timer;
95 Ecore_Timer *power_release_timer;
97 Eina_Bool is_long_press;
100 Eina_Bool is_home_focused;
104 .home_long_press_timer = NULL,
105 .home_multi_press_timer = NULL,
106 .keygrab_timer = NULL,
107 .cancel = EINA_FALSE,
110 .power_long_press_timer = NULL,
111 .power_release_timer = NULL,
112 .is_lcd_on = EINA_FALSE,
113 .is_long_press = EINA_FALSE,
115 .is_cancel = EINA_FALSE,
116 .is_home_focused = EINA_FALSE,
121 static Eina_Bool _long_press_timer_cb(void* data)
123 key_info.power_long_press_timer = NULL;
124 key_info.is_long_press = EINA_TRUE;
125 key_info.powerkey_count = 0;
127 if (0 < status_passive_get()->remote_lock_islocked) {
128 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
129 return ECORE_CALLBACK_CANCEL;
132 if (key_info.power_release_timer) {
133 ecore_timer_del(key_info.power_release_timer);
134 key_info.power_release_timer = NULL;
135 _D("delete power_release_timer");
138 #if USE_DBUS_POWEROFF
139 dbus_util_send_poweroff_signal();
141 _D("launch power off syspopup");
142 process_mgr_syspopup_launch("poweroff-syspopup", NULL, NULL, NULL, NULL);
145 feedback_initialize();
146 feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_HOLD);
147 feedback_deinitialize();
149 return ECORE_CALLBACK_CANCEL;
154 static void _launch_last_app(void)
156 struct rua_rec record;
161 pkgmgrinfo_appinfo_h handle;
162 bool is_taskmanage = false;
163 char *last_app = NULL;
166 _E("Failed to initialize rua");
170 if (rua_history_load_db(&table, &nrows, &ncols) || !table) {
171 _E("Failed to load rua history db");
174 _E("Failed to finalize rua");
180 for (row = 0; row < nrows; row++) {
181 if (rua_history_get_rec(&record, table, nrows, ncols, row)) {
182 _E("Failed to get rua history record");
186 _D("[%d] rua history(%s)", row, record.pkg_name);
188 if (!strcmp(record.pkg_name, HOMESCREEN_PKG_NAME) ||
189 !strcmp(record.pkg_name, ISE_DEFAULT_PKG_NAME) ||
190 !strcmp(record.pkg_name, status_passive_get()->wms_clocks_set_idle)) {
194 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_appinfo(record.pkg_name, &handle)) {
195 _E("Failed to get app info(%s)", record.pkg_name);
199 if (PMINFO_R_OK != pkgmgrinfo_appinfo_is_taskmanage(handle, &is_taskmanage)) {
200 _E("Failed to get taskmanage info");
201 pkgmgrinfo_appinfo_destroy_appinfo(handle);
205 if (!is_taskmanage) {
206 _E("This app(%s) is not showing on taskmanager", record.pkg_name);
207 pkgmgrinfo_appinfo_destroy_appinfo(handle);
211 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_pkgid(handle, &last_app)) {
212 _E("Failed to get pkgid");
213 pkgmgrinfo_appinfo_destroy_appinfo(handle);
217 if (last_app == NULL) {
218 _E("last pkg name is NULL");
219 pkgmgrinfo_appinfo_destroy_appinfo(handle);
223 _D("last app : %s", last_app);
224 process_mgr_must_launch(last_app, NULL, NULL, NULL, NULL);
226 pkgmgrinfo_appinfo_destroy_appinfo(handle);
231 if (rua_history_unload_db(&table)) {
232 _E("Failed to unload rua history db");
236 _E("Failed to finalize rua");
242 static void _do_double_home_key_operation(void)
245 int is_watch_face_shown = 0;
247 op = status_passive_get()->setappl_double_press_home_key;
248 _D("Dobule home key operation : %d", op);
250 is_watch_face_shown = status_passive_get()->homescreen_watch_face_visibility;
251 _D("Watch face status : %d", is_watch_face_shown);
254 case VCONFKEY_DOUBLE_PRESS_HOME_KEY_NONE:
256 case VCONFKEY_DOUBLE_PRESS_HOME_KEY_LAST_APP:
257 if (is_watch_face_shown) {
260 home_mgr_launch_home_by_power((key_info.is_home_focused == EINA_TRUE) ? "powerkey_focused" : "powerkey_unfocused");
263 case VCONFKEY_DOUBLE_PRESS_HOME_KEY_RECENT_APPS:
264 process_mgr_must_launch(TASKMGR_PKG_NAME, NULL, NULL, NULL, NULL);
267 _E("invalid operation(%d)", op);
274 static Eina_Bool _powerkey_timer_cb(void *data)
276 _W("%s, powerkey count[%d]", __func__, key_info.powerkey_count);
278 key_info.power_release_timer = NULL;
280 if (VCONFKEY_PM_KEY_LOCK == status_passive_get()->pm_key_ignore) {
281 _E("Critical Low Batt Clock Mode");
282 key_info.powerkey_count = 0;
283 if (key_info.is_lcd_on) {
284 _W("just turn off LCD");
285 display_change_state(LCD_OFF);
287 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
289 return ECORE_CALLBACK_CANCEL;
292 if (key_info.powerkey_count % 2 == 0) {
294 _W("powerkey double press");
295 key_info.powerkey_count = 0;
296 _do_double_home_key_operation();
297 return ECORE_CALLBACK_CANCEL;
299 key_info.powerkey_count = 0;
301 if (key_info.is_lcd_on) {
302 if (VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
303 _E("Already lcd state was changed while powerkey op. starter ignore powerkey operation");
304 return ECORE_CALLBACK_CANCEL;
307 _W("just turn on LCD by powerkey.. starter ignore powerkey operation");
308 return ECORE_CALLBACK_CANCEL;
311 if (VCONFKEY_CALL_VOICE_ACTIVE == status_passive_get()->call_state) {
312 _W("call state is [%d] -> just turn off LCD");
313 display_change_state(LCD_OFF);
314 return ECORE_CALLBACK_CANCEL;
317 if (VCONFKEY_IDLE_LOCK == status_passive_get()->idle_lock_state) {
318 _W("lock state is [%d] -> just turn off LCD");
319 display_change_state(LCD_OFF);
320 return ECORE_CALLBACK_CANCEL;
323 if (0 < status_passive_get()->remote_lock_islocked) {
324 _W("remote lock is on top (%d), -> just turn off LCD", status_passive_get()->remote_lock_islocked);
325 display_change_state(LCD_OFF);
326 return ECORE_CALLBACK_CANCEL;
329 home_mgr_launch_home_by_power((key_info.is_home_focused == EINA_TRUE) ? "powerkey_focused" : "powerkey_unfocused");
331 return ECORE_CALLBACK_CANCEL;
336 static Eina_Bool _key_release_cb(void *data, int type, void *event)
338 Evas_Event_Key_Up *ev = event;
340 retv_if(!ev, ECORE_CALLBACK_RENEW);
341 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
343 _D("_key_release_cb : %s Released", ev->keyname);
345 if (!strcmp(ev->keyname, key_name[KEY_POWER])) {
346 _W("POWER Key is released");
348 if (key_info.power_long_press_timer) {
349 ecore_timer_del(key_info.power_long_press_timer);
350 key_info.power_long_press_timer = NULL;
351 _D("delete long press timer");
354 // Check powerkey timer
355 if (key_info.power_release_timer) {
356 ecore_timer_del(key_info.power_release_timer);
357 key_info.power_release_timer = NULL;
358 _D("delete powerkey timer");
361 // Cancel key operation
362 if (EINA_TRUE == key_info.is_cancel) {
363 _D("Cancel key is activated");
364 key_info.is_cancel = EINA_FALSE;
365 key_info.powerkey_count = 0; //initialize powerkey count
366 return ECORE_CALLBACK_RENEW;
369 // Check long press operation
370 if (key_info.is_long_press) {
371 _D("ignore power key release by long poress");
372 key_info.is_long_press = EINA_FALSE;
373 return ECORE_CALLBACK_RENEW;
376 if (key_info.is_lcd_on) {
377 key_info.power_release_timer = ecore_timer_add(POWERKEY_TIMER_SEC, _powerkey_timer_cb, NULL);
379 _D("lcd off --> [%f]sec timer", POWERKEY_LCDOFF_TIMER_SEC);
380 key_info.power_release_timer = ecore_timer_add(POWERKEY_LCDOFF_TIMER_SEC, _powerkey_timer_cb, NULL);
382 if (!key_info.power_release_timer) {
383 _E("Critical, cannot add a timer for powerkey");
385 } else if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
386 _D("CANCEL Key is released");
387 key_info.is_cancel = EINA_FALSE;
390 return ECORE_CALLBACK_RENEW;
395 static Eina_Bool _key_press_cb(void *data, int type, void *event)
397 Evas_Event_Key_Down *ev = event;
399 retv_if(!ev, ECORE_CALLBACK_RENEW);
400 retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
402 _D("_key_press_cb : %s Pressed", ev->keyname);
404 if (!strcmp(ev->keyname, key_name[KEY_POWER])) {
407 _W("POWER Key is pressed");
416 if (VCONFKEY_PM_STATE_LCDDIM >= status_active_get()->pm_state) {
417 key_info.is_lcd_on = EINA_TRUE;
418 } else if (VCONFKEY_PM_STATE_LCDOFF <= status_active_get()->pm_state) {
419 key_info.is_lcd_on = EINA_FALSE;
422 key_info.powerkey_count++;
423 _W("powerkey count : %d", key_info.powerkey_count);
425 if (key_info.power_release_timer) {
426 ecore_timer_del(key_info.power_release_timer);
427 key_info.power_release_timer = NULL;
430 if (key_info.power_long_press_timer) {
431 ecore_timer_del(key_info.power_long_press_timer);
432 key_info.power_long_press_timer = NULL;
435 key_info.is_long_press = EINA_FALSE;
436 key_info.power_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _long_press_timer_cb, NULL);
437 if (!key_info.power_long_press_timer) {
438 _E("Failed to add power_long_press_timer");
441 status = aul_app_get_status("org.tizen.w-home");
442 key_info.is_home_focused = (status == STATUS_FOCUS) ? EINA_TRUE : EINA_FALSE;
443 _D("home focus status : %d", key_info.is_home_focused);
444 } else if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
445 _D("CANCEL key is pressed");
446 key_info.is_cancel = EINA_TRUE;
449 return ECORE_CALLBACK_RENEW;
454 static Eina_Bool __keygrab_timer_cb(void *data)
459 for (i = 0; i < KEY_NAME_MAX; i++) {
460 ret = ecore_wl2_window_keygrab_set(NULL, key_name[i], 0, 0, 0, ECORE_WL2_WINDOW_KEYGRAB_SHARED);
461 _D("key grab : %s / ret : %d", key_name[i], ret);
464 key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
465 if (!key_info.key_up) {
466 _E("Failed to register a key up event handler");
469 key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
470 if (!key_info.key_down) {
471 _E("Failed to register a key down event handler");
474 return ECORE_CALLBACK_CANCEL;
479 void hw_key_create_window(void)
481 if (key_info.keygrab_timer) {
482 ecore_timer_del(key_info.keygrab_timer);
483 key_info.keygrab_timer = NULL;
486 key_info.keygrab_timer = ecore_timer_add(1.0f, __keygrab_timer_cb, NULL);
487 if (!key_info.keygrab_timer) {
488 _E("Failed to add timer for keygrab");
494 void hw_key_destroy_window(void)
498 for (i = 0; i < KEY_NAME_MAX; i++) {
499 ecore_wl2_window_keygrab_unset(NULL, key_name[i], 0, 0);
502 if (key_info.keygrab_timer) {
503 ecore_timer_del(key_info.keygrab_timer);
504 key_info.keygrab_timer = NULL;
507 if (key_info.key_up) {
508 ecore_event_handler_del(key_info.key_up);
509 key_info.key_up = NULL;
512 if (key_info.key_down) {
513 ecore_event_handler_del(key_info.key_down);
514 key_info.key_down = NULL;