capi-appfw-application
app-utils
pkgmgr-info
+ capi-appfw-package-manager
)
IF(NOT DEFINED PACKAGE_NAME)
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,
#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
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__ */
enum update_type {
UPDATE_ID = 0,
UPDATE_FAVORITE,
+ UPDATE_GRID,
UPDATE_SHOW_TOAST,
};
<label>Apps</label>
<icon>@DESKTOP_ICON@</icon>
</ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
+ </privileges>
</manifest>
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
}
program {
- name, "activated";
- signal, "elm,state,activated";
- source, "elm";
- after, "item_selected";
- }
-
- program {
name, "selected";
signal, "elm,state,selected";
source, "elm";
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;
{
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)
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);
*list = eina_list_append(*list, adata);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
+
return 0;
}
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) {
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;
#include <Elementary.h>
#include <app_control.h>
#include <app_debug.h>
+#include <package_manager.h>
#include "define.h"
#include "utils.h"
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;
+}
enum action_type {
BTN_LIVETV = 0,
BTN_FAVORITE,
- BTN_LOCK,
BTN_UNINSTALL,
};
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 {
{
.id = BTN_UNINSTALL,
.title = STR_UNINSTALL,
- .style = STYLE_ACTION_MENU_UNINSTALL_BTN,
- .disable = EINA_TRUE
+ .style = STYLE_ACTION_MENU_UNINSTALL_BTN
}
};
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;
break;
case BTN_UNINSTALL:
- /* It is not supported yet. */
+ _uninstall_selected(priv);
break;
default:
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)
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)
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;
}
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)
{
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:
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,
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);
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;
}
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)
}
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.");
}
priv = view_data;
- if (update_type == UPDATE_FAVORITE) {
+ switch (update_type) {
+ case UPDATE_FAVORITE:
adata = data;
if (!adata)
return;
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.");
}
}