mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-28 02:30:35 +00:00
Merge pull request #11272 from jdgleaver/play-feature-delivery-switch
(Android/Play Store Builds) Add option to switch all installed cores to Play Store versions
This commit is contained in:
commit
b7fff53d16
@ -723,6 +723,15 @@ bool core_info_get_list(core_info_list_t **core)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns number of installed cores */
|
||||
size_t core_info_count(void)
|
||||
{
|
||||
core_info_state_t *p_coreinfo = coreinfo_get_ptr();
|
||||
if (!p_coreinfo || !p_coreinfo->curr_list)
|
||||
return 0;
|
||||
return p_coreinfo->curr_list->count;
|
||||
}
|
||||
|
||||
bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info,
|
||||
bool *set_missing_bios)
|
||||
{
|
||||
|
@ -180,6 +180,9 @@ bool core_info_init_list(const char *path_info, const char *dir_cores,
|
||||
|
||||
bool core_info_get_list(core_info_list_t **core);
|
||||
|
||||
/* Returns number of installed cores */
|
||||
size_t core_info_count(void);
|
||||
|
||||
bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info,
|
||||
bool *set_missing_bios);
|
||||
|
||||
|
@ -105,6 +105,7 @@ RETRO_BEGIN_DECLS
|
||||
#define FILE_PATH_CORE_BACKUP_EXTENSION ".lcbk"
|
||||
#define FILE_PATH_CORE_BACKUP_EXTENSION_NO_DOT "lcbk"
|
||||
#define FILE_PATH_LOCK_EXTENSION ".lck"
|
||||
#define FILE_PATH_BACKUP_EXTENSION ".bak"
|
||||
|
||||
enum application_special_type
|
||||
{
|
||||
|
@ -1084,6 +1084,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES,
|
||||
"update_installed_cores"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD,
|
||||
"switch_installed_cores_pfd"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_CONTENT_DIR,
|
||||
"content_directory"
|
||||
|
@ -291,6 +291,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_UPDATE_INSTALLED_CORES,
|
||||
"Update all installed cores to the latest version available."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SWITCH_INSTALLED_CORES_PFD,
|
||||
"Switch Cores to Play Store Versions"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_SWITCH_INSTALLED_CORES_PFD,
|
||||
"Replace all legacy and manually installed cores with the latest versions from the Play Store, where available."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST,
|
||||
"Thumbnails Updater"
|
||||
@ -10100,6 +10108,10 @@ MSG_HASH(
|
||||
MSG_ALL_CORES_UPDATED,
|
||||
"All installed cores at latest version"
|
||||
)
|
||||
MSG_HASH(
|
||||
MSG_ALL_CORES_SWITCHED_PFD,
|
||||
"All supported cores switched to Play Store versions"
|
||||
)
|
||||
MSG_HASH(
|
||||
MSG_NUM_CORES_UPDATED,
|
||||
"cores updated: "
|
||||
|
@ -90,6 +90,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include "../../file_path_special.h"
|
||||
#include "../../play_feature_delivery/play_feature_delivery.h"
|
||||
#endif
|
||||
|
||||
@ -4512,7 +4513,7 @@ static int action_ok_core_updater_download(const char *path,
|
||||
* the play feature delivery interface */
|
||||
if (play_feature_delivery_enabled())
|
||||
task_push_play_feature_delivery_core_install(
|
||||
core_list, path);
|
||||
core_list, path, false);
|
||||
else
|
||||
#endif
|
||||
task_push_core_updater_download(
|
||||
@ -4544,6 +4545,25 @@ static int action_ok_update_installed_cores(const char *path,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
static int action_ok_switch_installed_cores_pfd(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *path_dir_libretro = settings->paths.directory_libretro;
|
||||
const char *path_libretro_info = settings->paths.path_libretro_info;
|
||||
|
||||
/* Ensure networking is initialised */
|
||||
generic_action_ok_command(CMD_EVENT_NETWORK_INIT);
|
||||
|
||||
/* Push core switch/update task */
|
||||
task_push_play_feature_delivery_switch_installed_cores(
|
||||
path_dir_libretro, path_libretro_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int action_ok_sideload_core(const char *path,
|
||||
@ -6735,11 +6755,32 @@ static int action_ok_core_delete(const char *path,
|
||||
if (play_feature_delivery_enabled())
|
||||
{
|
||||
const char *core_filename = path_basename(core_path);
|
||||
char backup_core_path[PATH_MAX_LENGTH];
|
||||
|
||||
backup_core_path[0] = '\0';
|
||||
|
||||
if (play_feature_delivery_core_installed(core_filename))
|
||||
play_feature_delivery_delete(core_filename);
|
||||
else
|
||||
filestream_delete(core_path);
|
||||
|
||||
/* When installing cores via play feature
|
||||
* delivery, there is a low probability of
|
||||
* backup core files being left behind if
|
||||
* something interrupts the install process
|
||||
* (i.e. a crash or user exit while the
|
||||
* install task is running). To prevent the
|
||||
* accumulation of mess, additionally check
|
||||
* for and remove any such backups when deleting
|
||||
* a core */
|
||||
strlcpy(backup_core_path, core_path,
|
||||
sizeof(backup_core_path));
|
||||
strlcat(backup_core_path, FILE_PATH_BACKUP_EXTENSION,
|
||||
sizeof(backup_core_path));
|
||||
|
||||
if (!string_is_empty(backup_core_path) &&
|
||||
path_is_valid(backup_core_path))
|
||||
filestream_delete(backup_core_path);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -7008,6 +7049,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_DOWNLOAD_CORE_CONTENT_DIRS, action_ok_core_content_dirs_list},
|
||||
{MENU_ENUM_LABEL_CORE_UPDATER_LIST, action_ok_core_updater_list},
|
||||
{MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES, action_ok_update_installed_cores},
|
||||
#if defined(ANDROID)
|
||||
{MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD, action_ok_switch_installed_cores_pfd},
|
||||
#endif
|
||||
{MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST, action_ok_thumbnails_updater_list},
|
||||
{MENU_ENUM_LABEL_PL_THUMBNAILS_UPDATER_LIST, action_ok_pl_thumbnails_updater_list},
|
||||
{MENU_ENUM_LABEL_DOWNLOAD_PL_ENTRY_THUMBNAILS, action_ok_pl_entry_content_thumbnails},
|
||||
|
@ -365,6 +365,9 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_start_core, MENU_
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_list, MENU_ENUM_SUBLABEL_CORE_LIST)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_download_core, MENU_ENUM_SUBLABEL_DOWNLOAD_CORE)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_update_installed_cores, MENU_ENUM_SUBLABEL_UPDATE_INSTALLED_CORES)
|
||||
#if defined(ANDROID)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_switch_installed_cores_pfd, MENU_ENUM_SUBLABEL_SWITCH_INSTALLED_CORES_PFD)
|
||||
#endif
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_sideload_core_list, MENU_ENUM_SUBLABEL_SIDELOAD_CORE_LIST)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_manager_list, MENU_ENUM_SUBLABEL_CORE_MANAGER_LIST)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_load_disc, MENU_ENUM_SUBLABEL_LOAD_DISC)
|
||||
@ -3122,6 +3125,11 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_update_installed_cores);
|
||||
break;
|
||||
#if defined(ANDROID)
|
||||
case MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_switch_installed_cores_pfd);
|
||||
break;
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_CORE_MANAGER_LIST:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_manager_list);
|
||||
break;
|
||||
|
@ -9903,7 +9903,8 @@ static void materialui_list_insert(
|
||||
node->icon_texture_index = MUI_TEXTURE_START_CORE;
|
||||
node->icon_type = MUI_ICON_TYPE_INTERNAL;
|
||||
}
|
||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_STATE)))
|
||||
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_STATE)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD)))
|
||||
{
|
||||
node->icon_texture_index = MUI_TEXTURE_LOAD_STATE;
|
||||
node->icon_type = MUI_ICON_TYPE_INTERNAL;
|
||||
|
@ -131,6 +131,7 @@ uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
|
||||
case MENU_ENUM_LABEL_CORE_SETTINGS:
|
||||
case MENU_ENUM_LABEL_CORE_UPDATER_LIST:
|
||||
case MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES:
|
||||
case MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD:
|
||||
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_CORE:
|
||||
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE:
|
||||
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CORE:
|
||||
|
@ -2577,6 +2577,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
case MENU_ENUM_LABEL_CORE_SETTINGS:
|
||||
case MENU_ENUM_LABEL_CORE_UPDATER_LIST:
|
||||
case MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES:
|
||||
case MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD:
|
||||
case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_CORE:
|
||||
case MENU_ENUM_LABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE:
|
||||
case MENU_ENUM_LABEL_REMAP_FILE_SAVE_CORE:
|
||||
|
@ -11065,18 +11065,36 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
count++;
|
||||
|
||||
/* Only show 'update installed cores' if
|
||||
* one or more cores are installed */
|
||||
if (core_info_count() > 0)
|
||||
{
|
||||
#if defined(ANDROID)
|
||||
/* Play Store builds auto-update installed
|
||||
* cores, rendering the 'update installed
|
||||
* cores' option irrelevant/useless */
|
||||
if (!play_feature_delivery_enabled())
|
||||
/* When using Play Store builds, cores are
|
||||
* updated automatically - the 'update
|
||||
* installed cores' option is therefore
|
||||
* irrelevant/useless, so we instead present
|
||||
* an option for switching any existing buildbot
|
||||
* or sideloaded cores to the latest Play Store
|
||||
* version */
|
||||
if (play_feature_delivery_enabled())
|
||||
{
|
||||
if (menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SWITCH_INSTALLED_CORES_PFD),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD),
|
||||
MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
count++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UPDATE_INSTALLED_CORES),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES),
|
||||
MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
count++;
|
||||
if (menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UPDATE_INSTALLED_CORES),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES),
|
||||
MENU_ENUM_LABEL_UPDATE_INSTALLED_CORES,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
count++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -2065,6 +2065,7 @@ enum msg_hash_enums
|
||||
|
||||
/* Core updater */
|
||||
MENU_LABEL(UPDATE_INSTALLED_CORES),
|
||||
MENU_LABEL(SWITCH_INSTALLED_CORES_PFD),
|
||||
|
||||
MSG_FETCHING_CORE_LIST,
|
||||
MSG_CORE_LIST_FAILED,
|
||||
@ -2077,6 +2078,7 @@ enum msg_hash_enums
|
||||
MSG_SCANNING_CORES,
|
||||
MSG_CHECKING_CORE,
|
||||
MSG_ALL_CORES_UPDATED,
|
||||
MSG_ALL_CORES_SWITCHED_PFD,
|
||||
MSG_NUM_CORES_UPDATED,
|
||||
MSG_NUM_CORES_LOCKED,
|
||||
MSG_CORE_UPDATE_DISABLED,
|
||||
|
@ -87,7 +87,6 @@ JNIEXPORT void JNICALL Java_com_retroarch_browser_retroactivity_RetroActivityCom
|
||||
(JNIEnv *env, jobject this_obj, jstring core_name, jboolean successful)
|
||||
{
|
||||
play_feature_delivery_state_t* state = play_feature_delivery_get_state();
|
||||
const char *core_name_c = NULL;
|
||||
|
||||
/* Lock mutex */
|
||||
#ifdef HAVE_THREADS
|
||||
@ -523,7 +522,14 @@ bool play_feature_delivery_download(const char *core_file)
|
||||
/* We only support one download at a time */
|
||||
if (!state->active)
|
||||
{
|
||||
/* Convert to a Java-style string */
|
||||
/* Update status */
|
||||
state->download_progress = 0;
|
||||
state->last_status = PLAY_FEATURE_DELIVERY_PENDING;
|
||||
state->active = true;
|
||||
strlcpy(state->last_core_name, core_name,
|
||||
sizeof(state->last_core_name));
|
||||
|
||||
/* Convert core name to a Java-style string */
|
||||
core_name_jni = (*env)->NewStringUTF(env, core_name);
|
||||
|
||||
/* Request download */
|
||||
@ -533,13 +539,6 @@ bool play_feature_delivery_download(const char *core_file)
|
||||
/* Free core_name_jni reference */
|
||||
(*env)->DeleteLocalRef(env, core_name_jni);
|
||||
|
||||
/* Update status */
|
||||
state->download_progress = 0;
|
||||
state->last_status = PLAY_FEATURE_DELIVERY_PENDING;
|
||||
state->active = true;
|
||||
strlcpy(state->last_core_name, core_name,
|
||||
sizeof(state->last_core_name));
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,10 @@
|
||||
#include "file_path_special.h"
|
||||
#include "core_info.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include "play_feature_delivery/play_feature_delivery.h"
|
||||
#endif
|
||||
|
||||
#ifndef PLAYLIST_ENTRIES
|
||||
#define PLAYLIST_ENTRIES 6
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "../core_updater_list.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include "../file_path_special.h"
|
||||
#include "../play_feature_delivery/play_feature_delivery.h"
|
||||
#endif
|
||||
|
||||
@ -131,8 +132,8 @@ typedef struct update_installed_cores_handle
|
||||
bool auto_backup;
|
||||
} update_installed_cores_handle_t;
|
||||
|
||||
/* Play feature delivery core install */
|
||||
#if defined(ANDROID)
|
||||
/* Play feature delivery core install */
|
||||
enum play_feature_delivery_install_task_status
|
||||
{
|
||||
PLAY_FEATURE_DELIVERY_INSTALL_BEGIN = 0,
|
||||
@ -144,11 +145,35 @@ typedef struct play_feature_delivery_install_handle
|
||||
{
|
||||
char *core_filename;
|
||||
char *local_core_path;
|
||||
char *backup_core_path;
|
||||
char *display_name;
|
||||
enum play_feature_delivery_install_task_status status;
|
||||
bool success;
|
||||
bool core_already_installed;
|
||||
} play_feature_delivery_install_handle_t;
|
||||
|
||||
/* Play feature delivery switch installed cores */
|
||||
enum play_feature_delivery_switch_cores_task_status
|
||||
{
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_BEGIN = 0,
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE,
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_INSTALL_CORE,
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_WAIT_INSTALL,
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_END
|
||||
};
|
||||
|
||||
typedef struct play_feature_delivery_switch_cores_handle
|
||||
{
|
||||
char *path_dir_libretro;
|
||||
char *path_libretro_info;
|
||||
char *error_msg;
|
||||
core_updater_list_t* core_list;
|
||||
retro_task_t *install_task;
|
||||
size_t list_size;
|
||||
size_t list_index;
|
||||
size_t installed_index;
|
||||
enum play_feature_delivery_switch_cores_task_status status;
|
||||
} play_feature_delivery_switch_cores_handle_t;
|
||||
#endif
|
||||
|
||||
/*********************/
|
||||
@ -1517,12 +1542,11 @@ error:
|
||||
free_update_installed_cores_handle(update_installed_handle);
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
/**************************************/
|
||||
/* Play feature delivery core install */
|
||||
/**************************************/
|
||||
|
||||
#if defined(ANDROID)
|
||||
|
||||
static void free_play_feature_delivery_install_handle(
|
||||
play_feature_delivery_install_handle_t *pfd_install_handle)
|
||||
{
|
||||
@ -1535,6 +1559,9 @@ static void free_play_feature_delivery_install_handle(
|
||||
if (pfd_install_handle->local_core_path)
|
||||
free(pfd_install_handle->local_core_path);
|
||||
|
||||
if (pfd_install_handle->backup_core_path)
|
||||
free(pfd_install_handle->backup_core_path);
|
||||
|
||||
if (pfd_install_handle->display_name)
|
||||
free(pfd_install_handle->display_name);
|
||||
|
||||
@ -1574,10 +1601,54 @@ static void task_play_feature_delivery_core_install_handler(retro_task_t *task)
|
||||
}
|
||||
|
||||
/* If core is already installed via other
|
||||
* means, must delete it before attempting
|
||||
* means, must remove it before attempting
|
||||
* play feature delivery transaction */
|
||||
if (path_is_valid(pfd_install_handle->local_core_path))
|
||||
filestream_delete(pfd_install_handle->local_core_path);
|
||||
{
|
||||
char backup_core_path[PATH_MAX_LENGTH];
|
||||
bool backup_successful = false;
|
||||
|
||||
backup_core_path[0] = '\0';
|
||||
|
||||
/* Have to create a backup, in case install
|
||||
* process fails
|
||||
* > Note: since only one install task can
|
||||
* run at a time, a UID is not required */
|
||||
|
||||
/* Generate backup file name */
|
||||
strlcpy(backup_core_path, pfd_install_handle->local_core_path,
|
||||
sizeof(backup_core_path));
|
||||
strlcat(backup_core_path, FILE_PATH_BACKUP_EXTENSION,
|
||||
sizeof(backup_core_path));
|
||||
|
||||
if (!string_is_empty(backup_core_path))
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* If an old backup file exists (i.e. leftovers
|
||||
* from a mid-task crash/user exit), delete it */
|
||||
if (path_is_valid(backup_core_path))
|
||||
filestream_delete(backup_core_path);
|
||||
|
||||
/* Attempt to rename core file */
|
||||
ret = filestream_rename(
|
||||
pfd_install_handle->local_core_path,
|
||||
backup_core_path);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
/* Success - cache backup file name */
|
||||
pfd_install_handle->backup_core_path = strdup(backup_core_path);
|
||||
backup_successful = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If backup failed, all we can do is delete
|
||||
* the existing core file... */
|
||||
if (!backup_successful &&
|
||||
path_is_valid(pfd_install_handle->local_core_path))
|
||||
filestream_delete(pfd_install_handle->local_core_path);
|
||||
}
|
||||
|
||||
/* Start download */
|
||||
if (play_feature_delivery_download(
|
||||
@ -1659,6 +1730,34 @@ static void task_play_feature_delivery_core_install_handler(retro_task_t *task)
|
||||
sizeof(task_title));
|
||||
|
||||
task_set_title(task, strdup(task_title));
|
||||
|
||||
/* Check whether a core backup file was created */
|
||||
if (!string_is_empty(pfd_install_handle->backup_core_path) &&
|
||||
path_is_valid(pfd_install_handle->backup_core_path))
|
||||
{
|
||||
/* If install was successful, delete backup */
|
||||
if (pfd_install_handle->success)
|
||||
filestream_delete(pfd_install_handle->backup_core_path);
|
||||
else
|
||||
{
|
||||
/* Otherwise, attempt to restore backup */
|
||||
int ret = filestream_rename(
|
||||
pfd_install_handle->backup_core_path,
|
||||
pfd_install_handle->local_core_path);
|
||||
|
||||
/* If restore failed, all we can do is attempt
|
||||
* to delete the backup... */
|
||||
if (ret && path_is_valid(pfd_install_handle->backup_core_path))
|
||||
filestream_delete(pfd_install_handle->backup_core_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* If task is muted and install failed, set
|
||||
* error string (allows status to be checked
|
||||
* externally) */
|
||||
if (!pfd_install_handle->success &&
|
||||
task_get_mute(task))
|
||||
task_set_error(task, strdup(task_title));
|
||||
}
|
||||
/* fall-through */
|
||||
default:
|
||||
@ -1688,9 +1787,10 @@ static bool task_play_feature_delivery_core_install_finder(
|
||||
return false;
|
||||
}
|
||||
|
||||
void task_push_play_feature_delivery_core_install(
|
||||
void *task_push_play_feature_delivery_core_install(
|
||||
core_updater_list_t* core_list,
|
||||
const char *filename)
|
||||
const char *filename,
|
||||
bool mute)
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
char task_title[PATH_MAX_LENGTH];
|
||||
@ -1727,6 +1827,7 @@ void task_push_play_feature_delivery_core_install(
|
||||
/* Configure handle */
|
||||
pfd_install_handle->core_filename = strdup(list_entry->remote_filename);
|
||||
pfd_install_handle->local_core_path = strdup(list_entry->local_core_path);
|
||||
pfd_install_handle->backup_core_path = NULL;
|
||||
pfd_install_handle->display_name = strdup(list_entry->display_name);
|
||||
pfd_install_handle->success = false;
|
||||
pfd_install_handle->core_already_installed = false;
|
||||
@ -1746,7 +1847,7 @@ void task_push_play_feature_delivery_core_install(
|
||||
|
||||
task->handler = task_play_feature_delivery_core_install_handler;
|
||||
task->state = pfd_install_handle;
|
||||
task->mute = false;
|
||||
task->mute = mute;
|
||||
task->title = strdup(task_title);
|
||||
task->alternative_look = true;
|
||||
task->progress = 0;
|
||||
@ -1762,6 +1863,372 @@ void task_push_play_feature_delivery_core_install(
|
||||
/* Push task */
|
||||
task_queue_push(task);
|
||||
|
||||
return task;
|
||||
|
||||
error:
|
||||
|
||||
/* Clean up task */
|
||||
if (task)
|
||||
{
|
||||
free(task);
|
||||
task = NULL;
|
||||
}
|
||||
|
||||
/* Clean up handle */
|
||||
free_play_feature_delivery_install_handle(pfd_install_handle);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Play feature delivery switch installed cores */
|
||||
/************************************************/
|
||||
|
||||
static void free_play_feature_delivery_switch_cores_handle(
|
||||
play_feature_delivery_switch_cores_handle_t *pfd_switch_cores_handle)
|
||||
{
|
||||
if (!pfd_switch_cores_handle)
|
||||
return;
|
||||
|
||||
if (pfd_switch_cores_handle->path_dir_libretro)
|
||||
free(pfd_switch_cores_handle->path_dir_libretro);
|
||||
|
||||
if (pfd_switch_cores_handle->path_libretro_info)
|
||||
free(pfd_switch_cores_handle->path_libretro_info);
|
||||
|
||||
if (pfd_switch_cores_handle->error_msg)
|
||||
free(pfd_switch_cores_handle->error_msg);
|
||||
|
||||
core_updater_list_free(pfd_switch_cores_handle->core_list);
|
||||
|
||||
free(pfd_switch_cores_handle);
|
||||
pfd_switch_cores_handle = NULL;
|
||||
}
|
||||
|
||||
static void task_play_feature_delivery_switch_cores_handler(retro_task_t *task)
|
||||
{
|
||||
play_feature_delivery_switch_cores_handle_t *pfd_switch_cores_handle = NULL;
|
||||
|
||||
if (!task)
|
||||
goto task_finished;
|
||||
|
||||
pfd_switch_cores_handle = (play_feature_delivery_switch_cores_handle_t*)task->state;
|
||||
|
||||
if (!pfd_switch_cores_handle)
|
||||
goto task_finished;
|
||||
|
||||
if (task_get_cancelled(task))
|
||||
goto task_finished;
|
||||
|
||||
switch (pfd_switch_cores_handle->status)
|
||||
{
|
||||
case PLAY_FEATURE_DELIVERY_SWITCH_CORES_BEGIN:
|
||||
{
|
||||
/* Query available cores
|
||||
* Note: It should never be possible for this
|
||||
* function (or the subsequent parsing of its
|
||||
* output) to fail. We handle error conditions
|
||||
* regardless, but there is no need to perform
|
||||
* detailed checking - just report any problems
|
||||
* to the user as a generic 'failed to retrieve
|
||||
* core list' error */
|
||||
struct string_list *available_cores =
|
||||
play_feature_delivery_available_cores();
|
||||
bool success = false;
|
||||
|
||||
if (!available_cores)
|
||||
{
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_END;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Populate core updater list */
|
||||
success = core_updater_list_parse_pfd_data(
|
||||
pfd_switch_cores_handle->core_list,
|
||||
pfd_switch_cores_handle->path_dir_libretro,
|
||||
pfd_switch_cores_handle->path_libretro_info,
|
||||
available_cores);
|
||||
|
||||
string_list_free(available_cores);
|
||||
|
||||
/* Cache list size */
|
||||
if (success)
|
||||
pfd_switch_cores_handle->list_size =
|
||||
core_updater_list_size(pfd_switch_cores_handle->core_list);
|
||||
|
||||
if (pfd_switch_cores_handle->list_size < 1)
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_END;
|
||||
else
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE;
|
||||
}
|
||||
break;
|
||||
case PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE:
|
||||
{
|
||||
const core_updater_list_entry_t *list_entry = NULL;
|
||||
bool core_installed = false;
|
||||
|
||||
/* Check whether we have reached the end
|
||||
* of the list */
|
||||
if (pfd_switch_cores_handle->list_index >=
|
||||
pfd_switch_cores_handle->list_size)
|
||||
{
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_END;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check whether current core is installed */
|
||||
if (core_updater_list_get_index(
|
||||
pfd_switch_cores_handle->core_list,
|
||||
pfd_switch_cores_handle->list_index,
|
||||
&list_entry) &&
|
||||
path_is_valid(list_entry->local_core_path))
|
||||
{
|
||||
core_installed = true;
|
||||
pfd_switch_cores_handle->installed_index =
|
||||
pfd_switch_cores_handle->list_index;
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_INSTALL_CORE;
|
||||
}
|
||||
|
||||
/* Update progress display */
|
||||
task_free_title(task);
|
||||
|
||||
if (core_installed)
|
||||
{
|
||||
char task_title[PATH_MAX_LENGTH];
|
||||
|
||||
task_title[0] = '\0';
|
||||
|
||||
strlcpy(task_title, msg_hash_to_str(MSG_CHECKING_CORE),
|
||||
sizeof(task_title));
|
||||
strlcat(task_title, list_entry->display_name,
|
||||
sizeof(task_title));
|
||||
|
||||
task_set_title(task, strdup(task_title));
|
||||
}
|
||||
else
|
||||
task_set_title(task, strdup(msg_hash_to_str(MSG_SCANNING_CORES)));
|
||||
|
||||
task_set_progress(task,
|
||||
(pfd_switch_cores_handle->list_index * 100) /
|
||||
pfd_switch_cores_handle->list_size);
|
||||
|
||||
/* Increment list index */
|
||||
pfd_switch_cores_handle->list_index++;
|
||||
}
|
||||
break;
|
||||
case PLAY_FEATURE_DELIVERY_SWITCH_CORES_INSTALL_CORE:
|
||||
{
|
||||
const core_updater_list_entry_t *list_entry = NULL;
|
||||
|
||||
/* Get list entry
|
||||
* > In the event of an error, just return
|
||||
* to PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE
|
||||
* state */
|
||||
if (!core_updater_list_get_index(
|
||||
pfd_switch_cores_handle->core_list,
|
||||
pfd_switch_cores_handle->installed_index,
|
||||
&list_entry))
|
||||
{
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check whether core is already installed via
|
||||
* play feature delivery */
|
||||
if (play_feature_delivery_core_installed(
|
||||
list_entry->remote_filename))
|
||||
{
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Existing core is not installed via
|
||||
* play feature delivery
|
||||
* > Request installation/replacement */
|
||||
pfd_switch_cores_handle->install_task = (retro_task_t*)
|
||||
task_push_play_feature_delivery_core_install(
|
||||
pfd_switch_cores_handle->core_list,
|
||||
list_entry->remote_filename,
|
||||
true);
|
||||
|
||||
/* Again, if an error occurred, just return to
|
||||
* PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE
|
||||
* state */
|
||||
if (!pfd_switch_cores_handle->install_task)
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE;
|
||||
else
|
||||
{
|
||||
char task_title[PATH_MAX_LENGTH];
|
||||
|
||||
task_title[0] = '\0';
|
||||
|
||||
/* Update task title */
|
||||
task_free_title(task);
|
||||
|
||||
strlcpy(task_title, msg_hash_to_str(MSG_UPDATING_CORE),
|
||||
sizeof(task_title));
|
||||
strlcat(task_title, list_entry->display_name,
|
||||
sizeof(task_title));
|
||||
|
||||
task_set_title(task, strdup(task_title));
|
||||
|
||||
/* Wait for installation to complete */
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_WAIT_INSTALL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PLAY_FEATURE_DELIVERY_SWITCH_CORES_WAIT_INSTALL:
|
||||
{
|
||||
bool install_complete = false;
|
||||
const char* error_msg = NULL;
|
||||
|
||||
/* > If task is running, check 'is finished' status
|
||||
* > If task is NULL, then it is finished by
|
||||
* definition */
|
||||
if (pfd_switch_cores_handle->install_task)
|
||||
{
|
||||
error_msg = task_get_error(
|
||||
pfd_switch_cores_handle->install_task);
|
||||
install_complete = task_get_finished(
|
||||
pfd_switch_cores_handle->install_task);
|
||||
}
|
||||
else
|
||||
install_complete = true;
|
||||
|
||||
/* Check for installation errors
|
||||
* > These should be considered 'serious', and
|
||||
* will trigger the task to end early */
|
||||
if (!string_is_empty(error_msg))
|
||||
{
|
||||
pfd_switch_cores_handle->error_msg = strdup(error_msg);
|
||||
pfd_switch_cores_handle->install_task = NULL;
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_END;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If installation is complete, return to
|
||||
* PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE
|
||||
* state */
|
||||
if (install_complete)
|
||||
{
|
||||
pfd_switch_cores_handle->install_task = NULL;
|
||||
pfd_switch_cores_handle->status =
|
||||
PLAY_FEATURE_DELIVERY_SWITCH_CORES_ITERATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PLAY_FEATURE_DELIVERY_SWITCH_CORES_END:
|
||||
{
|
||||
const char *task_title = msg_hash_to_str(MSG_CORE_LIST_FAILED);
|
||||
|
||||
/* Set final task title */
|
||||
task_free_title(task);
|
||||
|
||||
/* > Check whether core list was generated
|
||||
* successfully */
|
||||
if (pfd_switch_cores_handle->list_size > 0)
|
||||
{
|
||||
/* Check whether any installation errors occurred */
|
||||
if (!string_is_empty(pfd_switch_cores_handle->error_msg))
|
||||
task_title = pfd_switch_cores_handle->error_msg;
|
||||
else
|
||||
task_title = msg_hash_to_str(MSG_ALL_CORES_SWITCHED_PFD);
|
||||
}
|
||||
|
||||
task_set_title(task, strdup(task_title));
|
||||
}
|
||||
/* fall-through */
|
||||
default:
|
||||
task_set_progress(task, 100);
|
||||
goto task_finished;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
task_finished:
|
||||
|
||||
if (task)
|
||||
task_set_finished(task, true);
|
||||
|
||||
free_play_feature_delivery_switch_cores_handle(pfd_switch_cores_handle);
|
||||
}
|
||||
|
||||
static bool task_play_feature_delivery_switch_cores_finder(
|
||||
retro_task_t *task, void *user_data)
|
||||
{
|
||||
if (!task)
|
||||
return false;
|
||||
|
||||
if (task->handler == task_play_feature_delivery_switch_cores_handler)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void task_push_play_feature_delivery_switch_installed_cores(
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info)
|
||||
{
|
||||
task_finder_data_t find_data;
|
||||
retro_task_t *task = NULL;
|
||||
play_feature_delivery_switch_cores_handle_t *pfd_switch_cores_handle =
|
||||
(play_feature_delivery_switch_cores_handle_t*)
|
||||
calloc(1, sizeof(play_feature_delivery_switch_cores_handle_t));
|
||||
|
||||
/* Sanity check */
|
||||
if (string_is_empty(path_dir_libretro) ||
|
||||
string_is_empty(path_libretro_info) ||
|
||||
!pfd_switch_cores_handle ||
|
||||
!play_feature_delivery_enabled())
|
||||
goto error;
|
||||
|
||||
/* Only one instance of this task my run at a time */
|
||||
find_data.func = task_play_feature_delivery_switch_cores_finder;
|
||||
find_data.userdata = NULL;
|
||||
|
||||
if (task_queue_find(&find_data))
|
||||
goto error;
|
||||
|
||||
/* Configure handle */
|
||||
pfd_switch_cores_handle->path_dir_libretro = strdup(path_dir_libretro);
|
||||
pfd_switch_cores_handle->path_libretro_info = strdup(path_libretro_info);
|
||||
pfd_switch_cores_handle->error_msg = NULL;
|
||||
pfd_switch_cores_handle->core_list = core_updater_list_init();
|
||||
pfd_switch_cores_handle->install_task = NULL;
|
||||
pfd_switch_cores_handle->list_size = 0;
|
||||
pfd_switch_cores_handle->list_index = 0;
|
||||
pfd_switch_cores_handle->installed_index = 0;
|
||||
pfd_switch_cores_handle->status = PLAY_FEATURE_DELIVERY_SWITCH_CORES_BEGIN;
|
||||
|
||||
if (!pfd_switch_cores_handle->core_list)
|
||||
goto error;
|
||||
|
||||
/* Create task */
|
||||
task = task_init();
|
||||
|
||||
if (!task)
|
||||
goto error;
|
||||
|
||||
/* Configure task */
|
||||
task->handler = task_play_feature_delivery_switch_cores_handler;
|
||||
task->state = pfd_switch_cores_handle;
|
||||
task->title = strdup(msg_hash_to_str(MSG_SCANNING_CORES));
|
||||
task->alternative_look = true;
|
||||
task->progress = 0;
|
||||
|
||||
/* Push task */
|
||||
task_queue_push(task);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
@ -1774,7 +2241,7 @@ error:
|
||||
}
|
||||
|
||||
/* Clean up handle */
|
||||
free_play_feature_delivery_install_handle(pfd_install_handle);
|
||||
free_play_feature_delivery_switch_cores_handle(pfd_switch_cores_handle);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -97,9 +97,13 @@ void task_push_update_installed_cores(
|
||||
const char *path_dir_libretro,
|
||||
const char *path_dir_core_assets);
|
||||
#if defined(ANDROID)
|
||||
void task_push_play_feature_delivery_core_install(
|
||||
void *task_push_play_feature_delivery_core_install(
|
||||
core_updater_list_t* core_list,
|
||||
const char *filename);
|
||||
const char *filename,
|
||||
bool mute);
|
||||
void task_push_play_feature_delivery_switch_installed_cores(
|
||||
const char *path_dir_libretro,
|
||||
const char *path_libretro_info);
|
||||
#endif
|
||||
|
||||
bool task_push_pl_entry_thumbnail_download(
|
||||
|
Loading…
Reference in New Issue
Block a user