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"
35 #include "common/home_mgr.h"
37 #define VOLUME_ENABLE 1
39 #define HOME_TERMINATED "home_terminated"
41 #define SYSPOPUPID_VOLUME "org.tizen.volume-nui"
43 #define DEAD_TIMER_SEC 10.0
44 #define DEAD_TIMER_COUNT_MAX 2
46 #define APPID_INDICATOR "org.tizen.indicator"
47 #define APPID_SOFTKEY "org.tizen.softkey-container"
48 #define APPID_TASKBAR "org.tizen.taskbar"
50 #define HOMESCREEN_NUI_PKG_NAME "org.tizen.homescreen-nui"
61 Ecore_Timer *dead_timer;
66 .home_pid = (pid_t)-1,
67 .volume_pid = (pid_t)-1,
68 .indicator_pid = (pid_t)-1,
69 .softkey_pid = (pid_t)-1,
70 .taskbar_pid = (pid_t)-1,
79 static void home_mgr_softkey_change(void *user_data);
81 int home_mgr_get_home_pid(void)
83 return s_home_mgr.home_pid;
88 int home_mgr_get_volume_pid(void)
90 return s_home_mgr.volume_pid;
93 int home_mgr_get_indicator_pid(void)
95 return s_home_mgr.indicator_pid;
98 int home_mgr_get_softkey_pid(void)
100 return s_home_mgr.softkey_pid;
103 int home_mgr_get_taskbar_pid(void)
105 return s_home_mgr.taskbar_pid;
108 void home_mgr_softkey_dead_signal_received()
110 s_home_mgr.softkey_pid = -1;
113 static void _after_launch_home(int pid)
115 if (pid != s_home_mgr.home_pid) {
116 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
118 dbus_util_send_perceptible_signal(pid);
120 s_home_mgr.home_pid = pid;
125 /* Remove change home callback as no alternative home app in IoT profile */
126 /*static int _change_home_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
128 if (!strcmp(appid, MENU_SCREEN_PKG_NAME)) {
129 _E("We cannot do anything anymore.");
130 } else if (!strcmp(appid, status_active_get()->setappl_selected_package_name)) {
131 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
132 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
134 // change_home func will be called by changing the home
137 _E("cannot change home");
143 void home_mgr_open_home(const char *appid, const char *key, const char *val)
145 const char *home_appid = NULL;
148 home_appid = status_active_get()->setappl_selected_package_name;
149 if(strcmp(home_appid, HOMESCREEN_NUI_PKG_NAME) != 0){
150 home_appid = HOMESCREEN_NUI_PKG_NAME;
151 if(vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOMESCREEN_NUI_PKG_NAME) != 0){
152 _E("cannot set the vconf key as [%s]", HOMESCREEN_NUI_PKG_NAME );
159 process_mgr_must_launch(home_appid, key, val, NULL, _after_launch_home);
164 static int _show_home_cb(status_active_key_e key, void *data)
166 int seq = status_active_get()->starter_sequence;
169 _D("[MENU_DAEMON] _show_home_cb is invoked(%d) (key: %d)", seq, key);
173 if (s_home_mgr.home_pid > 0) {
174 _D("Home[%d] has to be terminated.", s_home_mgr.home_pid);
175 if (aul_terminate_pid(s_home_mgr.home_pid) != AUL_R_OK) {
176 _E("Failed to terminate %d", s_home_mgr.home_pid);
178 s_home_mgr.home_pid = -1; /* to freeze the dead_cb */
182 if (vconf_get_int(VCONFKEY_STARTER_IS_FALLBACK, &is_fallback) < 0) {
183 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
186 /* No need to set fallback package as no alternative home app in IoT profile */
188 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 0)) {
189 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
191 if (!strcmp(status_active_get()->setappl_selected_package_name, MENU_SCREEN_PKG_NAME)) {
193 fallback_pkg = vconf_get_str(VCONFKEY_STARTER_FALLBACK_PKG);
194 _D("fallback pkg : %s", fallback_pkg);
198 status = vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, fallback_pkg);
203 _E("Failed to set vconfkey : %s (%d)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, status);
205 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
210 home_mgr_open_home(NULL, NULL, NULL);
211 // we need to launch softkey after home-screen.
212 home_mgr_softkey_change(NULL);
215 _E("False sequence [%d]", seq);
224 static int _change_selected_package_name(status_active_key_e key, void *data)
226 const char *appid = NULL;
227 int seq = status_active_get()->starter_sequence;
230 _E("Sequence is not ready yet, do nothing");
234 _D("_change_selected_package_name is invoked");
236 appid = status_active_get()->setappl_selected_package_name;
240 _SECURE_D("pkg_name : %s", appid);
242 if (s_home_mgr.home_pid > 0) {
243 char old_appid[BUF_SIZE_512] = { 0 , };
245 if (aul_app_get_pkgname_bypid(s_home_mgr.home_pid, old_appid, sizeof(old_appid)) == AUL_R_OK) {
246 if (!strcmp(appid, old_appid)) {
247 _D("Package is changed but same package is selected");
252 if (AUL_R_OK != aul_terminate_pid(s_home_mgr.home_pid)) {
253 _D("Failed to terminate pid %d", s_home_mgr.home_pid);
255 s_home_mgr.home_pid = -1;
256 s_home_mgr.dead_count = 0;
257 if (s_home_mgr.dead_timer) {
258 ecore_timer_del(s_home_mgr.dead_timer);
259 s_home_mgr.dead_timer = NULL;
263 home_mgr_open_home(appid, NULL, NULL);
271 static void _after_launch_volume(int pid)
273 if (pid != s_home_mgr.volume_pid) {
274 _I("volume is launched new[%d] != old[%d]", pid, s_home_mgr.volume_pid);
276 dbus_util_send_perceptible_signal(pid);
278 s_home_mgr.volume_pid = pid;
284 static void _after_launch_indicator(int pid)
286 s_home_mgr.indicator_pid = pid;
289 static void _after_launch_softkey(int pid)
291 s_home_mgr.softkey_pid = pid;
294 static void _after_launch_taskbar(int pid)
296 s_home_mgr.taskbar_pid = pid;
299 static void _launch_after_home(int pid)
301 if (pid != s_home_mgr.home_pid) {
302 _I("home is created by power key new[%d] != old[%d]", pid, s_home_mgr.home_pid);
304 dbus_util_send_perceptible_signal(pid);
306 s_home_mgr.home_pid = pid;
312 static void _launch_home(const char *appid)
314 const char *home_appid = NULL;
317 home_appid = status_active_get()->setappl_selected_package_name;
323 process_mgr_must_launch(home_appid, HOME_TERMINATED, ISTRUE, NULL, _launch_after_home);
328 static void _popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
330 _D("popup is deleted");
332 s_home_mgr.popup = NULL;
337 static Eina_Bool _dead_timer_cb(void *data)
339 Evas_Object *popup = NULL;
340 char title[BUF_SIZE_128] = { 0, };
341 char text[BUF_SIZE_1024] = { 0, };
342 const char *appid = NULL;
344 appid = status_active_get()->setappl_selected_package_name;
347 return ECORE_CALLBACK_CANCEL;
350 _D("dead count : %s(%d)", appid, s_home_mgr.dead_count);
352 if (s_home_mgr.dead_count >= DEAD_TIMER_COUNT_MAX) {
353 _D("Change homescreen package to default");
355 /* set fallback status */
356 /* No need to set fallback package as no alternative home app in IoT profile */
357 /*if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 1) < 0) {
358 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
361 if (vconf_set_str(VCONFKEY_STARTER_FALLBACK_PKG, appid) < 0) {
362 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
365 strncpy(title, _("IDS_COM_POP_WARNING"), sizeof(title));
366 title[sizeof(title) - 1] = '\0';
368 snprintf(text, sizeof(text), _("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), appid);
369 _D("title : %s / text : %s", title, text);
371 if (!s_home_mgr.popup) {
372 popup = popup_create(title, text);
374 _E("Failed to create popup");
376 s_home_mgr.popup = popup;
377 evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _popup_del_cb, NULL);
381 /*if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, appid) != 0) {
382 _E("cannot set the vconf key as %s", appid);
383 return ECORE_CALLBACK_RENEW;
385 home_mgr_relaunch_homescreen();
388 s_home_mgr.dead_timer = NULL;
389 s_home_mgr.dead_count = 0;
391 return ECORE_CALLBACK_CANCEL;
396 void home_mgr_relaunch_homescreen(void)
398 const char *appid = NULL;
400 if (s_home_mgr.power_off) {
405 appid = status_active_get()->setappl_selected_package_name;
411 s_home_mgr.dead_count++;
412 _D("home dead count : %d", s_home_mgr.dead_count);
414 if (!s_home_mgr.dead_timer) {
415 _D("Add dead timer");
416 s_home_mgr.dead_timer = ecore_timer_add(DEAD_TIMER_SEC, _dead_timer_cb, NULL);
417 if (!s_home_mgr.dead_timer) {
418 _E("Failed to add a dead timer");
427 void home_mgr_relaunch_volume(void)
430 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
435 void home_mgr_relaunch_indicator(void)
437 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
440 void home_mgr_relaunch_taskbar(void)
442 process_mgr_must_launch(APPID_TASKBAR, NULL, NULL, NULL, _after_launch_taskbar);
445 void home_mgr_softkey_process_terminate(void)
447 process_mgr_terminate_app(s_home_mgr.softkey_pid,1);
448 s_home_mgr.softkey_pid = 0;
451 static void home_mgr_softkey_change(void *user_data)
453 _D("home_mgr_softkey_change");
458 ret = vconf_get_bool(VCONFKEY_SETAPPL_SOFT_KEY, &state);
460 _D("fail to get VCONFKEY_SETAPPL_SOFT_KEY:%d", ret);
464 _D("VCONFKEY_SETAPPL_SOFT_KEY STATUS == %d ", state);
466 pid = home_mgr_get_softkey_pid();
467 _D("SoftKey Process Id == %d ", pid);
471 _D("terminating softkey");
472 home_mgr_softkey_process_terminate();
478 _D("softkey is already running with PID: %d", pid);
480 process_mgr_must_launch(APPID_SOFTKEY, NULL, NULL, NULL, _after_launch_softkey);
483 static void _softkey_vconf_change_cb(keynode_t *node, void *data)
485 _D("_softkey_vconf_change_cb");
486 home_mgr_softkey_change(data);
489 void softkey_mgr_init(void)
491 int ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_SOFT_KEY, _softkey_vconf_change_cb, NULL);
493 _E("Failed to get vconfkey change for softkey app");
497 void softkey_mgr_fini(void)
499 if (vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOFT_KEY, _softkey_vconf_change_cb) < 0) {
500 _E("Failed to unregister the callback for %s", VCONFKEY_SETAPPL_SOFT_KEY);
504 static int _power_off_cb(status_active_key_e key, void *data)
506 int val = status_active_get()->sysman_power_off_status;
508 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
509 s_home_mgr.power_off = 1;
511 s_home_mgr.power_off = 0;
514 _D("power off status : %d", s_home_mgr.power_off);
522 static Eina_Bool _launch_apps_idler_cb(void *data)
525 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
527 process_mgr_must_launch(APPID_INDICATOR, NULL, NULL, NULL, _after_launch_indicator);
528 return ECORE_CALLBACK_CANCEL;
532 void home_mgr_init(void)
534 _D("[MENU_DAEMON]home_mgr_init is invoked");
536 status_active_register_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb, NULL);
537 status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
538 status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name, NULL);
539 _change_selected_package_name(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, NULL);
541 ecore_idler_add(_launch_apps_idler_cb, NULL);
546 void home_mgr_fini(void)
549 if (s_home_mgr.volume_pid > 0) {
550 process_mgr_terminate_app(s_home_mgr.volume_pid, 1);
551 s_home_mgr.volume_pid = -1;
555 status_active_unregister_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb);
556 status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
557 status_active_unregister_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name);