summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Narr the Reg2023-03-28 20:55:06 -0600
committerGravatar german772023-03-29 08:53:19 -0600
commit668eb5b8dad656c281c218ea8b4c34965b163b93 (patch)
tree5bbe7344abb001909ee32e7dd9422b1a91c72f9d /src/core
parentMerge pull request #9505 from liamwhite/request-exit (diff)
downloadyuzu-668eb5b8dad656c281c218ea8b4c34965b163b93.tar.gz
yuzu-668eb5b8dad656c281c218ea8b4c34965b163b93.tar.xz
yuzu-668eb5b8dad656c281c218ea8b4c34965b163b93.zip
service: am: Improve profile select applet
Diffstat (limited to 'src/core')
-rw-r--r--src/core/frontend/applets/profile_select.cpp3
-rw-r--r--src/core/frontend/applets/profile_select.h16
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp52
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.h102
4 files changed, 155 insertions, 18 deletions
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp
index 910d20c0d..c18f17a36 100644
--- a/src/core/frontend/applets/profile_select.cpp
+++ b/src/core/frontend/applets/profile_select.cpp
@@ -11,7 +11,8 @@ ProfileSelectApplet::~ProfileSelectApplet() = default;
11 11
12void DefaultProfileSelectApplet::Close() const {} 12void DefaultProfileSelectApplet::Close() const {}
13 13
14void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback) const { 14void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback,
15 const ProfileSelectParameters& parameters) const {
15 Service::Account::ProfileManager manager; 16 Service::Account::ProfileManager manager;
16 callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{})); 17 callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
17 LOG_INFO(Service_ACC, "called, selecting current user instead of prompting..."); 18 LOG_INFO(Service_ACC, "called, selecting current user instead of prompting...");
diff --git a/src/core/frontend/applets/profile_select.h b/src/core/frontend/applets/profile_select.h
index 76e963535..92e2737ea 100644
--- a/src/core/frontend/applets/profile_select.h
+++ b/src/core/frontend/applets/profile_select.h
@@ -5,25 +5,35 @@
5 5
6#include <functional> 6#include <functional>
7#include <optional> 7#include <optional>
8#include "common/uuid.h"
9 8
9#include "common/uuid.h"
10#include "core/frontend/applets/applet.h" 10#include "core/frontend/applets/applet.h"
11#include "core/hle/service/am/applets/applet_profile_select.h"
11 12
12namespace Core::Frontend { 13namespace Core::Frontend {
13 14
15struct ProfileSelectParameters {
16 Service::AM::Applets::UiMode mode;
17 std::array<Common::UUID, 8> invalid_uid_list;
18 Service::AM::Applets::UiSettingsDisplayOptions display_options;
19 Service::AM::Applets::UserSelectionPurpose purpose;
20};
21
14class ProfileSelectApplet : public Applet { 22class ProfileSelectApplet : public Applet {
15public: 23public:
16 using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>; 24 using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>;
17 25
18 virtual ~ProfileSelectApplet(); 26 virtual ~ProfileSelectApplet();
19 27
20 virtual void SelectProfile(SelectProfileCallback callback) const = 0; 28 virtual void SelectProfile(SelectProfileCallback callback,
29 const ProfileSelectParameters& parameters) const = 0;
21}; 30};
22 31
23class DefaultProfileSelectApplet final : public ProfileSelectApplet { 32class DefaultProfileSelectApplet final : public ProfileSelectApplet {
24public: 33public:
25 void Close() const override; 34 void Close() const override;
26 void SelectProfile(SelectProfileCallback callback) const override; 35 void SelectProfile(SelectProfileCallback callback,
36 const ProfileSelectParameters& parameters) const override;
27}; 37};
28 38
29} // namespace Core::Frontend 39} // namespace Core::Frontend
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index 07abc2563..89cb323e9 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -25,13 +25,29 @@ void ProfileSelect::Initialize() {
25 final_data.clear(); 25 final_data.clear();
26 26
27 Applet::Initialize(); 27 Applet::Initialize();
28 profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
28 29
29 const auto user_config_storage = broker.PopNormalDataToApplet(); 30 const auto user_config_storage = broker.PopNormalDataToApplet();
30 ASSERT(user_config_storage != nullptr); 31 ASSERT(user_config_storage != nullptr);
31 const auto& user_config = user_config_storage->GetData(); 32 const auto& user_config = user_config_storage->GetData();
32 33
33 ASSERT(user_config.size() >= sizeof(UserSelectionConfig)); 34 LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}",
34 std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig)); 35 profile_select_version);
36
37 switch (profile_select_version) {
38 case ProfileSelectAppletVersion::Version1:
39 ASSERT(user_config.size() == sizeof(UiSettingsV1));
40 std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1));
41 break;
42 case ProfileSelectAppletVersion::Version2:
43 case ProfileSelectAppletVersion::Version3:
44 ASSERT(user_config.size() == sizeof(UiSettings));
45 std::memcpy(&config, user_config.data(), sizeof(UiSettings));
46 break;
47 default:
48 UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
49 break;
50 }
35} 51}
36 52
37bool ProfileSelect::TransactionComplete() const { 53bool ProfileSelect::TransactionComplete() const {
@@ -52,11 +68,37 @@ void ProfileSelect::Execute() {
52 return; 68 return;
53 } 69 }
54 70
55 frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); }); 71 Core::Frontend::ProfileSelectParameters parameters{};
72
73 switch (profile_select_version) {
74 case ProfileSelectAppletVersion::Version1:
75 parameters = {
76 .mode = config_old.mode,
77 .invalid_uid_list = config_old.invalid_uid_list,
78 .display_options = config_old.display_options,
79 .purpose = UserSelectionPurpose::General,
80 };
81 break;
82 case ProfileSelectAppletVersion::Version2:
83 case ProfileSelectAppletVersion::Version3:
84 parameters = {
85 .mode = config.mode,
86 .invalid_uid_list = config.invalid_uid_list,
87 .display_options = config.display_options,
88 .purpose = config.purpose,
89 };
90 break;
91 default:
92 UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
93 break;
94 }
95
96 frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); },
97 parameters);
56} 98}
57 99
58void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { 100void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
59 UserSelectionOutput output{}; 101 UiReturnArg output{};
60 102
61 if (uuid.has_value() && uuid->IsValid()) { 103 if (uuid.has_value() && uuid->IsValid()) {
62 output.result = 0; 104 output.result = 0;
@@ -67,7 +109,7 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
67 output.uuid_selected = Common::InvalidUUID; 109 output.uuid_selected = Common::InvalidUUID;
68 } 110 }
69 111
70 final_data = std::vector<u8>(sizeof(UserSelectionOutput)); 112 final_data = std::vector<u8>(sizeof(UiReturnArg));
71 std::memcpy(final_data.data(), &output, final_data.size()); 113 std::memcpy(final_data.data(), &output, final_data.size());
72 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); 114 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
73 broker.SignalStateChanged(); 115 broker.SignalStateChanged();
diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h
index 85705c216..369f9250f 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.h
+++ b/src/core/hle/service/am/applets/applet_profile_select.h
@@ -16,19 +16,100 @@ class System;
16 16
17namespace Service::AM::Applets { 17namespace Service::AM::Applets {
18 18
19struct UserSelectionConfig { 19enum class ProfileSelectAppletVersion : u32 {
20 // TODO(DarkLordZach): RE this structure 20 Version1 = 0x1, // 1.0.0+
21 // It seems to be flags and the like that determine the UI of the applet on the switch... from 21 Version2 = 0x10000, // 2.0.0+
22 // my research this is safe to ignore for now. 22 Version3 = 0x20000, // 6.0.0+
23 INSERT_PADDING_BYTES(0xA0);
24}; 23};
25static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size.");
26 24
27struct UserSelectionOutput { 25// This is nn::account::UiMode
26enum class UiMode {
27 UserSelector,
28 UserCreator,
29 EnsureNetworkServiceAccountAvailable,
30 UserIconEditor,
31 UserNicknameEditor,
32 UserCreatorForStarter,
33 NintendoAccountAuthorizationRequestContext,
34 IntroduceExternalNetworkServiceAccount,
35 IntroduceExternalNetworkServiceAccountForRegistration,
36 NintendoAccountNnidLinker,
37 LicenseRequirementsForNetworkService,
38 LicenseRequirementsForNetworkServiceWithUserContextImpl,
39 UserCreatorForImmediateNaLoginTest,
40 UserQualificationPromoter,
41};
42
43// This is nn::account::UserSelectionPurpose
44enum class UserSelectionPurpose {
45 General,
46 GameCardRegistration,
47 EShopLaunch,
48 EShopItemShow,
49 PicturePost,
50 NintendoAccountLinkage,
51 SettingsUpdate,
52 SaveDataDeletion,
53 UserMigration,
54 SaveDataTransfer,
55};
56
57// This is nn::account::NintendoAccountStartupDialogType
58enum class NintendoAccountStartupDialogType {
59 LoginAndCreate,
60 Login,
61 Create,
62};
63
64// This is nn::account::UserSelectionSettingsForSystemService
65struct UserSelectionSettingsForSystemService {
66 UserSelectionPurpose purpose;
67 bool enable_user_creation;
68 INSERT_PADDING_BYTES(0x3);
69};
70static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8,
71 "UserSelectionSettingsForSystemService has incorrect size.");
72
73struct UiSettingsDisplayOptions {
74 bool is_network_service_account_required;
75 bool is_skip_enabled;
76 bool is_system_or_launcher;
77 bool is_registration_permitted;
78 bool show_skip_button;
79 bool aditional_select;
80 bool show_user_selector;
81 bool is_unqualified_user_selectable;
82};
83static_assert(sizeof(UiSettingsDisplayOptions) == 0x8,
84 "UiSettingsDisplayOptions has incorrect size.");
85
86struct UiSettingsV1 {
87 UiMode mode;
88 INSERT_PADDING_BYTES(0x4);
89 std::array<Common::UUID, 8> invalid_uid_list;
90 u64 application_id;
91 UiSettingsDisplayOptions display_options;
92};
93static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size.");
94
95// This is nn::account::UiSettings
96struct UiSettings {
97 UiMode mode;
98 INSERT_PADDING_BYTES(0x4);
99 std::array<Common::UUID, 8> invalid_uid_list;
100 u64 application_id;
101 UiSettingsDisplayOptions display_options;
102 UserSelectionPurpose purpose;
103 INSERT_PADDING_BYTES(0x4);
104};
105static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size.");
106
107// This is nn::account::UiReturnArg
108struct UiReturnArg {
28 u64 result; 109 u64 result;
29 Common::UUID uuid_selected; 110 Common::UUID uuid_selected;
30}; 111};
31static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size."); 112static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size.");
32 113
33class ProfileSelect final : public Applet { 114class ProfileSelect final : public Applet {
34public: 115public:
@@ -49,7 +130,10 @@ public:
49private: 130private:
50 const Core::Frontend::ProfileSelectApplet& frontend; 131 const Core::Frontend::ProfileSelectApplet& frontend;
51 132
52 UserSelectionConfig config; 133 UiSettings config;
134 UiSettingsV1 config_old;
135 ProfileSelectAppletVersion profile_select_version;
136
53 bool complete = false; 137 bool complete = false;
54 Result status = ResultSuccess; 138 Result status = ResultSuccess;
55 std::vector<u8> final_data; 139 std::vector<u8> final_data;