Implement common profile 95/59395/5 submit/tizen_common/20160216.082819
authorgs86.lee <gs86.lee@samsung.com>
Mon, 15 Feb 2016 08:54:06 +0000 (17:54 +0900)
committergs86.lee <gs86.lee@samsung.com>
Tue, 16 Feb 2016 06:17:29 +0000 (15:17 +0900)
Change-Id: Id069fb262c9f56fb0d0e8fbf7ad66e9949ae4a2e

14 files changed:
CMakeLists.txt
include/common/home_mgr.h [new file with mode: 0644]
include/common/hw_key.h [new file with mode: 0644]
include/common/lock_mgr.h [new file with mode: 0644]
include/common/popup.h [new file with mode: 0644]
include/common/starter.h [new file with mode: 0644]
packaging/starter.spec
res/edje/CMakeLists.txt
src/common/home_mgr.c [new file with mode: 0644]
src/common/hw_key.c [new file with mode: 0644]
src/common/lock_mgr.c [new file with mode: 0644]
src/common/popup.c [new file with mode: 0644]
src/common/starter.c [new file with mode: 0644]
src/common/window_mgr.c [new file with mode: 0644]

index f9cebc1..0056093 100644 (file)
@@ -9,10 +9,11 @@ SET(DATADIR "${PREFIX}/share")
 SET(RESDIR "${PREFIX}/res")
 SET(LOCALEDIR "${PREFIX}/share/locale")
 
-IF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
+IF("${TIZEN_PROFILE_NAME}" STREQUAL "COMMON")
+
 INCLUDE_DIRECTORIES(
        ${CMAKE_SOURCE_DIR}/include
-       ${CMAKE_SOURCE_DIR}/include/mobile
+       ${CMAKE_SOURCE_DIR}/include/common
 )
 INCLUDE(FindPkgConfig)
 pkg_check_modules(pkgs REQUIRED
@@ -51,14 +52,51 @@ pkg_check_modules(pkgs REQUIRED
        efl-extension
 )
 
-IF(X11_SUPPORT)
+ELSEIF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
+
+INCLUDE_DIRECTORIES(
+       ${CMAKE_SOURCE_DIR}/include
+       ${CMAKE_SOURCE_DIR}/include/mobile
+)
+INCLUDE(FindPkgConfig)
 pkg_check_modules(pkgs REQUIRED
-       ecore-x
-       utilX
-       )
-ENDIF(X11_SUPPORT)
+       aul
+       capi-system-media-key
+       db-util
+       dlog
+       ecore
+       ecore-wayland
+       ecore-evas
+       ecore-input
+       edbus
+       eina
+       elementary
+       evas
+       syspopup-caller
+       vconf
+       appcore-efl
+       glib-2.0
+       ui-gadget-1
+       bundle
+       capi-appfw-application
+       capi-appfw-app-manager
+       capi-network-bluetooth
+       capi-system-system-settings
+       feedback
+       alarm-service
+       pkgmgr-info
+       deviced
+       edbus
+       dbus-1
+       dbus-glib-1
+       tts
+       capi-message-port
+       security-manager
+       efl-extension
+)
+
+ELSEIF("${TIZEN_PROFILE_NAME}" STREQUAL "WEARABLE")
 
-ELSE()
 INCLUDE_DIRECTORIES(
        ${CMAKE_SOURCE_DIR}/include
        ${CMAKE_SOURCE_DIR}/include/wearable
@@ -95,6 +133,8 @@ pkg_check_modules(pkgs REQUIRED
        dbus-glib-1
 )
 
+ENDIF("${TIZEN_PROFILE_NAME}" STREQUAL "COMMON")
+
 IF(X11_SUPPORT)
 pkg_check_modules(pkgs REQUIRED
        ecore-x
@@ -102,9 +142,6 @@ pkg_check_modules(pkgs REQUIRED
        )
 ENDIF(X11_SUPPORT)
 
-ENDIF()
-
-
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
@@ -142,7 +179,24 @@ IF(WAYLAND_SUPPORT)
        ADD_DEFINITIONS("-DHAVE_WAYLAND")
 ENDIF(WAYLAND_SUPPORT)
 
-IF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
+IF("${TIZEN_PROFILE_NAME}" STREQUAL "COMMON")
+
+SET(BUILD_SOURCE
+       src/dbus_util.c
+       src/package_mgr.c
+       src/process_mgr.c
+       src/status.c
+
+       src/common/home_mgr.c
+       src/common/lock_mgr.c
+       src/common/starter.c
+       src/common/window_mgr.c
+       src/common/popup.c
+       src/common/hw_key.c
+)
+
+ELSEIF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
+
 SET(BUILD_SOURCE
        src/dbus_util.c
        src/package_mgr.c
@@ -162,7 +216,8 @@ SET(BUILD_SOURCE
        src/mobile/hw_key.c
 )
 
-ELSE("${TIZEN_PROFILE_NAME}" STREQUAL "WEARABLE")
+ELSEIF("${TIZEN_PROFILE_NAME}" STREQUAL "WEARABLE")
+
 SET(BUILD_SOURCE
        src/dbus_util.c
        src/package_mgr.c
@@ -175,13 +230,8 @@ SET(BUILD_SOURCE
        src/wearable/hw_key.c
        src/wearable/starter.c
 )
-IF(X11_SUPPORT)
-SET(BUILD_SOURCE
-       ${BUILD_SOURCE}
-       src/wearable/hw_key.c
-)
-ENDIF(X11_SUPPORT)
-ENDIF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
+
+ENDIF("${TIZEN_PROFILE_NAME}" STREQUAL "COMMON")
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${BUILD_SOURCE})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
diff --git a/include/common/home_mgr.h b/include/common/home_mgr.h
new file mode 100644 (file)
index 0000000..6fd5061
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bundle.h>
+#include <sys/types.h>
+#include <stdbool.h>
+
+extern int home_mgr_get_home_pid(void);
+extern int home_mgr_get_volume_pid(void);
+
+extern void home_mgr_init(void *data);
+extern void home_mgr_fini(void);
+
+void home_mgr_relaunch_homescreen(void);
+void home_mgr_relaunch_volume(void);
+extern int home_mgr_open_home(const char *pkgname);
+
+// End of a file
diff --git a/include/common/hw_key.h b/include/common/hw_key.h
new file mode 100644 (file)
index 0000000..787a779
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HW_KEY_H__
+#define __HW_KEY_H__
+
+#if HAVE_X11
+
+#define KEY_VOLUMEUP    "XF86AudioRaiseVolume"
+#define KEY_VOLUMEDOWN  "XF86AudioLowerVolume"
+#define KEY_HOME        "XF86Home"
+#define KEY_CONFIG      "XF86Camera_Full"
+#define KEY_SEARCH      "XF86Search"
+#define KEY_MEDIA       "XF86AudioMedia"
+#define KEY_TASKSWITCH  "XF86TaskPane"
+#define KEY_WEBPAGE     "XF86WWW"
+#define KEY_MAIL        "XF86Mail"
+#define KEY_VOICE       "XF86Voice"
+#define KEY_APPS        "XF86Apps"
+#define KEY_CONNECT     "XF86Call"
+#define KEY_BACK       "XF86Back"
+
+#elif HAVE_WAYLAND
+
+typedef enum {
+       KEY_VOLUMEUP = 0,
+       KEY_VOLUMEDOWN = 1,
+       KEY_POWER = 2,
+       KEY_MENU,
+       KEY_HOME,
+       KEY_BACK,
+       KLEY_CAMERA,
+       KEY_CONFIG,
+       KEY_SEARCH,
+       KEY_PLAYCD,
+       KEY_PAUSECB,
+       KEY_STOPCD,
+       KEY_NEXTSONG,
+       KEY_PRIVEIOUSSONG,
+       KEY_REWIND,
+       KEY_FASTFORWARD,
+       KEY_MEDIA,
+       KEY_PLAYPAUSE,
+       KEY_MUTE,
+       KEY_REC,
+       KEY_CANCEL,
+       KEY_SOFTBD,
+       KEY_QUICKPANEL,
+       KEY_TASKSWITCH,
+       KEY_HOMEPAGE,
+       KEY_WEBPAGE,
+       KEY_MAIL,
+       KEY_SCREENSAVER,
+       KEY_BRIGHTNESSDOWN,
+       KEY_BRIGHTNESSUP,
+       KEY_VOICE,
+       KEY_LANGUAGE,
+       KEY_APPS,
+       KEY_CONNECT,
+       KEY_GAMEPLAY,
+       KEY_VOICEWAKEUP_LPSD,
+       KEY_VOICEWAKEUP,
+       KEY_NAME_MAX,
+} key_name_e;
+#endif
+
+extern void hw_key_destroy_window(void);
+extern void hw_key_create_window(void);
+
+#endif
+// End of a file
diff --git a/include/common/lock_mgr.h b/include/common/lock_mgr.h
new file mode 100644 (file)
index 0000000..6db7a69
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCK_DAEMON_H__
+#define __LOCK_DAEMON_H__
+
+#include <Elementary.h>
+#include <E_DBus.h>
+#include <alarm.h>
+
+#include "window_mgr.h"
+
+#define _EDJ(x) elm_layout_edje_get(x)
+
+#ifdef TIZEN_BUILD_EMULATOR
+#define LOCK_MGR_DEFAULT_BG_PATH "/opt/share/settings/Wallpapers/Default.jpg"
+#else
+#define LOCK_MGR_DEFAULT_BG_PATH "/opt/share/settings/Wallpapers/Lock_default.png"
+#endif
+
+
+
+typedef enum {
+       LOCK_SOUND_LOCK,
+       LOCK_SOUND_UNLOCK,
+       LOCK_SOUND_BTN_KEY,
+       LOCK_SOUND_TAP,
+       LOCK_SOUND_MAX,
+} lock_sound_type_e;
+
+typedef enum {
+       LCD_STATE_ON,
+       LCD_STATE_OFF,
+       LCD_STATE_MAX,
+} lock_lcd_state_e;
+
+int lock_mgr_lcd_state_get(void);
+int lock_mgr_get_lock_pid(void);
+void lock_mgr_sound_play(lock_sound_type_e type);
+
+void lock_mgr_idle_lock_state_set(int lock_state);
+Eina_Bool lock_mgr_lockscreen_launch(void);
+void lock_mgr_unlock(void);
+
+
+int lock_mgr_daemon_start(void);
+void lock_mgr_daemon_end(void);
+
+#endif                         /* __LOCK_DAEMON_H__ */
diff --git a/include/common/popup.h b/include/common/popup.h
new file mode 100644 (file)
index 0000000..f8602ad
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __POPUP_H__
+#define __POPUP_H__
+
+#include <Elementary.h>
+
+extern Evas_Object *popup_create(const char *title, const char *text);
+
+#endif
+// End of a file
diff --git a/include/common/starter.h b/include/common/starter.h
new file mode 100644 (file)
index 0000000..a9700c2
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STARTER_H__
+#define __STARTER_H__
+
+#include <sys/time.h>
+
+struct appdata {
+       struct timeval tv_start;        /* start time */
+       int lcd_status;
+};
+
+#endif                         /* __STARTER_H__ */
index b4d2814..b6fac06 100644 (file)
@@ -26,7 +26,13 @@ BuildRequires:  pkgconfig(capi-system-media-key)
 BuildRequires:  pkgconfig(capi-network-bluetooth)
 BuildRequires:  pkgconfig(capi-system-system-settings)
 
-%if "%{profile}" == "mobile"
+%if "%{profile}" == "common"
+BuildRequires:  tts
+BuildRequires:  tts-devel
+BuildRequires:  pkgconfig(capi-message-port)
+BuildRequires:  pkgconfig(security-manager)
+BuildRequires:  pkgconfig(efl-extension)
+%else if "%{profile}" == "mobile"
 BuildRequires:  tts
 BuildRequires:  tts-devel
 BuildRequires:  pkgconfig(capi-message-port)
@@ -59,7 +65,6 @@ BuildRequires:  edje-bin
 BuildRequires:  gettext
 BuildRequires:  gettext-tools
 Requires(post): /usr/bin/vconftool
-#Requires: sys-assert
 
 %if !%{with wayland}
 BuildRequires:  pkgconfig(utilX)
@@ -79,14 +84,22 @@ export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
 export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
 %endif
 
+%if "%{profile}" == "common"
+%define TIZEN_PROFILE_NAME "COMMON"
+export CFLAGS="$CFLAGS -DTIZEN_PROFILE_COMMON"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_PROFILE_COMMON"
+%endif
+
+%if "%{profile}" == "mobile"
+%define TIZEN_PROFILE_NAME "MOBILE"
+export CFLAGS="$CFLAGS -DTIZEN_PROFILE_MOBILE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_PROFILE_MOBILE"
+%endif
+
 %if "%{profile}" == "wearable"
 %define TIZEN_PROFILE_NAME "WEARABLE"
 export CFLAGS="$CFLAGS -DTIZEN_PROFILE_WEARABLE"
 export CXXFLAGS="$CXXFLAGS -DTIZEN_PROFILE_WEARABLE"
-%else
-%define TIZEN_PROFILE_NAME "MOBILE"
-export CFLAGS="$CFLAGS -DTIZEN_PROFILE_MOBILE"
-export CXXFLAGS="$CXXFLAGS -DTIZEN_PROFILE_MOBILE"
 %endif
 
 %ifarch %{arm}
index a1ccc4d..058964d 100755 (executable)
@@ -1,3 +1,3 @@
 IF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
 ADD_SUBDIRECTORY(mobile)
-ENDIF()
+ENDIF("${TIZEN_PROFILE_NAME}" STREQUAL "MOBILE")
diff --git a/src/common/home_mgr.c b/src/common/home_mgr.c
new file mode 100644 (file)
index 0000000..d0517bc
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aul.h>
+#include <app.h>
+#include <db-util.h>
+#include <Elementary.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pkgmgr-info.h>
+#include <stdio.h>
+#include <dd-deviced.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include "util.h"
+#include "dbus_util.h"
+#include "status.h"
+#include "process_mgr.h"
+#include "popup.h"
+
+#define HOME_TERMINATED "home_terminated"
+#define ISTRUE "TRUE"
+#define SYSPOPUPID_VOLUME "volume"
+
+#define DEAD_TIMER_SEC 10.0
+#define DEAD_TIMER_COUNT_MAX 2
+
+
+
+int errno;
+static struct {
+       pid_t home_pid;
+       pid_t volume_pid;
+       int power_off;
+
+       Ecore_Timer *dead_timer;
+       int dead_count;
+
+       Evas_Object *popup;
+} s_home_mgr = {
+       .home_pid = (pid_t)-1,
+       .volume_pid = (pid_t)-1,
+       .power_off = 0,
+
+       .dead_timer = NULL,
+       .dead_count = 0,
+
+       .popup = NULL,
+};
+
+
+int home_mgr_get_home_pid(void)
+{
+       return s_home_mgr.home_pid;
+}
+
+
+
+int home_mgr_get_volume_pid(void)
+{
+       return s_home_mgr.volume_pid;
+}
+
+
+
+static void _after_launch_home(int pid)
+{
+       if (dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_HOMESCREEN) < 0){
+               _E("failed to send oom dbus signal");
+       }
+       s_home_mgr.home_pid = pid;
+}
+
+
+
+static int _change_home_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
+{
+       if (!strcmp(appid, MENU_SCREEN_PKG_NAME)) {
+               _E("We cannot do anything anymore.");
+       } else if (!strcmp(appid, status_active_get()->setappl_selected_package_name)) {
+               if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
+                       _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
+               }
+               /* change_home func will be called by changing the home */
+               return 0;
+       }
+       _E("cannot change home");
+       return -1;
+}
+
+
+
+#define SERVICE_OPERATION_MAIN_KEY "__APP_SVC_OP_TYPE__"
+#define SERVICE_OPERATION_MAIN_VALUE "http://tizen.org/appcontrol/operation/main"
+void home_mgr_open_home(const char *appid)
+{
+       char *home_appid = NULL;
+
+       if (!appid) {
+               home_appid = status_active_get()->setappl_selected_package_name;
+       } else {
+               home_appid = (char *) appid;
+       }
+       ret_if(!home_appid);
+
+       process_mgr_must_launch(home_appid, SERVICE_OPERATION_MAIN_KEY, SERVICE_OPERATION_MAIN_VALUE, _change_home_cb, _after_launch_home);
+}
+
+
+
+static int _show_home_cb(status_active_key_e key, void *data)
+{
+       int seq = status_active_get()->starter_sequence;
+       int is_fallback = 0;
+
+       _D("[MENU_DAEMON] _show_home_cb is invoked(%d)", seq);
+
+       switch (seq) {
+       case 0:
+               if (s_home_mgr.home_pid > 0) {
+                       _D("Home[%d] has to be terminated.", s_home_mgr.home_pid);
+                       if (aul_terminate_pid(s_home_mgr.home_pid) != AUL_R_OK) {
+                               _E("Failed to terminate %d", s_home_mgr.home_pid);
+                       }
+                       s_home_mgr.home_pid = -1; /* to freeze the dead_cb */
+               }
+               break;
+       case 1:
+               if (vconf_get_int(VCONFKEY_STARTER_IS_FALLBACK, &is_fallback) < 0) {
+                       _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
+               }
+
+               if (is_fallback) {
+                       if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 0)) {
+                               _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
+                       }
+
+                       if (!strcmp(status_active_get()->setappl_selected_package_name, MENU_SCREEN_PKG_NAME)) {
+                               char *fallback_pkg;
+
+                               fallback_pkg = vconf_get_str(VCONFKEY_STARTER_FALLBACK_PKG);
+                               _D("fallback pkg : %s", fallback_pkg);
+                               if (fallback_pkg) {
+                                       int status;
+
+                                       status = vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, fallback_pkg);
+                                       free(fallback_pkg);
+                                       if (status == 0) {
+                                               break;
+                                       }
+                                       _E("Failed to set vconfkey : %s (%d)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, status);
+                               } else {
+                                       _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
+                               }
+                       }
+               }
+
+               home_mgr_open_home(NULL);
+               break;
+       default:
+               _E("False sequence [%d]", seq);
+               break;
+       }
+
+       return 1;
+}
+
+
+
+static int _change_selected_package_name(status_active_key_e key, void *data)
+{
+       char *appid = NULL;
+       int seq = status_active_get()->starter_sequence;
+
+       if (seq < 1) {
+               _E("Sequence is not ready yet, do nothing");
+               return 1;
+       }
+
+       _D("_change_selected_package_name is invoked");
+
+       appid = status_active_get()->setappl_selected_package_name;
+       if (!appid) {
+               return 1;
+       }
+       _SECURE_D("pkg_name : %s", appid);
+
+       if (s_home_mgr.home_pid > 0) {
+               char old_appid[BUF_SIZE_512] = { 0 , };
+
+               if (aul_app_get_pkgname_bypid(s_home_mgr.home_pid, old_appid, sizeof(old_appid)) == AUL_R_OK) {
+                       if (!strcmp(appid, old_appid)) {
+                               _D("Package is changed but same package is selected");
+                               return 1;
+                       }
+               }
+
+               if (AUL_R_OK != aul_terminate_pid(s_home_mgr.home_pid)) {
+                       _D("Failed to terminate pid %d", s_home_mgr.home_pid);
+               }
+               s_home_mgr.home_pid = -1;
+               s_home_mgr.dead_count = 0;
+               if (s_home_mgr.dead_timer) {
+                       ecore_timer_del(s_home_mgr.dead_timer);
+                       s_home_mgr.dead_timer = NULL;
+               }
+       }
+
+       home_mgr_open_home(appid);
+
+       return 1;
+}
+
+
+
+static void _after_launch_volume(int pid)
+{
+       if (dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
+               _E("failed to send oom dbus signal");
+       }
+       s_home_mgr.volume_pid = pid;
+}
+
+
+
+static void _launch_after_home(int pid)
+{
+       if (pid > 0) {
+               if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_HOMESCREEN) < 0){
+                       _E("failed to send oom dbus signal");
+               }
+       }
+       s_home_mgr.home_pid = pid;
+}
+
+
+
+static void _launch_home(const char *appid)
+{
+       const char *home_appid = NULL;
+
+       if (!appid) {
+               home_appid = status_active_get()->setappl_selected_package_name;
+       } else {
+               home_appid = (char *) appid;
+       }
+       ret_if(!home_appid);
+
+       process_mgr_must_launch(home_appid, HOME_TERMINATED, ISTRUE, _change_home_cb, _launch_after_home);
+}
+
+
+
+static void _popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       _D("popup is deleted");
+
+       s_home_mgr.popup = NULL;
+}
+
+
+
+static Eina_Bool _dead_timer_cb(void *data)
+{
+       Evas_Object *popup = NULL;
+       char title[BUF_SIZE_128] = { 0, };
+       char text[BUF_SIZE_1024] = { 0, };
+       char *appid = NULL;
+
+       appid = status_active_get()->setappl_selected_package_name;
+       if (!appid) {
+               _E("appid is NULL");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       _D("dead count : %s(%d)", appid, s_home_mgr.dead_count);
+
+       if (s_home_mgr.dead_count >= DEAD_TIMER_COUNT_MAX) {
+               _D("Change homescreen package to default");
+
+               /* set fallback status */
+               if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 1) < 0) {
+                       _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
+               }
+
+               if (vconf_set_str(VCONFKEY_STARTER_FALLBACK_PKG, appid) < 0) {
+                       _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
+               }
+
+               strncpy(title, _("IDS_COM_POP_WARNING"), sizeof(title));
+               title[sizeof(title) - 1] = '\0';
+
+               snprintf(text, sizeof(text), _("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), appid);
+               _D("title : %s / text : %s", title, text);
+
+               if (!s_home_mgr.popup) {
+                       popup = popup_create(title, text);
+                       if (!popup) {
+                               _E("Failed to create popup");
+                       } else {
+                               s_home_mgr.popup = popup;
+                               evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _popup_del_cb, NULL);
+                       }
+               }
+
+               if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
+                       _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
+                       return ECORE_CALLBACK_RENEW;
+               }
+       }
+
+       s_home_mgr.dead_timer = NULL;
+       s_home_mgr.dead_count = 0;
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+void home_mgr_relaunch_homescreen(void)
+{
+       char *appid = NULL;
+
+       if (s_home_mgr.power_off) {
+               _E("power off");
+               return;
+       }
+
+       appid = status_active_get()->setappl_selected_package_name;
+       if (!appid) {
+               _E("appid is NULL");
+               return;
+       }
+
+       s_home_mgr.dead_count++;
+       _D("home dead count : %d", s_home_mgr.dead_count);
+
+       if (!s_home_mgr.dead_timer) {
+               _D("Add dead timer");
+               s_home_mgr.dead_timer = ecore_timer_add(DEAD_TIMER_SEC, _dead_timer_cb, NULL);
+               if (!s_home_mgr.dead_timer) {
+                       _E("Failed to add a dead timer");
+               }
+       }
+
+       _launch_home(appid);
+}
+
+
+
+void home_mgr_relaunch_volume(void)
+{
+       process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
+}
+
+
+
+static int _power_off_cb(status_active_key_e key, void *data)
+{
+       int val = status_active_get()->sysman_power_off_status;
+
+       if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
+               s_home_mgr.power_off = 1;
+       } else {
+               s_home_mgr.power_off = 0;
+       }
+
+       _D("power off status : %d", s_home_mgr.power_off);
+
+       return 1;
+}
+
+
+
+static Eina_Bool _launch_volume_idler_cb(void *data)
+{
+       process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+void home_mgr_init(void *data)
+{
+       _D( "[MENU_DAEMON]home_mgr_init is invoked");
+
+       status_active_register_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb, NULL);
+       status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
+       status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name, NULL);
+       _change_selected_package_name(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, NULL);
+
+       ecore_idler_add(_launch_volume_idler_cb, NULL);
+}
+
+
+
+void home_mgr_fini(void)
+{
+       if (s_home_mgr.volume_pid > 0) {
+               process_mgr_terminate_app(s_home_mgr.volume_pid, 1);
+               s_home_mgr.volume_pid = -1;
+       }
+
+       status_active_unregister_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb);
+       status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
+       status_active_unregister_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name);
+}
+
+
+
+// End of a file
diff --git a/src/common/hw_key.c b/src/common/hw_key.c
new file mode 100644 (file)
index 0000000..c7a615d
--- /dev/null
@@ -0,0 +1,959 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_X11
+
+#include <app.h>
+#include <bundle.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <Ecore_Input.h>
+#include <dd-deviced.h>
+#include <syspopup_caller.h>
+#include <utilX.h>
+#include <vconf.h>
+#include <system/media_key.h>
+#include <aul.h>
+#include <feedback.h>
+#include <system_settings.h>
+
+#include "hw_key.h"
+#include "home_mgr.h"
+#include "util.h"
+#include "dbus_util.h"
+#include "lock_mgr.h"
+#include "status.h"
+#include "process_mgr.h"
+#include "lock_pwd_util.h"
+
+#define APPID_CAMERA "org.tizen.camera-app"
+#define APPID_CALLLOG "org.tizen.calllog"
+#define APPID_MUSIC_PLAYER "org.tizen.music-player"
+#define APPID_TASKMGR "org.tizen.task-mgr"
+#define APPID_BROWSER "org.tizen.browser"
+#define APPID_EMAIL "org.tizen.email"
+#define APPID_DIALER "org.tizen.phone"
+
+#define STR_ATOM_XKEY_COMPOSITION "_XKEY_COMPOSITION"
+#define STR_ATOM_KEYROUTER_NOTIWINDOW "_KEYROUTER_NOTIWINDOW"
+
+#define LONG_PRESS_TIMER_SEC 0.4
+#define HOMEKEY_TIMER_SEC 0.2
+#define CANCEL_KEY_TIMER_SEC 0.3
+
+static struct {
+       Ecore_X_Window win;
+       Ecore_Event_Handler *key_up;
+       Ecore_Event_Handler *key_down;
+       Ecore_Timer *home_long_press_timer;
+       Ecore_Timer *home_multi_press_timer;
+       Eina_Bool cancel;
+       Ecore_X_Window keyrouter_notiwindow;
+       int homekey_count;
+} key_info = {
+       .win = 0x0,
+       .key_up = NULL,
+       .key_down = NULL,
+       .home_long_press_timer = NULL,
+       .home_multi_press_timer = NULL,
+       .cancel = EINA_FALSE,
+       .keyrouter_notiwindow = 0x0,
+       .homekey_count = 0,
+};
+
+
+
+static void _after_launch_taskmgr(int pid)
+{
+       if(0 < pid) {
+               if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
+                       _E("failed to send oom dbus signal");
+               }
+       }
+}
+
+
+
+static Eina_Bool _launch_taskmgr_cb(void* data)
+{
+       int val = -1;
+
+       _D("Launch TASKMGR");
+
+       key_info.home_long_press_timer = NULL;
+
+       if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
+               _E("Cannot get VCONFKEY for lock state");
+       } else if (VCONFKEY_IDLE_LOCK == val) {
+               _E("lock state, ignore home key long press..!!");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       process_mgr_must_launch(APPID_TASKMGR, NULL, NULL, NULL, _after_launch_taskmgr);
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static void _release_multimedia_key(const char *value)
+{
+       ret_if(NULL == value);
+       _D("Multimedia key is released with %s", value);
+       process_mgr_must_launch(APPID_MUSIC_PLAYER, "multimedia_key", value, NULL, NULL);
+}
+
+
+
+static Eina_Bool _launch_by_home_key(void *data)
+{
+       int ret = 0;
+
+       if (status_passive_get()->idle_lock_state > VCONFKEY_IDLE_UNLOCK) {
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       ret = home_mgr_open_home(NULL);
+       if(ret > 0) {
+               dbus_util_send_home_raise_signal();
+       }
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static Eina_Bool _home_multi_press_timer_cb(void *data)
+{
+       _W("homekey count[%d]", key_info.homekey_count);
+
+       key_info.home_multi_press_timer = NULL;
+
+       if(0 == key_info.homekey_count % 2) {
+               key_info.homekey_count = 0;
+               return ECORE_CALLBACK_CANCEL;
+       } else if(key_info.homekey_count >= 3) {
+               key_info.homekey_count = 0;
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /* Single homekey operation */
+       key_info.homekey_count = 0;
+       _launch_by_home_key(data);
+
+       return ECORE_CALLBACK_CANCEL;
+
+}
+
+
+
+#define SERVICE_OPERATION_POPUP_SEARCH "http://samsung.com/appcontrol/operation/search"
+#define SEARCH_PKG_NAME "org.tizen.sfinder"
+static int _launch_search(void)
+{
+       app_control_h app_control;
+       int ret = APP_CONTROL_ERROR_NONE;
+
+       app_control_create(&app_control);
+       app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
+       app_control_set_app_id(app_control, SEARCH_PKG_NAME);
+
+       ret = app_control_send_launch_request(app_control, NULL, NULL);
+
+       if(ret != APP_CONTROL_ERROR_NONE) {
+               _E("Cannot launch search!! err[%d]", ret);
+       }
+
+       app_control_destroy(app_control);
+       return ret;
+}
+
+
+
+static void _cancel_key_events(void)
+{
+       key_info.homekey_count = 0;
+
+       if (key_info.home_long_press_timer) {
+               ecore_timer_del(key_info.home_long_press_timer);
+               key_info.home_long_press_timer = NULL;
+       }
+
+       if(key_info.home_multi_press_timer) {
+               ecore_timer_del(key_info.home_multi_press_timer);
+               key_info.home_multi_press_timer = NULL;
+       }
+}
+
+
+
+static Eina_Bool _key_release_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Up *ev = event;
+
+       retv_if(!ev, ECORE_CALLBACK_RENEW);
+       retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
+
+       _D("_key_release_cb : %s Released", ev->keyname);
+
+       /* Priority 1 : Cancel event */
+       if (!strcmp(ev->keyname, KEY_CANCEL)) {
+               _D("CANCEL Key is released");
+               key_info.cancel = EINA_FALSE;
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       if (EINA_TRUE == key_info.cancel) {
+               _D("CANCEL is on");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 2 : Execute before checking the lock status */
+       if (!strcmp(ev->keyname, KEY_MEDIA)) {
+               _release_multimedia_key("KEY_PLAYCD");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 3 : Check the lock status */
+       if ((status_passive_get()->idle_lock_state  == VCONFKEY_IDLE_LOCK)
+               && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
+               if (!strcmp(ev->keyname, KEY_BACK)) {
+                       _D("Back key is released");
+                       lock_pwd_util_back_key_relased();
+               } else {
+                       _D("phone lock state, ignore home key.");
+               }
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 4 : These keys are only activated after checking the lock state */
+       if (!strcmp(ev->keyname, KEY_END)) {
+       } else if (!strcmp(ev->keyname, KEY_CONFIG)) {
+       } else if (!strcmp(ev->keyname, KEY_SEND)) {
+       } else if (!strcmp(ev->keyname, KEY_HOME)) {
+               _W("Home Key is released");
+
+               syspopup_destroy_all();
+
+               if(key_info.home_multi_press_timer) {
+                       _D("delete homekey timer");
+                       ecore_timer_del(key_info.home_multi_press_timer);
+                       key_info.home_multi_press_timer = NULL;
+               }
+
+               if (key_info.home_long_press_timer) {
+                       ecore_timer_del(key_info.home_long_press_timer);
+                       key_info.home_long_press_timer = NULL;
+               } else {
+                       key_info.homekey_count = 0;
+                       return ECORE_CALLBACK_RENEW;
+               }
+
+               key_info.home_multi_press_timer = ecore_timer_add(HOMEKEY_TIMER_SEC, _home_multi_press_timer_cb, NULL);
+               if (!key_info.home_multi_press_timer) {
+                       _E("Critical! cannot add a timer for home multi press");
+               }
+               return ECORE_CALLBACK_RENEW;
+       } else if (!strcmp(ev->keyname, KEY_PAUSE)) {
+       } else if (!strcmp(ev->keyname, KEY_APPS)) {
+               _D("App tray key is released");
+       } else if (!strcmp(ev->keyname, KEY_TASKSWITCH)) {
+               _D("Task switch key is released");
+               _launch_taskmgr_cb(NULL);
+       } else if (!strcmp(ev->keyname, KEY_WEBPAGE)) {
+               _D("Web page key is released");
+               process_mgr_must_open(APPID_BROWSER, NULL, NULL);
+       } else if (!strcmp(ev->keyname, KEY_MAIL)) {
+               _D("Mail key is released");
+               process_mgr_must_open(APPID_EMAIL, NULL, NULL);
+       } else if (!strcmp(ev->keyname, KEY_CONNECT)) {
+               _D("Connect key is released");
+               process_mgr_must_open(APPID_DIALER, NULL, NULL);
+       } else if (!strcmp(ev->keyname, KEY_SEARCH)) {
+               _D("Search key is released");
+               if (_launch_search() < 0) {
+                       _E("Failed to launch the search");
+               }
+       } else if (!strcmp(ev->keyname, KEY_VOICE)) {
+               _D("Voice key is released");
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+
+static Eina_Bool _key_press_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Down *ev = event;
+
+       retv_if(!ev, ECORE_CALLBACK_RENEW);
+       retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
+
+       _D("_key_press_cb : %s Pressed", ev->keyname);
+
+       /* Priority 1 : Cancel */
+       /*              every reserved events have to be canceld when cancel key is pressed */
+       if (!strcmp(ev->keyname, KEY_CANCEL)) {
+               _D("Cancel button is pressed");
+               key_info.cancel = EINA_TRUE;
+               _cancel_key_events();
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       if (EINA_TRUE == key_info.cancel) {
+               _D("CANCEL is on");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 2 : Check the lock status */
+       if ((status_passive_get()->idle_lock_state == VCONFKEY_IDLE_LOCK)
+               && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
+               _D("phone lock state, ignore key events.");
+               _cancel_key_events();
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 3 : other keys */
+       if (!strcmp(ev->keyname, KEY_SEND)) {
+               _D("Launch calllog");
+               process_mgr_must_open(APPID_CALLLOG, NULL, NULL);
+       } else if(!strcmp(ev->keyname, KEY_CONFIG)) {
+               _D("Launch camera");
+               process_mgr_must_open(APPID_CAMERA, NULL, NULL);
+       } else if (!strcmp(ev->keyname, KEY_HOME)) {
+               _W("Home Key is pressed");
+               if (key_info.home_long_press_timer) {
+                       ecore_timer_del(key_info.home_long_press_timer);
+                       key_info.home_long_press_timer = NULL;
+               }
+
+               key_info.homekey_count++;
+               _W("homekey count : %d", key_info.homekey_count);
+
+               if(key_info.home_multi_press_timer) {
+                       ecore_timer_del(key_info.home_multi_press_timer);
+                       key_info.home_multi_press_timer = NULL;
+                       _D("delete homekey timer");
+               }
+
+               _D("create long press timer");
+               key_info.home_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _launch_taskmgr_cb, NULL);
+               if (!key_info.home_long_press_timer) {
+                       _E("Failed to add timer for long press detection");
+               }
+       } else if (!strcmp(ev->keyname, KEY_MEDIA)) {
+               _D("Media key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_APPS)) {
+               _D("App tray key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_TASKSWITCH)) {
+               _D("Task switch key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_WEBPAGE)) {
+               _D("Web page key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_MAIL)) {
+               _D("Mail key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_SEARCH)) {
+               _D("Search key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_VOICE)) {
+               _D("Voice key is pressed");
+       } else if (!strcmp(ev->keyname, KEY_CONNECT)) {
+               _D("Connect key is pressed");
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+
+void _media_key_event_cb(media_key_e key, media_key_event_e status, void *user_data)
+{
+       _D("MEDIA KEY EVENT : %d", key);
+       if (MEDIA_KEY_STATUS_PRESSED == status) return;
+
+       switch (key) {
+       case MEDIA_KEY_PAUSE:
+               _release_multimedia_key("KEY_PAUSECD");
+               break;
+       case MEDIA_KEY_PLAY:
+               _release_multimedia_key("KEY_PLAYCD");
+               break;
+       case MEDIA_KEY_PLAYPAUSE:
+               _release_multimedia_key("KEY_PLAYPAUSECD");
+               break;
+       default:
+               _E("cannot reach here, key[%d]", key);
+               break;
+       }
+}
+
+
+
+void hw_key_create_window(void)
+{
+       int ret;
+       Ecore_X_Atom atomNotiWindow;
+       Ecore_X_Window keyrouter_notiwindow;
+
+       key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1);
+       if (!key_info.win) {
+               _D("Failed to create hidden window");
+               return;
+       }
+       ecore_x_event_mask_unset(key_info.win, ECORE_X_EVENT_MASK_NONE);
+       ecore_x_icccm_title_set(key_info.win, "menudaemon,key,receiver");
+       ecore_x_netwm_name_set(key_info.win, "menudaemon,key,receiver");
+       ecore_x_netwm_pid_set(key_info.win, getpid());
+
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_HOME, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_APPS, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_TASKSWITCH, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_WEBPAGE, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MAIL, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_SEARCH, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOICE, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CONNECT, SHARED_GRAB);
+       utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_POWER, SHARED_GRAB);
+
+       key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
+       if (!key_info.key_up)
+               _E("Failed to register a key up event handler");
+
+       key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
+       if (!key_info.key_down)
+               _E("Failed to register a key down event handler");
+
+       /* Get notifwindow */
+       atomNotiWindow = ecore_x_atom_get(STR_ATOM_KEYROUTER_NOTIWINDOW);
+       ret = ecore_x_window_prop_window_get(ecore_x_window_root_first_get(), atomNotiWindow, &keyrouter_notiwindow, 1);
+       if (ret > 0) {
+               _D("Succeed to get keyrouter notiwindow ! ret = %d (win=0x%x)\n"
+                               , ret, keyrouter_notiwindow);
+               ecore_x_window_sniff(keyrouter_notiwindow);
+               key_info.keyrouter_notiwindow = keyrouter_notiwindow;
+       } else {
+               _E("Failed to get keyrouter notiwindow! ret = %d, atomNotiWindow = 0x%x, keyrouter_notiwindow = 0x%x"
+                               , ret, atomNotiWindow, keyrouter_notiwindow);
+       }
+
+       media_key_reserve(_media_key_event_cb, NULL);
+}
+
+
+
+void hw_key_destroy_window(void)
+{
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_HOME);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONFIG);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_APPS);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_TASKSWITCH);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_WEBPAGE);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MAIL);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_SEARCH);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOICE);
+       utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CONNECT);
+
+       if (key_info.key_up) {
+               ecore_event_handler_del(key_info.key_up);
+               key_info.key_up = NULL;
+       }
+
+       if (key_info.key_down) {
+               ecore_event_handler_del(key_info.key_down);
+               key_info.key_down = NULL;
+       }
+
+       ecore_x_window_delete_request_send(key_info.win);
+       key_info.win = 0x0;
+
+       media_key_release();
+}
+
+#elif HAVE_WAYLAND
+
+#include <app.h>
+#include <bundle.h>
+#include <Elementary.h>
+#include <Ecore.h>
+#include <Ecore_Wayland.h>
+#include <Ecore_Input.h>
+#include <dd-deviced.h>
+#include <syspopup_caller.h>
+#include <vconf.h>
+#include <system/media_key.h>
+#include <aul.h>
+#include <feedback.h>
+#include <system_settings.h>
+
+#include "hw_key.h"
+#include "home_mgr.h"
+#include "util.h"
+#include "dbus_util.h"
+#include "lock_mgr.h"
+#include "status.h"
+#include "process_mgr.h"
+
+#define APPID_CAMERA "org.tizen.camera-app"
+#define APPID_CALLLOG "org.tizen.calllog"
+#define APPID_MUSIC_PLAYER "org.tizen.music-player"
+#define APPID_TASKMGR "org.tizen.task-mgr"
+#define APPID_BROWSER "org.tizen.browser"
+#define APPID_EMAIL "org.tizen.email"
+#define APPID_DIALER "org.tizen.phone"
+
+#define STR_ATOM_KEYROUTER_NOTIWINDOW "_KEYROUTER_NOTIWINDOW"
+
+#define LONG_PRESS_TIMER_SEC 0.4
+#define HOMEKEY_TIMER_SEC 0.2
+#define CANCEL_KEY_TIMER_SEC 0.3
+
+
+const char *key_name[KEY_NAME_MAX] = {
+       "XF86AudioRaiseVolume",
+       "XF86AudioLowerVolume",
+       "XF86PowerOff",
+       "XF86Menu",
+       "XF86Home",
+       "XF86Back",
+       "XF86Camera",
+       "XF86Camera_Full",
+       "XF86Search",
+       "XF86AudioPlay",
+       "XF86AudioPause",
+       "XF86AudioStop",
+       "XF86AudioNext",
+       "XF86AudioPrev",
+       "XF86AudioRewind",
+       "XF86AudioForward",
+       "XF86AudioMedia",
+       "XF86AudioPlayPause",
+       "XF86AudioMute",
+       "XF86AudioRecord",
+       "Cancel",
+       "XF86SoftKBD",
+       "XF86QuickPanel",
+       "XF86TaskPane",
+       "XF86HomePage",
+       "XF86WWW",
+       "XF86Mail",
+       "XF86ScreenSaver",
+       "XF86MonBrightnessDown",
+       "XF86MonBrightnessUp",
+       "XF86Voice",
+       "Hangul",
+       "XF86Apps",
+       "XF86Call",
+       "XF86Game",
+       "XF86VoiceWakeUp_LPSD",
+       "XF86VoiceWakeUp",
+       "KEY_NAME_MAX",
+};
+
+
+static struct {
+       Ecore_Event_Handler *key_up;
+       Ecore_Event_Handler *key_down;
+       Ecore_Timer *home_long_press_timer;
+       Ecore_Timer *home_multi_press_timer;
+       Ecore_Timer *keygrab_timer;
+       Eina_Bool cancel;
+       int homekey_count;
+} key_info = {
+       .key_up = NULL,
+       .key_down = NULL,
+       .home_long_press_timer = NULL,
+       .home_multi_press_timer = NULL,
+       .keygrab_timer = NULL,
+       .cancel = EINA_FALSE,
+       .homekey_count = 0,
+};
+
+
+
+
+static void _cancel_key_events(void)
+{
+       key_info.homekey_count = 0;
+
+       if (key_info.home_long_press_timer) {
+               ecore_timer_del(key_info.home_long_press_timer);
+               key_info.home_long_press_timer = NULL;
+       }
+
+       if(key_info.home_multi_press_timer) {
+               ecore_timer_del(key_info.home_multi_press_timer);
+               key_info.home_multi_press_timer = NULL;
+       }
+}
+
+
+
+#define SERVICE_OPERATION_POPUP_SEARCH "http://samsung.com/appcontrol/operation/search"
+#define SEARCH_PKG_NAME "org.tizen.sfinder"
+static int _launch_search(void)
+{
+       app_control_h app_control;
+       int ret = APP_CONTROL_ERROR_NONE;
+
+       app_control_create(&app_control);
+       app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
+       app_control_set_app_id(app_control, SEARCH_PKG_NAME);
+
+       ret = app_control_send_launch_request(app_control, NULL, NULL);
+
+       if(ret != APP_CONTROL_ERROR_NONE) {
+               _E("Cannot launch search!! err[%d]", ret);
+       }
+
+       app_control_destroy(app_control);
+       return ret;
+}
+
+
+
+static void _after_launch_taskmgr(int pid)
+{
+       if(0 < pid) {
+               if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
+                       _E("failed to send oom dbus signal");
+               }
+       }
+}
+
+
+
+static Eina_Bool _launch_taskmgr_cb(void* data)
+{
+       int val = -1;
+
+       _D("Launch TASKMGR");
+
+       key_info.home_long_press_timer = NULL;
+
+       if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
+               _E("Cannot get VCONFKEY for lock state");
+       } else if (VCONFKEY_IDLE_LOCK == val) {
+               _E("lock state, ignore home key long press..!!");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       process_mgr_must_launch(APPID_TASKMGR, NULL, NULL, NULL, _after_launch_taskmgr);
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static Eina_Bool _launch_by_home_key(void *data)
+{
+       int ret = 0;
+
+       if (status_passive_get()->idle_lock_state > VCONFKEY_IDLE_UNLOCK) {
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       ret = home_mgr_open_home(NULL);
+       if(ret > 0) {
+               dbus_util_send_home_raise_signal();
+       }
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static Eina_Bool _home_multi_press_timer_cb(void *data)
+{
+       _W("homekey count[%d]", key_info.homekey_count);
+
+       key_info.home_multi_press_timer = NULL;
+
+       if(0 == key_info.homekey_count % 2) {
+               key_info.homekey_count = 0;
+               return ECORE_CALLBACK_CANCEL;
+       } else if(key_info.homekey_count >= 3) {
+               key_info.homekey_count = 0;
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /* Single homekey operation */
+       key_info.homekey_count = 0;
+       _launch_by_home_key(data);
+
+       return ECORE_CALLBACK_CANCEL;
+
+}
+
+
+
+static void _release_multimedia_key(const char *value)
+{
+       ret_if(NULL == value);
+       _D("Multimedia key is released with %s", value);
+       process_mgr_must_launch(APPID_MUSIC_PLAYER, "multimedia_key", value, NULL, NULL);
+}
+
+
+
+static Eina_Bool _key_release_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Up *ev = event;
+
+       retv_if(!ev, ECORE_CALLBACK_RENEW);
+       retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
+
+       _D("_key_release_cb : %s Released", ev->keyname);
+
+       /* Priority 1 : Cancel event */
+       if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
+               _D("CANCEL Key is released");
+               key_info.cancel = EINA_FALSE;
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       if (EINA_TRUE == key_info.cancel) {
+               _D("CANCEL is on");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 2 : Execute before checking the lock status */
+       if (!strcmp(ev->keyname, key_name[KEY_MEDIA])) {
+               _release_multimedia_key("KEY_PLAYCD");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 3 : Check the lock status */
+       if ((status_passive_get()->idle_lock_state  == VCONFKEY_IDLE_LOCK)
+               && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
+               if (!strcmp(ev->keyname, key_name[KEY_BACK])) {
+                       _D("Back key is released");
+               } else {
+                       _D("phone lock state, ignore home key.");
+               }
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 4 : These keys are only activated after checking the lock state */
+       if (!strcmp(ev->keyname, key_name[KEY_HOME])) {
+               _W("Home Key is released");
+
+               syspopup_destroy_all();
+
+               if(key_info.home_multi_press_timer) {
+                       _D("delete homekey timer");
+                       ecore_timer_del(key_info.home_multi_press_timer);
+                       key_info.home_multi_press_timer = NULL;
+               }
+
+               if (key_info.home_long_press_timer) {
+                       ecore_timer_del(key_info.home_long_press_timer);
+                       key_info.home_long_press_timer = NULL;
+               } else {
+                       key_info.homekey_count = 0;
+                       return ECORE_CALLBACK_RENEW;
+               }
+
+               key_info.home_multi_press_timer = ecore_timer_add(HOMEKEY_TIMER_SEC, _home_multi_press_timer_cb, NULL);
+               if (!key_info.home_multi_press_timer) {
+                       _E("Critical! cannot add a timer for home multi press");
+               }
+               return ECORE_CALLBACK_RENEW;
+       } else if (!strcmp(ev->keyname, key_name[KEY_APPS])) {
+               _D("App tray key is released");
+       } else if (!strcmp(ev->keyname, key_name[KEY_TASKSWITCH])) {
+               _D("Task switch key is released");
+               _launch_taskmgr_cb(NULL);
+       } else if (!strcmp(ev->keyname, key_name[KEY_WEBPAGE])) {
+               _D("Web page key is released");
+               process_mgr_must_open(APPID_BROWSER, NULL, NULL);
+       } else if (!strcmp(ev->keyname, key_name[KEY_MAIL])) {
+               _D("Mail key is released");
+               process_mgr_must_open(APPID_EMAIL, NULL, NULL);
+       } else if (!strcmp(ev->keyname, key_name[KEY_CONNECT])) {
+               _D("Connect key is released");
+               process_mgr_must_open(APPID_DIALER, NULL, NULL);
+       } else if (!strcmp(ev->keyname, key_name[KEY_SEARCH])) {
+               _D("Search key is released");
+               if (_launch_search() < 0) {
+                       _E("Failed to launch the search");
+               }
+       } else if (!strcmp(ev->keyname, key_name[KEY_VOICE])) {
+               _D("Voice key is released");
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+
+static Eina_Bool _key_press_cb(void *data, int type, void *event)
+{
+       Evas_Event_Key_Down *ev = event;
+
+       retv_if(!ev, ECORE_CALLBACK_RENEW);
+       retv_if(!ev->keyname, ECORE_CALLBACK_RENEW);
+
+       _D("_key_press_cb : %s Pressed", ev->keyname);
+
+       /* Priority 1 : Cancel */
+       /*              every reserved events have to be canceld when cancel key is pressed */
+       if (!strcmp(ev->keyname, key_name[KEY_CANCEL])) {
+               _D("Cancel button is pressed");
+               key_info.cancel = EINA_TRUE;
+               _cancel_key_events();
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       if (EINA_TRUE == key_info.cancel) {
+               _D("CANCEL is on");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 2 : Check the lock status */
+       if ((status_passive_get()->idle_lock_state == VCONFKEY_IDLE_LOCK)
+               && (status_active_get()->setappl_screen_lock_type_int > SETTING_SCREEN_LOCK_TYPE_NONE)) {
+               _D("phone lock state, ignore key events.");
+               _cancel_key_events();
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Priority 3 : other keys */
+#if 0
+       if (!strcmp(ev->keyname, key_name[KEY_SEND])) {
+               _D("Launch calllog");
+               process_mgr_must_open(APPID_CALLLOG, NULL, NULL);
+       } else
+#endif
+       if(!strcmp(ev->keyname, key_name[KEY_CONFIG])) {
+               _D("Launch camera");
+               process_mgr_must_open(APPID_CAMERA, NULL, NULL);
+       } else if (!strcmp(ev->keyname, key_name[KEY_HOME])) {
+               _W("Home Key is pressed");
+               if (key_info.home_long_press_timer) {
+                       ecore_timer_del(key_info.home_long_press_timer);
+                       key_info.home_long_press_timer = NULL;
+               }
+
+               key_info.homekey_count++;
+               _W("homekey count : %d", key_info.homekey_count);
+
+               if(key_info.home_multi_press_timer) {
+                       ecore_timer_del(key_info.home_multi_press_timer);
+                       key_info.home_multi_press_timer = NULL;
+                       _D("delete homekey timer");
+               }
+
+               _D("create long press timer");
+               key_info.home_long_press_timer = ecore_timer_add(LONG_PRESS_TIMER_SEC, _launch_taskmgr_cb, NULL);
+               if (!key_info.home_long_press_timer) {
+                       _E("Failed to add timer for long press detection");
+               }
+       } else if (!strcmp(ev->keyname, key_name[KEY_MEDIA])) {
+               _D("Media key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_APPS])) {
+               _D("App tray key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_TASKSWITCH])) {
+               _D("Task switch key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_WEBPAGE])) {
+               _D("Web page key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_MAIL])) {
+               _D("Mail key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_SEARCH])) {
+               _D("Search key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_VOICE])) {
+               _D("Voice key is pressed");
+       } else if (!strcmp(ev->keyname, key_name[KEY_CONNECT])) {
+               _D("Connect key is pressed");
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+
+
+static Eina_Bool __keygrab_timer_cb(void *data)
+{
+       int i = 0;
+       int ret = 0;
+
+       for (i = 0; i < KEY_NAME_MAX; i++) {
+               ret = ecore_wl_window_keygrab_set(NULL, key_name[i], 0, 0, 0, ECORE_WL_WINDOW_KEYGRAB_SHARED);
+               _D("key grab : %s / ret : %d", key_name[i], ret);
+       }
+
+       key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
+       if (!key_info.key_up) {
+               _E("Failed to register a key up event handler");
+       }
+
+       key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
+       if (!key_info.key_down) {
+               _E("Failed to register a key down event handler");
+       }
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+void hw_key_create_window(void)
+{
+       if (key_info.keygrab_timer) {
+               ecore_timer_del(key_info.keygrab_timer);
+               key_info.keygrab_timer = NULL;
+       }
+
+       key_info.keygrab_timer = ecore_timer_add(1.0f, __keygrab_timer_cb, NULL);
+       if (!key_info.keygrab_timer) {
+               _E("Failed to add timer for keygrab");
+       }
+}
+
+
+
+void hw_key_destroy_window(void)
+{
+       int i = 0;
+
+       for (i = 0; i < KEY_NAME_MAX; i++) {
+               ecore_wl_window_keygrab_unset(NULL, key_name[i], 0, 0);
+       }
+
+       if (key_info.keygrab_timer) {
+               ecore_timer_del(key_info.keygrab_timer);
+               key_info.keygrab_timer = NULL;
+       }
+
+       if (key_info.key_up) {
+               ecore_event_handler_del(key_info.key_up);
+               key_info.key_up = NULL;
+       }
+
+       if (key_info.key_down) {
+               ecore_event_handler_del(key_info.key_down);
+               key_info.key_down = NULL;
+       }
+}
+
+#endif
+
+// End of a file
diff --git a/src/common/lock_mgr.c b/src/common/lock_mgr.c
new file mode 100644 (file)
index 0000000..f68fc9a
--- /dev/null
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <feedback.h>
+#include <time.h>
+#include <dd-deviced.h>
+#include <dd-display.h>
+#include <aul.h>
+#include <system_settings.h>
+
+#include "lock_mgr.h"
+#include "package_mgr.h"
+#include "process_mgr.h"
+#include "hw_key.h"
+#include "dbus_util.h"
+#include "util.h"
+#include "status.h"
+
+#define PASSWORD_LOCK_PROGRESS "/tmp/.passwordlock"
+
+static struct {
+       int checkfd;
+       alarm_id_t alarm_id;    /* -1 : None, others : set alarm */
+       Eina_Bool is_alarm;     /* EINA_TRUE : can use alarm EINA_FALSE : cannot use */
+
+       int old_lock_type;
+       int lock_pid;
+       int lcd_state;
+
+#ifdef HAVE_X11
+       lockw_data *lockw;
+#endif
+} s_lock_mgr = {
+       .checkfd = 0,
+       .alarm_id = -1,
+       .is_alarm = EINA_FALSE,
+
+       .old_lock_type = 0,
+       .lock_pid = -1,
+       .lcd_state = -1,
+
+#ifdef HVAE_X11
+       .lockw = NULL,
+#endif
+};
+
+
+
+int lock_mgr_lcd_state_get(void)
+{
+       return s_lock_mgr.lcd_state;
+}
+
+
+
+int lock_mgr_get_lock_pid(void)
+{
+       return s_lock_mgr.lock_pid;
+}
+
+
+
+static int _alarm_del(alarm_id_t id, void * user_param)
+{
+       int ret = ALARMMGR_RESULT_SUCCESS;
+
+       _D("delete alarm id : %d", id);
+
+       ret = alarmmgr_remove_alarm(id);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               _E("Failed to remove alarm(%d)", ret );
+       }
+
+       return 0;
+}
+
+
+
+static void _alarm_unset(void)
+{
+       int ret = ALARMMGR_RESULT_SUCCESS;
+
+       ret = alarmmgr_enum_alarm_ids(_alarm_del, NULL);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               _E("Failed to get list of alarm ids");
+       }
+}
+
+
+
+static void _alarm_lockscreen_launch(alarm_id_t alarm_id, void *data)
+{
+       int ret = ALARMMGR_RESULT_SUCCESS;
+
+       _D("alarm id : %d", alarm_id);
+
+       /* launch lockscreen */
+       if (!lock_mgr_lockscreen_launch()) {
+               _E("Failed to launch lockscreen");
+       }
+
+       if (alarm_id != -1) {
+               if (alarm_id != s_lock_mgr.alarm_id) {
+                       _E("alarm ids are different callback->id(%d), s_lock_mgr.alarm_id(%d)", alarm_id, s_lock_mgr.alarm_id);
+                       /* delete all registering alarm*/
+                       _alarm_unset();
+                       s_lock_mgr.alarm_id = -1;
+               } else {
+                       ret = alarmmgr_remove_alarm(alarm_id);
+                       if (ret != ALARMMGR_RESULT_SUCCESS) {
+                               _E("Failed to remove alaram(%d)", ret);
+                               /* delete all registering alarm*/
+                               _alarm_unset();
+                       }
+                       s_lock_mgr.alarm_id = -1;
+               }
+       }
+}
+
+
+
+static Eina_Bool _alarm_set(int sec)
+{
+       time_t current_time;
+       struct tm current_tm;
+       alarm_entry_t *alarm_info;
+       alarm_id_t alarm_id;
+       alarm_date_t alarm_time;
+       int ret = ALARMMGR_RESULT_SUCCESS;
+
+       /* delete before registering alarm ids */
+       if (s_lock_mgr.alarm_id != -1){
+               _E("ad->alarm_id(%d) deleted", s_lock_mgr.alarm_id);
+               ret = alarmmgr_remove_alarm(s_lock_mgr.alarm_id);
+               if (ret != ALARMMGR_RESULT_SUCCESS) {
+                       _E("Failed to remove alarm(%d) : %d", ret, s_lock_mgr.alarm_id);
+                       _alarm_unset();
+               }
+               s_lock_mgr.alarm_id = -1;
+       }
+
+       /* set alarm after sec */
+       time(&current_time);
+
+       _D("after %d SEC.s alarm set", sec);
+       localtime_r(&current_time, &current_tm);
+
+       alarm_info = alarmmgr_create_alarm();
+       retv_if(!alarm_info, EINA_FALSE);
+
+       alarm_time.year = 0;
+       alarm_time.month = 0;
+       alarm_time.day = 0;
+       alarm_time.hour = current_tm.tm_hour;
+       alarm_time.min = current_tm.tm_min;
+       alarm_time.sec = current_tm.tm_sec + sec;
+
+       alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_ONCE, 0);
+       alarmmgr_set_time(alarm_info, alarm_time);
+       alarmmgr_set_type(alarm_info, ALARM_TYPE_VOLATILE);
+
+       ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               _E("Failed to add alarm with localtime(%d)", ret);
+               alarmmgr_free_alarm(alarm_info) ;
+               return EINA_FALSE;
+       }
+
+       _D("alarm id(%d) is set", alarm_id);
+       s_lock_mgr.alarm_id = alarm_id;
+       alarmmgr_free_alarm(alarm_info) ;
+
+       return EINA_TRUE;
+}
+
+
+
+static Eina_Bool _alarm_init(void)
+{
+       int ret = 0;
+
+       /* alarm id initialize */
+       s_lock_mgr.alarm_id = -1;
+
+       ret = alarmmgr_init(PACKAGE_NAME);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               _E("Failed to initialize alarmmgr(%d)", ret);
+               return EINA_FALSE;
+       }
+
+       ret = alarmmgr_set_cb((alarm_cb_t)_alarm_lockscreen_launch, NULL);
+       if (ret != ALARMMGR_RESULT_SUCCESS) {
+               _E("Failed to set cb func(%d)", ret);
+               return EINA_FALSE;
+       }
+
+       _D("alarm init success");
+
+       return EINA_TRUE;
+}
+
+
+
+
+void lock_mgr_sound_play(lock_sound_type_e type)
+{
+       int val = status_passive_get()->setappl_sound_lock_bool;
+       ret_if(!val);
+
+       switch(type) {
+       case LOCK_SOUND_LOCK:
+               feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_LOCK);
+               break;
+       case LOCK_SOUND_UNLOCK:
+               feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
+               break;
+       case LOCK_SOUND_BTN_KEY:
+               feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_SIP);
+               break;
+       case LOCK_SOUND_TAP:
+               feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_TAP);
+               break;
+       default:
+               break;
+       }
+}
+
+
+
+void lock_mgr_idle_lock_state_set(int lock_state)
+{
+       _D("lock state : %d", lock_state);
+
+       int ret = 0;
+
+       ret = vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, lock_state);
+       if (ret < 0) {
+               _E("Failed to set vconfkey : VCONFKEY_IDLE_LOCK_STATE");
+       }
+}
+
+
+
+static void _after_launch_lock(int pid)
+{
+       int idle_lock_state = 0;
+
+       if (dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0) {
+               _E("cannot send oomadj for pid[%d]", pid);
+       }
+       process_mgr_set_lock_priority(pid);
+       display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+       s_lock_mgr.lock_pid = pid;
+
+       idle_lock_state = status_passive_get()->idle_lock_state;
+       if (!idle_lock_state) {
+               lock_mgr_idle_lock_state_set(VCONFKEY_IDLE_LOCK);
+               lock_mgr_sound_play(LOCK_SOUND_LOCK);
+       }
+}
+
+
+
+static int _lock_changed_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
+{
+       _D("%s", __func__);
+
+       return 0;
+}
+
+
+
+static void _other_lockscreen_unlock(void)
+{
+       _D("unlock other lock screen");
+
+#ifdef HAVE_X11
+       window_mgr_unregister_event(s_lock_mgr.lockw);
+       window_mgr_fini(s_lock_mgr.lockw);
+       s_lock_mgr.lockw = NULL;
+#endif
+}
+
+
+
+static Eina_Bool _lock_create_cb(void *data, int type, void *event)
+{
+#ifdef HAVE_X11
+       _D("lockw(%p), lock_pid(%d)", s_lock_mgr.lockw, s_lock_mgr.lock_pid);
+
+       if (window_mgr_set_effect(s_lock_mgr.lockw, s_lock_mgr.lock_pid, event) == EINA_TRUE) {
+               //FIXME sometimes show cb is not called.
+               if (window_mgr_set_prop(s_lock_mgr.lockw, s_lock_mgr.lock_pid, event) == EINA_FALSE) {
+                       _E("window is not matched..!!");
+               }
+       }
+#endif
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+
+
+static Eina_Bool _lock_show_cb(void *data, int type, void *event)
+{
+#ifdef HAVE_X11
+       _D("lockw(%p), lock_pid(%d)", s_lock_mgr.lockw, s_lock_mgr.lock_pid);
+
+       if (window_mgr_set_prop(s_lock_mgr.lockw, s_lock_mgr.lock_pid, event)) {
+               int lock_type = status_active_get()->setappl_screen_lock_type_int;
+               _D("lock type : %d", lock_type);
+
+               window_mgr_set_scroll_prop(s_lock_mgr.lockw, lock_type);
+       }
+#endif
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+void lock_mgr_unlock(void)
+{
+       int lock_type = status_active_get()->setappl_screen_lock_type_int;
+       _D("lock type(%d)", lock_type);
+
+       lock_mgr_idle_lock_state_set(VCONFKEY_IDLE_UNLOCK);
+       lock_mgr_sound_play(LOCK_SOUND_UNLOCK);
+       s_lock_mgr.lock_pid = 0;
+
+       if (lock_type == SETTING_SCREEN_LOCK_TYPE_OTHER) {
+               _other_lockscreen_unlock();
+       }
+
+#ifdef HAVE_X11
+       window_mgr_unregister_event(s_lock_mgr.lockw);
+#endif
+}
+
+
+
+#define LCD_OFF_ALARM_LOCK_TIME 5
+static void _lcd_off_by_timeout(void)
+{
+       int idle_lock_state = 0;
+
+       idle_lock_state = status_passive_get()->idle_lock_state;
+       if (idle_lock_state == VCONFKEY_IDLE_LOCK) {
+               _D("VCONFKEY is set(not need to set alarm), lock_pid : %d", s_lock_mgr.lock_pid);
+               return;
+       }
+
+       if (s_lock_mgr.alarm_id != -1) {
+               _E("Alarm is set yet (alarm_id = %d) : do nothing", s_lock_mgr.alarm_id);
+               return;
+       }
+
+       if (s_lock_mgr.is_alarm) {
+               _D("set alarm %d sec", LCD_OFF_ALARM_LOCK_TIME);
+               if (_alarm_set(LCD_OFF_ALARM_LOCK_TIME) != EINA_TRUE) {
+                       _E("Failed to set alarm");
+                       _alarm_lockscreen_launch(-1, NULL);
+               }
+       } else {
+               _E("is_alarm is EINA_FALSE");
+               _alarm_lockscreen_launch(-1, NULL);
+       }
+}
+
+
+
+static void _on_lcd_changed_receive(void *data, DBusMessage *msg)
+{
+       int lcd_on = 0;
+       int lcd_off = 0;
+
+       _D("LCD signal is received");
+
+       lcd_on = dbus_message_is_signal(msg, DEVICED_INTERFACE_DISPLAY, MEMBER_LCD_ON);
+       lcd_off = dbus_message_is_signal(msg, DEVICED_INTERFACE_DISPLAY, MEMBER_LCD_OFF);
+
+       if (lcd_on) {
+               _W("LCD on");
+               s_lock_mgr.lcd_state = LCD_STATE_ON;
+
+               /* delete all alarm registering */
+               _D("delete alarm : id(%d)", s_lock_mgr.alarm_id);
+               _alarm_unset();
+               s_lock_mgr.alarm_id = -1;
+       } else if (lcd_off) {
+               s_lock_mgr.lcd_state = LCD_STATE_OFF;
+
+               int idle_lock_state = status_passive_get()->idle_lock_state;
+               int lock_type = status_active_get()->setappl_screen_lock_type_int;
+               _D("idle_lock_state(%d), lock type(%d)", idle_lock_state, lock_type);
+
+               if (!lock_mgr_lockscreen_launch()) {
+                       _E("Failed to launch lockscreen");
+               }
+       } else {
+               _E("%s dbus_message_is_signal error", DEVICED_INTERFACE_DISPLAY);
+       }
+}
+
+
+
+Eina_Bool lock_mgr_lockscreen_launch(void)
+{
+       const char *lock_appid = NULL;
+       int lock_type = 0;
+
+       lock_type = status_active_get()->setappl_screen_lock_type_int;
+       _D("lock type : %d", lock_type);
+
+       //PM LOCK - don't go to sleep
+       display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+
+#ifdef HAVE_X11
+       /* reset window mgr before start win mgr  */
+       window_mgr_unregister_event(s_lock_mgr.lockw);
+       window_mgr_register_event(NULL, s_lock_mgr.lockw, _lock_create_cb, _lock_show_cb);
+#endif
+
+       lock_appid = status_passive_get()->setappl_3rd_lock_pkg_name_str;
+       if (!lock_appid) {
+               _E("set default lockscreen");
+               lock_appid = STATUS_DEFAULT_LOCK_PKG_NAME;
+       }
+
+       _D("lockscreen appid : %s", lock_appid);
+
+       switch (lock_type) {
+       //case SETTING_SCREEN_LOCK_TYPE_NONE:
+       case SETTING_SCREEN_LOCK_TYPE_OTHER:
+               if (!strcmp(lock_appid, STATUS_DEFAULT_LOCK_PKG_NAME)) {
+                       _D("ignore launching lockscreen");
+               } else {
+                       process_mgr_must_launch(lock_appid, NULL, NULL, _lock_changed_cb, _after_launch_lock);
+                       //@TODO: need to check(add error popup)
+               }
+               break;
+       case SETTING_SCREEN_LOCK_TYPE_SWIPE:
+               process_mgr_must_launch(lock_appid, NULL, NULL, _lock_changed_cb, _after_launch_lock);
+               goto_if(s_lock_mgr.lock_pid < 0, ERROR);
+               break;
+       case SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD:
+       case SETTING_SCREEN_LOCK_TYPE_PASSWORD:
+               process_mgr_must_launch(lock_appid, NULL, NULL, _lock_changed_cb, _after_launch_lock);
+               goto_if(s_lock_mgr.lock_pid < 0, ERROR);
+
+               if (dbus_util_send_oomadj(s_lock_mgr.lock_pid, OOM_ADJ_VALUE_DEFAULT) < 0){
+                       _E("Failed to send oom dbus signal");
+               }
+
+               process_mgr_set_lock_priority(s_lock_mgr.lock_pid);
+               display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+               break;
+       default:
+               _E("type error(%d)", lock_type);
+               goto ERROR;
+       }
+
+       _W("lock_pid : %d", s_lock_mgr.lock_pid);
+
+       return EINA_TRUE;
+
+ERROR:
+       _E("Failed to launch lockscreen");
+
+       display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+
+       return EINA_FALSE;
+}
+
+
+
+static void _lock_daemon_init(void)
+{
+       _SECURE_D("default lock screen pkg name is %s", status_passive_get()->setappl_3rd_lock_pkg_name_str);
+
+       /* init alarm manager */
+       s_lock_mgr.is_alarm = _alarm_init();
+
+       /* register lcd changed cb */
+       dbus_util_receive_lcd_status(_on_lcd_changed_receive, NULL);
+
+#ifdef HAVE_X11
+       /* Create internal 1x1 window */
+       s_lock_mgr.lockw = window_mgr_init();
+#endif
+}
+
+
+
+static int _lock_type_changed_cb(status_active_key_e key, void *data)
+{
+       int lock_type = status_active_get()->setappl_screen_lock_type_int;
+       retv_if(lock_type == s_lock_mgr.old_lock_type, 1);
+
+       _D("lock type is changed : %d -> %d", s_lock_mgr.old_lock_type, lock_type);
+
+       s_lock_mgr.old_lock_type = lock_type;
+
+       return 1;
+}
+
+
+int lock_mgr_daemon_start(void)
+{
+       int lock_type = 0;
+       int ret = 0;
+
+       _lock_daemon_init();
+
+       lock_type = status_active_get()->setappl_screen_lock_type_int;
+       _D("lock type : %d", lock_type);
+
+       ret = lock_mgr_lockscreen_launch();
+       _D("ret : %d", ret);
+
+       status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SCREEN_LOCK_TYPE_INT, _lock_type_changed_cb, NULL);
+
+       if (feedback_initialize() != FEEDBACK_ERROR_NONE) {
+               _E("Failed to initialize feedback");
+       }
+
+       return ret;
+}
+
+
+
+void lock_mgr_daemon_end(void)
+{
+#ifdef HAVE_X11
+       if (s_lock_mgr.lockw) {
+               free(s_lock_mgr.lockw);
+       }
+#endif
+}
diff --git a/src/common/popup.c b/src/common/popup.c
new file mode 100644 (file)
index 0000000..c52c055
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <efl_extension.h>
+
+#include "popup.h"
+#include "util.h"
+
+#define POPUP_DATA_KEY_WINDOW "__popup_window__"
+
+static void _popup_destroy(Evas_Object *popup)
+{
+       Evas_Object *win = NULL;
+
+       if (popup) {
+               win = evas_object_data_del(popup, POPUP_DATA_KEY_WINDOW);
+               evas_object_del(popup);
+
+               if (win) {
+                       evas_object_del(win);
+               }
+       }
+}
+
+static Evas_Object *_window_create(void)
+{
+       Evas_Object *win = NULL;
+       int win_w = 0, win_h = 0;
+
+       win = elm_win_add(NULL, "STARTER-POPUP", ELM_WIN_DIALOG_BASIC);
+       retv_if(!win, NULL);
+
+       elm_win_title_set(win, "STARTER-POPUP");
+       elm_win_alpha_set(win, EINA_TRUE);
+       elm_win_borderless_set(win, EINA_TRUE);
+       elm_win_autodel_set(win, EINA_TRUE);
+       elm_win_raise(win);
+
+       elm_win_screen_size_get(win, NULL, NULL, &win_w, &win_h);
+       _D("win size : (%dx%d)", win_w, win_h);
+       evas_object_resize(win, win_w, win_h);
+
+       evas_object_show(win);
+
+       return win;
+}
+
+
+
+static void _popup_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       Evas_Object *popup = (Evas_Object *)data;
+       ret_if(!popup);
+
+       _popup_destroy(popup);
+}
+
+
+
+static void _popup_del_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       ret_if(!obj);
+
+       _popup_destroy(obj);
+}
+
+
+
+Evas_Object *popup_create(const char *title, const char *text)
+{
+       Evas_Object *win = NULL;
+       Evas_Object *popup = NULL;
+       Evas_Object *btn = NULL;
+
+       retv_if(!title, NULL);
+       retv_if(!text, NULL);
+
+       win = _window_create();
+       goto_if(!win, ERROR);
+
+       popup = elm_popup_add(win);
+       goto_if(!popup, ERROR);
+
+       elm_popup_orient_set(popup, ELM_POPUP_ORIENT_BOTTOM);
+       evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       elm_object_part_text_set(popup, "title,text", title);
+       elm_object_text_set(popup, text);
+       evas_object_data_set(popup, POPUP_DATA_KEY_WINDOW, win);
+       eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, _popup_del_cb, NULL);
+       evas_object_smart_callback_add(popup, "block,clicked", _popup_del_cb, NULL);
+
+       /* ok button */
+       btn = elm_button_add(popup);
+       goto_if(!btn, ERROR);
+
+       elm_object_style_set(btn, "popup");
+       elm_object_text_set(btn, S_("IDS_COM_SK_CONFIRM"));
+       elm_object_part_content_set(popup, "button1", btn);
+       evas_object_smart_callback_add(btn, "clicked", _popup_btn_clicked_cb, popup);
+
+       evas_object_show(popup);
+
+       return popup;
+
+ERROR:
+       _E("Failed to create popup");
+
+       _popup_destroy(popup);
+
+       return NULL;
+}
+
diff --git a/src/common/starter.c b/src/common/starter.c
new file mode 100644 (file)
index 0000000..3567c8b
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <aul.h>
+#include <vconf.h>
+#include <signal.h>
+
+#include "starter.h"
+#include "lock_mgr.h"
+#include "home_mgr.h"
+#include "hw_key.h"
+#include "process_mgr.h"
+#include "util.h"
+#include "status.h"
+#include "hw_key.h"
+
+#define PWLOCK_LITE_PKG_NAME "org.tizen.pwlock-lite"
+
+#define DATA_UNENCRYPTED "unencrypted"
+#define DATA_MOUNTED "mounted"
+#define SD_DATA_ENCRYPTED "encrypted"
+#define SD_CRYPT_META_FILE ".MetaEcfsFile"
+#define MMC_MOUNT_POINT        "/opt/storage/sdcard"
+
+
+
+static void _hide_home(void)
+{
+       int seq = status_active_get()->starter_sequence;
+       ret_if(seq == 1);
+
+       vconf_set_int(VCONFKEY_STARTER_SEQUENCE, 0);
+}
+
+
+
+static void _show_home(void)
+{
+       int show_menu = 0;
+
+       if (status_active_get()->starter_sequence || !show_menu) {
+               vconf_set_int(VCONFKEY_STARTER_SEQUENCE, 1);
+       }
+}
+
+
+
+static Eina_Bool _finish_boot_animation(void *data)
+{
+       if (vconf_set_int(VCONFKEY_BOOT_ANIMATION_FINISHED, 1) != 0) {
+               _E("Failed to set boot animation finished set");
+       }
+       _show_home();
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static int _fail_to_launch_pwlock(const char *appid, const char *key, const char *value, void *cfn, void *afn)
+{
+       _finish_boot_animation(NULL);
+       return 0;
+}
+
+
+
+static void _after_launch_pwlock(int pid)
+{
+       process_mgr_set_pwlock_priority(pid);
+       ecore_timer_add(0.5, _finish_boot_animation, NULL);
+}
+
+
+
+static void _signal_handler(int signum, siginfo_t *info, void *unused)
+{
+    _D("_signal_handler : Terminated...");
+    elm_exit();
+}
+
+
+
+static int _power_off_cb(status_active_key_e key, void *data)
+{
+       int val = status_active_get()->sysman_power_off_status;
+
+       if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT
+               || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART)
+       {
+           _D("_power_off_cb : Terminated...");
+           elm_exit();
+       }
+
+       return 1;
+}
+
+
+
+static int _boot_animation_finished_cb(status_active_key_e key, void *data)
+{
+       int val = status_active_get()->boot_animation_finished;
+       _D("boot animation finished : %d", val);
+
+       if (val == 1) {
+               lock_mgr_daemon_start();
+               _show_home();
+       }
+
+       return 1;
+}
+
+
+
+static void _language_changed_cb(keynode_t *node, void *data)
+{
+       char *lang = NULL;
+
+       ret_if(!node);
+
+       lang = vconf_keynode_get_str(node);
+       ret_if(!lang);
+
+       _D("language is changed : %s", lang);
+
+       elm_language_set(lang);
+}
+
+
+
+static int _set_i18n(const char *domain, const char *dir)
+{
+       char *r = NULL;
+
+       if (domain == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       char *lang = vconf_get_str(VCONFKEY_LANGSET);
+       r = setlocale(LC_ALL, lang);
+       if (!r) {
+               _E("setlocale() error");
+       }
+       if (lang) {
+               free(lang);
+       }
+
+       r = bindtextdomain(domain, dir);
+       if (!r) {
+               _E("bindtextdomain() error");
+       }
+
+       r = textdomain(domain);
+       if (!r) {
+               _E("textdomain() error");
+       }
+
+       if (vconf_notify_key_changed(VCONFKEY_LANGSET, _language_changed_cb, NULL) < 0) {
+               _E("Failed to register changed cb : %s", VCONFKEY_LANGSET);
+       }
+
+       return 0;
+}
+
+
+
+static int _check_dead_signal(int pid, void *data)
+{
+       int home_pid = 0;
+       int volume_pid = 0;
+       int lock_pid = 0;
+
+       _D("Process %d is termianted", pid);
+
+       if (pid < 0) {
+               _E("pid : %d", pid);
+               return 0;
+       }
+
+       home_pid = home_mgr_get_home_pid();
+       volume_pid = home_mgr_get_volume_pid();
+       lock_pid = lock_mgr_get_lock_pid();
+
+       if (pid == home_pid) {
+               _D("Homescreen is dead");
+               home_mgr_relaunch_homescreen();
+       } else if (pid == volume_pid) {
+               _D("volume is dead");
+               home_mgr_relaunch_volume();
+       } else if (pid == lock_pid) {
+               _D("lockscreen is dead");
+               lock_mgr_unlock();
+       } else {
+               _D("Unknown process, ignore it");
+       }
+
+       return 0;
+}
+
+
+
+static void _init(struct appdata *ad)
+{
+       struct sigaction act;
+
+       memset(&act,0x00,sizeof(struct sigaction));
+       act.sa_sigaction = _signal_handler;
+       act.sa_flags = SA_SIGINFO;
+
+       int ret = sigemptyset(&act.sa_mask);
+       if (ret < 0) {
+               _E("Failed to sigemptyset[%s]", strerror(errno));
+       }
+       ret = sigaddset(&act.sa_mask, SIGTERM);
+       if (ret < 0) {
+               _E("Failed to sigaddset[%s]", strerror(errno));
+       }
+       ret = sigaction(SIGTERM, &act, NULL);
+       if (ret < 0) {
+               _E("Failed to sigaction[%s]", strerror(errno));
+       }
+
+       _set_i18n(PACKAGE, LOCALEDIR);
+
+       status_register();
+       status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
+       status_active_register_cb(STATUS_ACTIVE_KEY_BOOT_ANIMATION_FINISHED, _boot_animation_finished_cb, NULL);
+
+       /* Ordering : _hide_home -> process_mgr_must_launch(pwlock) -> _show_home */
+       _hide_home();
+#if 0
+       process_mgr_must_launch(PWLOCK_LITE_PKG_NAME, NULL, NULL, _fail_to_launch_pwlock, _after_launch_pwlock);
+#endif
+
+       hw_key_create_window();
+       home_mgr_init(NULL);
+
+       aul_listen_app_dead_signal(_check_dead_signal, NULL);
+}
+
+
+
+static void _fini(struct appdata *ad)
+{
+       home_mgr_fini();
+       hw_key_destroy_window();
+       lock_mgr_daemon_end();
+
+       status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
+       status_active_unregister_cb(STATUS_ACTIVE_KEY_BOOT_ANIMATION_FINISHED, _boot_animation_finished_cb);
+       status_unregister();
+
+       if (vconf_ignore_key_changed(VCONFKEY_LANGSET, _language_changed_cb) < 0) {
+               _E("Failed to unregister changed cb : %s", VCONFKEY_LANGSET);
+       }
+}
+
+
+
+int main(int argc, char *argv[])
+{
+       struct appdata ad;
+       int ret = 0;
+
+       _D("starter is launched..!!");
+
+       ret = elm_init(argc, argv);
+       if (ret != 1) {
+               _E("elm_init() failed : %d", ret);
+               return -1;
+       }
+
+       _init(&ad);
+
+       elm_run();
+
+       _fini(&ad);
+       elm_shutdown();
+
+       return 0;
+}
diff --git a/src/common/window_mgr.c b/src/common/window_mgr.c
new file mode 100644 (file)
index 0000000..2f1a198
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <vconf.h>
+#include <bundle.h>
+#include <appcore-efl.h>
+#include <app.h>
+
+#ifdef HAVE_X11
+#include <Ecore_X.h>
+#include <utilX.h>
+#include <ui-gadget.h>
+#endif
+
+#include "window_mgr.h"
+#include "util.h"
+
+#define STR_ATOM_PANEL_SCROLLABLE_STATE         "_E_MOVE_PANEL_SCROLLABLE_STATE"
+
+
+
+#ifdef HAVE_X11
+struct _lockw_data {
+       Eina_Bool is_registered;
+       Ecore_X_Window lock_x_window;
+
+       Ecore_Event_Handler *h_wincreate;
+       Ecore_Event_Handler *h_winshow;
+       Ecore_Event_Handler *h_winhide;
+};
+
+
+
+static int _is_on_screen(Ecore_X_Display * dpy, Ecore_X_Window window)
+{
+       Ecore_X_Window root;
+       Window child;
+       Window win;
+
+       int rel_x = 0;
+       int rel_y = 0;
+       int abs_x = 0;
+       int abs_y = 0;
+
+       unsigned int width = 0;
+       unsigned int height = 0;
+       unsigned int border = 0;
+       unsigned int depth = 0;
+       unsigned int root_w = 0;
+       unsigned int root_h = 0;
+
+       Eina_Bool ret = FALSE;
+
+       root = ecore_x_window_root_first_get();
+       XGetGeometry(dpy, root, &win, &rel_x, &rel_y, &root_w, &root_h, &border, &depth);
+       _D("root rel_x[%d] rel_y[%d] border[%d] width[%d] height[%d]", rel_x, rel_y, border, root_w, root_h);
+
+       if (XGetGeometry(dpy, window, &win, &rel_x, &rel_y, &width, &height, &border, &depth)) {
+               if (XTranslateCoordinates(dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
+                   _D("abs_x[%d] abs_y[%d] border[%d] width[%d] height[%d]", abs_x, abs_y, border, width, height);
+                       if ((abs_x - border) >= root_w
+                               || (abs_y - border) >= root_h
+                           || (width + abs_x) <= 0 || (height + abs_y) <= 0)
+                       {
+                               ret = FALSE;
+                       } else {
+                               ret = (width == root_w) && (height == root_h);
+                       }
+               }
+       }
+
+       return ret;
+}
+
+
+
+static Window _get_user_created_window(Window win)
+{
+       Atom type_ret = 0;
+       int ret, size_ret = 0;
+       unsigned long num_ret = 0, bytes = 0;
+       unsigned char *prop_ret = NULL;
+       unsigned int xid;
+       Atom prop_user_created_win;
+
+       prop_user_created_win = XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
+
+       ret = XGetWindowProperty(ecore_x_display_get()
+                                                       , win, prop_user_created_win
+                                                       , 0L, 1L
+                                                       , False, 0
+                                                       , &type_ret, &size_ret
+                                                       , &num_ret, &bytes
+                                                       , &prop_ret);
+       if (ret != Success) {
+               if (prop_ret)
+                       XFree((void *) prop_ret);
+               return win;
+       } else if (!prop_ret) {
+               return win;
+       }
+
+       memcpy(&xid, prop_ret, sizeof(unsigned int));
+       XFree((void *)prop_ret);
+
+       return xid;
+
+}
+
+
+
+int window_mgr_get_focus_window_pid(void)
+{
+       Ecore_X_Window x_win_focused = 0;
+       int pid = 0;
+       int ret = -1;
+
+       _D("%s, %d", __func__, __LINE__);
+
+       x_win_focused = ecore_x_window_focus_get();
+       ret = ecore_x_netwm_pid_get(x_win_focused, &pid);
+       if(ret != 1) {
+               _E("Can't get pid for focus x window (%x)\n", x_win_focused);
+               return -1;
+       }
+       _D("PID(%d) for focus x window (%x)\n", pid, x_win_focused);
+
+       return pid;
+}
+
+
+
+static void _pwd_transient_set(Ecore_X_Window win, Ecore_X_Window for_win)
+{
+       _W("%p is transient for %p", win, for_win);
+
+       ecore_x_icccm_transient_for_set(win, for_win);
+}
+
+
+
+static void _pwd_transient_unset(Ecore_X_Window xwin)
+{
+       ret_if(!xwin);
+
+       _W("%p is not transient", xwin);
+       ecore_x_icccm_transient_for_unset(xwin);
+}
+
+
+
+Eina_Bool window_mgr_pwd_transient_set(void *data)
+{
+       Evas_Object *pwd_win = NULL;
+       Ecore_X_Window pwd_x_win;
+       lockw_data *lockw = (lockw_data *) data;
+       retv_if(!lockw, EINA_FALSE);
+
+       pwd_win = lock_pwd_util_win_get();
+       retv_if(!pwd_win, EINA_FALSE);
+
+       pwd_x_win = elm_win_xwindow_get(pwd_win);
+       retv_if(!pwd_x_win, EINA_FALSE);
+
+       retv_if(!lockw->lock_x_window, EINA_FALSE);
+
+       /* unset transient */
+       _pwd_transient_unset(lockw->lock_x_window);
+
+       /* set transient */
+       _pwd_transient_set(lockw->lock_x_window, pwd_x_win);
+
+       return EINA_TRUE;
+}
+
+
+
+Eina_Bool window_mgr_set_prop(lockw_data * data, int lock_app_pid, void *event)
+{
+       Ecore_X_Event_Window_Create *e = event;
+       Ecore_X_Window user_window = 0;
+       lockw_data *lockw = (lockw_data *) data;
+       int pid = 0;
+       int ret = 0;
+
+       retv_if(!lockw, EINA_FALSE);
+
+       user_window = _get_user_created_window((Window) (e->win));
+
+       ret = ecore_x_netwm_pid_get(user_window, &pid);
+       retv_if(ret != 1, EINA_FALSE);
+
+       _D("Check PID(%d) window. (lock_app_pid : %d)", pid, lock_app_pid);
+
+       if (lock_app_pid == pid) {
+               if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
+                       lockw->lock_x_window = user_window;
+                       /* window effect : fade in /out */
+                       ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN", "LOCK_SCREEN");
+                       ecore_x_netwm_window_type_set(user_window, ECORE_X_WINDOW_TYPE_NOTIFICATION);
+                       utilx_set_system_notification_level(ecore_x_display_get(), user_window, UTILX_NOTIFICATION_LEVEL_NORMAL);
+                       utilx_set_window_opaque_state(ecore_x_display_get(), user_window, UTILX_OPAQUE_STATE_ON);
+
+                       /* set transient */
+                       if (!window_mgr_pwd_transient_set(lockw)) {
+                               _E("Failed to set transient");
+                       }
+
+                       return EINA_TRUE;
+               }
+       }
+       return EINA_FALSE;
+}
+
+
+
+Eina_Bool window_mgr_set_effect(lockw_data * data, int lock_app_pid, void *event)
+{
+       Ecore_X_Event_Window_Create *e = event;
+       Ecore_X_Window user_window = 0;
+       int pid = 0;
+       int ret = 0;
+
+       user_window = _get_user_created_window((Window) (e->win));
+       ret = ecore_x_netwm_pid_get(user_window, &pid);
+       retv_if(ret != 1, EINA_FALSE);
+
+       if (lock_app_pid == pid) {
+               if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
+                       Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0;
+                       unsigned int effect_state = 0;
+
+                       ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
+                       if (ATOM_WINDOW_EFFECT_ENABLE) {
+                               ecore_x_window_prop_card32_set(user_window, ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
+                       } else {
+                               _E("ecore_x_atom_get() failed");
+                       }
+                       return EINA_TRUE;
+               }
+       }
+       return EINA_FALSE;
+}
+
+
+
+void window_mgr_set_scroll_prop(lockw_data *data, int lock_type)
+{
+       lockw_data *lockw = (lockw_data *) data;
+       Ecore_X_Atom ATOM_PANEL_SCROLLABLE_STATE = 0;
+       unsigned int val[3] = { 0, };
+
+       ret_if(!lockw);
+
+       ATOM_PANEL_SCROLLABLE_STATE = ecore_x_atom_get(STR_ATOM_PANEL_SCROLLABLE_STATE);
+       if (lock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD ||
+                       lock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD) {
+               val[0] = 0; // always enable F
+               val[1] = 0; // quickpanel enable F
+               val[2] = 0; // apptray enable F
+       } else {
+               val[0] = 0; // always enable F
+               val[1] = 1; // quickpanel enable T
+               val[2] = 0; // apptray enable F
+       }
+       ecore_x_window_prop_card32_set(lockw->lock_x_window, ATOM_PANEL_SCROLLABLE_STATE, val, 3);
+}
+
+
+
+void window_mgr_register_event(void *data, lockw_data * lockw,
+                           Eina_Bool (*create_cb) (void *, int, void *),
+                           Eina_Bool (*show_cb) (void *, int, void *))
+{
+       Ecore_X_Window root_window;
+
+       ret_if(!lockw);
+
+       if (lockw->is_registered) {
+               _E("Already register event cb");
+               return;
+       }
+
+       /* For getting window x event */
+       root_window = ecore_x_window_root_first_get();
+       ecore_x_window_client_sniff(root_window);
+
+       lockw->h_wincreate = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb, data);
+       lockw->h_winshow = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
+
+       lockw->is_registered = EINA_TRUE;
+}
+
+
+
+static inline void _unregister_event(lockw_data *lockw)
+{
+       Ecore_X_Window root_window;
+
+       /* unset transient */
+       _pwd_transient_unset(lockw->lock_x_window);
+
+       /* delete getting window x event */
+       root_window = ecore_x_window_root_first_get();
+       ecore_x_window_client_sniff(root_window);
+
+       /* delete window create event handler */
+       if (lockw->h_wincreate) {
+               ecore_event_handler_del(lockw->h_wincreate);
+               lockw->h_wincreate = NULL;
+       }
+       if (lockw->h_winshow) {
+               ecore_event_handler_del(lockw->h_winshow);
+               lockw->h_winshow = NULL;
+       }
+       if (lockw->h_winhide) {
+               ecore_event_handler_del(lockw->h_winhide);
+               lockw->h_winhide = NULL;
+       }
+
+       ecore_x_pointer_ungrab();
+
+       lockw->is_registered = EINA_FALSE;
+}
+
+
+
+void window_mgr_unregister_event(lockw_data *lockw)
+{
+       ret_if(!lockw);
+
+       if (!lockw->is_registered) {
+               _E("event cb is not registered");
+               return;
+       }
+
+       _unregister_event(lockw);
+}
+
+
+
+lockw_data *window_mgr_init(void)
+{
+       lockw_data *lockw = NULL;
+
+       lockw = calloc(1, sizeof(*lockw));
+
+       return lockw;
+}
+
+
+
+void window_mgr_fini(lockw_data *lockw)
+{
+       ret_if(!lockw);
+
+       if (lockw->is_registered) {
+               _unregister_event(lockw);
+       }
+
+       free(lockw);
+}
+#endif