2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
18 #include "mgr-app-common-debug.h"
19 #include "mgr-app-common-error.h"
20 #include "mgr-app-common-util.h"
21 #include "mgr-app-view-main.h"
22 #include "mgr-app-view-common.h"
23 #include "mgr-app-string.h"
24 #include "mgr-app-widget.h"
25 #include "mgr-app-uigadget.h"
28 #include <package-manager.h>
29 #include <pkgmgr-info.h>
31 #include <app_manager.h>
33 #define WRT_PREFIX "wgt"
34 #define TPK_PREFIX "tpk"
35 #define RPM_PREFIX "rpm"
37 #define STR_ICON "icon"
39 #define EDC_FILE EDJDIR"/ug-setting-manage-applications-efl/ug-setting-manage-applications-efl.edj"
41 #define ELM_TEXT "elm.text"
42 #define ITC_ITEM_STYLE "dialogue/1text.1icon.2"
43 #define ITC_SEP_ITEM_STYLE "dialogue/separator"
44 #define GENLIST_BLOCK_CNT 10
46 #define MAX_BUF_SIZE 32
47 #define MAX_APP_CNT 1024
51 #define STR_INSTALL "install"
52 #define STR_UNINSTALL "uninstall"
53 #define STR_START "start"
56 #define STR_CANCEL "cancel"
57 #define STR_ERROR "error"
58 #define STR_FAIL "fail"
59 #define STR_POPUP_OK "OK"
61 static Evas_Object *_genlist = NULL;
62 static Eina_Bool _initialize = false;
63 static GList *_installed_list = NULL;
64 static int _installed_cnt = 0;
65 static Elm_Object_Item *_tabbar_item[VIEW_TYPE_MAX] = {NULL,};
66 static Elm_Object_Item *_navi_it = NULL;
68 static Elm_Genlist_Item_Class *itc = NULL;
69 static Elm_Genlist_Item_Class *itc_sep = NULL;
71 static void _free_resources(struct ug_data * ugd)
75 mgr_app_app_info_t *app_info = NULL;
78 for (i = 0; i < _installed_cnt; i++ ) {
79 app_info = (mgr_app_app_info_t *)g_list_nth_data(_installed_list, 0);
80 if (NULL == app_info) {
83 MGR_APP_MEM_FREE(app_info->pkg_label);
84 MGR_APP_MEM_FREE(app_info->pkg_name);
85 MGR_APP_MEM_FREE(app_info->pkg_type);
86 MGR_APP_MEM_FREE(app_info->icon_path);
87 MGR_APP_MEM_FREE(app_info->main_appid);
88 _installed_list = g_list_remove(_installed_list, app_info);
91 elm_genlist_item_class_free(itc);
92 elm_genlist_item_class_free(itc_sep);
95 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
99 struct ug_data *ugd = (struct ug_data*)data;
101 mgr_app_doubletap_sensor_disable();
103 _free_resources(ugd);
105 mgrapp_set_view_type(VIEW_TYPE_NONE);
107 elm_naviframe_item_pop(ugd->navi_bar);
109 /* bg must delete before starting on_destroy */
110 if (ugd && ugd->bg) {
111 evas_object_del(ugd->bg);
115 if (ugd && ugd->ug) {
116 ug_destroy_me(ugd->ug);
123 /* callback for 'deletion' */
124 static void _gl_del(void *data, Evas_Object *obj)
128 ret_if(data == NULL);
129 mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
132 MGR_APP_MEM_FREE(app_info->pkg_name);
133 MGR_APP_MEM_FREE(app_info->pkg_label);
134 MGR_APP_MEM_FREE(app_info->pkg_type);
135 MGR_APP_MEM_FREE(app_info->icon_path);
136 MGR_APP_MEM_FREE(app_info->main_appid);
137 //MGR_APP_MEM_FREE(app_info);
143 /* callback for 'selection' */
144 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
148 ret_if(data == NULL);
149 ret_if(event_info == NULL);
151 struct ug_data *ugd = (struct ug_data*)data;
152 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
154 mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)elm_object_item_data_get(item);
155 ret_if(app_info == NULL);
157 elm_genlist_item_selected_set(item, 0);
159 /* create app info view */
160 ugd->data = (void*)app_info;
161 mgrapp_view_info_create(app_info->pkg_name, (void*)ugd);
166 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
170 retv_if(data == NULL, NULL);
171 mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
174 char *package_label = app_info->pkg_label;
175 char *icon_path = app_info->icon_path;
177 MGR_APP_DEBUG("package_label:[%s], icon_path:[%s]\n", package_label, icon_path);
178 MGR_APP_DEBUG("part:%s\n", part);
180 /* label for 'elm.text' part */
181 if (package_label && 0 == strcmp(part, ELM_TEXT)) {
182 MGR_APP_MEM_STRDUP(label, package_label);
184 MGR_APP_MEM_STRDUP(label, MGRAPP_STR_ERROR);
191 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
195 retv_if(data == NULL, NULL);
196 mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
198 retv_if(app_info->icon_path == NULL, NULL);
199 char *icon_path = NULL;
200 icon_path = app_info->icon_path;
202 Evas_Object *icon = NULL;
204 MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
205 MGR_APP_DEBUG("part:%s\n", part);
207 /* icon for 'elm.icon' part */
208 icon = elm_icon_add(obj);
209 retv_if(icon == NULL, NULL);
210 evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
211 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
212 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
214 elm_image_file_set(icon, icon_path, STR_ICON);
215 evas_object_show(icon);
221 static gint _app_list_qsort_cb(gconstpointer a, gconstpointer b)
225 retv_if(NULL == a, 0);
226 retv_if(NULL == b, 0);
228 mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t *)a;
229 mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t *)b;
230 char *pkg_label1 = NULL;
231 char *pkg_label2 = NULL;
235 pkg_label1 = app_info1->pkg_label;
236 pkg_label2 = app_info2->pkg_label;
237 retv_if(NULL == pkg_label1, 0);
238 retv_if(NULL == pkg_label2, 0);
240 MGR_APP_DEBUG("pkg_label1: %s", pkg_label1);
241 MGR_APP_DEBUG("pkg_label2: %s", pkg_label2);
243 len = (strlen(pkg_label1) >= strlen(pkg_label2)) ? strlen(pkg_label1) : strlen(pkg_label2);
244 r = strncasecmp(pkg_label1, pkg_label2, len);
250 static void _get_appinfo_from_pkgmgr(const pkgmgrinfo_pkginfo_h handler, mgr_app_app_info_t *app_info)
254 ret_if(NULL == handler || NULL == app_info);
257 char *pkg_name = NULL;
258 char *icon_path = NULL;
259 char *main_appid = NULL;
260 char *pkg_label = NULL;
261 pkgmgrinfo_appinfo_h appinfo_h = NULL;
263 r = pkgmgrinfo_pkginfo_get_pkgid(handler, &pkg_name);
265 MGR_APP_DEBUG_ERR("pkgmgrinfo_pkginfo_get_pkgid is failed %d", r);
268 MGR_APP_MEM_STRDUP(app_info->pkg_name, pkg_name);
269 MGR_APP_DEBUG("pkg_name: %s", pkg_name);
271 /* get label/icon from mainapp */
272 r = pkgmgrinfo_pkginfo_get_mainappid(handler, &main_appid);
274 MGR_APP_DEBUG_ERR("pkgmgrinfo_pkginfo_get_mainappid is failed %d", r);
277 MGR_APP_DEBUG("main_appid: %s", main_appid);
278 MGR_APP_MEM_STRDUP(app_info->main_appid, main_appid);
280 r = pkgmgrinfo_appinfo_get_appinfo(main_appid, &appinfo_h);
282 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo is failed %d", r);
286 r = pkgmgrinfo_appinfo_is_nodisplay(appinfo_h, &app_info->nodisplay);
288 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_is_nodisplay failed. %d", r);
292 r = pkgmgrinfo_appinfo_get_icon(appinfo_h, &icon_path);
294 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_get_icon is failed %d", r);
297 MGR_APP_MEM_STRDUP(app_info->icon_path, icon_path);
298 if (app_info->nodisplay) {
299 mgr_app_set_default_icon(&app_info->icon_path, DEFAULT_ICON_SERVICE);
301 mgr_app_set_default_icon(&app_info->icon_path, DEFAULT_ICON_APP);
303 MGR_APP_DEBUG("icon_path: %s", icon_path);
305 r = pkgmgrinfo_pkginfo_get_label(handler, &pkg_label);
307 MGR_APP_DEBUG_ERR("pkgmgrinfo_pkginfo_get_label is failed %d", r);
310 MGR_APP_MEM_STRDUP(app_info->pkg_label, pkg_label);
311 MGR_APP_DEBUG("pkg_label: %s", pkg_label);
315 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
321 static void _notify_by_uninstall(void *data)
325 ret_if(data == NULL);
326 struct ug_data *ugd = (struct ug_data*)data;
328 Evas_Object *noti = elm_notify_add(ugd->navi_bar);
329 elm_notify_align_set(noti, ELM_NOTIFY_ALIGN_FILL, 1.0);
331 Evas_Object *layout = elm_layout_add(noti);
332 elm_layout_theme_set(layout, "standard", "selectioninfo", "center_text");
334 elm_object_content_set(noti, layout);
335 elm_notify_timeout_set(noti, 2);
336 edje_object_part_text_set(_EDJ(layout), ELM_TEXT, MGRAPP_STR_UNINSTALLED);
337 evas_object_show(noti);
342 static void mgrapp_view_list_update_by_install(const char *pkg_type, const char *pkg_name, void *data)
346 ret_if(pkg_name == NULL || data == NULL);
348 struct ug_data *ugd = (struct ug_data*)data;
349 pkgmgr_pkginfo_h pkg_handle = NULL;
350 mgr_app_app_info_t *app_info = NULL;
351 Elm_Object_Item *item = NULL;
354 _initialize = EINA_FALSE;
356 r = pkgmgr_pkginfo_get_pkginfo(pkg_name, &pkg_handle);
358 MGR_APP_DEBUG_ERR("pkgmgr_pkginfo_get_pkginfo is failed. %d", r);
362 app_info = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
363 if (NULL == app_info) {
366 memset(app_info, 0, sizeof(mgr_app_app_info_t));
368 _get_appinfo_from_pkgmgr(pkg_handle, app_info);
370 item = elm_genlist_item_append(_genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
372 MGR_APP_DEBUG_ERR("It failed to append new item in gentlist");
379 pkgmgr_pkginfo_destroy_pkginfo(pkg_handle);
385 void mgrapp_view_list_update_by_uninstall(const char *pkg_type, const char *pkg_name, void *data)
389 ret_if(pkg_name == NULL);
391 mgr_app_app_info_t *app_info = NULL;
392 Elm_Object_Item *item = NULL;
395 /* header separator */
396 item = elm_genlist_first_item_get(_genlist);
397 ret_if(item == NULL);
398 item = elm_genlist_item_next_get(item);
399 ret_if(item == NULL);
402 for (i = 0; i < _installed_cnt; i++) {
404 app_info = (mgr_app_app_info_t *)elm_object_item_data_get(item);
405 ret_if(app_info == NULL);
407 if (app_info->pkg_name && 0 == strcmp(app_info->pkg_name, pkg_name)) {
408 _installed_list = g_list_remove(_installed_list, app_info);
409 elm_object_item_del(item);
412 MGR_APP_DEBUG("deleted");
415 item = elm_genlist_item_next_get(item);
416 ret_if(item == NULL);
419 elm_genlist_realized_items_update(_genlist);
424 static void _response_cb(void *data, Evas_Object *obj, void *event_info)
429 evas_object_del(data);
436 int mgrapp_view_listen_cb(int req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data)
440 MGR_APP_DEBUG("key:%s val:%s", key, val);
441 MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
442 retv_if(data == NULL, -1);
443 struct ug_data *ugd = (struct ug_data*)data;
445 if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
446 ugd->uninstall = EINA_TRUE;
447 } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
448 ugd->uninstall = EINA_FALSE;
449 } else if (!strncmp(key, STR_ERROR, strlen(key))) {
450 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_FAIL, strlen(val))) {
451 mgrapp_destroy_popup_progressbar();
452 mgrapp_create_popup_text_1button(ugd->win_main, MGRAPP_STR_FAILED, STR_POPUP_OK, _response_cb);
453 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
454 if (ugd->uninstall) {
455 mgrapp_destroy_popup_progressbar();
456 mgrapp_create_popup_text_1button(ugd->win_main, MGRAPP_STR_SUCCESS, STR_POPUP_OK, _response_cb);
457 mgrapp_view_list_update_by_uninstall(pkg_type, pkg_name, (void*)ugd);
459 mgrapp_view_list_update_by_install(pkg_type, pkg_name, (void*)ugd);
462 /* check the info view was opened */
463 if (VIEW_TYPE_APP_INFO == mgrapp_get_view_type()) {
464 if (ugd->uninstall) {
465 mgrapp_view_info_destroy(ugd);
466 _notify_by_uninstall((void*)ugd);
467 ugd->uninstall = EINA_FALSE;
470 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
478 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
483 ret_if(event_info == NULL);
485 if (event_info == elm_genlist_item_next_get(elm_genlist_first_item_get(obj))) { // first is a separator
486 elm_object_item_signal_emit(event_info, "elm,state,top", "");
487 } else if (event_info == elm_genlist_item_prev_get(elm_genlist_last_item_get(obj))) { // last is a separator
488 elm_object_item_signal_emit(event_info, "elm,state,bottom", "");
490 elm_object_item_signal_emit(event_info, "elm,state,center", "");
496 static int _pkgmgr_iter_fn(pkgmgr_pkginfo_h handle, void *data)
500 retv_if(NULL == handle, 0);
502 mgr_app_app_info_t *app_info = NULL;
504 app_info = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
505 retv_if(app_info == NULL, -1);
506 memset(app_info, 0, sizeof(mgr_app_app_info_t));
508 _get_appinfo_from_pkgmgr(handle, app_info);
510 _installed_list = g_list_append(_installed_list, (gpointer)app_info);
512 MGR_APP_DEBUG("installed cnt %d", _installed_cnt);
518 static void _create_genlist_app_list(seg_type_t seg, void *data)
522 ret_if(data == NULL);
523 struct ug_data *ugd = (struct ug_data*)data;
524 Evas_Object *genlist = NULL;
525 Elm_Object_Item *item_sep = NULL;
526 Elm_Object_Item *item = NULL;
528 mgr_app_app_info_t *app_info = NULL;
530 int r = PKGMGR_R_ERROR;
532 bool is_running = false;
534 /* set the genlist item style */
535 itc = elm_genlist_item_class_new();
537 itc_sep = elm_genlist_item_class_new();
538 ret_if(itc_sep == NULL);
540 itc->item_style = ITC_ITEM_STYLE;
541 itc->func.text_get = _gl_label_get;
542 itc->func.content_get = _gl_icon_get;
543 itc->func.state_get = NULL;
544 itc->func.del = _gl_del;
546 itc_sep->item_style = ITC_SEP_ITEM_STYLE;
547 itc_sep->func.text_get = NULL;
548 itc_sep->func.content_get= NULL;
549 itc_sep->func.state_get = NULL;
550 itc_sep->func.del = NULL;
553 genlist = elm_genlist_add(ugd->navi_bar);
554 ret_if(genlist == NULL);
555 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
556 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
557 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
558 elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
559 elm_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
560 evas_object_show(genlist);
561 evas_object_smart_callback_add(genlist, "realized", _gl_realized, NULL);
566 item_sep = elm_genlist_item_append(genlist, itc_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
568 elm_genlist_item_select_mode_set(item_sep, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
570 for (i = 0; i < _installed_cnt; i++) {
572 app_info = (mgr_app_app_info_t *)g_list_nth_data(_installed_list, i);
573 if (NULL == app_info) {
574 MGR_APP_DEBUG_ERR("app_info is a null");
577 MGR_APP_DEBUG("genlist %d app_info->pkg_label: %s", i, app_info->pkg_label);
579 if (LIST_SEG_TYPE_RUNNING == seg
580 && APP_MANAGER_ERROR_NONE == app_manager_is_running(app_info->main_appid, &is_running)
581 && false == is_running) {
585 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
587 MGR_APP_DEBUG_ERR("It failed to append new item in gentlist");
592 item_sep = elm_genlist_item_append(genlist, itc_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
594 elm_genlist_item_select_mode_set(item_sep, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
596 elm_object_item_part_content_set(_navi_it, "elm.swallow.content", genlist);
598 /* register pkg-mgr listener */
599 ret_if(ugd->pc_listen == NULL);
600 r = pkgmgr_client_listen_status(ugd->pc_listen, mgrapp_view_listen_cb, (void*)ugd);
602 MGR_APP_DEBUG_ERR("status listen failed!\n");
609 static void _doubletap_sensor_cb(void *data)
613 ret_if(NULL == data);
615 Evas_Object *genlist = (Evas_Object*)data;
616 Elm_Object_Item *item = NULL;
618 item = elm_genlist_first_item_get(genlist);
619 ret_if(NULL == item);
621 elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
626 static void _create_genlist_app_cb(void *data, Evas_Object *obj, void *event_info)
630 ret_if(NULL == data);
632 _create_genlist_app_list(LIST_SEG_TYPE_APPLICATION, data);
637 static void _create_genlist_all_cb(void *data, Evas_Object *obj, void *event_info)
641 ret_if(NULL == data);
643 _create_genlist_app_list(LIST_SEG_TYPE_ALL, data);
648 static void _create_genlist_running_cb(void *data, Evas_Object *obj, void *event_info)
652 ret_if(NULL == data);
654 _create_genlist_app_list(LIST_SEG_TYPE_RUNNING, data);
659 void mgrapp_view_list_create(void *data)
663 ret_if(data == NULL);
665 struct ug_data *ugd = (struct ug_data *)data;
666 Evas_Object *back_btn = NULL;
667 Evas_Object *tabbar = NULL;
668 Elm_Object_Item *navi_it = NULL;
671 mgrapp_set_view_type(VIEW_TYPE_APP_LIST);
673 Evas_Object *nocontents = NULL;
674 nocontents = elm_layout_add(ugd->navi_bar);
675 ret_if(NULL == nocontents);
676 elm_layout_theme_set(nocontents, "layout", "nocontents", "full");
679 back_btn = elm_button_add(ugd->navi_bar);
680 ret_if(NULL == back_btn);
681 elm_object_style_set(back_btn, "naviframe/end_btn/default");
682 evas_object_smart_callback_add(back_btn, "clicked", _app_list_back_cb, (void*)ugd);
684 _navi_it = navi_it = elm_naviframe_item_push(ugd->navi_bar, MGRAPP_STR_MANAGE_APPLICATIONS, back_btn, NULL, nocontents, "tabbar");
686 r = pkgmgr_pkginfo_get_list(_pkgmgr_iter_fn, data);
687 if (PKGMGR_R_OK != r) {
688 MGR_APP_DEBUG_ERR("pkgmgr_get_pkg_list failed. %d", r);
691 /* sorting by pkg_label */
692 _installed_list = g_list_sort(_installed_list, _app_list_qsort_cb);
695 tabbar = elm_toolbar_add(ugd->navi_bar);
696 ret_if(NULL == tabbar);
697 elm_toolbar_shrink_mode_set(tabbar, ELM_TOOLBAR_SHRINK_EXPAND);
698 elm_object_style_set(tabbar, "tabbar");
699 elm_object_item_part_content_set(navi_it, "tabbar", tabbar);
701 _tabbar_item[LIST_SEG_TYPE_APPLICATION] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_APPLICATION, _create_genlist_app_cb, (void*)ugd);
702 _tabbar_item[LIST_SEG_TYPE_RUNNING] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_RUNNING, _create_genlist_running_cb, (void*)ugd);
703 _tabbar_item[LIST_SEG_TYPE_ALL] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_ALL, _create_genlist_all_cb, (void*)ugd);
704 elm_toolbar_item_selected_set(_tabbar_item[LIST_SEG_TYPE_APPLICATION], EINA_TRUE);
706 mgr_app_doubletap_sensor_set_cb(_doubletap_sensor_cb, _genlist);
707 mgr_app_doubletap_sensor_enable();
712 void mgrapp_view_list_update(void *data)
717 mgr_app_doubletap_sensor_set_cb(_doubletap_sensor_cb, _genlist);
718 mgr_app_doubletap_sensor_enable();