3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
23 #include <appcore-efl.h>
35 #include "taskmanager.h"
37 #include "_util_log.h"
38 #include "_util_efl.h"
43 #include "_progressbar.h"
45 static Elm_Object_Item *g_egi;
47 /* group list:gl, data list:dl, button list:bl, no list: nl */
48 static Elm_Genlist_Item_Class itc_gl;
49 static Elm_Genlist_Item_Class itc_hl;
50 static Elm_Genlist_Item_Class itc_dl;
51 static Elm_Genlist_Item_Class itc_bl;
52 static Elm_Genlist_Item_Class itc_nl;
53 static Elm_Genlist_Item_Class itc_separator4;
54 static Elm_Genlist_Item_Class itc_separator2;
56 static char *button_text[TS_MAX] = {
57 "IDS_TASKMGR_BUTTON_CLOSE_ALL_APPLICATIONS",
58 "IDS_TASKMGR_BUTTON_CLEAR_HISTORY_ABB"
61 static void end_all_inuse_cb(void *data, Evas_Object *obj, void *event_info);
62 static void delete_all_history_cb(void *data, Evas_Object *obj,
64 void (*func_del[TS_MAX]) (void *data, Evas_Object *obj, void *event_info) = {
65 &end_all_inuse_cb, &delete_all_history_cb};
67 static void end_inuse_cb(void *data, Evas_Object *obj, void *event_info);
68 static void delete_history_cb(void *data, Evas_Object *obj, void *event_info);
69 void (*func_end[TS_MAX]) (void *data, Evas_Object *obj, void *event_info) = {
70 &end_inuse_cb, &delete_history_cb};
72 static char *group_name[TS_MAX] = {
73 "IDS_TASKMGR_HEADER_RUNNING",
74 "IDS_TASKMGR_MBODY_RECENTLY_USED"
77 static char *nolist_text[TS_MAX] = {
78 "IDS_TASKMGR_MBODY_NO_APPS_OPEN",
79 "IDS_TASKMGR_MBODY_NO_RECENTLY_USED_APPS"
82 void taskmanager_free_info(struct _task_info *info);
83 Eina_Bool _update_list(void *data);
85 static void clear_genlist(void *data)
89 struct appdata *ad = data;
92 elm_genlist_clear(ad->gl);
96 void clear_task_manager_list(void *data)
100 struct appdata *ad = data;
101 _free_einalist_all(ad);
105 static void app_genlist_item_update(void *data)
107 ret_if(data == NULL);
109 struct appdata *ad = (struct appdata *)data;
111 Elm_Object_Item *it_r;
112 Eina_List *realized_item_list, *l_r;
113 unsigned int cnt = 0;
115 realized_item_list = elm_genlist_realized_items_get(ad->gl);
116 cnt = eina_list_count(realized_item_list);
118 EINA_LIST_FOREACH(realized_item_list, l_r, it_r) {
120 elm_genlist_item_update(it_r);
126 Eina_Bool alert_app_info(void *data)
128 retv_if(data == NULL, -1);
130 struct appdata *ad = (struct appdata *)data;
132 app_genlist_item_update(ad);
133 return ECORE_CALLBACK_CANCEL;
136 static void end_all_inuse_cb(void *data, Evas_Object *obj, void *event_info)
138 ret_if(data == NULL);
140 struct appdata *ad = data;
141 char buf[_BUF_MAX] = { 0, };
143 ad->mode = MODE_END_ALL_INUSE;
144 snprintf(buf, sizeof(buf), T_("IDS_TASKMGR_POP_CLOSE_ALL_APPS_Q_THIS_MAY_CAUSE_DATA_TO_BE_LOST"));
146 evas_object_del(ad->popup_ask);
147 ad->popup_ask = NULL;
149 ad->popup_ask = _add_popup_ask(ad->win, buf, ad);
153 delete_all_history_cb(void *data, Evas_Object *obj, void *event_info)
156 ret_if(data == NULL);
158 struct appdata *ad = data;
159 char buf[_BUF_MAX] = { 0, };
161 ad->mode = MODE_DEL_ALL_HISTORY;
162 snprintf(buf, sizeof(buf), T_("IDS_TASKMGR_POP_CLEAR_ALL_APP_HISTORY_Q"));
164 evas_object_del(ad->popup_ask);
165 ad->popup_ask = NULL;
167 ad->popup_ask = _add_popup_ask(ad->win, buf, ad);
170 static void end_inuse_cb(void *data, Evas_Object *obj, void *event_info)
172 ret_if(data == NULL);
174 struct _task_info *info_ev = (struct _task_info *)data;
175 struct appdata *ad = info_ev->ad;
176 char buf[_BUF_MAX] = { 0, };
178 ad->mode = MODE_END_INUSE;
179 snprintf(buf, _BUF_MAX, T_("IDS_TASKMGR_POP_CLOSE_PS_APP_Q_THIS_MAY_CAUSE_DATA_TO_BE_LOST"), info_ev->app_name);
181 evas_object_del(ad->popup_ask);
182 ad->popup_ask = NULL;
184 ad->popup_ask = _add_popup_ask(ad->win, buf, ad);
185 g_egi = (void *)info_ev->it;
188 static void delete_history_cb(void *data, Evas_Object *obj, void *event_info)
190 ret_if(data == NULL);
192 struct _task_info *info_ev = (struct _task_info *)data;
193 struct appdata *ad = info_ev->ad;
194 char buf[_BUF_MAX] = { 0, };
196 ad->mode = MODE_DEL_HISTORY;
198 snprintf(buf, _BUF_MAX, T_("IDS_TASKMGR_POP_CLEAR_PS_HISTORY_Q"), info_ev->app_name);
200 evas_object_del(ad->popup_ask);
201 ad->popup_ask = NULL;
203 ad->popup_ask = _add_popup_ask(ad->win, buf, ad);
204 g_egi = (void *)info_ev->it;
207 static void nl_sel(void *data, Evas_Object *obj, void *event_info)
210 Elm_Object_Item *item = (Elm_Object_Item *) event_info;
211 elm_genlist_item_selected_set(item, EINA_FALSE);
215 static char *nl_text_get(void *data, Evas_Object *obj, const char *part)
217 char buf[_BUF_MAX] = { 0, };
219 if (!strcmp(part, "elm.text")) {
220 snprintf(buf, sizeof(buf), "%s", T_(nolist_text[(int)data]));
227 static void _gl_sel_app(void *data, Evas_Object *obj, void *event_info)
230 Elm_Object_Item *item = (Elm_Object_Item *) event_info;
231 struct appdata *ad = (struct appdata *)data;
232 struct _task_info *info;
233 /* parameter to block double click */
234 static int selected = 0;
235 Elm_Object_Item *it = (Elm_Object_Item *) event_info;
238 elm_genlist_item_selected_set(it, EINA_FALSE);
240 retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
242 if (ad->update_timer) {
243 ecore_timer_del(ad->update_timer);
244 ad->update_timer = NULL;
252 _E("[Error] Cannot find genlist item\n");
257 info = (struct _task_info *)elm_object_item_data_get(item);
259 _E("[Error] Cannot get item data: info\n");
265 /* when application is alive */
266 ret = aul_resume_pid(info->pid);
269 /* when application is dead */
270 if (info->pkg_name == NULL) {
271 util_show_popup_with_message(info->ad->win,
273 T_("IDS_TASKMGR_POP_UNABLE_TO_OPEN_APPLICATION"));
277 _unset_notification_level(info->ad->win);
279 if (!strcmp(info->pkg_name, "org.tizen.phone")) {
280 /* exception : Because dialer doesn't need bundle
281 * since being unifyed dialer, voice call and video call
283 ret = aul_open_app(info->pkg_name);
286 ret = aul_open_app(info->pkg_name);
292 _D("exit after 0.3 sec\n");
293 ad->exit_timer = ecore_timer_add(0.3, _exit_cb, ad);
298 static Evas_Object *_gl_content_get_app(void *data, Evas_Object *obj,
301 struct _task_info *info = (struct _task_info *)data;
302 char buf[_BUF_MAX] = { 0, };
304 Evas_Object *icon = NULL;
305 Evas_Object *btn = NULL;
307 Evas_Object *rt, *icon_ly = NULL;
309 retvm_if(data == NULL, NULL, "Invalid argument: task info is NULL\n");
311 if (!strcmp(part, "elm.icon.1")) {
312 snprintf(buf, sizeof(buf), "%s", info->icn_path);
313 retvm_if(buf == NULL, NULL, "%s icon is NULL\n", info->app_name);
314 if (!ecore_file_exists(buf) || strlen(buf) < 4)
315 snprintf((char *)buf, (size_t) sizeof(buf),
316 (const char *)IMAGEDIR "/icon_taskmgr.png");
318 if (!strncmp(&buf[strlen(buf) - 3], "edj", 3)) {
319 icon_ly = _add_layout(obj, buf, "icon");
322 icon_ly = elm_icon_add(obj);
323 elm_image_file_set(icon_ly, buf, NULL);
326 icon = _add_layout(obj, EDJ_NAME, "icon");
327 retvm_if(icon == NULL, NULL, "Cannot add layout: icon\n");
329 rt = evas_object_rectangle_add(evas_object_evas_get(obj));
330 retvm_if(rt == NULL, NULL, "Failed to add rectangle\n");
332 evas_object_color_set(rt, 0, 0, 0, 0);
333 evas_object_size_hint_min_set(rt,
334 (int)72 * elm_config_scale_get(),
335 (int)72 * elm_config_scale_get());
336 elm_object_part_content_set(icon, "icon_ly", rt);
338 elm_object_part_content_set(icon, "icon", icon_ly);
342 } else if (!strcmp(part, "elm.icon.2")) {
343 btn = elm_button_add(obj);
344 elm_object_text_set(btn, S_("IDS_COM_BODY_END"));
345 elm_object_style_set(btn, "default");
347 evas_object_smart_callback_add(btn, "clicked",
348 func_end[info->category], info);
349 elm_object_focus_set(btn, EINA_FALSE);
350 evas_object_propagate_events_set(btn, EINA_FALSE);
358 static char *_gl_text_get_app(void *data, Evas_Object *obj, const char *part)
360 struct _task_info *info = (struct _task_info *)data;
361 char buf[_BUF_MAX] = { 0, };
363 retvm_if(data == NULL, NULL, "Invalid argument: task info is NULL\n");
364 retvm_if(part == NULL, NULL, "Invalid argument: part is NULL\n");
366 if (!strcmp(part, "elm.text")) {
367 snprintf(buf, _BUF_MAX, "%s", info->app_name);
374 static void _bl_sel(void *data, Evas_Object *obj, void *event_info)
377 Elm_Object_Item *item = (Elm_Object_Item *) event_info;
378 elm_genlist_item_selected_set(item, EINA_FALSE);
381 static Evas_Object *_bl_content_get(void *data, Evas_Object *obj,
384 Evas_Object *btn = NULL;
385 struct appdata *ad = evas_object_data_get(obj, "appdata");
387 if (!strcmp(part, "elm.icon")) {
389 btn = elm_button_add(obj);
390 elm_object_style_set(btn, "default");
392 elm_object_text_set(btn, T_(button_text[(int)data]));
393 evas_object_smart_callback_add(btn, "clicked",
394 func_del[(int)data], ad);
395 elm_object_focus_set(btn, EINA_FALSE);
397 evas_object_size_hint_min_set(btn, 0, 50);
398 evas_object_size_hint_max_set(btn, 0, 50);
399 evas_object_propagate_events_set(btn, EINA_FALSE);
407 static char *_gl_text_get_title(void *data, Evas_Object *obj, const char *part)
411 if (!strcmp(part, "elm.text")) {
412 snprintf(buf, sizeof(buf), "%s (%d)",
413 T_(group_name[(int)data]), _get_grp_cnt((int)data));
419 static char *_gl_text_get_his(void *data, Evas_Object *obj, const char *part)
421 struct _task_info *info = (struct _task_info *)data;
422 char buf[_BUF_MAX] = { 0, };
424 if (!strcmp(part, "elm.text")) {
425 snprintf(buf, _BUF_MAX, "%s", info->app_name);
431 static Evas_Object *_gl_content_get_his(void *data, Evas_Object *obj,
434 struct _task_info *info = (struct _task_info *)data;
435 char buf[_BUF_MAX] = { 0, };
437 Evas_Object *icon = NULL;
438 Evas_Object *btn = NULL;
440 retvm_if(data == NULL, NULL, "Invalid argument: task info is NULL\n");
442 if (!strcmp(part, "elm.icon.1")) {
443 snprintf(buf, sizeof(buf), "%s", info->icn_path);
444 retvm_if(buf == NULL, NULL, "%s icon is NULL\n", info->app_name);
445 if (!ecore_file_exists(buf) || strlen(buf) < 4)
446 snprintf((char *)buf, (size_t) sizeof(buf),
447 (const char *)IMAGEDIR "/icon_taskmgr.png");
449 icon = elm_icon_add(obj);
450 elm_image_file_set(icon, buf, NULL);
451 elm_image_preload_disabled_set(icon, EINA_TRUE);
453 evas_object_size_hint_min_set(icon,
454 (int)72 * elm_config_scale_get(),
455 (int)72 * elm_config_scale_get());
459 } else if (!strcmp(part, "elm.icon.2")) {
460 btn = elm_button_add(obj);
461 elm_object_text_set(btn, S_("IDS_COM_OPT_DELETE"));
462 elm_object_style_set(btn, "default");
464 evas_object_smart_callback_add(btn, "clicked",
465 func_end[info->category], info);
466 elm_object_focus_set(btn, EINA_FALSE);
467 evas_object_propagate_events_set(btn, EINA_FALSE);
478 itc_gl.item_style = "grouptitle";
479 itc_gl.func.text_get = _gl_text_get_title;
481 //itc_dl.item_style = "2text.2icon.7";
482 itc_dl.item_style = "1text.2icon.4";
483 itc_dl.func.text_get = _gl_text_get_app;
484 itc_dl.func.content_get = _gl_content_get_app;
486 itc_hl.item_style = "1text.2icon.4";
487 itc_hl.func.text_get = _gl_text_get_his;
488 itc_hl.func.content_get = _gl_content_get_his;
490 itc_separator4.item_style = "dialogue/seperator";
491 itc_separator2.item_style = "dialogue/seperator";
493 itc_bl.item_style = "1icon";
494 itc_bl.func.content_get = _bl_content_get;
496 itc_nl.item_style = "1text";
497 itc_nl.func.text_get = nl_text_get;
501 int check_genlist(struct appdata *ad)
503 Elm_Object_Item *egi;
504 struct _task_info *info;
506 egi = elm_genlist_first_item_get(ad->gl);
508 info = (struct _task_info *)elm_object_item_data_get(egi);
510 _D("%s info[0x%x]\n", (int)info < 3 ? "-" : info->app_name, info);
514 egi = elm_genlist_item_next_get(egi);
520 int _set_genlist_from_eina(struct appdata *ad)
524 Elm_Object_Item *git, *item;
525 struct _task_info *info;
528 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
529 retvm_if(ad->gl == NULL, -1, "Invalid argument:genlist is NULL\n");
531 for (i = 0; i < TS_MAX; i++) {
532 git = elm_genlist_item_append(ad->gl, &itc_gl,
534 ELM_GENLIST_ITEM_NONE,
536 retvm_if(git == NULL, -1, "Failed append item\n");
537 elm_genlist_item_select_mode_set(git, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
539 if (eina_list_count(ad->applist[i]) > 0) {
541 item = elm_genlist_item_append(ad->gl, &itc_separator4,
543 ELM_GENLIST_ITEM_NONE,
545 elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
547 elm_genlist_item_append(ad->gl, &itc_bl,
549 ELM_GENLIST_ITEM_NONE,
552 item = elm_genlist_item_append(ad->gl, &itc_separator2,
554 ELM_GENLIST_ITEM_NONE,
556 elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
558 ad->applist[i] = eina_list_nth_list(ad->applist[i], 0);
559 EINA_LIST_FOREACH(ad->applist[i], l, info) {
561 info->it = elm_genlist_item_append(ad->gl,
562 (i == TS_INUSE) ? &itc_dl : &itc_hl,
564 ELM_GENLIST_ITEM_NONE,
569 item = elm_genlist_item_append(ad->gl, &itc_nl,
571 ELM_GENLIST_ITEM_NONE,
573 elm_genlist_item_select_mode_set(item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
579 void _set_genlist(struct appdata *ad)
582 retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
583 int ret = AUL_R_ERROR;
585 int sleep_value = 1000;
589 while (ret != AUL_R_OK && retry_cnt < 5) {
591 ret = aul_app_get_running_app_info(runapp_info_get, ad);
593 if (ret != AUL_R_OK) {
594 _D("Fail to get running app information from ail");
601 taskmanager_get_history_app_info(ad);
602 _set_genlist_from_eina(ad);
606 void refresh_app_info(struct appdata *ad)
609 retm_if(ad == NULL, "Invalid argument: appdata is NULL\n");
611 _free_einalist_all(ad);
620 void _del_popup_timer(struct appdata *ad)
622 if (ad->popup_timer) {
623 ecore_timer_del(ad->popup_timer);
624 ad->popup_timer = NULL;
628 void taskmanager_free_info(struct _task_info *info)
631 if (info->app_name) {
632 free(info->app_name);
633 info->app_name = NULL;
635 if (info->pkg_name) {
636 free(info->pkg_name);
637 info->pkg_name = NULL;
639 if (info->icn_path) {
640 free(info->icn_path);
641 info->icn_path = NULL;
648 int response_end_inuse(struct appdata *ad)
651 Eina_List *l, *l_next;
652 struct _task_info *info;
653 Eina_Bool dead = EINA_FALSE;
655 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
657 ad->ending = EINA_TRUE;
659 EINA_LIST_FOREACH_SAFE(ad->applist[TS_INUSE], l, l_next, info) {
660 _D("applist pid : %d", info->pid);
661 if (info->it == g_egi) {
662 _D("matched applist pid : %d", info->pid);
664 if (aul_terminate_pid(info->pid) < 0) {
665 kill(info->pid, SIGKILL);
672 ad->ending = EINA_FALSE;
675 _D("matched applist is nothing\n");
676 _del_progressbar(ad);
682 Eina_Bool _refresh_idler_cb(void *data)
685 struct appdata *ad = (struct appdata *)data;
686 retvm_if(data == NULL, ECORE_CALLBACK_CANCEL, "Invalid argument: appdata is NULL\n:");
688 _del_popup_timer(ad);
689 _del_progressbar(ad);
690 refresh_app_info(ad);
691 return ECORE_CALLBACK_CANCEL;
694 int response_end_all_inuse(struct appdata *ad)
697 struct _task_info *info;
699 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
701 ad->ending = EINA_TRUE;
703 if(ad->update_timer) {
704 ecore_timer_del(ad->update_timer);
705 ad->update_timer = NULL;
708 ad->endcnt = eina_list_count(ad->applist[TS_INUSE]);
709 _D("set end count (%d)\n", ad->endcnt);
711 EINA_LIST_FOREACH(ad->applist[TS_INUSE], l, info) {
713 _D("applist pid : %d", info->pid);
715 if (aul_terminate_pid(info->pid) < 0) {
716 kill(info->pid, SIGKILL);
722 ad->ending = EINA_FALSE;
726 int response_del_history(struct appdata *ad)
728 Eina_List *l, *l_next;
729 struct _task_info *info;
731 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
733 _show_progressbar(ad);
734 EINA_LIST_FOREACH_SAFE(ad->applist[TS_HISTORY], l, l_next, info) {
735 _D("history applist pid : %d", info->pid);
736 if (info->it == g_egi) {
738 if (rua_init() == -1) {
741 rua_delete_history_with_pkgname(info->pkg_name);
744 ad->applist[TS_HISTORY] =
745 eina_list_remove_list(ad->applist[TS_HISTORY], l);
748 bundle_free(info->b);
751 elm_object_item_del(info->it);
752 taskmanager_free_info(info);
757 refresh_app_info(ad);
758 _del_popup_timer(ad);
759 _del_progressbar(ad);
761 ad->mode = MODE_NONE;
765 int response_del_all_history(struct appdata *ad)
768 struct _task_info *info;
770 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
772 if(ad->update_timer) {
773 _D("update timer is deleted\n");
774 ecore_timer_del(ad->update_timer);
775 ad->update_timer = NULL;
779 _show_progressbar(ad);
781 if (rua_init() == -1) {
785 EINA_LIST_FOREACH(ad->applist[TS_HISTORY], l, info) {
787 rua_delete_history_with_pkgname(info->pkg_name);
791 if (eina_list_count(ad->applist[TS_INUSE]) == 0) {
796 refresh_app_info(ad);
797 _del_popup_timer(ad);
798 _del_progressbar(ad);
800 ad->mode = MODE_NONE;
804 int response_kill_inuse(struct appdata *ad)
806 Eina_List *l, *l_next;
807 struct _task_info *info;
809 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
811 _show_progressbar(ad);
813 EINA_LIST_FOREACH_SAFE(ad->applist[TS_INUSE], l, l_next, info) {
814 _D("kill applist pid : %d", info->pid);
815 if (info->it == g_egi) {
817 kill(info->pid, SIGKILL);
820 ad->applist[TS_INUSE] =
821 eina_list_remove_list(ad->applist[TS_INUSE], l);
822 taskmanager_free_info(info);
826 refresh_app_info(ad);
827 _del_progressbar(ad);
832 int response_kill_all_inuse(struct appdata *ad)
835 struct _task_info *info;
837 retvm_if(ad == NULL, -1, "Invalid argument: appdata is NULL\n");
839 _show_progressbar(ad);
841 EINA_LIST_FOREACH(ad->applist[TS_INUSE], l, info) {
842 _D("kill all applist pid : %d", info->pid);
845 kill(info->pid, SIGKILL);
849 refresh_app_info(ad);
850 _del_progressbar(ad);