Display TitleDB app information during installation.

This commit is contained in:
Steveice10 2017-03-01 10:08:53 -08:00
parent a62655d896
commit 0897b3ecde
9 changed files with 94 additions and 54 deletions

View File

@ -68,7 +68,7 @@ static void info_draw_bottom(ui_view* view, void* data, float x1, float y1, floa
}
ui_view* info_display(const char* name, const char* info, bool bar, void* data, void (*update)(ui_view* view, void* data, float* progress, char* text),
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2)) {
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2)) {
info_data* infoData = (info_data*) calloc(1, sizeof(info_data));
if(infoData == NULL) {
error_display(NULL, NULL, "Failed to allocate info data.");

View File

@ -3,6 +3,7 @@
typedef struct ticket_info_s ticket_info;
typedef struct linked_list_s linked_list;
typedef struct list_item_s list_item;
typedef struct ui_view_s ui_view;
#define INSTALL_URL_MAX 1024
#define INSTALL_URLS_MAX 128
@ -52,7 +53,8 @@ void action_import_secure_value(linked_list* items, list_item* selected);
void action_export_secure_value(linked_list* items, list_item* selected);
void action_delete_secure_value(linked_list* items, list_item* selected);
void action_url_install(const char* confirmMessage, const char* urls, void* finishedData, void (*finished)(void* data));
void action_url_install(const char* confirmMessage, const char* urls, void* userData, void (*finished)(void* data),
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index));
void action_install_titledb(linked_list* items, list_item* selected);
void action_update_titledb(linked_list* items, list_item* selected);

View File

@ -1,5 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <3ds.h>
@ -7,34 +6,16 @@
#include "../task/task.h"
#include "../../error.h"
#include "../../list.h"
#include "../../ui.h"
#include "../../../core/linkedlist.h"
static void action_install_titledb_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index) {
ui_draw_titledb_info(view, ((list_item*) data)->data, x1, y1, x2, y2);
}
void action_install_titledb(linked_list* items, list_item* selected) {
char url[64];
snprintf(url, INSTALL_URL_MAX, "https://3ds.titledb.com/v1/cia/%lu/download", ((titledb_info*) selected->data)->id);
action_url_install("Install the selected title from TitleDB?", url, NULL, NULL);
}
void action_update_titledb(linked_list* items, list_item* selected) {
char* urls = (char*) calloc(1, INSTALL_URL_MAX * INSTALL_URLS_MAX);
if(urls != NULL) {
linked_list_iter iter;
linked_list_iterate(items, &iter);
size_t pos = 0;
while(linked_list_iter_has_next(&iter) && pos < INSTALL_URL_MAX * INSTALL_URLS_MAX) {
titledb_info* info = (titledb_info*) ((list_item*) linked_list_iter_next(&iter))->data;
if(info->outdated) {
pos += snprintf(urls + pos, (INSTALL_URL_MAX * INSTALL_URLS_MAX) - pos, "https://3ds.titledb.com/v1/cia/%lu/download\n", info->id);
}
}
action_url_install("Update installed titles from TitleDB?", urls, NULL, NULL);
free(urls);
} else {
error_display_res(NULL, NULL, R_FBI_OUT_OF_MEMORY, "Failed to allocate URL text buffer.");
}
action_url_install("Install the selected title from TitleDB?", url, selected, NULL, action_install_titledb_draw_top);
}

View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <3ds.h>
#include "action.h"
#include "../task/task.h"
#include "../../error.h"
#include "../../list.h"
#include "../../ui.h"
#include "../../../core/linkedlist.h"
static void action_update_titledb_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index) {
linked_list* items = (linked_list*) data;
if(index < linked_list_size(items)) {
ui_draw_titledb_info(view, ((list_item*) linked_list_get(items, index))->data, x1, y1, x2, y2);
}
}
void action_update_titledb(linked_list* items, list_item* selected) {
char* urls = (char*) calloc(1, INSTALL_URL_MAX * INSTALL_URLS_MAX);
if(urls != NULL) {
linked_list_iter iter;
linked_list_iterate(items, &iter);
size_t pos = 0;
while(linked_list_iter_has_next(&iter) && pos < INSTALL_URL_MAX * INSTALL_URLS_MAX) {
titledb_info* info = (titledb_info*) ((list_item*) linked_list_iter_next(&iter))->data;
if(info->installed && info->installedVersion < info->latestVersion) {
pos += snprintf(urls + pos, (INSTALL_URL_MAX * INSTALL_URLS_MAX) - pos, "https://3ds.titledb.com/v1/cia/%lu/download\n", info->id);
}
}
action_url_install("Update installed titles from TitleDB?", urls, items, NULL, action_update_titledb_draw_top);
free(urls);
} else {
error_display_res(NULL, NULL, R_FBI_OUT_OF_MEMORY, "Failed to allocate URL text buffer.");
}
}

View File

@ -16,8 +16,9 @@
typedef struct {
char urls[INSTALL_URLS_MAX][INSTALL_URL_MAX];
void* finishedData;
void* userData;
void (*finished)(void* data);
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index);
bool cdn;
bool cdnDecided;
@ -33,7 +34,7 @@ typedef struct {
static void action_url_install_free_data(url_install_data* data) {
if(data->finished != NULL) {
data->finished(data->finishedData);
data->finished(data->userData);
}
free(data);
@ -50,6 +51,14 @@ static void action_url_install_n3ds_onresponse(ui_view* view, void* data, bool r
((url_install_data*) data)->n3dsContinue = response;
}
static void action_url_install_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
url_install_data* installData = (url_install_data*) data;
if(installData->drawTop != NULL) {
installData->drawTop(view, installData->userData, x1, y1, x2, y2, installData->installInfo.processed);
}
}
static Result action_url_install_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
@ -107,7 +116,7 @@ static Result action_url_install_open_dst(void* data, u32 index, void* initialRe
if(*(u16*) initialReadBlock == 0x0100) {
if(!installData->cdnDecided) {
ui_view* view = prompt_display("Optional", "Install ticket titles from CDN?", COLOR_TEXT, true, data, NULL, action_url_install_cdn_check_onresponse);
ui_view* view = prompt_display("Optional", "Install ticket titles from CDN?", COLOR_TEXT, true, data, action_url_install_draw_top, action_url_install_cdn_check_onresponse);
if(view != NULL) {
svcWaitSynchronization(view->active, U64_MAX);
}
@ -126,7 +135,7 @@ static Result action_url_install_open_dst(void* data, u32 index, void* initialRe
bool n3ds = false;
if(R_SUCCEEDED(APT_CheckNew3DS(&n3ds)) && !n3ds && ((titleId >> 28) & 0xF) == 2) {
ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, NULL, action_url_install_n3ds_onresponse);
ui_view* view = prompt_display("Confirmation", "Title is intended for New 3DS systems.\nContinue?", COLOR_TEXT, true, data, action_url_install_draw_top, action_url_install_n3ds_onresponse);
if(view != NULL) {
svcWaitSynchronization(view->active, U64_MAX);
}
@ -229,15 +238,15 @@ static bool action_url_install_error(void* data, u32 index, Result res) {
if(res == R_FBI_HTTP_RESPONSE_CODE) {
if(strlen(url) > 38) {
view = error_display(NULL, NULL, "Failed to install from URL.\n%.35s...\nHTTP server returned response code %d", url, installData->responseCode);
view = error_display(data, action_url_install_draw_top, "Failed to install from URL.\n%.35s...\nHTTP server returned response code %d", url, installData->responseCode);
} else {
view = error_display(NULL, NULL, "Failed to install from URL.\n%.38s\nHTTP server returned response code %d", url, installData->responseCode);
view = error_display(data, action_url_install_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(NULL, NULL, res, "Failed to install from URL.\n%.35s...", url);
view = error_display_res(data, action_url_install_draw_top, res, "Failed to install from URL.\n%.35s...", url);
} else {
view = error_display_res(NULL, NULL, res, "Failed to install from URL.\n%.38s", url);
view = error_display_res(data, action_url_install_draw_top, res, "Failed to install from URL.\n%.38s", url);
}
}
@ -279,7 +288,7 @@ static void action_url_install_confirm_onresponse(ui_view* view, void* data, boo
if(response) {
Result res = task_data_op(&installData->installInfo);
if(R_SUCCEEDED(res)) {
info_display("Installing From URL(s)", "Press B to cancel.", true, data, action_url_install_install_update, NULL);
info_display("Installing From URL(s)", "Press B to cancel.", true, data, action_url_install_install_update, action_url_install_draw_top);
} else {
error_display_res(NULL, NULL, res, "Failed to initiate installation.");
@ -290,7 +299,8 @@ static void action_url_install_confirm_onresponse(ui_view* view, void* data, boo
}
}
void action_url_install(const char* confirmMessage, const char* urls, void* finishedData, void (*finished)(void* data)) {
void action_url_install(const char* confirmMessage, const char* urls, void* userData, void (*finished)(void* data),
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, u32 index)) {
url_install_data* data = (url_install_data*) calloc(1, sizeof(url_install_data));
if(data == NULL) {
error_display(NULL, NULL, "Failed to allocate URL install data.");
@ -331,8 +341,9 @@ void action_url_install(const char* confirmMessage, const char* urls, void* fini
}
}
data->finishedData = finishedData;
data->userData = userData;
data->finished = finished;
data->drawTop = drawTop;
data->cdn = false;
data->cdnDecided = false;
@ -372,5 +383,5 @@ void action_url_install(const char* confirmMessage, const char* urls, void* fini
data->installInfo.finished = true;
prompt_display("Confirmation", confirmMessage, COLOR_TEXT, true, data, NULL, action_url_install_confirm_onresponse);
prompt_display("Confirmation", confirmMessage, COLOR_TEXT, true, data, action_url_install_draw_top, action_url_install_confirm_onresponse);
}

View File

@ -174,7 +174,7 @@ static void remoteinstall_network_update(ui_view* view, void* data, float* progr
}
remoteinstall_set_last_urls(urls);
action_url_install("Install from the received URL(s)?", urls, data, remoteinstall_network_close_client);
action_url_install("Install from the received URL(s)?", urls, data, remoteinstall_network_close_client, NULL);
free(urls);
} else if(errno != EAGAIN) {
@ -365,7 +365,7 @@ static void remoteinstall_qr_update(ui_view* view, void* data, float* progress,
remoteinstall_set_last_urls((const char*) qrData.payload);
action_url_install("Install from the scanned QR code?", (const char*) qrData.payload, NULL, NULL);
action_url_install("Install from the scanned QR code?", (const char*) qrData.payload, NULL, NULL, NULL);
return;
}
}
@ -430,7 +430,7 @@ void remoteinstall_manually_enter_urls() {
if(swkbdInputText(&swkbd, textBuf, INSTALL_URL_MAX * INSTALL_URLS_MAX) == SWKBD_BUTTON_CONFIRM) {
remoteinstall_set_last_urls(textBuf);
action_url_install("Install from the entered URL(s)?", textBuf, NULL, NULL);
action_url_install("Install from the entered URL(s)?", textBuf, NULL, NULL, NULL);
}
free(textBuf);
@ -443,7 +443,7 @@ void remoteinstall_repeat_last_request() {
char* textBuf = (char*) calloc(1, INSTALL_URL_MAX * INSTALL_URLS_MAX);
if(textBuf != NULL) {
if(remoteinstall_get_last_urls(textBuf, INSTALL_URL_MAX * INSTALL_URLS_MAX)) {
action_url_install("Install from the last requested URL(s)?", textBuf, NULL, NULL);
action_url_install("Install from the last requested URL(s)?", textBuf, NULL, NULL, NULL);
} else {
prompt_display("Failure", "No previously requested URL(s) could be found.", COLOR_TEXT, false, NULL, NULL, NULL);
}

View File

@ -75,7 +75,7 @@ static void task_populate_titledb_thread(void* arg) {
u32 micro = 0;
sscanf(subVal->u.string.ptr, "%lu.%lu.%lu", &major, &minor, &micro);
titledbInfo->version = ((u8) (major & 0x3F) << 10) | ((u8) (minor & 0x3F) << 4) | ((u8) (micro & 0xF));
titledbInfo->latestVersion = ((u8) (major & 0x3F) << 10) | ((u8) (minor & 0x3F) << 4) | ((u8) (micro & 0xF));
} else if(strncmp(name, "name_s", nameLen) == 0) {
strncpy(titledbInfo->meta.shortDescription, subVal->u.string.ptr, sizeof(titledbInfo->meta.shortDescription));
} else if(strncmp(name, "name_l", nameLen) == 0) {
@ -94,7 +94,7 @@ static void task_populate_titledb_thread(void* arg) {
AM_TitleEntry entry;
titledbInfo->installed = R_SUCCEEDED(AM_GetTitleInfo(util_get_title_destination(titledbInfo->titleId), 1, &titledbInfo->titleId, &entry));
titledbInfo->outdated = titledbInfo->installed && entry.version < titledbInfo->version;
titledbInfo->installedVersion = titledbInfo->installed ? entry.version : (u16) 0;
if(strlen(titledbInfo->meta.shortDescription) > 0) {
strncpy(item->name, titledbInfo->meta.shortDescription, LIST_ITEM_NAME_MAX);
@ -102,10 +102,12 @@ static void task_populate_titledb_thread(void* arg) {
snprintf(item->name, LIST_ITEM_NAME_MAX, "%016llX", titledbInfo->titleId);
}
if(titledbInfo->outdated) {
item->color = COLOR_TITLEDB_OUTDATED;
} else if(titledbInfo->installed) {
item->color = COLOR_TITLEDB_INSTALLED;
if(titledbInfo->installed) {
if(titledbInfo->installedVersion < titledbInfo->latestVersion) {
item->color = COLOR_TITLEDB_OUTDATED;
} else {
item->color = COLOR_TITLEDB_INSTALLED;
}
} else {
item->color = COLOR_TITLEDB_NOT_INSTALLED;
}
@ -121,7 +123,7 @@ static void task_populate_titledb_thread(void* arg) {
titledb_info* currTitledbInfo = (titledb_info*) currItem->data;
if(titledbInfo->titleId == currTitledbInfo->titleId) {
if(titledbInfo->version >= currTitledbInfo->version) {
if(titledbInfo->latestVersion >= currTitledbInfo->latestVersion) {
linked_list_iter_remove(&iter);
task_free_titledb(currItem);
} else {

View File

@ -73,10 +73,10 @@ typedef struct file_info_s {
typedef struct titledb_info_s {
u32 id;
u64 titleId;
u16 version;
u16 installedVersion;
u16 latestVersion;
u64 size;
bool installed;
bool outdated;
meta_info meta;
} titledb_info;

View File

@ -615,10 +615,12 @@ void ui_draw_titledb_info(ui_view* view, void* data, float x1, float y1, float x
snprintf(infoText, sizeof(infoText),
"Title ID: %016llX\n"
"Version: %hu (%d.%d.%d)\n"
"Installed Version: %hu (%d.%d.%d)\n"
"Latest Version: %hu (%d.%d.%d)\n"
"Size: %.2f %s",
info->titleId,
info->version, (info->version >> 10) & 0x3F, (info->version >> 4) & 0x3F, info->version & 0xF,
info->installedVersion, (info->installedVersion >> 10) & 0x3F, (info->installedVersion >> 4) & 0x3F, info->installedVersion & 0xF,
info->latestVersion, (info->latestVersion >> 10) & 0x3F, (info->latestVersion >> 4) & 0x3F, info->latestVersion & 0xF,
util_get_display_size(info->size), util_get_display_size_units(info->size));
float infoWidth;