From: Lukasz Stanislawski Date: Thu, 4 Jun 2020 16:34:24 +0000 (+0200) Subject: storage: fix uninstallation X-Git-Tag: submit/tizen/20200605.053619^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7125f557112e55439a4caa19d8e064e6a4cf025b;p=profile%2Fcommon%2Fapps%2Fnative%2Fsettings.git storage: fix uninstallation * fix layout bugs * remove non-thread safe gui calls from non-ui thread * fix data races Change-Id: I7a002985f9d92aa012f0ad28bfd050ebc59e7c20 --- diff --git a/resource/setting-theme.edc b/resource/setting-theme.edc index 0f6ad62..fd8390a 100644 --- a/resource/setting-theme.edc +++ b/resource/setting-theme.edc @@ -3810,7 +3810,7 @@ collections type: SPACER; scale: 1; description { state: "default" 0.0; - min: 0 90; + min: 345 174; fixed: 1 0; } } @@ -3840,9 +3840,8 @@ collections type: SWALLOW; scale: 1; description { state: "default" 0.0; - fixed: 1 1; - min: 36 36; - max: 36 36; + min: 30 30; + max: 30 30; rel1 { relative: 1.0 0.0; to_x: "pad_l"; diff --git a/setting-common/include/setting-common-general-func.h b/setting-common/include/setting-common-general-func.h index 63627b6..3adfd2d 100755 --- a/setting-common/include/setting-common-general-func.h +++ b/setting-common/include/setting-common-general-func.h @@ -76,4 +76,8 @@ extern char *get_pa_backlight_time_value_str(); extern const char *setting_get_resource_path(const char *filename); extern bool isZero(double val); +typedef void *(transform_cb)(void *data, void *user_data); + +extern Eina_Array *eina_array_transform(Eina_Array *array, transform_cb cb, void *user_data); + #endif /* __SETTING_COMMON_GENERAL_FUNC_H__ */ diff --git a/setting-common/src/setting-common-draw-popup.c b/setting-common/src/setting-common-draw-popup.c index 071b463..bbfcc80 100755 --- a/setting-common/src/setting-common-draw-popup.c +++ b/setting-common/src/setting-common-draw-popup.c @@ -436,7 +436,7 @@ Evas_Object *setting_create_popup_with_progressbar(void *data, popup = elm_popup_add(parent); retv_if(NULL == popup, NULL); - elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 0.5); evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); diff --git a/setting-common/src/setting-common-general-func.c b/setting-common/src/setting-common-general-func.c index b43cfac..7a26d74 100755 --- a/setting-common/src/setting-common-general-func.c +++ b/setting-common/src/setting-common-general-func.c @@ -934,3 +934,16 @@ extern bool isZero(double val) } return false; } + +EXPORT_PUBLIC +extern Eina_Array *eina_array_transform(Eina_Array *array, transform_cb cb, void *user_data) +{ + unsigned int size = eina_array_count_get(array); + + for (unsigned int idx = 0; idx < size; idx++) { + void *data = eina_array_data_get(array, idx); + eina_array_data_set(array, idx, cb(data, user_data)); + } + + return array; +} diff --git a/setting-storage/include/setting-storage.h b/setting-storage/include/setting-storage.h index 9809ec9..c06bda5 100755 --- a/setting-storage/include/setting-storage.h +++ b/setting-storage/include/setting-storage.h @@ -152,12 +152,14 @@ typedef struct _SettingStorage { Evas_Object *cancel_delete_btn; Evas_Object *done_delete_btn; + Evas_Object *more_btn; int mmc_status; media_content_noti_h h_mcdb_noti; char *launch_mode; int apps_to_move; + Eina_Array *packages_to_remove; } SettingStorage; typedef struct { diff --git a/setting-storage/src/setting-storage-applications-utils.c b/setting-storage/src/setting-storage-applications-utils.c index 8005d3c..baf626e 100755 --- a/setting-storage/src/setting-storage-applications-utils.c +++ b/setting-storage/src/setting-storage-applications-utils.c @@ -284,11 +284,11 @@ void node_get_size_cb(const char *package_id, const package_size_info_h size_inf size_to_str(info->total_size, desc, sizeof(desc)); info->size_str = strdup(desc); - if (info->size_str) { + if (info->size_str && info->data) { free(info->data->sub_desc); info->data->sub_desc = strdup(info->size_str); + elm_genlist_item_update(info->data->item); } - elm_genlist_item_update(info->data->item); return; } } diff --git a/setting-storage/src/setting-storage-applications.c b/setting-storage/src/setting-storage-applications.c index 882cef1..f23fff4 100755 --- a/setting-storage/src/setting-storage-applications.c +++ b/setting-storage/src/setting-storage-applications.c @@ -127,6 +127,17 @@ static void _genlist_check_hide(SettingStorage *ad, bool hide) SETTING_TRACE_END; } +static void _setting_storage_clear_misc_view(SettingStorage *ad) +{ + Node_Info *node = NULL; + Eina_List *cur = NULL; + + EINA_LIST_FOREACH(ad->data_list, cur, node) { + node->data = NULL; + } + elm_genlist_clear(ad->misces_genlist); +} + /** * [UI-CALLBACK] 'Delete' button handler on ctxpopup */ @@ -140,7 +151,7 @@ static void _ctx_uninstall_click_cb(void *data, Evas_Object *ctxpopup, ad->select_mode = true; elm_ctxpopup_dismiss(ctxpopup); - elm_genlist_clear(ad->misces_genlist); + _setting_storage_clear_misc_view(ad); storage_append_select_all_item(ad, __select_all_cb, __select_all_chk_btn_cb); storage_apps_gl_append_removable_items(ad); @@ -478,9 +489,9 @@ static void storage_apps_gl_append_removable_items(SettingStorage *ad) continue; item_data = setting_create_Gendial_field_def(ad->misces_genlist, - &(itc_1text_1icon), + &(ad->itc_1text_1icon), storage_apps_genlist_sel, ad, - SWALLOW_Type_1CHECK_RIGHT_INVISIBLE, + SWALLOW_Type_1CHECK, node->l_icon, NULL, 0, node->name, node->size_str, storage_apps_genlist_chk_cb); @@ -549,7 +560,7 @@ static void _update_ui_list(SettingStorage *ad) ad->misces_checked = 0; ad->misces_is_select_all = EINA_FALSE; - elm_genlist_clear(ad->misces_genlist); + _setting_storage_clear_misc_view(ad); /* Add items to genlist */ storage_apps_gl_append_items(ad); @@ -615,51 +626,45 @@ static int _uninstall_app_thread_func(SettingStorage *ad) { SETTING_TRACE_BEGIN; - Node_Info *node = NULL; - Setting_GenGroupItem_Data *item_data = NULL; - Elm_Object_Item *it = NULL; package_manager_request_h req = NULL; int req_id = 0; int ret = 0; retv_if(NULL == ad, SETTING_GENERAL_ERR_NULL_DATA_PARAMETER); + retv_if(NULL == ad->packages_to_remove, SETTING_GENERAL_ERR_NULL_DATA_PARAMETER); - it = elm_genlist_first_item_get(ad->misces_genlist); - /* Skip "Select all" item: */ - it = elm_genlist_item_next_get(it); - while (it) { - item_data = (Setting_GenGroupItem_Data *)elm_object_item_data_get(it); - if (!item_data->chk_status) { - it = elm_genlist_item_next_get(it); - continue; - } + Eina_Array *array = ad->packages_to_remove; + ad->packages_to_remove = NULL; - node = item_data->userdata; - req = NULL; - req_id = 0; - SETTING_TRACE("Trying to uninstall %s", node->name); + unsigned int size = eina_array_count_get(array); + + for (unsigned int idx = 0; idx < size; idx++) { + char *pkgid = eina_array_data_get(array, idx); + + SETTING_TRACE("Trying to uninstall '%s'", pkgid); ret = package_manager_request_create(&req); if (PACKAGE_MANAGER_ERROR_NONE != ret) { SETTING_TRACE_ERROR("package_manager_request_create() %s", get_error_message(ret)); - it = elm_genlist_item_next_get(it); + free(pkgid); continue; } - ret = package_manager_request_uninstall(req, node->id, &req_id); + ret = package_manager_request_uninstall(req, pkgid, &req_id); if (PACKAGE_MANAGER_ERROR_NONE != ret) { SETTING_TRACE_ERROR("package_manager_request_uninstall() %s", get_error_message(ret)); + free(pkgid); package_manager_request_destroy(req); - it = elm_genlist_item_next_get(it); continue; } - package_manager_request_destroy(req); - it = elm_genlist_item_next_get(it); sleep(1); storage_STOP_POINT; + free(pkgid); + package_manager_request_destroy(req); } + eina_array_free(array); sleep(4); SETTING_TRACE_END; @@ -667,53 +672,6 @@ static int _uninstall_app_thread_func(SettingStorage *ad) return SETTING_RETURN_SUCCESS; } -/** - * [UI] Done button -> create popup -> button handler - */ -static void _apps_delete_popup_cb(void *data, Evas_Object *obj, void *event_info) -{ - SETTING_TRACE_BEGIN; - - int response_type; - SettingStorage *ad = data; - - ret_if(NULL == data); - ret_if(NULL == obj); - - response_type = btn_type(obj); - - evas_object_del(ad->popup); - ad->popup = NULL; - - if (POPUP_RESPONSE_OK != response_type) { - SETTING_TRACE("CANCEL"); - return; - } - - SETTING_TRACE(">>>>> checked : %d before deletion ", - ad->misces_checked); - - if (ad->misces_checked) { - ad->popup = setting_create_popup_with_progressbar(ad, - ad->md.window, PROGRESSBAR_STYLE, - NULL, _("IDS_ST_POP_UNINSTALLING_ING"), - storage_popup_del, 0, TRUE, TRUE, - 0); - - if (ad->del_worker) - storage_stop_async_worker(ad->del_worker); - ad->del_worker = storage_start_async_worker( - _uninstall_app_thread_func, - _uninstall_app_thread_func_cb, ad); - } else { - ad->popup = setting_create_popup(ad, ad->md.window, NULL, - STORAGE_STR_NO_SELECTED, storage_popup_del, - SETTING_STORAGE_POPUP_TIMER, FALSE, FALSE, 0); - } - - SETTING_TRACE_END; -} - static void _move_request_cb(int id, const char *type, const char *package, @@ -896,6 +854,40 @@ static void _move_to_sd(SettingStorage *ad) SETTING_TRACE_END; } +/** + * @brief Gets list of selected nodes on ad->misces_genlist + * @note The retuned list should be free with @eina_list_free + */ +static Eina_Array *_setting_storage_get_selected_items(Evas_Object *genlist) +{ + Eina_Array *ret = NULL; + Setting_GenGroupItem_Data *item_data; + Elm_Object_Item *it = elm_genlist_first_item_get(genlist); + + ret = eina_array_new(4); + if (!ret) return NULL; + + /* Skip "Select all" item: */ + it = elm_genlist_item_next_get(it); + + while (it) { + item_data = (Setting_GenGroupItem_Data *)elm_object_item_data_get(it); + if (item_data->chk_status) { + eina_array_push(ret, item_data); + } + it = elm_genlist_item_next_get(it); + } + + return ret; +} + +static void *_pkgid_from_item(void *data, void *user_data) +{ + Setting_GenGroupItem_Data *item_data = data; + Node_Info *node = item_data->userdata; + return node->id ? strdup(node->id) : strdup(""); +} + /** * Done button handler for 'delete' */ @@ -919,9 +911,26 @@ static void _apps_delete_click_cb(void *data, Evas_Object *obj, void *event_info return; } - ad->popup = setting_create_popup(ad, ad->md.window, NULL, - STORAGE_STR_DELETE_Q, _apps_delete_popup_cb, 0, FALSE, FALSE, - 2, STORAGE_STR_DELETE, STORAGE_STR_CANCEL); + if (ad->misces_checked) { + ad->popup = setting_create_popup_with_progressbar(ad, + ad->md.window, PROGRESSBAR_STYLE, + NULL, _("IDS_ST_POP_UNINSTALLING_ING"), + storage_popup_del, 0, TRUE, TRUE, + 0); + + if (ad->del_worker) + storage_stop_async_worker(ad->del_worker); + Eina_Array *selected = _setting_storage_get_selected_items(ad->misces_genlist); + // no better way to pass params to _uninstall_app_thread_func then this pseudo-global + ad->packages_to_remove = eina_array_transform(selected, _pkgid_from_item, NULL); + ad->del_worker = storage_start_async_worker( + _uninstall_app_thread_func, + _uninstall_app_thread_func_cb, ad); + } else { + ad->popup = setting_create_popup(ad, ad->md.window, NULL, + STORAGE_STR_NO_SELECTED, storage_popup_del, + SETTING_STORAGE_POPUP_TIMER, FALSE, FALSE, 0); + } SETTING_TRACE_END; } @@ -944,6 +953,7 @@ static int storage_apps_create(void *data) ad->misces_genlist = elm_genlist_add(ad->md.naviframe); elm_genlist_mode_set(ad->misces_genlist, ELM_LIST_COMPRESS); elm_genlist_homogeneous_set(ad->misces_genlist, EINA_TRUE); + evas_object_smart_callback_add(ad->misces_genlist, "realized", __gl_realized_cb, &(ad->md)); ad->select_mode = ad->launched_by_external_app; diff --git a/setting-storage/src/setting-storage-utils.c b/setting-storage/src/setting-storage-utils.c index 7728c83..4e5465a 100755 --- a/setting-storage/src/setting-storage-utils.c +++ b/setting-storage/src/setting-storage-utils.c @@ -376,26 +376,27 @@ void storage_gl_add_button_support( retm_if(ad == NULL, "SettingStorage *ad parameter is NULL"); SETTING_TRACE_BEGIN; - Evas_Object *btn = NULL; /* Cancel Button */ ad->cancel_delete_btn = setting_create_button(ad->md.naviframe, - _("IDS_MSG_ACBUTTON_CANCEL_ABB"), "naviframe/title_left", + _("IDS_MSG_ACBUTTON_CANCEL_ABB"), "textbutton", cancel_btn_cb, ad); + evas_object_size_hint_min_set(ad->cancel_delete_btn, ELM_SCALE_SIZE(148), ELM_SCALE_SIZE(48)); evas_object_hide(ad->cancel_delete_btn); /* Delete Button */ ad->done_delete_btn = setting_create_button(ad->md.naviframe, - _("IDS_MSG_ACBUTTON_DONE_ABB"), "naviframe/title_right", + _("IDS_MSG_ACBUTTON_DONE_ABB"), "textbutton", done_btn_cb, ad); + evas_object_size_hint_min_set(ad->done_delete_btn, ELM_SCALE_SIZE(148), ELM_SCALE_SIZE(48)); evas_object_hide(ad->done_delete_btn); /* Add ctx popup handler */ - btn = setting_create_button(ad->md.naviframe, + ad->more_btn = setting_create_button(ad->md.naviframe, NULL, "naviframe/more", more_btn_cb, ad); elm_object_item_part_content_set(ad->misces_navi_it, "title_content", - btn); + ad->more_btn); SETTING_TRACE_END; } @@ -403,29 +404,15 @@ void storage_naviframe_update_buttons(SettingStorage *ad) { /*update delete item buttons*/ if (ad->select_mode) { - if (elm_object_item_part_content_get( - ad->misces_navi_it, "title_left_btn") == NULL) { - elm_object_item_part_content_set(ad->misces_navi_it, - "title_left_btn", ad->cancel_delete_btn); - } - if (elm_object_item_part_content_get( - ad->misces_navi_it, "title_right_btn") == NULL) { - elm_object_item_part_content_set(ad->misces_navi_it, - "title_right_btn", ad->done_delete_btn); - } + elm_object_item_part_content_unset(ad->misces_navi_it, "title_content"); + evas_object_hide(ad->more_btn); + evas_object_show(ad->done_delete_btn); + elm_object_item_part_content_set(ad->misces_navi_it, "title_content", ad->done_delete_btn); } else { - if (elm_object_item_part_content_get( - ad->misces_navi_it, "title_left_btn") != NULL) { - elm_object_item_part_content_unset(ad->misces_navi_it, - "title_left_btn"); - evas_object_hide(ad->cancel_delete_btn); - } - if (elm_object_item_part_content_get( - ad->misces_navi_it, "title_right_btn") != NULL) { - elm_object_item_part_content_unset(ad->misces_navi_it, - "title_right_btn"); - evas_object_hide(ad->done_delete_btn); - } + elm_object_item_part_content_unset(ad->misces_navi_it, "title_content"); + evas_object_hide(ad->done_delete_btn); + evas_object_show(ad->more_btn); + elm_object_item_part_content_set(ad->misces_navi_it, "title_content", ad->more_btn); } } @@ -592,15 +579,13 @@ void storage_append_select_all_item(SettingStorage *ad, c2 = check_sel_cb; item_data = setting_create_Gendial_field_def(ad->misces_genlist, - &(itc_1text_1icon), c1, - ad, SWALLOW_Type_1ICON_1RADIO, NULL, NULL, 0, + &(ad->itc_1text), c1, + ad, SWALLOW_Type_1CHECK, NULL, NULL, 0, _("IDS_ST_BODY_SELECT_ALL"), NULL, c2); if (item_data) { item_data->userdata = ad; item_data->isItemHideFlag = true; - elm_genlist_item_select_mode_set(item_data->item, - ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); } else { SETTING_TRACE_ERROR("item_data is NULL"); }