2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.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>
25 #include <pkgmgr-info.h>
28 #include <syspopup_caller.h>
29 #include <sys/types.h>
35 #include "pkg_event.h"
43 #define QUERY_UPDATE_NAME "UPDATE app_info SET name='%s' where package='%s';"
44 #define SAT_DESKTOP_FILE "/opt/share/applications/org.tizen.sat-ui.desktop"
45 #define RELAUNCH_INTERVAL 100*1000
46 #define RETRY_MAXCOUNT 30
61 int menu_daemon_open_app(const char *pkgname)
64 int r = AUL_R_ETIMEOUT;
65 for (i = 0; AUL_R_ETIMEOUT == r && i < RETRY_COUNT; i ++) {
66 r = aul_open_app(pkgname);
69 _D("aul_open_app error(%d)", r);
70 _F("cannot open an app(%s) by %d", pkgname, r);
80 int menu_daemon_launch_app(const char *pkgname, bundle *b)
83 int r = AUL_R_ETIMEOUT;
84 for (i = 0; AUL_R_ETIMEOUT == r && i < RETRY_COUNT; i ++) {
85 r = aul_launch_app(pkgname, b);
88 _D("aul_launch_app error(%d)", r);
89 _F("cannot launch an app(%s) by %d", pkgname, r);
99 bool menu_daemon_is_homescreen(pid_t pid)
101 if (s_info.home_pid == pid) return true;
107 inline char *menu_daemon_get_selected_pkgname(void)
109 char *pkgname = NULL;
111 pkgname = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
112 retv_if(NULL == pkgname, NULL);
119 static bool _exist_package(char *pkgid)
122 pkgmgrinfo_pkginfo_h handle = NULL;
124 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
125 if (PMINFO_R_OK != ret || NULL == handle) {
126 _D("%s doesn't exist in this binary", pkgid);
130 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
137 inline void menu_daemon_open_homescreen(const char *pkgname)
139 char *homescreen = NULL;
142 system("echo -e '[${_G}menu-daemon launches home-screen${C_}]' > /dev/kmsg");
144 if (NULL == pkgname) {
145 tmp = menu_daemon_get_selected_pkgname();
149 homescreen = (char *) pkgname;
152 syspopup_destroy_all();
155 ret = menu_daemon_open_app(homescreen);
156 _D("can%s launch %s now. (%d)", ret < 0 ? "not" : "", homescreen, ret);
157 if (ret < 0 && strcmp(homescreen, HOME_SCREEN_PKG_NAME) && _exist_package(HOME_SCREEN_PKG_NAME)) {
158 _E("cannot launch package %s", homescreen);
160 if (0 != vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME)) {
161 _E("Cannot set value(%s) into key(%s)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME);
164 while (AUL_R_ETIMEOUT == ret) {
165 _E("Failed to open a default home, %s", HOME_SCREEN_PKG_NAME);
166 ret = menu_daemon_open_app(HOME_SCREEN_PKG_NAME);
171 _E("Critical! Starter cannot launch anymore[%d]", ret);
172 _F("Critical! Starter cannot launch anymore[%d]", ret);
175 s_info.home_pid = ret;
177 if (-1 == sysconf_set_mempolicy_bypid(ret, OOM_IGNORE)) {
178 _E("Cannot set the memory policy for Home-screen(%d)", ret);
180 _D("Set the memory policy for Home-screen(%d)", ret);
189 static void _show_cb(keynode_t* node, void *data)
193 _D("[MENU_DAEMON] _show_cb is invoked");
196 seq = vconf_keynode_get_int(node);
198 if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) {
199 _E("Failed to get sequence info");
206 if (s_info.home_pid > 0) {
208 _D("pid[%d] is terminated.", s_info.home_pid);
209 pid = s_info.home_pid;
210 s_info.home_pid = -1;
212 if (aul_terminate_pid(pid) != AUL_R_OK)
213 _E("Failed to terminate %d", s_info.home_pid);
217 menu_daemon_open_homescreen(NULL);
220 _E("False sequence [%d]", seq);
229 static void _pkg_changed(keynode_t* node, void *data)
234 if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) {
235 _E("Do nothing, there is no sequence info yet");
240 _E("Sequence is not ready yet, do nothing");
244 _D("_pkg_changed is invoked");
246 pkgname = menu_daemon_get_selected_pkgname();
250 _D("pkg_name : %s", pkgname);
252 if (s_info.home_pid > 0) {
253 char old_pkgname[256];
255 if (aul_app_get_pkgname_bypid(s_info.home_pid, old_pkgname, sizeof(old_pkgname)) == AUL_R_OK) {
256 if (!strcmp(pkgname, old_pkgname)) {
257 _D("Package is changed but same package is selected");
263 if (AUL_R_OK != aul_terminate_pid(s_info.home_pid))
264 _D("Failed to terminate pid %d", s_info.home_pid);
266 /* If there is no running home */
267 menu_daemon_open_homescreen(pkgname);
276 static void _launch_volume(void)
280 _D("_launch_volume");
282 for (i=0; i<RETRY_MAXCOUNT; i++)
284 pid = syspopup_launch("volume", NULL);
286 _D("syspopup_launch(volume), pid = %d", pid);
289 _D("syspopup_launch(volume)is failed [%d]times", i);
290 usleep(RELAUNCH_INTERVAL);
292 s_info.volume_pid = pid;
298 int menu_daemon_check_dead_signal(int pid)
300 if (s_info.power_off) {
301 _D("Power off. ignore dead cb\n");
305 _D("Process %d is termianted", pid);
310 if (pid == s_info.home_pid) {
311 char *pkgname = NULL;
312 pkgname = menu_daemon_get_selected_pkgname();
313 retv_if(NULL == pkgname, 0);
315 _D("pkg_name : %s", pkgname);
316 menu_daemon_open_homescreen(pkgname);
318 } else if (pid == s_info.volume_pid) {
321 _D("Unknown process, ignore it (pid %d, home pid %d)",
322 pid, s_info.home_pid);
331 void menu_daemon_init(void *data)
333 _D( "[MENU_DAEMON]menu_daemon_init is invoked");
335 aul_launch_init(NULL,NULL);
338 if (xmonitor_init() < 0) _E("cannot init xmonitor");
343 if (unlink(SAT_DESKTOP_FILE) != 0)
344 _E("cannot remove sat-ui desktop.");
346 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, _pkg_changed, NULL) < 0)
347 _E("Failed to add the callback for package change event");
349 if (vconf_notify_key_changed(VCONFKEY_STARTER_SEQUENCE, _show_cb, NULL) < 0)
350 _E("Failed to add the callback for show event");
352 _pkg_changed(NULL, NULL);
353 vconf_set_int(VCONFKEY_IDLE_SCREEN_LAUNCHED, VCONFKEY_IDLE_SCREEN_LAUNCHED_TRUE);
358 void menu_daemon_fini(void)
360 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, _pkg_changed) < 0)
361 _E("Failed to ignore the callback for package change event");
363 if (vconf_ignore_key_changed(VCONFKEY_STARTER_SEQUENCE, _show_cb) < 0)
364 _E("Failed to ignore the callback for show event");
368 destroy_key_window();