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 VOLUME_ENABLE 1
38 #define HOME_TERMINATED "home_terminated"
40 #define SYSPOPUPID_VOLUME "org.tizen.volume-nui"
42 #define DEAD_TIMER_SEC 10.0
43 #define DEAD_TIMER_COUNT_MAX 2
45 #define APPID_INDICATOR "org.tizen.indicator"
46 #define APPID_SOFTKEY "org.tizen.softkey-container"
47 #define APPID_TASKBAR "org.tizen.taskbar"
49 #define HOMESCREEN_NUI_PKG_NAME "org.tizen.homescreen-nui"
60 Ecore_Timer *dead_timer;
65 .home_pid = (pid_t)-1,
66 .volume_pid = (pid_t)-1,
67 .indicator_pid = (pid_t)-1,
68 .softkey_pid = (pid_t)-1,
69 .taskbar_pid = (pid_t)-1,
78 static void home_mgr_softkey_change(void *user_data);
80 int home_mgr_get_home_pid(void)
82 return s_home_mgr.home_pid;
87 int home_mgr_get_volume_pid(void)
89 return s_home_mgr.volume_pid;
92 int home_mgr_get_indicator_pid(void)
94 return s_home_mgr.indicator_pid;
97 int home_mgr_get_softkey_pid(void)
99 return s_home_mgr.softkey_pid;
102 int home_mgr_get_taskbar_pid(void)
104 return s_home_mgr.taskbar_pid;
107 void home_mgr_softkey_dead_signal_received()
109 s_home_mgr.softkey_pid = -1;
112 static void _after_launch_home(int pid)
114 if (pid != s_home_mgr.home_pid) {
115 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
117 dbus_util_send_perceptible_signal(pid);
119 s_home_mgr.home_pid = pid;
124 /* Remove change home callback as no alternative home app in IoT profile */
125 /*static int _change_home_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
127 if (!strcmp(appid, MENU_SCREEN_PKG_NAME)) {
128 _E("We cannot do anything anymore.");
129 } else if (!strcmp(appid, status_active_get()->setappl_selected_package_name)) {
130 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
131 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
133 // change_home func will be called by changing the home
136 _E("cannot change home");
142 void home_mgr_open_home(const char *appid, const char *key, const char *val)
144 const char *home_appid = NULL;
147 home_appid = status_active_get()->setappl_selected_package_name;
148 if(strcmp(home_appid, HOMESCREEN_NUI_PKG_NAME) != 0){
149 home_appid = HOMESCREEN_NUI_PKG_NAME;
150 if(vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOMESCREEN_NUI_PKG_NAME) != 0){
151 _E("cannot set the vconf key as [%s]", HOMESCREEN_NUI_PKG_NAME );
158 process_mgr_must_launch(home_appid, key, val, NULL, _after_launch_home);
163 static int _show_home_cb(status_active_key_e key, void *data)
165 int seq = status_active_get()->starter_sequence;
168 _D("[MENU_DAEMON] _show_home_cb is invoked(%d) (key: %d)", seq, key);
172 if (s_home_mgr.home_pid > 0) {
173 _D("Home[%d] has to be terminated.", s_home_mgr.home_pid);
174 if (aul_terminate_pid(s_home_mgr.home_pid) != AUL_R_OK) {
175 _E("Failed to terminate %d", s_home_mgr.home_pid);
177 s_home_mgr.home_pid = -1; /* to freeze the dead_cb */
181 if (vconf_get_int(VCONFKEY_STARTER_IS_FALLBACK, &is_fallback) < 0) {
182 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
185 /* No need to set fallback package as no alternative home app in IoT profile */
187 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 0)) {
188 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
190 if (!strcmp(status_active_get()->setappl_selected_package_name, MENU_SCREEN_PKG_NAME)) {
192 fallback_pkg = vconf_get_str(VCONFKEY_STARTER_FALLBACK_PKG);
193 _D("fallback pkg : %s", fallback_pkg);
197 status = vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, fallback_pkg);
202 _E("Failed to set vconfkey : %s (%d)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, status);
204 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
209 home_mgr_open_home(NULL, NULL, NULL);
210 // we need to launch softkey after home-screen.
211 home_mgr_softkey_change(NULL);
214 _E("False sequence [%d]", seq);
223 static int _change_selected_package_name(status_active_key_e key, void *data)
225 const char *appid = NULL;
226 int seq = status_active_get()->starter_sequence;
229 _E("Sequence is not ready yet, do nothing");
233 _D("_change_selected_package_name is invoked");
235 appid = status_active_get()->setappl_selected_package_name;
239 _SECURE_D("pkg_name : %s", appid);
241 if (s_home_mgr.home_pid > 0) {
242 char old_appid[BUF_SIZE_512] = { 0 , };
244 if (aul_app_get_pkgname_bypid(s_home_mgr.home_pid, old_appid, sizeof(old_appid)) == AUL_R_OK) {
245 if (!strcmp(appid, old_appid)) {
246 _D("Package is changed but same package is selected");
251 if (AUL_R_OK != aul_terminate_pid(s_home_mgr.home_pid)) {
252 _D("Failed to terminate pid %d", s_home_mgr.home_pid);
254 s_home_mgr.home_pid = -1;
255 s_home_mgr.dead_count = 0;
256 if (s_home_mgr.dead_timer) {
257 ecore_timer_del(s_home_mgr.dead_timer);
258 s_home_mgr.dead_timer = NULL;
262 home_mgr_open_home(appid, NULL, NULL);
270 static void _after_launch_volume(int pid)
272 if (pid != s_home_mgr.volume_pid) {
273 _I("volume is launched new[%d] != old[%d]", pid, s_home_mgr.volume_pid);
275 dbus_util_send_perceptible_signal(pid);
277 s_home_mgr.volume_pid = pid;
283 static void _after_launch_indicator(int pid)
285 s_home_mgr.indicator_pid = pid;
288 static void _after_launch_softkey(int pid)
290 s_home_mgr.softkey_pid = pid;
293 static void _after_launch_taskbar(int pid)
295 s_home_mgr.taskbar_pid = pid;
298 static void _launch_after_home(int pid)
300 if (pid != s_home_mgr.home_pid) {
301 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
303 dbus_util_send_perceptible_signal(pid);
305 s_home_mgr.home_pid = pid;
311 static void _launch_home(const char *appid)
313 const char *home_appid = NULL;
316 home_appid = status_active_get()->setappl_selected_package_name;
322 process_mgr_must_launch(home_appid, HOME_TERMINATED, ISTRUE, NULL, _launch_after_home);
327 static void _popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
329 _D("popup is deleted");
331 s_home_mgr.popup = NULL;
336 static Eina_Bool _dead_timer_cb(void *data)
338 Evas_Object *popup = NULL;
339 char title[BUF_SIZE_128] = { 0, };
340 char text[BUF_SIZE_1024] = { 0, };
341 const char *appid = NULL;
343 appid = status_active_get()->setappl_selected_package_name;
346 return ECORE_CALLBACK_CANCEL;
349 _D("dead count : %s(%d)", appid, s_home_mgr.dead_count);
351 if (s_home_mgr.dead_count >= DEAD_TIMER_COUNT_MAX) {
352 _D("Change homescreen package to default");
354 /* set fallback status */
355 /* No need to set fallback package as no alternative home app in IoT profile */
356 /*if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 1) < 0) {
357 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
360 if (vconf_set_str(VCONFKEY_STARTER_FALLBACK_PKG, appid) < 0) {
361 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
364 strncpy(title, _("IDS_COM_POP_WARNING"), sizeof(title));
365 title[sizeof(title) - 1] = '\0';
367 snprintf(text, sizeof(text), _("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), appid);
368 _D("title : %s / text : %s", title, text);
370 if (!s_home_mgr.popup) {
371 popup = popup_create(title, text);
373 _E("Failed to create popup");
375 s_home_mgr.popup = popup;
376 evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _popup_del_cb, NULL);
380 /*if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, appid) != 0) {
381 _E("cannot set the vconf key as %s", appid);
382 return ECORE_CALLBACK_RENEW;
384 home_mgr_relaunch_homescreen();
387 s_home_mgr.dead_timer = NULL;
388 s_home_mgr.dead_count = 0;
390 return ECORE_CALLBACK_CANCEL;
395 void home_mgr_relaunch_homescreen(void)
397 const char *appid = NULL;
399 if (s_home_mgr.power_off) {
404 appid = status_active_get()->setappl_selected_package_name;
410 s_home_mgr.dead_count++;
411 _D("home dead count : %d", s_home_mgr.dead_count);
413 if (!s_home_mgr.dead_timer) {
414 _D("Add dead timer");
415 s_home_mgr.dead_timer = ecore_timer_add(DEAD_TIMER_SEC, _dead_timer_cb, NULL);
416 if (!s_home_mgr.dead_timer) {
417 _E("Failed to add a dead timer");
426 void home_mgr_relaunch_volume(void)
429 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
434 void home_mgr_relaunch_indicator(void)
436 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
439 void home_mgr_relaunch_taskbar(void)
441 process_mgr_must_launch(APPID_TASKBAR, NULL, NULL, NULL, _after_launch_taskbar);
444 void home_mgr_softkey_process_terminate(void)
446 process_mgr_terminate_app(s_home_mgr.softkey_pid,1);
447 s_home_mgr.softkey_pid = 0;
450 static void home_mgr_softkey_change(void *user_data)
452 _D("home_mgr_softkey_change");
457 ret = vconf_get_bool(VCONFKEY_SETAPPL_SOFT_KEY, &state);
459 _D("fail to get VCONFKEY_SETAPPL_SOFT_KEY:%d", ret);
463 _D("VCONFKEY_SETAPPL_SOFT_KEY STATUS == %d ", state);
465 pid = home_mgr_get_softkey_pid();
466 _D("SoftKey Process Id == %d ", pid);
470 _D("terminating softkey");
471 home_mgr_softkey_process_terminate();
477 _D("softkey is already running with PID: %d", pid);
479 process_mgr_must_launch(APPID_SOFTKEY, NULL, NULL, NULL, _after_launch_softkey);
482 static void _softkey_vconf_change_cb(keynode_t *node, void *data)
484 _D("_softkey_vconf_change_cb");
485 home_mgr_softkey_change(data);
488 void softkey_mgr_init(void)
490 int ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_SOFT_KEY, _softkey_vconf_change_cb, NULL);
492 _E("Failed to get vconfkey change for softkey app");
496 void softkey_mgr_fini(void)
498 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOFT_KEY, _softkey_vconf_change_cb) < 0) {
499 _E("Failed to unregister the callback for %s", VCONFKEY_SETAPPL_SOFT_KEY);
503 static int _power_off_cb(status_active_key_e key, void *data)
505 int val = status_active_get()->sysman_power_off_status;
507 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
508 s_home_mgr.power_off = 1;
510 s_home_mgr.power_off = 0;
513 _D("power off status : %d", s_home_mgr.power_off);
521 static Eina_Bool _launch_apps_idler_cb(void *data)
524 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
526 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
527 return ECORE_CALLBACK_CANCEL;
531 void home_mgr_init(void)
533 _D("[MENU_DAEMON]home_mgr_init is invoked");
535 status_active_register_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb, NULL);
536 status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
537 status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name, NULL);
538 _change_selected_package_name(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, NULL);
540 ecore_idler_add(_launch_apps_idler_cb, NULL);
545 void home_mgr_fini(void)
548 if (s_home_mgr.volume_pid > 0) {
549 process_mgr_terminate_app(s_home_mgr.volume_pid, 1);
550 s_home_mgr.volume_pid = -1;
554 status_active_unregister_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb);
555 status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
556 status_active_unregister_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name);