From 8d4748b526c15cfa7ed1a9824cf87a4605338e2a Mon Sep 17 00:00:00 2001 From: Steveice10 Date: Wed, 29 Nov 2017 12:45:22 -0800 Subject: [PATCH] Clean up data op error reporting, add retry option. --- source/ui/section/action/deletecontents.c | 17 ++-------- .../ui/section/action/deletependingtitles.c | 17 ++-------- source/ui/section/action/deletetickets.c | 17 ++-------- source/ui/section/action/erasetwlsave.c | 13 ++------ source/ui/section/action/exporttwlsave.c | 13 ++------ source/ui/section/action/importtwlsave.c | 13 ++------ source/ui/section/action/installcdn.c | 11 +++---- source/ui/section/action/installcias.c | 17 ++-------- source/ui/section/action/installtickets.c | 17 ++-------- source/ui/section/action/installurl.c | 24 ++++---------- source/ui/section/action/pastecontents.c | 17 ++-------- source/ui/section/dumpnand.c | 11 ++----- source/ui/section/task/dataop.c | 32 +++++++++++++++++-- source/ui/section/task/task.h | 6 +++- 14 files changed, 77 insertions(+), 148 deletions(-) diff --git a/source/ui/section/action/deletecontents.c b/source/ui/section/action/deletecontents.c index 11ea541..74e45b1 100644 --- a/source/ui/section/action/deletecontents.c +++ b/source/ui/section/action/deletecontents.c @@ -83,20 +83,9 @@ static Result action_delete_restore(void* data, u32 index) { return 0; } -static bool action_delete_error(void* data, u32 index, Result res) { - delete_data* deleteData = (delete_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Delete cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else { - ui_view* view = error_display_res(data, action_delete_draw_top, res, "Failed to delete content."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < deleteData->deleteInfo.total - 1; +static bool action_delete_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_delete_draw_top, res, "Failed to delete content."); + return true; } static void action_delete_free_data(delete_data* data) { diff --git a/source/ui/section/action/deletependingtitles.c b/source/ui/section/action/deletependingtitles.c index 7dec06d..1088c55 100644 --- a/source/ui/section/action/deletependingtitles.c +++ b/source/ui/section/action/deletependingtitles.c @@ -67,20 +67,9 @@ static Result action_delete_pending_titles_restore(void* data, u32 index) { return 0; } -static bool action_delete_pending_titles_error(void* data, u32 index, Result res) { - delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Delete cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else { - ui_view* view = error_display_res(data, action_delete_pending_titles_draw_top, res, "Failed to delete pending title."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < deleteData->deleteInfo.total - 1; +static bool action_delete_pending_titles_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_delete_pending_titles_draw_top, res, "Failed to delete pending title."); + return true; } static void action_delete_pending_titles_free_data(delete_pending_titles_data* data) { diff --git a/source/ui/section/action/deletetickets.c b/source/ui/section/action/deletetickets.c index 09036f5..12886b7 100644 --- a/source/ui/section/action/deletetickets.c +++ b/source/ui/section/action/deletetickets.c @@ -63,20 +63,9 @@ static Result action_delete_tickets_restore(void* data, u32 index) { return 0; } -static bool action_delete_tickets_error(void* data, u32 index, Result res) { - delete_tickets_data* deleteData = (delete_tickets_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Delete cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else { - ui_view* view = error_display_res(data, action_delete_tickets_draw_top, res, "Failed to delete ticket(s)."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < deleteData->deleteInfo.total - 1; +static bool action_delete_tickets_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_delete_tickets_draw_top, res, "Failed to delete ticket(s)."); + return true; } static void action_delete_tickets_free_data(delete_tickets_data* data) { diff --git a/source/ui/section/action/erasetwlsave.c b/source/ui/section/action/erasetwlsave.c index d86139f..30db5ed 100644 --- a/source/ui/section/action/erasetwlsave.c +++ b/source/ui/section/action/erasetwlsave.c @@ -89,16 +89,9 @@ static Result action_erase_twl_save_restore(void* data, u32 index) { return 0; } -static bool action_erase_twl_save_error(void* data, u32 index, Result res) { - erase_twl_save_data* eraseData = (erase_twl_save_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Erase cancelled.", COLOR_TEXT, eraseData->title, ui_draw_title_info, NULL); - } else { - error_display_res(eraseData->title, ui_draw_title_info, res, "Failed to erase save."); - } - - return false; +static bool action_erase_twl_save_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(((erase_twl_save_data*) data)->title, ui_draw_title_info, res, "Failed to erase save."); + return true; } static void action_erase_twl_save_update(ui_view* view, void* data, float* progress, char* text) { diff --git a/source/ui/section/action/exporttwlsave.c b/source/ui/section/action/exporttwlsave.c index e5d064c..abbd5f9 100644 --- a/source/ui/section/action/exporttwlsave.c +++ b/source/ui/section/action/exporttwlsave.c @@ -111,16 +111,9 @@ static Result action_export_twl_save_restore(void* data, u32 index) { return 0; } -static bool action_export_twl_save_error(void* data, u32 index, Result res) { - export_twl_save_data* exportData = (export_twl_save_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Export cancelled.", COLOR_TEXT, exportData->title, ui_draw_title_info, NULL); - } else { - error_display_res(exportData->title, ui_draw_title_info, res, "Failed to export save."); - } - - return false; +static bool action_export_twl_save_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(((export_twl_save_data*) data)->title, ui_draw_title_info, res, "Failed to export save."); + return true; } static void action_export_twl_save_update(ui_view* view, void* data, float* progress, char* text) { diff --git a/source/ui/section/action/importtwlsave.c b/source/ui/section/action/importtwlsave.c index 43b8831..ba53d14 100644 --- a/source/ui/section/action/importtwlsave.c +++ b/source/ui/section/action/importtwlsave.c @@ -97,16 +97,9 @@ static Result action_import_twl_save_restore(void* data, u32 index) { return 0; } -static bool action_import_twl_save_error(void* data, u32 index, Result res) { - import_twl_save_data* importData = (import_twl_save_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Import cancelled.", COLOR_TEXT, importData->title, ui_draw_title_info, NULL); - } else { - error_display_res(importData->title, ui_draw_title_info, res, "Failed to import save."); - } - - return false; +static bool action_import_twl_save_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(((import_twl_save_data*) data)->title, ui_draw_title_info, res, "Failed to import save."); + return true; } static void action_import_twl_save_update(ui_view* view, void* data, float* progress, char* text) { diff --git a/source/ui/section/action/installcdn.c b/source/ui/section/action/installcdn.c index 5ba51c1..1a18a37 100644 --- a/source/ui/section/action/installcdn.c +++ b/source/ui/section/action/installcdn.c @@ -173,15 +173,14 @@ static Result action_install_cdn_restore(void* data, u32 index) { return AM_InstallTitleResume(util_get_title_destination(installData->ticket->titleId), installData->ticket->titleId); } -bool action_install_cdn_error(void* data, u32 index, Result res) { +bool action_install_cdn_error(void* data, u32 index, Result res, ui_view** errorView) { install_cdn_data* installData = (install_cdn_data*) data; - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Install cancelled.", COLOR_TEXT, installData->ticket, ui_draw_ticket_info, NULL); - } else if(res == R_FBI_HTTP_RESPONSE_CODE) { - error_display(installData->ticket, ui_draw_ticket_info, "Failed to install CDN title.\nHTTP server returned response code %d", installData->responseCode); + const char* itemType = index == 0 ? "TMD" : "content"; + if(res == R_FBI_HTTP_RESPONSE_CODE) { + *errorView = error_display(installData->ticket, ui_draw_ticket_info, "Failed to install %s from CDN.\nHTTP server returned response code %d", itemType, installData->responseCode); } else { - error_display_res(installData->ticket, ui_draw_ticket_info, res, "Failed to install CDN title."); + *errorView = error_display_res(installData->ticket, ui_draw_ticket_info, res, "Failed to install %s from CDN.", itemType); } return false; diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index 21403fd..dcd5824 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -193,20 +193,9 @@ static Result action_install_cias_restore(void* data, u32 index) { return 0; } -bool action_install_cias_error(void* data, u32 index, Result res) { - install_cias_data* installData = (install_cias_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Install cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else if(res != R_FBI_WRONG_SYSTEM) { - ui_view* view = error_display_res(data, action_install_cias_draw_top, res, "Failed to install CIA file."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < installData->installInfo.total - 1; +bool action_install_cias_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_install_cias_draw_top, res, "Failed to install CIA file."); + return true; } static void action_install_cias_free_data(install_cias_data* data) { diff --git a/source/ui/section/action/installtickets.c b/source/ui/section/action/installtickets.c index 84840df..cf156c4 100644 --- a/source/ui/section/action/installtickets.c +++ b/source/ui/section/action/installtickets.c @@ -156,20 +156,9 @@ static Result action_install_tickets_restore(void* data, u32 index) { return 0; } -static bool action_install_tickets_error(void* data, u32 index, Result res) { - install_tickets_data* installData = (install_tickets_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Install cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else { - ui_view* view = error_display_res(data, action_install_tickets_draw_top, res, "Failed to install ticket."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < installData->installInfo.total - 1; +static bool action_install_tickets_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_install_tickets_draw_top, res, "Failed to install ticket."); + return true; } static void action_install_tickets_free_data(install_tickets_data* data) { diff --git a/source/ui/section/action/installurl.c b/source/ui/section/action/installurl.c index 12cae18..9de06da 100644 --- a/source/ui/section/action/installurl.c +++ b/source/ui/section/action/installurl.c @@ -324,37 +324,27 @@ static Result action_install_url_restore(void* data, u32 index) { return 0; } -static bool action_install_url_error(void* data, u32 index, Result res) { +static bool action_install_url_error(void* data, u32 index, Result res, ui_view** errorView) { install_url_data* installData = (install_url_data*) data; - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Install cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else if(res != R_FBI_WRONG_SYSTEM) { + if(res != R_FBI_WRONG_SYSTEM) { char* url = installData->urls[index]; - - ui_view* view = NULL; - if(res == R_FBI_HTTP_RESPONSE_CODE) { if(strlen(url) > 38) { - view = error_display(data, action_install_url_draw_top, "Failed to install from URL.\n%.35s...\nHTTP server returned response code %d", url, installData->responseCode); + *errorView = error_display(data, action_install_url_draw_top, "Failed to install from URL.\n%.35s...\nHTTP server returned response code %d", url, installData->responseCode); } else { - view = error_display(data, action_install_url_draw_top, "Failed to install from URL.\n%.38s\nHTTP server returned response code %d", url, installData->responseCode); + *errorView = error_display(data, action_install_url_draw_top, "Failed to install from URL.\n%.38s\nHTTP server returned response code %d", url, installData->responseCode); } } else { if(strlen(url) > 38) { - view = error_display_res(data, action_install_url_draw_top, res, "Failed to install from URL.\n%.35s...", url); + *errorView = error_display_res(data, action_install_url_draw_top, res, "Failed to install from URL.\n%.35s...", url); } else { - view = error_display_res(data, action_install_url_draw_top, res, "Failed to install from URL.\n%.38s", url); + *errorView = error_display_res(data, action_install_url_draw_top, res, "Failed to install from URL.\n%.38s", url); } } - - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } } - return index < installData->installInfo.total - 1; + return true; } static void action_install_url_install_update(ui_view* view, void* data, float* progress, char* text) { diff --git a/source/ui/section/action/pastecontents.c b/source/ui/section/action/pastecontents.c index 8489012..2b7886d 100644 --- a/source/ui/section/action/pastecontents.c +++ b/source/ui/section/action/pastecontents.c @@ -225,20 +225,9 @@ static Result action_paste_contents_restore(void* data, u32 index) { return 0; } -static bool action_paste_contents_error(void* data, u32 index, Result res) { - paste_contents_data* pasteData = (paste_contents_data*) data; - - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Paste cancelled.", COLOR_TEXT, NULL, NULL, NULL); - return false; - } else { - ui_view* view = error_display_res(data, action_paste_contents_draw_top, res, "Failed to paste content."); - if(view != NULL) { - svcWaitSynchronization(view->active, U64_MAX); - } - } - - return index < pasteData->pasteInfo.total - 1; +static bool action_paste_contents_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(data, action_paste_contents_draw_top, res, "Failed to paste content."); + return true; } static void action_paste_contents_free_data(paste_contents_data* data) { diff --git a/source/ui/section/dumpnand.c b/source/ui/section/dumpnand.c index f68a398..293df01 100644 --- a/source/ui/section/dumpnand.c +++ b/source/ui/section/dumpnand.c @@ -91,14 +91,9 @@ static Result dumpnand_restore(void* data, u32 index) { return 0; } -static bool dumpnand_error(void* data, u32 index, Result res) { - if(res == R_FBI_CANCELLED) { - prompt_display_notify("Failure", "Dump cancelled.", COLOR_TEXT, NULL, NULL, NULL); - } else { - error_display_res(NULL, NULL, res, "Failed to dump NAND."); - } - - return false; +static bool dumpnand_error(void* data, u32 index, Result res, ui_view** errorView) { + *errorView = error_display_res(NULL, NULL, res, "Failed to dump NAND."); + return true; } static void dumpnand_update(ui_view* view, void* data, float* progress, char* text) { diff --git a/source/ui/section/task/dataop.c b/source/ui/section/task/dataop.c index eb5a6ad..43e36ad 100644 --- a/source/ui/section/task/dataop.c +++ b/source/ui/section/task/dataop.c @@ -5,6 +5,9 @@ #include "task.h" #include "../../error.h" +#include "../../prompt.h" +#include "../../ui.h" +#include "../../../core/screen.h" static Result task_data_op_check_running(data_op_data* data, u32 index, u32* srcHandle, u32* dstHandle) { Result res = 0; @@ -146,6 +149,10 @@ static Result task_data_op_delete(data_op_data* data, u32 index) { return data->delete(data->data, index); } +static void task_data_op_retry_onresponse(ui_view* view, void* data, u32 response) { + ((data_op_data*) data)->retryResponse = response == PROMPT_YES; +} + static void task_data_op_thread(void* arg) { data_op_data* data = (data_op_data*) arg; @@ -167,8 +174,29 @@ static void task_data_op_thread(void* arg) { data->result = res; - if(R_FAILED(res) && !data->error(data->data, data->processed, res)) { - break; + if(R_FAILED(res)) { + if(res != R_FBI_CANCELLED) { + ui_view* errorView = NULL; + bool proceed = data->error(data->data, data->processed, res, &errorView); + + if(errorView != NULL) { + svcWaitSynchronization(errorView->active, U64_MAX); + } + + ui_view* retryView = prompt_display_yes_no("Confirmation", "Retry?", COLOR_TEXT, data, NULL, task_data_op_retry_onresponse); + if(retryView != NULL) { + svcWaitSynchronization(retryView->active, U64_MAX); + + if(data->retryResponse) { + data->processed--; + } else if(!proceed) { + break; + } + } + } else { + prompt_display_notify("Failure", "Operation cancelled.", COLOR_TEXT, NULL, NULL, NULL); + break; + } } } diff --git a/source/ui/section/task/task.h b/source/ui/section/task/task.h index a753fc7..28486eb 100644 --- a/source/ui/section/task/task.h +++ b/source/ui/section/task/task.h @@ -5,6 +5,7 @@ typedef struct linked_list_s linked_list; typedef struct list_item_s list_item; +typedef struct ui_view_s ui_view; typedef struct meta_info_s { char shortDescription[0x100]; @@ -147,12 +148,15 @@ typedef struct data_op_data_s { Result (*restore)(void* data, u32 index); // Errors - bool (*error)(void* data, u32 index, Result res); + bool (*error)(void* data, u32 index, Result res, ui_view** errorView); // General volatile bool finished; Result result; Handle cancelEvent; + + // Internal + volatile bool retryResponse; } data_op_data; typedef struct populate_ext_save_data_data_s {