Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions command.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ enum event_command
#ifdef HAVE_CLOUDSYNC
/* Trigger cloud sync */
CMD_EVENT_CLOUD_SYNC,
/* Resolve cloud sync conflicts by keeping local files */
CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
/* Resolve cloud sync conflicts by keeping server files */
CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
#endif
/* Shutdown the OS */
CMD_EVENT_SHUTDOWN,
Expand Down
8 changes: 8 additions & 0 deletions intl/msg_hash_lbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,14 @@ MSG_HASH(
MENU_ENUM_LABEL_CLOUD_SYNC_SYNC_NOW,
"cloud_sync_sync_now"
)
MSG_HASH(
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
"cloud_sync_resolve_keep_local"
)
MSG_HASH(
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
"cloud_sync_resolve_keep_server"
)
MSG_HASH(
MENU_ENUM_LABEL_RDB_ENTRY,
"rdb_entry"
Expand Down
16 changes: 16 additions & 0 deletions intl/msg_hash_us.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,22 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_CLOUD_SYNC_SYNC_NOW,
"Manually trigger cloud synchronization."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
"Resolve Conflicts: Keep Local"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
"Resolve all conflicts by uploading local files to the server."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
"Resolve Conflicts: Keep Server"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
"Resolve all conflicts by downloading server files, replacing local copies."
)
MSG_HASH(
MENU_ENUM_SUBLABEL_QUIT_RETROARCH_NOSAVE,
"Quit RetroArch application. Configuration save on exit is disabled."
Expand Down
8 changes: 8 additions & 0 deletions menu/cbs/menu_cbs_sublabel.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,8 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_list_unload, MENU_
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)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_sync_now, MENU_ENUM_SUBLABEL_CLOUD_SYNC_SYNC_NOW)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_resolve_keep_local, MENU_ENUM_SUBLABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_resolve_keep_server, MENU_ENUM_SUBLABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER)
#if defined(ANDROID)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_switch_installed_cores_pfd, MENU_ENUM_SUBLABEL_SWITCH_INSTALLED_CORES_PFD)
#endif
Expand Down Expand Up @@ -4632,6 +4634,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_CLOUD_SYNC_SYNC_NOW:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_sync_now);
break;
case MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_resolve_keep_local);
break;
case MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_resolve_keep_server);
break;
#if defined(ANDROID)
case MENU_ENUM_LABEL_SWITCH_INSTALLED_CORES_PFD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_switch_installed_cores_pfd);
Expand Down
17 changes: 17 additions & 0 deletions menu/menu_displaylist.c
Original file line number Diff line number Diff line change
Expand Up @@ -11116,6 +11116,23 @@ unsigned menu_displaylist_build_list(
false) == 0)
count++;
}

/* Add action items when cloud sync is enabled */
if (settings->bools.cloud_sync_enable)
{
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_CLOUD_SYNC_SYNC_NOW,
PARSE_ACTION, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
PARSE_ACTION, false) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
PARSE_ACTION, false) == 0)
count++;
}
}
break;
#ifdef HAVE_MIST
Expand Down
21 changes: 21 additions & 0 deletions menu/menu_setting.c
Original file line number Diff line number Diff line change
Expand Up @@ -10222,6 +10222,24 @@ static bool setting_append_list(
&subgroup_info,
parent_group);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_CLOUD_SYNC);

CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
MENU_ENUM_LABEL_VALUE_CLOUD_SYNC_RESOLVE_KEEP_LOCAL,
&group_info,
&subgroup_info,
parent_group);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_LOCAL);

CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
MENU_ENUM_LABEL_VALUE_CLOUD_SYNC_RESOLVE_KEEP_SERVER,
&group_info,
&subgroup_info,
parent_group);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_SERVER);
#endif

CONFIG_ACTION(
Expand Down Expand Up @@ -11795,6 +11813,9 @@ static bool setting_append_list(
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
(*list)[list_info->index - 1].action_ok = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_left = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = &setting_bool_action_right_with_refresh;

CONFIG_BOOL(
list, list_info,
Expand Down
2 changes: 2 additions & 0 deletions msg_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -3302,6 +3302,8 @@ enum msg_hash_enums
MENU_LABEL(CLOUD_SYNC_USERNAME),
MENU_LABEL(CLOUD_SYNC_PASSWORD),
MENU_LABEL(CLOUD_SYNC_SYNC_NOW),
MENU_LABEL(CLOUD_SYNC_RESOLVE_KEEP_LOCAL),
MENU_LABEL(CLOUD_SYNC_RESOLVE_KEEP_SERVER),
MENU_LABEL(RECORDING_SETTINGS),
MENU_LABEL(OVERLAY_SETTINGS),
MENU_LABEL(REWIND_SETTINGS),
Expand Down
6 changes: 6 additions & 0 deletions retroarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -4641,6 +4641,12 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_CLOUD_SYNC:
task_push_cloud_sync();
break;
case CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_LOCAL:
task_push_cloud_sync_resolve_keep_local();
break;
case CMD_EVENT_CLOUD_SYNC_RESOLVE_KEEP_SERVER:
task_push_cloud_sync_resolve_keep_server();
break;
#endif
case CMD_EVENT_MENU_RESET_TO_DEFAULT_CONFIG:
config_set_defaults(global_get_ptr());
Expand Down
63 changes: 48 additions & 15 deletions tasks/task_cloudsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,19 @@ typedef struct
bool need_manifest_uploaded;
bool failures;
bool conflicts;
/* Conflict resolution mode: 0=none, 1=keep_local, 2=keep_server */
int conflict_resolution;
uint32_t uploads;
uint32_t downloads;
retro_time_t start_time;
} task_cloud_sync_state_t;

static slock_t *tcs_running_lock = NULL;

/* Forward declarations for conflict resolution */
static void task_cloud_sync_upload_current_file(task_cloud_sync_state_t *sync_state);
static void task_cloud_sync_fetch_server_file(task_cloud_sync_state_t *sync_state);

static void task_cloud_sync_begin_handler(void *user_data, const char *path, bool success, RFILE *file)
{
retro_task_t *task = (retro_task_t *)user_data;
Expand Down Expand Up @@ -680,19 +686,28 @@ static void task_cloud_sync_fetch_server_file(task_cloud_sync_state_t *sync_stat

static void task_cloud_sync_resolve_conflict(task_cloud_sync_state_t *sync_state)
{
/*
* rather than pop up some UI let's just resolve it ourselves!
* three options:
* 1. rename the server file and replace it
* 2. rename the local file and replace it
* 3. ignore it
* If we ignore it then we need to keep it out of the new local manifest
*/
struct item_file *server_file = &sync_state->server_manifest->list[sync_state->server_idx];
RARCH_WARN(CSPFX "Conflicting change of %s.\n", CS_FILE_KEY(server_file));
task_cloud_sync_add_to_updated_manifest(sync_state, CS_FILE_KEY(server_file), CS_FILE_HASH(server_file), true);
/* no need to mark need_manifest_uploaded, nothing changed */
sync_state->conflicts = true;

if (sync_state->conflict_resolution == 1)
{
/* Keep local: upload local file to server */
RARCH_LOG(CSPFX "Conflict on %s, keeping local.\n", CS_FILE_KEY(server_file));
task_cloud_sync_upload_current_file(sync_state);
}
else if (sync_state->conflict_resolution == 2)
{
/* Keep server: download server file */
RARCH_LOG(CSPFX "Conflict on %s, keeping server.\n", CS_FILE_KEY(server_file));
task_cloud_sync_fetch_server_file(sync_state);
}
else
{
/* Default: ignore the conflict, keep file out of local manifest */
RARCH_WARN(CSPFX "Conflicting change of %s.\n", CS_FILE_KEY(server_file));
task_cloud_sync_add_to_updated_manifest(sync_state, CS_FILE_KEY(server_file), CS_FILE_HASH(server_file), true);
/* no need to mark need_manifest_uploaded, nothing changed */
sync_state->conflicts = true;
}
}

static void task_cloud_sync_upload_cb(void *user_data, const char *path, bool success, RFILE *file)
Expand Down Expand Up @@ -1333,7 +1348,7 @@ static bool task_cloud_sync_task_finder(retro_task_t *task, void *user_data)
return task->handler == task_cloud_sync_task_handler;
}

void task_push_cloud_sync(void)
static void task_push_cloud_sync_with_mode(int conflict_resolution)
{
char task_title[128];
task_finder_data_t find_data;
Expand Down Expand Up @@ -1364,8 +1379,9 @@ void task_push_cloud_sync(void)
return;
}

sync_state->phase = CLOUD_SYNC_PHASE_BEGIN;
sync_state->start_time = cpu_features_get_time_usec();
sync_state->phase = CLOUD_SYNC_PHASE_BEGIN;
sync_state->start_time = cpu_features_get_time_usec();
sync_state->conflict_resolution = conflict_resolution;

strlcpy(task_title, "Cloud Sync in progress", sizeof(task_title));

Expand All @@ -1377,6 +1393,11 @@ void task_push_cloud_sync(void)
task_queue_push(task);
}

void task_push_cloud_sync(void)
{
task_push_cloud_sync_with_mode(0);
}

void task_push_cloud_sync_update_driver(void)
{
char manifest_path[PATH_MAX_LENGTH];
Expand All @@ -1392,3 +1413,15 @@ void task_push_cloud_sync_update_driver(void)
task_cloud_sync_manifest_filename(manifest_path, sizeof(manifest_path), false);
filestream_delete(manifest_path);
}

void task_push_cloud_sync_resolve_keep_local(void)
{
RARCH_LOG(CSPFX "Starting sync with conflict resolution: keep local.\n");
task_push_cloud_sync_with_mode(1);
}

void task_push_cloud_sync_resolve_keep_server(void)
{
RARCH_LOG(CSPFX "Starting sync with conflict resolution: keep server.\n");
task_push_cloud_sync_with_mode(2);
}
2 changes: 2 additions & 0 deletions tasks/tasks_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ extern const char* const input_builtin_autoconfs[];
/* cloud sync tasks */
void task_push_cloud_sync_update_driver(void);
void task_push_cloud_sync(void);
void task_push_cloud_sync_resolve_keep_local(void);
void task_push_cloud_sync_resolve_keep_server(void);

RETRO_END_DECLS

Expand Down
Loading