mirror of https://git.suyu.dev/suyu/suyu
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> {
|
||||
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"},
|
||||
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
|
||||
user_id{user_id_} {
|
||||
profile_manager{profile_manager_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
|
@ -545,7 +546,7 @@ private:
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<u64>(user_id.Hash());
|
||||
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||
}
|
||||
|
||||
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
|
||||
|
@ -575,17 +576,20 @@ private:
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<u64>(user_id.Hash());
|
||||
rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
|
||||
}
|
||||
|
||||
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
profile_manager->StoreOpenedUsers();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
|
||||
Common::UUID user_id{};
|
||||
std::shared_ptr<ProfileManager> profile_manager;
|
||||
};
|
||||
|
||||
// 6.0.0+
|
||||
|
@ -790,7 +794,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
|||
LOG_DEBUG(Service_ACC, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
|
||||
rb.PushIpcInterface<IManagerForApplication>(system, profile_manager);
|
||||
}
|
||||
|
||||
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
|
||||
|
@ -849,22 +853,10 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
|
|||
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) {
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
// TODO(ogniK): Handle open contexts
|
||||
ctx.WriteBuffer(profile_manager->GetOpenUsers());
|
||||
ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx);
|
||||
void GetProfileEditor(Kernel::HLERequestContext& ctx);
|
||||
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
|
||||
void LoadOpenContext(Kernel::HLERequestContext& ctx);
|
||||
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
|
||||
void StoreSaveDataThumbnailApplication(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"},
|
||||
{111, nullptr, "ClearSaveDataThumbnail"},
|
||||
{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+
|
||||
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
|
||||
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
|
||||
|
|
|
@ -261,6 +261,31 @@ UUID ProfileManager::GetLastOpenedUser() const {
|
|||
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.
|
||||
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
||||
UserData& data) const {
|
||||
|
|
|
@ -86,6 +86,8 @@ public:
|
|||
UserIDArray GetOpenUsers() const;
|
||||
UserIDArray GetAllUsers() const;
|
||||
Common::UUID GetLastOpenedUser() const;
|
||||
UserIDArray GetStoredOpenedUsers() const;
|
||||
void StoreOpenedUsers();
|
||||
|
||||
bool CanSystemRegisterUser() const;
|
||||
|
||||
|
@ -101,6 +103,7 @@ private:
|
|||
bool RemoveProfileAtIndex(std::size_t index);
|
||||
|
||||
std::array<ProfileInfo, MAX_USERS> profiles{};
|
||||
std::array<ProfileInfo, MAX_USERS> stored_opened_profiles{};
|
||||
std::size_t user_count{};
|
||||
Common::UUID last_opened_user{};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue