diff options
Diffstat (limited to 'src/core/hle/service/acc/acc.cpp')
-rw-r--r-- | src/core/hle/service/acc/acc.cpp | 126 |
1 files changed, 64 insertions, 62 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index f3c5b1b9c..979f2f892 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -3,7 +3,10 @@ // Refer to the license.txt file included. #include <array> +#include "common/common_types.h" #include "common/logging/log.h" +#include "common/swap.h" +#include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc_aa.h" @@ -13,7 +16,6 @@ #include "core/settings.h" namespace Service::Account { - // TODO: RE this structure struct UserData { INSERT_PADDING_WORDS(1); @@ -25,19 +27,13 @@ struct UserData { }; static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); -struct ProfileBase { - u128 user_id; - u64 timestamp; - std::array<u8, 0x20> username; -}; -static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); - // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? -static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; +static UUID DEFAULT_USER_ID{1ull, 0ull}; class IProfile final : public ServiceFramework<IProfile> { public: - explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { + explicit IProfile(UUID user_id, ProfileManager& profile_manager) + : ServiceFramework("IProfile"), user_id(user_id), profile_manager(profile_manager) { static const FunctionInfo functions[] = { {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, @@ -49,38 +45,34 @@ public: private: void Get(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { - std::copy_n(Settings::values.username.begin(), profile_base.username.size(), - profile_base.username.begin()); + std::array<u8, MAX_DATA> data{}; + if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { + ctx.WriteBuffer(data); + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); } else { - std::copy(Settings::values.username.begin(), Settings::values.username.end(), - profile_base.username.begin()); + LOG_ERROR(Service_ACC, "Failed to get profile base and data for user={}", + user_id.Format()); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } void GetBase(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - - // TODO(Subv): Retrieve this information from somewhere. + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { - std::copy_n(Settings::values.username.begin(), profile_base.username.size(), - profile_base.username.begin()); + if (profile_manager.GetProfileBase(user_id, profile_base)) { + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); } else { - std::copy(Settings::values.username.begin(), Settings::values.username.end(), - profile_base.username.begin()); + LOG_ERROR(Service_ACC, "Failed to get profile base for user={}", user_id.Format()); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } void LoadImage(Kernel::HLERequestContext& ctx) { @@ -104,7 +96,8 @@ private: rb.Push<u32>(jpeg_size); } - u128 user_id; ///< The user id this profile refers to. + const ProfileManager& profile_manager; + UUID user_id; ///< The user id this profile refers to. }; class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { @@ -141,44 +134,57 @@ private: }; void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_INFO(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push<u32>(1); + rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount())); } void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + UUID user_id = rp.PopRaw<UUID>(); + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(true); // TODO: Check when this is supposed to return true and when not + rb.Push(profile_manager->UserExists(user_id)); } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector<u128> user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetAllUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector<u128> user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetOpenUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } +void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<UUID>(profile_manager->GetLastOpenedUser()); +} + void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - u128 user_id = rp.PopRaw<u128>(); + UUID user_id = rp.PopRaw<UUID>(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IProfile>(user_id); - LOG_DEBUG(Service_ACC, "called user_id=0x{:016X}{:016X}", user_id[1], user_id[0]); + rb.PushIpcInterface<IProfile>(user_id, *profile_manager); + LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); +} + +void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(profile_manager->CanSystemRegisterUser()); } void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { @@ -194,22 +200,18 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); } -void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(DEFAULT_USER_ID); -} - -Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) - : ServiceFramework(name), module(std::move(module)) {} +Module::Interface::Interface(std::shared_ptr<Module> module, + std::shared_ptr<ProfileManager> profile_manager, const char* name) + : ServiceFramework(name), module(std::move(module)), + profile_manager(std::move(profile_manager)) {} void InstallInterfaces(SM::ServiceManager& service_manager) { auto module = std::make_shared<Module>(); - std::make_shared<ACC_AA>(module)->InstallAsService(service_manager); - std::make_shared<ACC_SU>(module)->InstallAsService(service_manager); - std::make_shared<ACC_U0>(module)->InstallAsService(service_manager); - std::make_shared<ACC_U1>(module)->InstallAsService(service_manager); + auto profile_manager = std::make_shared<ProfileManager>(); + std::make_shared<ACC_AA>(module, profile_manager)->InstallAsService(service_manager); + std::make_shared<ACC_SU>(module, profile_manager)->InstallAsService(service_manager); + std::make_shared<ACC_U0>(module, profile_manager)->InstallAsService(service_manager); + std::make_shared<ACC_U1>(module, profile_manager)->InstallAsService(service_manager); } } // namespace Service::Account |