mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
Keep sign-in dialogs active until user dismissal through shared system presentation
This commit is contained in:
+122
-88
@@ -14,6 +14,81 @@
|
||||
// NOLINTNEXTLINE(modernize-concat-nested-namespaces)
|
||||
namespace Libs::Dialog {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int DIALOG_STATUS_RUNNING = 2;
|
||||
constexpr int DIALOG_STATUS_FINISHED = 3;
|
||||
|
||||
struct DialogState {
|
||||
int status = 0;
|
||||
uint64_t generation = 0;
|
||||
};
|
||||
|
||||
std::mutex g_dialog_mutex;
|
||||
DialogState g_error;
|
||||
DialogState g_signin;
|
||||
uint64_t g_dialog_generation = 0;
|
||||
uint64_t g_dialog_revision = 0;
|
||||
int32_t g_error_code = 0;
|
||||
void (*g_dialog_visibility_callback)() = nullptr;
|
||||
|
||||
void SetDialogStatus(DialogState& dialog, int status, std::unique_lock<std::mutex>& lock) {
|
||||
const bool visibility_changed =
|
||||
(dialog.status == DIALOG_STATUS_RUNNING) != (status == DIALOG_STATUS_RUNNING);
|
||||
dialog.status = status;
|
||||
if (visibility_changed) {
|
||||
g_dialog_revision++;
|
||||
if (status == DIALOG_STATUS_RUNNING) {
|
||||
dialog.generation = ++g_dialog_generation;
|
||||
}
|
||||
}
|
||||
const auto callback = visibility_changed ? g_dialog_visibility_callback : nullptr;
|
||||
lock.unlock();
|
||||
if (callback != nullptr) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace SystemDialog {
|
||||
|
||||
bool GetHostSnapshot(HostSnapshot* snapshot) {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status == DIALOG_STATUS_RUNNING) {
|
||||
*snapshot = {Kind::Signin, g_signin.generation, 0};
|
||||
return true;
|
||||
}
|
||||
if (g_error.status == DIALOG_STATUS_RUNNING) {
|
||||
*snapshot = {Kind::Error, g_error.generation, g_error_code};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VisualState GetVisualState() noexcept {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
const bool signin = g_signin.status == DIALOG_STATUS_RUNNING;
|
||||
return {g_error.status == DIALOG_STATUS_RUNNING || signin, signin, g_dialog_revision};
|
||||
}
|
||||
|
||||
void SetVisibilityCallback(void (*callback)()) {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
g_dialog_visibility_callback = callback;
|
||||
}
|
||||
|
||||
bool HostClose(uint64_t generation) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
auto& dialog = g_signin.status == DIALOG_STATUS_RUNNING ? g_signin : g_error;
|
||||
if (dialog.status != DIALOG_STATUS_RUNNING || generation != dialog.generation) {
|
||||
return false;
|
||||
}
|
||||
SetDialogStatus(dialog, DIALOG_STATUS_FINISHED, lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace SystemDialog
|
||||
|
||||
namespace CommonDialog {
|
||||
|
||||
LIB_NAME("CommonDialog", "CommonDialog");
|
||||
@@ -207,6 +282,7 @@ constexpr int SIGNIN_ERROR_NOT_INITIALIZED = static_cast<int>(0x81350001u);
|
||||
constexpr int SIGNIN_ERROR_ALREADY_INITIALIZED = static_cast<int>(0x81350002u);
|
||||
constexpr int SIGNIN_ERROR_PARAM_INVALID = static_cast<int>(0x81350003u);
|
||||
constexpr int SIGNIN_ERROR_INVALID_STATE = static_cast<int>(0x81350005u);
|
||||
constexpr int SIGNIN_ERROR_INVALID_USER_ID = static_cast<int>(0x81350007u);
|
||||
|
||||
struct SigninDialogResult {
|
||||
int32_t result;
|
||||
@@ -222,70 +298,78 @@ struct SigninDialogParam {
|
||||
static_assert(sizeof(SigninDialogResult) == 16);
|
||||
static_assert(sizeof(SigninDialogParam) == 16);
|
||||
|
||||
static int g_signin_status = SIGNIN_STATUS_NONE;
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogInitialize() {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status != SIGNIN_STATUS_NONE) {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status != SIGNIN_STATUS_NONE) {
|
||||
return SIGNIN_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
g_signin_status = SIGNIN_STATUS_INITIALIZED;
|
||||
g_signin.status = SIGNIN_STATUS_INITIALIZED;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogTerminate() {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status == SIGNIN_STATUS_NONE) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status == SIGNIN_STATUS_NONE) {
|
||||
return SIGNIN_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
g_signin_status = SIGNIN_STATUS_NONE;
|
||||
SetDialogStatus(g_signin, SIGNIN_STATUS_NONE, lock);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogOpen(const void* param) {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status != SIGNIN_STATUS_INITIALIZED && g_signin_status != SIGNIN_STATUS_FINISHED) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status == SIGNIN_STATUS_NONE) {
|
||||
return SIGNIN_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (g_signin.status != SIGNIN_STATUS_INITIALIZED && g_signin.status != SIGNIN_STATUS_FINISHED) {
|
||||
return SIGNIN_ERROR_INVALID_STATE;
|
||||
}
|
||||
if (param == nullptr ||
|
||||
static_cast<const SigninDialogParam*>(param)->size != sizeof(SigninDialogParam)) {
|
||||
if (param == nullptr) {
|
||||
return SIGNIN_ERROR_PARAM_INVALID;
|
||||
}
|
||||
g_signin_status = SIGNIN_STATUS_RUNNING;
|
||||
const auto* p = static_cast<const SigninDialogParam*>(param);
|
||||
if (p->size != sizeof(SigninDialogParam) || p->reserved[0] != 0 || p->reserved[1] != 0) {
|
||||
return SIGNIN_ERROR_PARAM_INVALID;
|
||||
}
|
||||
if (p->user_id != Config::GetUserId()) {
|
||||
return SIGNIN_ERROR_INVALID_USER_ID;
|
||||
}
|
||||
SetDialogStatus(g_signin, SIGNIN_STATUS_RUNNING, lock);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogClose() {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status == SIGNIN_STATUS_NONE) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status == SIGNIN_STATUS_NONE) {
|
||||
return SIGNIN_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (g_signin_status != SIGNIN_STATUS_RUNNING && g_signin_status != SIGNIN_STATUS_FINISHED) {
|
||||
return SIGNIN_ERROR_INVALID_STATE;
|
||||
}
|
||||
g_signin_status = SIGNIN_STATUS_FINISHED;
|
||||
SetDialogStatus(g_signin, SIGNIN_STATUS_FINISHED, lock);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogUpdateStatus() {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status == SIGNIN_STATUS_RUNNING) {
|
||||
g_signin_status = SIGNIN_STATUS_FINISHED;
|
||||
}
|
||||
return g_signin_status;
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
return g_signin.status;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogGetStatus() {
|
||||
PRINT_NAME();
|
||||
return g_signin_status;
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
return g_signin.status;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI SigninDialogGetResult(void* result) {
|
||||
PRINT_NAME();
|
||||
if (g_signin_status == SIGNIN_STATUS_NONE) {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
if (g_signin.status == SIGNIN_STATUS_NONE) {
|
||||
return SIGNIN_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
if (g_signin_status != SIGNIN_STATUS_FINISHED) {
|
||||
if (g_signin.status != SIGNIN_STATUS_FINISHED) {
|
||||
return SIGNIN_ERROR_INVALID_STATE;
|
||||
}
|
||||
if (result == nullptr) {
|
||||
@@ -661,64 +745,15 @@ struct ErrorDialogParam {
|
||||
|
||||
static_assert(sizeof(ErrorDialogParam) == 16);
|
||||
|
||||
static std::mutex g_error_mutex;
|
||||
static int g_error_status = STATUS_NONE;
|
||||
static uint64_t g_error_generation = 0;
|
||||
static uint64_t g_error_revision = 0;
|
||||
static int32_t g_error_code = 0;
|
||||
static void (*g_error_visibility_callback)() = nullptr;
|
||||
|
||||
static void SetStatus(int status, std::unique_lock<std::mutex>& lock) {
|
||||
const bool visibility_changed =
|
||||
(g_error_status == STATUS_RUNNING) != (status == STATUS_RUNNING);
|
||||
g_error_status = status;
|
||||
if (visibility_changed) {
|
||||
g_error_revision++;
|
||||
}
|
||||
const auto callback = visibility_changed ? g_error_visibility_callback : nullptr;
|
||||
lock.unlock();
|
||||
if (callback != nullptr) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
bool GetHostSnapshot(HostSnapshot* snapshot) {
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
if (g_error_status != STATUS_RUNNING) {
|
||||
return false;
|
||||
}
|
||||
*snapshot = {g_error_generation, g_error_code};
|
||||
return true;
|
||||
}
|
||||
|
||||
VisualState GetVisualState() noexcept {
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
return {g_error_status == STATUS_RUNNING, g_error_revision};
|
||||
}
|
||||
|
||||
void SetVisibilityCallback(void (*callback)()) {
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
g_error_visibility_callback = callback;
|
||||
}
|
||||
|
||||
bool HostAccept(uint64_t generation) {
|
||||
std::unique_lock lock(g_error_mutex);
|
||||
if (g_error_status != STATUS_RUNNING || generation != g_error_generation) {
|
||||
return false;
|
||||
}
|
||||
SetStatus(STATUS_FINISHED, lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI ErrorDialogInitialize() {
|
||||
PRINT_NAME();
|
||||
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
if (g_error_status != STATUS_NONE) {
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
if (g_error.status != STATUS_NONE) {
|
||||
return ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
g_error_status = STATUS_INITIALIZED;
|
||||
g_error.status = STATUS_INITIALIZED;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -726,8 +761,8 @@ int KYTY_SYSV_ABI ErrorDialogInitialize() {
|
||||
int KYTY_SYSV_ABI ErrorDialogOpen(const void* param) {
|
||||
PRINT_NAME();
|
||||
|
||||
std::unique_lock lock(g_error_mutex);
|
||||
if (g_error_status != STATUS_INITIALIZED && g_error_status != STATUS_FINISHED) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_error.status != STATUS_INITIALIZED && g_error.status != STATUS_FINISHED) {
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
if (param == nullptr) {
|
||||
@@ -745,8 +780,7 @@ int KYTY_SYSV_ABI ErrorDialogOpen(const void* param) {
|
||||
p->size, static_cast<uint32_t>(p->error_code), p->user_id);
|
||||
|
||||
g_error_code = p->error_code;
|
||||
g_error_generation++;
|
||||
SetStatus(STATUS_RUNNING, lock);
|
||||
SetDialogStatus(g_error, STATUS_RUNNING, lock);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -754,12 +788,12 @@ int KYTY_SYSV_ABI ErrorDialogOpen(const void* param) {
|
||||
int KYTY_SYSV_ABI ErrorDialogClose() {
|
||||
PRINT_NAME();
|
||||
|
||||
std::unique_lock lock(g_error_mutex);
|
||||
if (g_error_status != STATUS_RUNNING) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_error.status != STATUS_RUNNING) {
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
SetStatus(STATUS_FINISHED, lock);
|
||||
SetDialogStatus(g_error, STATUS_FINISHED, lock);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -767,12 +801,12 @@ int KYTY_SYSV_ABI ErrorDialogClose() {
|
||||
int KYTY_SYSV_ABI ErrorDialogTerminate() {
|
||||
PRINT_NAME();
|
||||
|
||||
std::unique_lock lock(g_error_mutex);
|
||||
if (g_error_status == STATUS_NONE) {
|
||||
std::unique_lock lock(g_dialog_mutex);
|
||||
if (g_error.status == STATUS_NONE) {
|
||||
return ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
SetStatus(STATUS_NONE, lock);
|
||||
SetDialogStatus(g_error, STATUS_NONE, lock);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -780,15 +814,15 @@ int KYTY_SYSV_ABI ErrorDialogTerminate() {
|
||||
int KYTY_SYSV_ABI ErrorDialogUpdateStatus() {
|
||||
PRINT_NAME();
|
||||
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
return g_error_status;
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
return g_error.status;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI ErrorDialogGetStatus() {
|
||||
PRINT_NAME();
|
||||
|
||||
std::scoped_lock lock(g_error_mutex);
|
||||
return g_error_status;
|
||||
std::scoped_lock lock(g_dialog_mutex);
|
||||
return g_error.status;
|
||||
}
|
||||
|
||||
} // namespace ErrorDialog
|
||||
|
||||
+10
-2
@@ -68,22 +68,30 @@ int KYTY_SYSV_ABI MsgDialogProgressBarSetMsg(int target, const char* msg);
|
||||
|
||||
} // namespace MsgDialog
|
||||
|
||||
namespace ErrorDialog {
|
||||
namespace SystemDialog {
|
||||
|
||||
enum class Kind { Error, Signin };
|
||||
|
||||
struct HostSnapshot {
|
||||
Kind kind;
|
||||
uint64_t generation;
|
||||
int32_t error_code;
|
||||
};
|
||||
|
||||
struct VisualState {
|
||||
bool active;
|
||||
bool background;
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
bool GetHostSnapshot(HostSnapshot* snapshot);
|
||||
VisualState GetVisualState() noexcept;
|
||||
void SetVisibilityCallback(void (*callback)());
|
||||
bool HostAccept(uint64_t generation);
|
||||
bool HostClose(uint64_t generation);
|
||||
|
||||
} // namespace SystemDialog
|
||||
|
||||
namespace ErrorDialog {
|
||||
|
||||
int KYTY_SYSV_ABI ErrorDialogInitialize();
|
||||
int KYTY_SYSV_ABI ErrorDialogOpen(const void* param);
|
||||
|
||||
@@ -163,8 +163,10 @@ static int KYTY_SYSV_ABI SystemServiceGetStatus(SystemServiceStatus* status) {
|
||||
return SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
*status = SystemServiceStatus();
|
||||
status->is_system_ui_overlaid = Dialog::ErrorDialog::GetVisualState().active;
|
||||
const auto dialog = Dialog::SystemDialog::GetVisualState();
|
||||
*status = SystemServiceStatus();
|
||||
status->is_system_ui_overlaid = dialog.active;
|
||||
status->is_in_background_execution = dialog.background;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user