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:
Autechre 2020-09-03 01:55:39 +02:00 committed by GitHub
commit b7fff53d16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 610 additions and 32 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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
{

View File

@ -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"

View File

@ -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: "

View File

@ -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},

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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(