diff options
Diffstat (limited to 'src/menu_daemon.c')
-rw-r--r-- | src/menu_daemon.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/src/menu_daemon.c b/src/menu_daemon.c new file mode 100644 index 0000000..4b4e2cf --- /dev/null +++ b/src/menu_daemon.c @@ -0,0 +1,300 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 <ail.h> +#include <aul.h> +#include <db-util.h> +#include <Elementary.h> +#include <heynoti.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <vconf.h> +#include <errno.h> + +#include "desktop_to_db.h" +#include "hw_key.h" +#include "parser.h" +#include "pkg_event.h" +#include "util.h" + + +int errno; + + +#define QUERY_UPDATE_NAME "UPDATE app_info SET name='%s' where package='%s';" +#define SAT_DESKTOP_FILE "/opt/share/applications/org.tizen.sat-ui.desktop" + + + +// Define prototype of the "hidden API of AUL" +extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data); + + + +static struct info { + pid_t pid; +} s_info = { + .pid = -1, +}; + + + +static inline char *_get_pkgname(keynode_t *node) +{ + char *pkgname; + + if (node) + pkgname = vconf_keynode_get_str(node); + else + pkgname = vconf_get_str(MENU_PKG_VCONF_KEY); + + if (!pkgname) { + _E("Cannot get pkgname from vconf."); + pkgname = strdup(HOME_SCREEN_PKG_NAME); + if (!pkgname) + _E("strdup error for pkgname, %s", strerror(errno)); + } + + return pkgname; +} + + + +static inline void _open_homescreen(const char *pkgname) +{ + int ret; + char *homescreen = (char *) pkgname; + + ret = aul_open_app(homescreen); + _D("can%s launch %s now. (%d)", ret < 0 ? "not" : "", homescreen, ret); + if (ret < 0 && strcmp(homescreen, HOME_SCREEN_PKG_NAME)) { + ret = aul_open_app(HOME_SCREEN_PKG_NAME); + if (ret < 0) { + _E("Failed to open a default home, %s", HOME_SCREEN_PKG_NAME); + } else { + homescreen = HOME_SCREEN_PKG_NAME; + } + } + + s_info.pid = ret; +} + + + +static void _show_cb(keynode_t* node, void *data) +{ + int seq; + char *pkgname; + + _D("[MENU_DAEMON] _show_cb is invoked"); + + pkgname = _get_pkgname(NULL); + if (!pkgname) + return; + + if (node) { + seq = vconf_keynode_get_int(node); + } else { + if (vconf_get_int("memory/startapps/sequence", &seq) < 0) { + _E("Failed to get sequence info"); + free(pkgname); + return; + } + } + + switch (seq) { + case 0: + if (s_info.pid > 0) { + int pid; + _D("pid[%d] is terminated.", s_info.pid); + + pid = s_info.pid; + s_info.pid = -1; /* to freeze the dead_cb */ + + if (aul_terminate_pid(pid) != AUL_R_OK) + _E("Failed to terminate %d", s_info.pid); + } + break; + case 1: + _open_homescreen(pkgname); + break; + default: + _E("False sequence [%d]", seq); + break; + } + + free(pkgname); + return; + +} + + + +static void _pkg_changed(keynode_t* node, void *data) +{ + char *pkgname; + int seq; + + if (vconf_get_int("memory/startapps/sequence", &seq) < 0) { + _E("Do nothing, there is no sequence info yet"); + return; + } + + if (seq < 1) { + _E("Sequence is not ready yet, do nothing"); + return; + } + + _D("_pkg_changed is invoked"); + + pkgname = _get_pkgname(node); + if (!pkgname) + return; + + _D("pkg_name : %s", pkgname); + + if (s_info.pid > 0) { + char old_pkgname[256]; + + if (aul_app_get_pkgname_bypid(s_info.pid, old_pkgname, sizeof(old_pkgname)) == AUL_R_OK) { + if (!strcmp(pkgname, old_pkgname)) { + _D("Package is changed but same package is selected"); + free(pkgname); + return; + } + } + + if (aul_terminate_pid(s_info.pid) != AUL_R_OK) + _D("Failed to terminate pid %d", s_info.pid); + } else { + /* If there is no running home */ + _open_homescreen(pkgname); + } + + /* NOTE: Dead callback will catch the termination of a current menuscreen + * _open_homescreen(pkgname); + */ + free(pkgname); + return; +} + + + +static int _dead_cb(int pid, void *data) +{ + char *pkgname; + + _D("Process %d is termianted", pid); + if (pid != s_info.pid || s_info.pid <= 0) { + _D("Unknown process, ignore it (pid %d, menu pid %d)", pid, s_info.pid); + return 0; + } + + pkgname = _get_pkgname(NULL); + if (!pkgname) + return 0; + + _D("pkg_name : %s", pkgname); + + /* Relaunch */ + _open_homescreen(pkgname); + free(pkgname); + return 0; +} + + + +static void _hibernation_preleave_cb(void *data) +{ + _D( "[MENU_DAEMON]_hibernation_preleave_cb is invoked"); + + aul_launch_init(NULL,NULL); + aul_listen_app_dead_signal(_dead_cb, NULL); + + create_key_window(); + pkg_event_init(); + + if (unlink(SAT_DESKTOP_FILE) != 0) + _E("cannot remove sat-ui desktop."); + + if (vconf_notify_key_changed(MENU_PKG_VCONF_KEY, _pkg_changed, NULL) < 0) + _E("Failed to add callback for package change event"); + + if (vconf_notify_key_changed("memory/startapps/sequence", _show_cb, NULL) < 0) + _E("Failed to add callback for show event"); + + _pkg_changed(NULL, NULL); + // THIS ROUTINE IS FOR SAT. + vconf_set_int("memory/menu-screen/is_menu_screen_done", 1); +} + + + +int elm_main(int argc, char *argv[]) +{ + FILE *fp; + int fd; + + elm_init(argc, argv); + fd = heynoti_init(); + + system("/usr/bin/ail_initdb"); + + fp = fopen("/opt/etc/.hib_capturing", "r"); + if (!fp) { + fprintf(stderr, "[MENU_DAEMON]hib_capturing file is not found\n"); + _hibernation_preleave_cb(NULL); + } else { + fprintf(stderr,"\n\n\n Menu Daemon enter %s hey noti init\n", __func__); + if (fd < 0) { + fprintf(stderr, "[MENU_DAEMON]\n\n\n Hey Noti Init Failed\n"); + } else { + if (heynoti_subscribe(fd, "HIBERNATION_PRELEAVE", _hibernation_preleave_cb, NULL)) { + fprintf(stderr,"Heynoti subscribe is failed\n"); + } else { + fprintf(stderr,"Heynoti subscribe is done\n"); + } + + if (heynoti_attach_handler(fd)) { + fprintf(stderr,"Heynoti attach handler is failed\n"); + } else { + fprintf(stderr,"Heynoti attach handler is done\n"); + if (vconf_set_int("memory/hibernation/menuscreen_ready", 1)) { + fprintf(stderr, "[MENU_DAEMON]vconf_set_int FAIL\n"); + } else { + fprintf(stderr, "[MENU_DAEMON]vconf_set_int OK\n"); + } + } + } + fclose(fp); + } + + elm_run(); + destroy_key_window(); + elm_exit(); + return 0; +} + + + +ELM_MAIN() + + + +// End of a file |