2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <Elementary.h>
23 #include <pkgmgr-info.h>
25 #include <sys/types.h>
31 #include "dbus_util.h"
33 #include "process_mgr.h"
36 #define HOME_TERMINATED "home_terminated"
38 #define SYSPOPUPID_VOLUME "org.tizen.volume-nui"
39 #define APPID_INDICATOR "org.tizen.indicator"
40 #define APPID_QUICKPANEL "org.tizen.quickpanel"
41 #define APPID_TASKBAR "org.tizen.taskbar"
43 #define DEAD_TIMER_SEC 10.0
44 #define DEAD_TIMER_COUNT_MAX 2
57 Ecore_Timer *dead_timer;
62 .home_pid = (pid_t)-1,
63 .volume_pid = (pid_t)-1,
64 .indicator_pid = (pid_t)-1,
65 .quickpanel_pid = (pid_t)-1,
66 .taskbar_pid = (pid_t)-1,
76 int home_mgr_get_home_pid(void)
78 return s_home_mgr.home_pid;
83 int home_mgr_get_volume_pid(void)
85 return s_home_mgr.volume_pid;
90 int home_mgr_get_indicator_pid(void)
92 return s_home_mgr.indicator_pid;
97 int home_mgr_get_quickpanel_pid(void)
99 return s_home_mgr.quickpanel_pid;
104 int home_mgr_get_taskbar_pid(void)
106 return s_home_mgr.taskbar_pid;
111 static void _after_launch_home(int pid)
113 if (pid != s_home_mgr.home_pid) {
114 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
116 dbus_util_send_perceptible_signal(pid);
118 s_home_mgr.home_pid = pid;
124 static int _change_home_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
126 if (!strcmp(appid, MENU_SCREEN_PKG_NAME)) {
127 _E("We cannot do anything anymore.");
128 } else if (!strcmp(appid, status_active_get()->setappl_selected_package_name)) {
129 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
130 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
132 /* change_home func will be called by changing the home */
135 _E("cannot change home");
141 void home_mgr_open_home(const char *appid, const char *key, const char *val)
143 char *home_appid = NULL;
146 home_appid = status_active_get()->setappl_selected_package_name;
148 home_appid = (char *) appid;
152 process_mgr_must_launch(home_appid, key, val, _change_home_cb, _after_launch_home);
157 static int _show_home_cb(status_active_key_e key, void *data)
159 int seq = status_active_get()->starter_sequence;
162 _D("[MENU_DAEMON] _show_home_cb is invoked(%d)", seq);
166 if (s_home_mgr.home_pid > 0) {
167 _D("Home[%d] has to be terminated.", s_home_mgr.home_pid);
168 if (aul_terminate_pid(s_home_mgr.home_pid) != AUL_R_OK) {
169 _E("Failed to terminate %d", s_home_mgr.home_pid);
171 s_home_mgr.home_pid = -1; /* to freeze the dead_cb */
175 if (vconf_get_int(VCONFKEY_STARTER_IS_FALLBACK, &is_fallback) < 0) {
176 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
180 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 0)) {
181 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
184 if (!strcmp(status_active_get()->setappl_selected_package_name, MENU_SCREEN_PKG_NAME)) {
187 fallback_pkg = vconf_get_str(VCONFKEY_STARTER_FALLBACK_PKG);
188 _D("fallback pkg : %s", fallback_pkg);
192 status = vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, fallback_pkg);
197 _E("Failed to set vconfkey : %s (%d)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, status);
199 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
204 home_mgr_open_home(NULL, NULL, NULL);
207 _E("False sequence [%d]", seq);
216 static int _change_selected_package_name(status_active_key_e key, void *data)
219 int seq = status_active_get()->starter_sequence;
222 _E("Sequence is not ready yet, do nothing");
226 _D("_change_selected_package_name is invoked");
228 appid = status_active_get()->setappl_selected_package_name;
232 _SECURE_D("pkg_name : %s", appid);
234 if (s_home_mgr.home_pid > 0) {
235 char old_appid[BUF_SIZE_512] = { 0 , };
237 if (aul_app_get_pkgname_bypid(s_home_mgr.home_pid, old_appid, sizeof(old_appid)) == AUL_R_OK) {
238 if (!strcmp(appid, old_appid)) {
239 _D("Package is changed but same package is selected");
244 if (AUL_R_OK != aul_terminate_pid(s_home_mgr.home_pid)) {
245 _D("Failed to terminate pid %d", s_home_mgr.home_pid);
247 s_home_mgr.home_pid = -1;
248 s_home_mgr.dead_count = 0;
249 if (s_home_mgr.dead_timer) {
250 ecore_timer_del(s_home_mgr.dead_timer);
251 s_home_mgr.dead_timer = NULL;
255 home_mgr_open_home(appid, NULL, NULL);
262 static void _after_launch_volume(int pid)
264 if (pid != s_home_mgr.volume_pid) {
265 _I("volume is launched new[%d] != old[%d]", pid, s_home_mgr.volume_pid);
267 dbus_util_send_perceptible_signal(pid);
269 s_home_mgr.volume_pid = pid;
275 static void _after_launch_indicator(int pid)
277 s_home_mgr.indicator_pid = pid;
282 static void _after_launch_quickpanel(int pid)
284 s_home_mgr.quickpanel_pid = pid;
289 static void _after_launch_taskbar(int pid)
291 s_home_mgr.taskbar_pid = pid;
296 static void _launch_after_home(int pid)
298 if (pid != s_home_mgr.home_pid) {
299 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
301 dbus_util_send_perceptible_signal(pid);
303 s_home_mgr.home_pid = pid;
309 static void _launch_home(const char *appid)
311 const char *home_appid = NULL;
314 home_appid = status_active_get()->setappl_selected_package_name;
316 home_appid = (char *) appid;
320 process_mgr_must_launch(home_appid, HOME_TERMINATED, ISTRUE, _change_home_cb, _launch_after_home);
325 static void _popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
327 _D("popup is deleted");
329 s_home_mgr.popup = NULL;
334 static Eina_Bool _dead_timer_cb(void *data)
336 Evas_Object *popup = NULL;
337 char title[BUF_SIZE_128] = { 0, };
338 char text[BUF_SIZE_1024] = { 0, };
341 appid = status_active_get()->setappl_selected_package_name;
344 return ECORE_CALLBACK_CANCEL;
347 _D("dead count : %s(%d)", appid, s_home_mgr.dead_count);
349 if (s_home_mgr.dead_count >= DEAD_TIMER_COUNT_MAX) {
350 _D("Change homescreen package to default");
352 /* set fallback status */
353 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 1) < 0) {
354 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
357 if (vconf_set_str(VCONFKEY_STARTER_FALLBACK_PKG, appid) < 0) {
358 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
361 strncpy(title, _("IDS_COM_POP_WARNING"), sizeof(title));
362 title[sizeof(title) - 1] = '\0';
364 snprintf(text, sizeof(text), _("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), appid);
365 _D("title : %s / text : %s", title, text);
367 if (!s_home_mgr.popup) {
368 popup = popup_create(title, text);
370 _E("Failed to create popup");
372 s_home_mgr.popup = popup;
373 evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _popup_del_cb, NULL);
377 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
378 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
379 return ECORE_CALLBACK_RENEW;
383 s_home_mgr.dead_timer = NULL;
384 s_home_mgr.dead_count = 0;
386 return ECORE_CALLBACK_CANCEL;
391 void home_mgr_relaunch_homescreen(void)
395 if (s_home_mgr.power_off) {
400 appid = status_active_get()->setappl_selected_package_name;
406 s_home_mgr.dead_count++;
407 _D("home dead count : %d", s_home_mgr.dead_count);
409 if (!s_home_mgr.dead_timer) {
410 _D("Add dead timer");
411 s_home_mgr.dead_timer = ecore_timer_add(DEAD_TIMER_SEC, _dead_timer_cb, NULL);
412 if (!s_home_mgr.dead_timer) {
413 _E("Failed to add a dead timer");
422 void home_mgr_relaunch_volume(void)
424 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
429 void home_mgr_relaunch_indicator(void)
431 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
436 void home_mgr_relaunch_quickpanel(void)
438 process_mgr_must_launch(APPID_QUICKPANEL, NULL, NULL, NULL, _after_launch_quickpanel);
443 void home_mgr_relaunch_taskbar(void)
445 process_mgr_must_launch(APPID_TASKBAR, NULL, NULL, NULL, _after_launch_taskbar);
450 static int _power_off_cb(status_active_key_e key, void *data)
452 int val = status_active_get()->sysman_power_off_status;
454 if (val > VCONFKEY_SYSMAN_POWER_OFF_NONE) {
455 s_home_mgr.power_off = 1;
457 s_home_mgr.power_off = 0;
460 _D("power off status : %d", s_home_mgr.power_off);
467 static Eina_Bool _launch_apps_idler_cb(void *data)
469 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
470 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
471 process_mgr_must_launch(APPID_QUICKPANEL, NULL, NULL, NULL, _after_launch_quickpanel);
472 process_mgr_must_launch(APPID_TASKBAR, NULL, NULL, NULL, _after_launch_taskbar);
474 return ECORE_CALLBACK_CANCEL;
479 void home_mgr_init(void *data)
481 _D("[MENU_DAEMON]home_mgr_init is invoked");
483 status_active_register_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb, NULL);
484 status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
485 status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name, NULL);
487 ecore_idler_add(_launch_apps_idler_cb, NULL);
492 void home_mgr_fini(void)
494 if (s_home_mgr.volume_pid > 0) {
495 process_mgr_terminate_app(s_home_mgr.volume_pid, 1);
496 s_home_mgr.volume_pid = -1;
499 status_active_unregister_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb);
500 status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
501 status_active_unregister_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name);