From 19c5cf9c637d7fb685ca6977fb7cbf06e075cedf Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 9 Oct 2018 22:35:02 -0400 Subject: [PATCH] acc: Load user images from config dir --- src/core/hle/service/acc/acc.cpp | 54 ++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index e61748ca38..0149ea8b3d 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -3,8 +3,11 @@ // Refer to the license.txt file included. #include +#include "common/common_paths.h" #include "common/common_types.h" +#include "common/file_util.h" #include "common/logging/log.h" +#include "common/string_util.h" #include "common/swap.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" @@ -16,6 +19,9 @@ #include "core/hle/service/acc/profile_manager.h" namespace Service::Account { + +constexpr u32 MAX_JPEG_IMAGE_SIZE = 0x20000; + // TODO: RE this structure struct UserData { INSERT_PADDING_WORDS(1); @@ -27,6 +33,11 @@ struct UserData { }; static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); +static std::string GetImagePath(const std::string& username) { + return FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "users" + DIR_SEP + username + + ".jpg"; +} + class IProfile final : public ServiceFramework { public: explicit IProfile(UUID user_id, ProfileManager& profile_manager) @@ -38,6 +49,15 @@ public: {11, &IProfile::LoadImage, "LoadImage"}, }; RegisterHandlers(functions); + + ProfileBase profile_base{}; + if (profile_manager.GetProfileBase(user_id, profile_base)) { + image = std::make_unique( + GetImagePath(Common::StringFromFixedZeroTerminatedBuffer( + reinterpret_cast(profile_base.username.data()), + profile_base.username.size())), + "rb"); + } } private: @@ -73,11 +93,11 @@ private: } void LoadImage(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_DEBUG(Service_ACC, "called"); // smallest jpeg https://github.com/mathiasbynens/small/blob/master/jpeg.jpg - // TODO(mailwl): load actual profile image from disk, width 256px, max size 0x20000 - constexpr u32 jpeg_size = 107; - static constexpr std::array jpeg{ + // used as a backup should the one on disk not exist + constexpr u32 backup_jpeg_size = 107; + static constexpr std::array backup_jpeg{ 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x06, 0x06, 0x05, 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, @@ -87,22 +107,38 @@ private: 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9, }; - ctx.WriteBuffer(jpeg); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(jpeg_size); + + if (image == nullptr) { + ctx.WriteBuffer(backup_jpeg); + rb.Push(backup_jpeg_size); + } else { + const auto size = std::min(image->GetSize(), MAX_JPEG_IMAGE_SIZE); + std::vector buffer(size); + image->ReadBytes(buffer.data(), buffer.size()); + + ctx.WriteBuffer(buffer.data(), buffer.size()); + rb.Push(buffer.size()); + } } void GetImageSize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - constexpr u32 jpeg_size = 107; + LOG_DEBUG(Service_ACC, "called"); + constexpr u32 backup_jpeg_size = 107; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(jpeg_size); + + if (image == nullptr) + rb.Push(backup_jpeg_size); + else + rb.Push(std::min(image->GetSize(), MAX_JPEG_IMAGE_SIZE)); } const ProfileManager& profile_manager; UUID user_id; ///< The user id this profile refers to. + std::unique_ptr image = nullptr; }; class IManagerForApplication final : public ServiceFramework {