2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <Elementary.h>
26 #include <syspopup_caller.h>
27 #include <sys/types.h>
33 #include "pkg_event.h"
41 #define QUERY_UPDATE_NAME "UPDATE app_info SET name='%s' where package='%s';"
42 #define SAT_DESKTOP_FILE "/opt/share/applications/org.tizen.sat-ui.desktop"
43 #define RELAUNCH_INTERVAL 100*1000
44 #define RETRY_MAXCOUNT 30
48 // Define prototype of the "hidden API of AUL"
49 //extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data);
65 bool menu_daemon_is_homescreen(pid_t pid)
67 if (s_info.home_pid == pid) return true;
73 static inline char *_get_selected_pkgname(void)
77 pkgname = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
79 _E("Cannot get pkgname from vconf.");
81 pkgname = strdup(HOME_SCREEN_PKG_NAME);
83 _E("strdup error for pkgname, %s", strerror(errno));
93 static inline void _open_homescreen(const char *pkgname)
96 char *homescreen = (char *) pkgname;
98 system("echo -e '[${_G}menu-daemon launches home-screen${C_}]' > /dev/kmsg");
99 ret = aul_open_app(homescreen);
100 _D("can%s launch %s now. (%d)", ret < 0 ? "not" : "", homescreen, ret);
101 if (ret < 0 && strcmp(homescreen, HOME_SCREEN_PKG_NAME)) {
102 _E("cannot launch package %s", homescreen);
104 if (-1 == ret) { // -1 : AUL returns '-1' when there is no package name in DB.
105 ret = aul_open_app(HOME_SCREEN_PKG_NAME);
107 _E("Failed to open a default home, %s(err:%d)", HOME_SCREEN_PKG_NAME, ret);
112 s_info.home_pid = ret;
114 if (-1 == sysconf_set_mempolicy_bypid(ret, OOM_IGNORE)) {
115 _E("Cannot set the memory policy for Home-screen(%d)", ret);
117 _E("Set the memory policy for Home-screen(%d)", ret);
124 static void _show_cb(keynode_t* node, void *data)
129 _D("[MENU_DAEMON] _show_cb is invoked");
131 pkgname = _get_selected_pkgname();
136 seq = vconf_keynode_get_int(node);
138 if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) {
139 _E("Failed to get sequence info");
147 if (s_info.home_pid > 0) {
149 _D("pid[%d] is terminated.", s_info.home_pid);
151 pid = s_info.home_pid;
152 s_info.home_pid = -1; /* to freeze the dead_cb */
154 if (aul_terminate_pid(pid) != AUL_R_OK)
155 _E("Failed to terminate %d", s_info.home_pid);
159 _open_homescreen(pkgname);
162 _E("False sequence [%d]", seq);
173 static void _pkg_changed(keynode_t* node, void *data)
178 if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) {
179 _E("Do nothing, there is no sequence info yet");
184 _E("Sequence is not ready yet, do nothing");
188 _D("_pkg_changed is invoked");
190 pkgname = _get_selected_pkgname();
194 _D("pkg_name : %s", pkgname);
196 if (s_info.home_pid > 0) {
197 char old_pkgname[256];
199 if (aul_app_get_pkgname_bypid(s_info.home_pid, old_pkgname, sizeof(old_pkgname)) == AUL_R_OK) {
200 if (!strcmp(pkgname, old_pkgname)) {
201 _D("Package is changed but same package is selected");
207 if (aul_terminate_pid(s_info.home_pid) != AUL_R_OK)
208 _D("Failed to terminate pid %d", s_info.home_pid);
210 /* If there is no running home */
211 _open_homescreen(pkgname);
214 /* NOTE: Dead callback will catch the termination of a current menuscreen
215 * _open_homescreen(pkgname);
221 static void _launch_volume(void)
225 _D("_launch_volume");
227 for (i=0; i<RETRY_MAXCOUNT; i++)
229 pid = syspopup_launch("volume", NULL);
231 _D("syspopup_launch(volume), pid = %d", pid);
234 _D("syspopup_launch(volume)is failed [%d]times", i);
235 usleep(RELAUNCH_INTERVAL);
237 s_info.volume_pid = pid;
243 int menu_daemon_check_dead_signal(int pid)
247 if (s_info.power_off) {
248 _D("Power off. ignore dead cb\n");
252 _D("Process %d is termianted", pid);
257 pkgname = _get_selected_pkgname();
261 if (pid == s_info.home_pid) {
263 _D("pkg_name : %s", pkgname);
264 _open_homescreen(pkgname);
265 } else if (pid == s_info.volume_pid) {
269 _D("Unknown process, ignore it (pid %d, home pid %d)",
270 pid, s_info.home_pid);
280 void menu_daemon_init(void *data)
282 _D( "[MENU_DAEMON]menu_daemon_init is invoked");
284 aul_launch_init(NULL,NULL);
287 if (xmonitor_init() < 0) _E("cannot init xmonitor");
292 if (unlink(SAT_DESKTOP_FILE) != 0)
293 _E("cannot remove sat-ui desktop.");
295 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, _pkg_changed, NULL) < 0)
296 _E("Failed to add callback for package change event");
298 if (vconf_notify_key_changed(VCONFKEY_STARTER_SEQUENCE, _show_cb, NULL) < 0)
299 _E("Failed to add callback for show event");
301 _pkg_changed(NULL, NULL);
302 // THIS ROUTINE IS FOR SAT.
303 vconf_set_int(VCONFKEY_IDLE_SCREEN_LAUNCHED, VCONFKEY_IDLE_SCREEN_LAUNCHED_TRUE);
308 void menu_daemon_fini(void)
310 vconf_ignore_key_changed(VCONFKEY_STARTER_SEQUENCE, _show_cb);
311 vconf_ignore_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, _pkg_changed);
315 destroy_key_window();