Add the function for uninstalling tpk, wgt package 38/46938/1 accepted/tizen/tv/20150829.030906 submit/tizen/20150828.103950
authorHyojung Jo <hj903.jo@samsung.com>
Thu, 27 Aug 2015 10:01:39 +0000 (19:01 +0900)
committerHyojung Jo <hj903.jo@samsung.com>
Thu, 27 Aug 2015 10:01:39 +0000 (19:01 +0900)
Change-Id: I2469344ad73f8dd2c3743eda3a02e4eb35371e21
Signed-off-by: Hyojung Jo <hj903.jo@samsung.com>
12 files changed:
CMakeLists.txt
include/data/app.h
include/define.h
include/utils.h
include/view.h
org.tizen.apps.xml.in
packaging/org.tizen.apps.spec
res/widget/gengrid.edc
src/data/app.c
src/utils.c
src/view/view_action_menu.c
src/view/view_base.c

index b4bce5c..b677503 100644 (file)
@@ -23,6 +23,7 @@ pkg_check_modules(PKGS REQUIRED
                capi-appfw-application
                app-utils
                pkgmgr-info
+               capi-appfw-package-manager
                )
 
 IF(NOT DEFINED PACKAGE_NAME)
index 3447b4a..2752d69 100644 (file)
@@ -23,8 +23,10 @@ struct app_data;
 
 Eina_List *get_app_list(void);
 char *get_app_id(struct app_data *adata);
+char *get_pkg_id(struct app_data *adata);
 char *get_app_name(struct app_data *adata);
 char *get_app_icon(struct app_data *adata);
+char *get_pkg_type(struct app_data *adata);
 bool get_app_favorite(struct app_data *adata, bool *isfavorite);
 bool set_app_favorite(struct app_data *adata, bool isfavorite);
 bool get_app_icon_bg_color(struct app_data *adata,
index d6b43a8..b916cd4 100644 (file)
 #define STR_NO_FAVORITE "No favorite contents"
 #define STR_ADD_FAVORITE "Added to your favorite."
 #define STR_REMOVE_FAVORITE "Removed from your favorite."
+#define STR_WGT "wgt"
+#define STR_TPK "tpk"
 
 /* Count */
 #define MENU_COUNT 2
index 0c5178f..f6bdefd 100644 (file)
@@ -32,5 +32,6 @@ Evas_Object *utils_add_notify(Evas_Object *parent, const char *text,
                const char *noti_style, const char *label_style,
                int timeout);
 bool utils_launch_app(const char *appid);
+bool utils_uninstall_app(const char *pkgid, const char *pkgtype);
 
 #endif /* __AIR_APPS_UTILS_H__ */
index 0305a51..f555637 100644 (file)
@@ -23,6 +23,7 @@ view_class *view_action_menu_get_vclass(void);
 enum update_type {
        UPDATE_ID = 0,
        UPDATE_FAVORITE,
+       UPDATE_GRID,
        UPDATE_SHOW_TOAST,
 };
 
index 01ba59f..4e01684 100644 (file)
@@ -7,4 +7,7 @@
                <label>Apps</label>
                <icon>@DESKTOP_ICON@</icon>
        </ui-application>
+       <privileges>
+               <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+       </privileges>
 </manifest>
index 5942fd5..ff87ac1 100644 (file)
@@ -12,6 +12,7 @@ BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(capi-appfw-application)
 BuildRequires: pkgconfig(app-utils)
 BuildRequires: pkgconfig(pkgmgr-info)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
 
 %define _appdir /usr/apps/%{name}
 %define _bindir %{_appdir}/bin
index 8cac833..304a1ad 100644 (file)
@@ -627,13 +627,6 @@ group {
                }
 
                program {
-                       name, "activated";
-                       signal, "elm,state,activated";
-                       source, "elm";
-                       after, "item_selected";
-               }
-
-               program {
                        name, "selected";
                        signal, "elm,state,selected";
                        source, "elm";
index 9034e48..a2035bd 100644 (file)
 
 struct app_data {
        char *appid;
+       char *pkgid;
        char *name;
        char *icon;
+       char *pkgtype;
        bool is_locked;
        struct color_data icon_bg;
        struct color_data text_bg;
@@ -42,7 +44,8 @@ static int _get_app_data_foreach(pkgmgrinfo_appinfo_h handle, void *data)
 {
        Eina_List **list;
        struct app_data *adata;
-       char *appid, *name, *icon;
+       char *appid, *pkgid, *name, *icon, *pkgtype;
+       pkgmgrinfo_pkginfo_h pkginfo_h;
        bool nodisplay;
 
        if (!data)
@@ -59,24 +62,41 @@ static int _get_app_data_foreach(pkgmgrinfo_appinfo_h handle, void *data)
        if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK)
                return -1;
 
-       if (pkgmgrinfo_appinfo_get_label(handle, &name) != PMINFO_R_OK)
+       if (pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid) != PMINFO_R_OK)
                return -1;
 
+       if (pkgmgrinfo_appinfo_get_label(handle, &name) != PMINFO_R_OK)
+               return 0;
+
        if (pkgmgrinfo_appinfo_get_icon(handle, &icon) != PMINFO_R_OK)
                return 0;
 
+       if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(),
+                               &pkginfo_h) != PMINFO_R_OK)
+               return 0;
+
+       if (pkgmgrinfo_pkginfo_get_type(pkginfo_h, &pkgtype) != PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+               return 0;
+       }
+
        adata = calloc(1, sizeof(*adata));
        if (!adata) {
                _ERR("Calloc failed.");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
                return -1;
        }
 
        if (appid)
                adata->appid = strdup(appid);
+       if (pkgid)
+               adata->pkgid = strdup(pkgid);
        if (name)
                adata->name = strdup(name);
        if (icon)
                adata->icon = strdup(icon);
+       if (pkgtype)
+               adata->pkgtype = strdup(pkgtype);
 
        if (!strcmp(appid, STR_BROWSER_ID)) {
                _set_default_color(&adata->icon_bg);
@@ -87,6 +107,8 @@ static int _get_app_data_foreach(pkgmgrinfo_appinfo_h handle, void *data)
 
        *list = eina_list_append(*list, adata);
 
+       pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+
        return 0;
 }
 
@@ -110,6 +132,16 @@ char *get_app_id(struct app_data *adata)
        return adata->appid;
 }
 
+char *get_pkg_id(struct app_data *adata)
+{
+       if (!adata) {
+               _ERR("Invalid argument.");
+               return NULL;
+       }
+
+       return adata->pkgid;
+}
+
 char *get_app_name(struct app_data *adata)
 {
        if (!adata) {
@@ -130,6 +162,16 @@ char *get_app_icon(struct app_data *adata)
        return adata->icon;
 }
 
+char *get_pkg_type(struct app_data *adata)
+{
+       if (!adata) {
+               _ERR("Invalid argument.");
+               return NULL;
+       }
+
+       return adata->pkgtype;
+}
+
 bool get_app_favorite(struct app_data *adata,  bool *isfavorite)
 {
        int r;
index 829dd42..824d720 100644 (file)
@@ -17,6 +17,7 @@
 #include <Elementary.h>
 #include <app_control.h>
 #include <app_debug.h>
+#include <package_manager.h>
 
 #include "define.h"
 #include "utils.h"
@@ -272,3 +273,46 @@ bool utils_launch_app(const char *appid)
 
        return true;
 }
+
+bool utils_uninstall_app(const char *pkgid, const char *pkgtype)
+{
+       package_manager_request_h request_h;
+       int r, id;
+
+       if (!pkgid || !pkgtype) {
+               _ERR("Invalid argument.");
+               return false;
+       }
+
+       r = package_manager_request_create(&request_h);
+       if (r != PACKAGE_MANAGER_ERROR_NONE) {
+               _ERR("Request handle create failed.");
+               return false;
+       }
+
+       r = package_manager_request_set_type(request_h, pkgtype);
+       if (r != PACKAGE_MANAGER_ERROR_NONE) {
+               _ERR("Set pkg type failed.");
+               package_manager_request_destroy(request_h);
+               return false;
+       }
+
+       r = package_manager_request_set_mode(request_h,
+                       PACKAGE_MANAGER_REQUEST_MODE_QUIET);
+       if (r != PACKAGE_MANAGER_ERROR_NONE) {
+               _ERR("Set request mode failed.");
+               package_manager_request_destroy(request_h);
+               return false;
+       }
+
+       r = package_manager_request_uninstall(request_h, pkgid, &id);
+       if (r != PACKAGE_MANAGER_ERROR_NONE) {
+               _ERR("Uninstall failed.");
+               package_manager_request_destroy(request_h);
+               return false;
+       }
+
+       package_manager_request_destroy(request_h);
+
+       return true;
+}
index c4171d7..61157b7 100644 (file)
@@ -29,7 +29,6 @@
 enum action_type {
        BTN_LIVETV = 0,
        BTN_FAVORITE,
-       BTN_LOCK,
        BTN_UNINSTALL,
 };
 
@@ -39,9 +38,10 @@ struct _priv {
        Evas_Object *base;
        Evas_Object *grid;
        Evas_Object *live_btn;
-       Evas_Object *menu_btn[ACTION_MENU_COUNT];
+       Evas_Object *menu[ACTION_MENU_COUNT];
        struct gridmgr *gmgr;
        Eina_List *fav_list;
+       bool uninstallable;
 };
 
 struct _action_info {
@@ -61,8 +61,7 @@ static struct _action_info action_info[] = {
        {
                .id = BTN_UNINSTALL,
                .title = STR_UNINSTALL,
-               .style = STYLE_ACTION_MENU_UNINSTALL_BTN,
-               .disable = EINA_TRUE
+               .style = STYLE_ACTION_MENU_UNINSTALL_BTN
        }
 };
 
@@ -114,6 +113,25 @@ static void _favorite_selected(struct _priv *priv)
        viewmgr_hide_view(VIEW_ACTION_MENU);
 }
 
+static void _uninstall_selected(struct _priv *priv)
+{
+       struct app_data *adata;
+       bool isfavorite;
+
+       adata = priv->adata;
+
+       if (!utils_uninstall_app(get_pkg_id(adata), get_pkg_type(adata))) {
+               _ERR("Uninstall failed.");
+               return;
+       }
+
+       if (get_app_favorite(adata, &isfavorite) && isfavorite)
+               set_app_favorite(adata, false);
+
+       viewmgr_update_view(VIEW_BASE, UPDATE_GRID, adata);
+       viewmgr_hide_view(VIEW_ACTION_MENU);
+}
+
 static void _clicked_cb(int id, void *data, Evas_Object *obj)
 {
        struct _priv *priv;
@@ -133,7 +151,7 @@ static void _clicked_cb(int id, void *data, Evas_Object *obj)
                break;
 
        case BTN_UNINSTALL:
-               /* It is not supported yet. */
+               _uninstall_selected(priv);
                break;
 
        default:
@@ -261,28 +279,33 @@ static bool _draw_livetv_area(struct _priv *priv)
 
        inputmgr_add_callback(btn, BTN_LIVETV, &_btn_input_handler, priv);
 
-       elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_UP);
-       elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_LEFT);
-       elm_object_focus_next_object_set(btn, btn, ELM_FOCUS_RIGHT);
-
        priv->live_btn = btn;
 
        return true;
 }
 
-void _set_action_state(int idx, Evas_Object *btn, struct app_data *adata)
+void _set_action_state(int idx, Evas_Object *btn, struct _priv *priv)
 {
+       char *pkgtype;
        bool isfavorite;
 
-       if (action_info[idx].disable) {
-               elm_object_disabled_set(btn, EINA_TRUE);
-               return;
-       }
-
        if (action_info[idx].id == BTN_FAVORITE) {
-               if (get_app_favorite(adata, &isfavorite) && isfavorite)
+               if (get_app_favorite(priv->adata, &isfavorite) && isfavorite)
                        elm_object_signal_emit(btn, SIG_TOGGLE, SRC_ACTION_BTN);
+       } else if (action_info[idx].id == BTN_UNINSTALL) {
+               /* The 'rpm' type package uninstallation is not supported */
+               pkgtype = get_pkg_type(priv->adata);
+               if (!strcmp(pkgtype, STR_WGT) || !strcmp(pkgtype, STR_TPK)) {
+                       action_info[idx].disable = EINA_FALSE;
+                       priv->uninstallable = true;
+               } else {
+                       action_info[idx].disable = EINA_TRUE;
+                       priv->uninstallable = false;
+               }
        }
+
+       if (action_info[idx].disable)
+               elm_object_disabled_set(btn, EINA_TRUE);
 }
 
 static bool _draw_action_area(struct _priv *priv)
@@ -309,34 +332,57 @@ static bool _draw_action_area(struct _priv *priv)
                inputmgr_add_callback(btn, action_info[i].id,
                                &_btn_input_handler, priv);
 
-               _set_action_state(i, btn, priv->adata);
+               _set_action_state(i, btn, priv);
 
                col = i % SIZE_COL_MAX;
                row = i / SIZE_COL_MAX;
 
                elm_table_pack(table, btn, col, row, 1, 1);
 
-               priv->menu_btn[i] = btn;
+               priv->menu[i] = btn;
        }
 
-       /* 'Favorite' can only be focused now. */
-       elm_object_focus_next_object_set(priv->menu_btn[0], priv->menu_btn[0],
+       return true;
+}
+
+static void _set_focus_policy(struct _priv *priv)
+{
+       int i;
+
+       elm_object_focus_next_object_set(priv->live_btn, priv->live_btn,
+                       ELM_FOCUS_UP);
+       elm_object_focus_next_object_set(priv->live_btn, priv->live_btn,
                        ELM_FOCUS_LEFT);
-       elm_object_focus_next_object_set(priv->menu_btn[0], priv->menu_btn[0],
+       elm_object_focus_next_object_set(priv->live_btn, priv->live_btn,
                        ELM_FOCUS_RIGHT);
-       elm_object_focus_next_object_set(priv->menu_btn[0], priv->menu_btn[0],
-                       ELM_FOCUS_DOWN);
-       elm_object_focus_next_object_set(priv->live_btn, priv->menu_btn[0],
+       elm_object_focus_next_object_set(priv->live_btn, priv->menu[0],
                        ELM_FOCUS_DOWN);
 
-       if (priv->fav_list) {
-               elm_object_focus_next_object_set(priv->menu_btn[0], priv->grid,
-                               ELM_FOCUS_DOWN);
-               elm_object_focus_next_object_set(priv->grid, priv->menu_btn[0],
-                               ELM_FOCUS_UP);
-       }
-
-       return true;
+       for (i = 0; i < ACTION_MENU_COUNT; i++) {
+               if (priv->fav_list)
+                       elm_object_focus_next_object_set(priv->menu[i],
+                                       priv->grid, ELM_FOCUS_DOWN);
+               else
+                       elm_object_focus_next_object_set(priv->menu[i],
+                                       priv->menu[i], ELM_FOCUS_DOWN);
+       }
+
+       if (priv->uninstallable) {
+               elm_object_focus_next_object_set(priv->menu[0], priv->menu[1],
+                               ELM_FOCUS_LEFT);
+               elm_object_focus_next_object_set(priv->menu[1], priv->menu[0],
+                               ELM_FOCUS_RIGHT);
+       } else {
+               elm_object_focus_next_object_set(priv->menu[0], priv->menu[0],
+                               ELM_FOCUS_LEFT);
+               elm_object_focus_next_object_set(priv->menu[0], priv->menu[0],
+                               ELM_FOCUS_RIGHT);
+       }
+
+       elm_object_focus_next_object_set(priv->grid, priv->menu[0],
+                       ELM_FOCUS_UP);
+       elm_object_focus_next_object_set(priv->grid, priv->grid,
+                       ELM_FOCUS_LEFT);
 }
 
 static bool _draw_favorite_area(struct _priv *priv)
@@ -357,8 +403,7 @@ static bool _draw_favorite_area(struct _priv *priv)
 
        elm_object_part_content_set(priv->base, PART_FAVORITE, priv->grid);
 
-       elm_object_focus_next_object_set(priv->grid, priv->grid,
-                       ELM_FOCUS_LEFT);
+       _set_focus_policy(priv);
 
        return true;
 }
index 958070a..5a1f4f9 100644 (file)
@@ -78,6 +78,37 @@ static void _mouse_move_cb(int id, void *data, Evas *e, Evas_Object *obj,
                elm_object_focus_set(obj, EINA_TRUE);
 }
 
+static bool _draw_myapps_grid(struct _priv *priv)
+{
+       char str[SIZE_STR];
+       int c;
+
+       if (!priv->app_list) {
+               elm_object_part_text_set(priv->base, PART_CONTENTS_TEXT,
+                               STR_NO_CONTENTS);
+               elm_object_disabled_set(priv->sort_btn, EINA_TRUE);
+               elm_object_part_content_unset(priv->base, PART_GENGRID);
+
+               return true;
+       }
+
+       elm_object_part_text_set(priv->base, PART_CONTENTS_TEXT, "");
+
+       if (!gridmgr_append_list(priv->gmgr, STR_MYAPPS, priv->app_list)) {
+               _ERR("Gridmgr append list failed.");
+               return false;
+       }
+
+       elm_object_part_content_set(priv->base, PART_GENGRID, priv->grid);
+       priv->focused_item = elm_gengrid_first_item_get(priv->grid);
+
+       c = eina_list_count(priv->app_list);
+       snprintf(str, sizeof(str), " %d "STR_APPS, c);
+       elm_object_part_text_set(priv->base, PART_APP_COUNT, str);
+
+       return true;
+}
+
 static void _menu_focused_cb(int id, void *data, Evas_Object *obj,
                Elm_Object_Item *item)
 {
@@ -99,13 +130,7 @@ static void _menu_focused_cb(int id, void *data, Evas_Object *obj,
        switch (id) {
        case MENU_MYAPPS:
                elm_object_signal_emit(priv->base, SIG_VISIBLE, SRC_MYAPPS);
-               if (priv->app_list)
-                       elm_object_part_text_set(priv->base,
-                                       PART_CONTENTS_TEXT, "");
-               else
-                       elm_object_part_text_set(priv->base,
-                                       PART_CONTENTS_TEXT, STR_NO_CONTENTS);
-
+               _draw_myapps_grid(priv);
                break;
 
        case MENU_APPSTORE:
@@ -483,9 +508,6 @@ static void _grid_focused_cb(int id, void *data, Evas_Object *obj,
        priv = data;
 
        elm_object_signal_emit(priv->focused_menu, SIG_SELECTED, SRC_MENU_BTN);
-
-       if (priv->focused_item)
-               elm_object_item_focus_set(priv->focused_item, EINA_TRUE);
 }
 
 static void _grid_item_focused_cb(void *data, Elm_Object_Item *it,
@@ -676,11 +698,9 @@ static bool _draw_top_area(struct _priv *priv)
        return true;
 }
 
-static bool _draw_bottom_area(struct _priv *priv)
+static bool _draw_sort_area(struct _priv *priv)
 {
        Evas_Object *btn;
-       char str[SIZE_STR];
-       int c;
 
        btn = utils_add_button(priv->base, PART_SORT,
                        str_sort[priv->sort_type], STYLE_SORT_BTN);
@@ -699,33 +719,6 @@ static bool _draw_bottom_area(struct _priv *priv)
 
        priv->sort_btn = btn;
 
-       if (!priv->app_list)
-               elm_object_disabled_set(btn, EINA_TRUE);
-
-       c = eina_list_count(priv->app_list);
-       snprintf(str, sizeof(str), " %d "STR_APPS, c);
-       elm_object_part_text_set(priv->base, PART_APP_COUNT, str);
-
-       return true;
-}
-
-static bool _draw_myapps_grid(struct _priv *priv)
-{
-       priv->app_list = get_app_list();
-       if (!priv->app_list)
-               return true;
-
-       _sort_by_recently_used(priv);
-
-       if (!gridmgr_append_list(priv->gmgr, STR_MYAPPS, priv->app_list)) {
-               _ERR("Gridmgr append list failed.");
-               return false;
-       }
-
-       elm_object_part_content_set(priv->base, PART_GENGRID, priv->grid);
-
-       priv->focused_item = NULL;
-
        return true;
 }
 
@@ -771,8 +764,8 @@ static void _draw_view_content(struct _priv *priv)
                return;
        }
 
-       if (!_draw_bottom_area(priv))
-               _ERR("Draw bottom area failed.");
+       if (!_draw_sort_area(priv))
+               _ERR("Draw sort area failed.");
 }
 
 static Evas_Object *_create(Evas_Object *win, void *data)
@@ -818,6 +811,8 @@ static Evas_Object *_create(Evas_Object *win, void *data)
        }
 
        priv->grid = grid;
+       priv->app_list = get_app_list();
+       _sort_by_recently_used(priv);
 
        if (!viewmgr_set_view_data(VIEW_BASE, priv)) {
                _ERR("Set view data failed.");
@@ -876,7 +871,8 @@ static void _update(void *view_data, int update_type, void *data)
        }
        priv = view_data;
 
-       if (update_type == UPDATE_FAVORITE) {
+       switch (update_type) {
+       case UPDATE_FAVORITE:
                adata = data;
                if (!adata)
                        return;
@@ -890,9 +886,25 @@ static void _update(void *view_data, int update_type, void *data)
                else
                        elm_object_item_signal_emit(priv->focused_item,
                                        SIG_UNFAVORITE, SRC_FAVORITE_ICON);
-       } else if (update_type == UPDATE_SHOW_TOAST) {
+
+               break;
+
+       case UPDATE_SHOW_TOAST:
                priv->notify = utils_add_notify(priv->base, (char *)data,
                                STYLE_TOAST, STYLE_TOAST, SIZE_TOAST_TIMEOUT);
+               break;
+
+       case UPDATE_GRID:
+               adata = data;
+               if (!adata)
+                       return;
+
+               priv->app_list = eina_list_remove(priv->app_list, adata);
+               _draw_myapps_grid(priv);
+               break;
+
+       default:
+               _ERR("Unhandled update type.");
        }
 }