core: hle: service: acc: Fix ListOpenContextStoredUsers/StoreOpenContext.
- These APIs are used to capture the opened users and allow that state to be persisted across processes. - They are not intended to just return the system opened users, that is what ListOpenUsers is for. - Fixes the launch hang with Bayonetta 3.
This commit is contained in:
parent
83f649240e
commit
75ab52f05b
|
@ -512,10 +512,11 @@ protected:
|
||||||
|
|
||||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||||
public:
|
public:
|
||||||
explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
|
explicit IManagerForApplication(Core::System& system_,
|
||||||
|
const std::shared_ptr<ProfileManager>& profile_manager_)
|
||||||
: ServiceFramework{system_, "IManagerForApplication"},
|
: ServiceFramework{system_, "IManagerForApplication"},
|
||||||
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
|
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
|
||||||
user_id{user_id_} {
|
profile_manager{profile_manager_} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||||
|
@ -545,7 +546,7 @@ private:
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushRaw<u64>(user_id.Hash());
|
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
|
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
|
||||||
|
@ -575,17 +576,20 @@ private:
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushRaw<u64>(user_id.Hash());
|
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
|
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
LOG_DEBUG(Service_ACC, "called");
|
||||||
|
|
||||||
|
profile_manager->StoreOpenedUsers();
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
|
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
|
||||||
Common::UUID user_id{};
|
std::shared_ptr<ProfileManager> profile_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 6.0.0+
|
// 6.0.0+
|
||||||
|
@ -790,7 +794,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
||||||
LOG_DEBUG(Service_ACC, "called");
|
LOG_DEBUG(Service_ACC, "called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
||||||
|
@ -849,22 +853,10 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
|
|
||||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
|
||||||
|
|
||||||
// This is similar to GetBaasAccountManagerForApplication
|
|
||||||
// This command is used concurrently with ListOpenContextStoredUsers
|
|
||||||
// TODO: Find the differences between this and GetBaasAccountManagerForApplication
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
LOG_DEBUG(Service_ACC, "called");
|
||||||
|
|
||||||
// TODO(ogniK): Handle open contexts
|
ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers());
|
||||||
ctx.WriteBuffer(profile_manager->GetOpenUsers());
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ public:
|
||||||
void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx);
|
void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx);
|
||||||
void GetProfileEditor(Kernel::HLERequestContext& ctx);
|
void GetProfileEditor(Kernel::HLERequestContext& ctx);
|
||||||
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
||||||
void LoadOpenContext(Kernel::HLERequestContext& ctx);
|
|
||||||
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
|
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
|
||||||
void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx);
|
void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx);
|
||||||
void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx);
|
void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
|
|
@ -28,7 +28,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
|
||||||
{110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
|
{110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
|
||||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||||
{120, nullptr, "CreateGuestLoginRequest"},
|
{120, nullptr, "CreateGuestLoginRequest"},
|
||||||
{130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+
|
{130, nullptr, "LoadOpenContext"}, // 5.0.0+
|
||||||
{131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
|
{131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
|
||||||
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
|
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
|
||||||
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
||||||
|
|
|
@ -261,6 +261,31 @@ UUID ProfileManager::GetLastOpenedUser() const {
|
||||||
return last_opened_user;
|
return last_opened_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the list of stored opened users.
|
||||||
|
UserIDArray ProfileManager::GetStoredOpenedUsers() const {
|
||||||
|
UserIDArray output{};
|
||||||
|
std::ranges::transform(stored_opened_profiles, output.begin(), [](const ProfileInfo& p) {
|
||||||
|
if (p.is_open)
|
||||||
|
return p.user_uuid;
|
||||||
|
return Common::InvalidUUID;
|
||||||
|
});
|
||||||
|
std::stable_partition(output.begin(), output.end(),
|
||||||
|
[](const UUID& uuid) { return uuid.IsValid(); });
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Captures the opened users, which can be queried across process launches with
|
||||||
|
/// ListOpenContextStoredUsers.
|
||||||
|
void ProfileManager::StoreOpenedUsers() {
|
||||||
|
size_t profile_index{};
|
||||||
|
stored_opened_profiles = {};
|
||||||
|
std::for_each(profiles.begin(), profiles.end(), [&](const auto& profile) {
|
||||||
|
if (profile.is_open) {
|
||||||
|
stored_opened_profiles[profile_index++] = profile;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the users profile base and the unknown arbitary data.
|
/// Return the users profile base and the unknown arbitary data.
|
||||||
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
||||||
UserData& data) const {
|
UserData& data) const {
|
||||||
|
|
|
@ -86,6 +86,8 @@ public:
|
||||||
UserIDArray GetOpenUsers() const;
|
UserIDArray GetOpenUsers() const;
|
||||||
UserIDArray GetAllUsers() const;
|
UserIDArray GetAllUsers() const;
|
||||||
Common::UUID GetLastOpenedUser() const;
|
Common::UUID GetLastOpenedUser() const;
|
||||||
|
UserIDArray GetStoredOpenedUsers() const;
|
||||||
|
void StoreOpenedUsers();
|
||||||
|
|
||||||
bool CanSystemRegisterUser() const;
|
bool CanSystemRegisterUser() const;
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ private:
|
||||||
bool RemoveProfileAtIndex(std::size_t index);
|
bool RemoveProfileAtIndex(std::size_t index);
|
||||||
|
|
||||||
std::array<ProfileInfo, MAX_USERS> profiles{};
|
std::array<ProfileInfo, MAX_USERS> profiles{};
|
||||||
|
std::array<ProfileInfo, MAX_USERS> stored_opened_profiles{};
|
||||||
std::size_t user_count{};
|
std::size_t user_count{};
|
||||||
Common::UUID last_opened_user{};
|
Common::UUID last_opened_user{};
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue