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 <dd-deviced.h>
26 #include <sys/types.h>
32 #include "dbus_util.h"
34 #include "process_mgr.h"
37 #define HOME_TERMINATED "home_terminated"
39 #define SYSPOPUPID_VOLUME "volume"
41 #define DEAD_TIMER_SEC 2.0
42 #define DEAD_TIMER_COUNT_MAX 2
44 #define VCONFKEY_STARTER_IS_FALLBACK "db/starter/is_fallback"
45 #define VCONFKEY_STARTER_FALLBACK_PKG "db/starter/fallback_pkg"
55 Ecore_Timer *dead_timer;
60 .home_pid = (pid_t)-1,
61 .volume_pid = (pid_t)-1,
72 static void _after_launch_home(int pid)
74 if (dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_HOMESCREEN) < 0){
75 _E("failed to send oom dbus signal");
77 s_home_mgr.home_pid = pid;
82 static int _change_home_cb(const char *appid, const char *key, const char *value, void *cfn, void *afn)
84 if (!strcmp(appid, MENU_SCREEN_PKG_NAME)) {
85 _E("We cannot do anything anymore.");
86 } else if (!strcmp(appid, status_active_get()->setappl_selected_package_name)) {
87 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
88 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
90 /* change_home func will be called by changing the home */
93 _E("cannot change home");
99 #define SERVICE_OPERATION_MAIN_KEY "__APP_SVC_OP_TYPE__"
100 #define SERVICE_OPERATION_MAIN_VALUE "http://tizen.org/appcontrol/operation/main"
101 void home_mgr_open_home(const char *appid)
103 char *home_appid = NULL;
105 if (status_passive_get()->idle_screen_safemode) {
106 home_appid = MENU_SCREEN_PKG_NAME;
108 home_appid = status_active_get()->setappl_selected_package_name;
110 home_appid = (char *) appid;
114 if (!strncmp(home_appid, MENU_SCREEN_PKG_NAME, strlen(home_appid))) {
115 process_mgr_must_launch(home_appid, SERVICE_OPERATION_MAIN_KEY, SERVICE_OPERATION_MAIN_VALUE, _change_home_cb, _after_launch_home);
117 process_mgr_must_open(home_appid, _change_home_cb, _after_launch_home);
123 static int _show_home_cb(status_active_key_e key, void *data)
125 int seq = status_active_get()->starter_sequence;
127 char *fallback_pkg = NULL;
129 _D("[MENU_DAEMON] _show_home_cb is invoked(%d)", seq);
133 if (s_home_mgr.home_pid > 0) {
134 _D("Home[%d] has to be terminated.", s_home_mgr.home_pid);
135 if (aul_terminate_pid(s_home_mgr.home_pid) != AUL_R_OK) {
136 _E("Failed to terminate %d", s_home_mgr.home_pid);
138 s_home_mgr.home_pid = -1; /* to freeze the dead_cb */
142 if (vconf_get_int(VCONFKEY_STARTER_IS_FALLBACK, &is_fallback) < 0) {
143 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
147 fallback_pkg = vconf_get_str(VCONFKEY_STARTER_FALLBACK_PKG);
149 _E("Failed to get vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
150 home_mgr_open_home(NULL);
153 _D("fallback pkg : %s", fallback_pkg);
155 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, fallback_pkg) < 0) {
156 _E("Failed to set vconfkey : %s", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME);
157 home_mgr_open_home(NULL);
162 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 0)) {
163 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
168 home_mgr_open_home(NULL);
172 _E("False sequence [%d]", seq);
181 static int _change_selected_package_name(status_active_key_e key, void *data)
184 int seq = status_active_get()->starter_sequence;
187 _E("Sequence is not ready yet, do nothing");
191 _D("_change_selected_package_name is invoked");
193 appid = status_active_get()->setappl_selected_package_name;
197 _SECURE_D("pkg_name : %s", appid);
199 if (s_home_mgr.home_pid > 0) {
200 char old_appid[BUF_SIZE_512] = { 0 , };
202 if (aul_app_get_pkgname_bypid(s_home_mgr.home_pid, old_appid, sizeof(old_appid)) == AUL_R_OK) {
203 if (!strcmp(appid, old_appid)) {
204 _D("Package is changed but same package is selected");
209 if (AUL_R_OK != aul_terminate_pid(s_home_mgr.home_pid)) {
210 _D("Failed to terminate pid %d", s_home_mgr.home_pid);
212 s_home_mgr.home_pid = -1;
213 s_home_mgr.dead_count = 0;
214 if (s_home_mgr.dead_timer) {
215 ecore_timer_del(s_home_mgr.dead_timer);
216 s_home_mgr.dead_timer = NULL;
220 home_mgr_open_home(appid);
227 static void _after_launch_volume(int pid)
229 if (dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_DEFAULT) < 0){
230 _E("failed to send oom dbus signal");
232 s_home_mgr.volume_pid = pid;
237 static void _launch_after_home(int pid)
240 if(dbus_util_send_oomadj(pid, OOM_ADJ_VALUE_HOMESCREEN) < 0){
241 _E("failed to send oom dbus signal");
244 s_home_mgr.home_pid = pid;
249 static void _launch_home(const char *appid)
251 const char *home_appid = NULL;
253 if (status_passive_get()->idle_screen_safemode) {
254 home_appid = MENU_SCREEN_PKG_NAME;
256 home_appid = status_active_get()->setappl_selected_package_name;
258 home_appid = (char *) appid;
262 process_mgr_must_launch(home_appid, HOME_TERMINATED, ISTRUE, _change_home_cb, _launch_after_home);
267 static void _popup_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
269 _D("popup is deleted");
271 s_home_mgr.popup = NULL;
276 static Eina_Bool _dead_timer_cb(void *data)
278 Evas_Object *popup = NULL;
279 char title[BUF_SIZE_128] = { 0, };
280 char text[BUF_SIZE_1024] = { 0, };
282 char *appid = (char *)data;
283 retv_if(!appid, ECORE_CALLBACK_CANCEL);
285 _D("dead count : %s(%d)", appid, s_home_mgr.dead_count);
287 if (s_home_mgr.dead_count >= DEAD_TIMER_COUNT_MAX) {
288 _D("Change homescreen package to default");
290 if (vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, MENU_SCREEN_PKG_NAME) != 0) {
291 _E("cannot set the vconf key as %s", MENU_SCREEN_PKG_NAME);
292 return ECORE_CALLBACK_RENEW;
295 strncpy(title, _("IDS_COM_POP_WARNING"), sizeof(title));
296 title[sizeof(title) - 1] = '\0';
298 snprintf(text, sizeof(text), _("IDS_IDLE_POP_UNABLE_TO_LAUNCH_PS"), appid);
299 _D("title : %s / text : %s", title, text);
301 if (!s_home_mgr.popup) {
302 popup = popup_create(title, text);
304 _E("Failed to create popup");
306 s_home_mgr.popup = popup;
307 evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _popup_del_cb, NULL);
311 /* set fallback status */
312 if (vconf_set_int(VCONFKEY_STARTER_IS_FALLBACK, 1) < 0) {
313 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_IS_FALLBACK);
316 if (vconf_set_str(VCONFKEY_STARTER_FALLBACK_PKG, appid) < 0) {
317 _E("Failed to set vconfkey : %s", VCONFKEY_STARTER_FALLBACK_PKG);
321 s_home_mgr.dead_timer = NULL;
322 s_home_mgr.dead_count = 0;
324 return ECORE_CALLBACK_CANCEL;
329 int home_mgr_check_dead_signal(int pid, void *data)
333 _D("Process %d is termianted", pid);
340 if (s_home_mgr.power_off) {
345 appid = status_active_get()->setappl_selected_package_name;
351 if (pid == s_home_mgr.home_pid) {
352 s_home_mgr.dead_count++;
353 _D("home dead count : %d", s_home_mgr.dead_count);
355 if (!s_home_mgr.dead_timer) {
356 _D("Add dead timer");
357 s_home_mgr.dead_timer = ecore_timer_add(DEAD_TIMER_SEC, _dead_timer_cb, (void *)appid);
361 } else if (pid == s_home_mgr.volume_pid) {
362 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
364 _D("Unknown process, ignore it (dead pid %d, home pid %d)", pid, s_home_mgr.home_pid);
372 static int _power_off_cb(status_active_key_e key, void *data)
374 int val = status_active_get()->sysman_power_off_status;
376 if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) {
377 s_home_mgr.power_off = 1;
379 s_home_mgr.power_off = 0;
382 _D("power off status : %d", s_home_mgr.power_off);
389 static Eina_Bool _launch_volume_idler_cb(void *data)
391 process_mgr_must_syspopup_launch(SYSPOPUPID_VOLUME, NULL, NULL, NULL, _after_launch_volume);
392 return ECORE_CALLBACK_CANCEL;
397 void home_mgr_init(void *data)
399 _D( "[MENU_DAEMON]home_mgr_init is invoked");
401 status_active_register_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb, NULL);
402 status_active_register_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb, NULL);
403 status_active_register_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name, NULL);
404 _change_selected_package_name(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, NULL);
406 ecore_idler_add(_launch_volume_idler_cb, NULL);
408 aul_listen_app_dead_signal(home_mgr_check_dead_signal, NULL);
413 void home_mgr_fini(void)
415 if (s_home_mgr.volume_pid > 0) {
416 process_mgr_terminate_app(s_home_mgr.volume_pid, 1);
417 s_home_mgr.volume_pid = -1;
420 status_active_unregister_cb(STATUS_ACTIVE_KEY_STARTER_SEQUENCE, _show_home_cb);
421 status_active_unregister_cb(STATUS_ACTIVE_KEY_SYSMAN_POWER_OFF_STATUS, _power_off_cb);
422 status_active_unregister_cb(STATUS_ACTIVE_KEY_SETAPPL_SELECTED_PACKAGE_NAME, _change_selected_package_name);