summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-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;
void DefaultProfileSelectApplet::Close() const {}
-void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback) const {
+void DefaultProfileSelectApplet::SelectProfile(SelectProfileCallback callback,
+ const ProfileSelectParameters& parameters) const {
Service::Account::ProfileManager manager;
callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
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 @@
#include <functional>
#include <optional>
-#include "common/uuid.h"
+#include "common/uuid.h"
#include "core/frontend/applets/applet.h"
+#include "core/hle/service/am/applets/applet_profile_select.h"
namespace Core::Frontend {
+struct ProfileSelectParameters {
+ Service::AM::Applets::UiMode mode;
+ std::array<Common::UUID, 8> invalid_uid_list;
+ Service::AM::Applets::UiSettingsDisplayOptions display_options;
+ Service::AM::Applets::UserSelectionPurpose purpose;
+};
+
class ProfileSelectApplet : public Applet {
public:
using SelectProfileCallback = std::function<void(std::optional<Common::UUID>)>;
virtual ~ProfileSelectApplet();
- virtual void SelectProfile(SelectProfileCallback callback) const = 0;
+ virtual void SelectProfile(SelectProfileCallback callback,
+ const ProfileSelectParameters& parameters) const = 0;
};
class DefaultProfileSelectApplet final : public ProfileSelectApplet {
public:
void Close() const override;
- void SelectProfile(SelectProfileCallback callback) const override;
+ void SelectProfile(SelectProfileCallback callback,
+ const ProfileSelectParameters& parameters) const override;
};
} // 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() {
final_data.clear();
Applet::Initialize();
+ profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
const auto user_config_storage = broker.PopNormalDataToApplet();
ASSERT(user_config_storage != nullptr);
const auto& user_config = user_config_storage->GetData();
- ASSERT(user_config.size() >= sizeof(UserSelectionConfig));
- std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig));
+ LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}",
+ profile_select_version);
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ ASSERT(user_config.size() == sizeof(UiSettingsV1));
+ std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1));
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ ASSERT(user_config.size() == sizeof(UiSettings));
+ std::memcpy(&config, user_config.data(), sizeof(UiSettings));
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
}
bool ProfileSelect::TransactionComplete() const {
@@ -52,11 +68,37 @@ void ProfileSelect::Execute() {
return;
}
- frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); });
+ Core::Frontend::ProfileSelectParameters parameters{};
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ parameters = {
+ .mode = config_old.mode,
+ .invalid_uid_list = config_old.invalid_uid_list,
+ .display_options = config_old.display_options,
+ .purpose = UserSelectionPurpose::General,
+ };
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ parameters = {
+ .mode = config.mode,
+ .invalid_uid_list = config.invalid_uid_list,
+ .display_options = config.display_options,
+ .purpose = config.purpose,
+ };
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
+
+ frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); },
+ parameters);
}
void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
- UserSelectionOutput output{};
+ UiReturnArg output{};
if (uuid.has_value() && uuid->IsValid()) {
output.result = 0;
@@ -67,7 +109,7 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
output.uuid_selected = Common::InvalidUUID;
}
- final_data = std::vector<u8>(sizeof(UserSelectionOutput));
+ final_data = std::vector<u8>(sizeof(UiReturnArg));
std::memcpy(final_data.data(), &output, final_data.size());
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
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;
namespace Service::AM::Applets {
-struct UserSelectionConfig {
- // TODO(DarkLordZach): RE this structure
- // It seems to be flags and the like that determine the UI of the applet on the switch... from
- // my research this is safe to ignore for now.
- INSERT_PADDING_BYTES(0xA0);
+enum class ProfileSelectAppletVersion : u32 {
+ Version1 = 0x1, // 1.0.0+
+ Version2 = 0x10000, // 2.0.0+
+ Version3 = 0x20000, // 6.0.0+
};
-static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size.");
-struct UserSelectionOutput {
+// This is nn::account::UiMode
+enum class UiMode {
+ UserSelector,
+ UserCreator,
+ EnsureNetworkServiceAccountAvailable,
+ UserIconEditor,
+ UserNicknameEditor,
+ UserCreatorForStarter,
+ NintendoAccountAuthorizationRequestContext,
+ IntroduceExternalNetworkServiceAccount,
+ IntroduceExternalNetworkServiceAccountForRegistration,
+ NintendoAccountNnidLinker,
+ LicenseRequirementsForNetworkService,
+ LicenseRequirementsForNetworkServiceWithUserContextImpl,
+ UserCreatorForImmediateNaLoginTest,
+ UserQualificationPromoter,
+};
+
+// This is nn::account::UserSelectionPurpose
+enum class UserSelectionPurpose {
+ General,
+ GameCardRegistration,
+ EShopLaunch,
+ EShopItemShow,
+ PicturePost,
+ NintendoAccountLinkage,
+ SettingsUpdate,
+ SaveDataDeletion,
+ UserMigration,
+ SaveDataTransfer,
+};
+
+// This is nn::account::NintendoAccountStartupDialogType
+enum class NintendoAccountStartupDialogType {
+ LoginAndCreate,
+ Login,
+ Create,
+};
+
+// This is nn::account::UserSelectionSettingsForSystemService
+struct UserSelectionSettingsForSystemService {
+ UserSelectionPurpose purpose;
+ bool enable_user_creation;
+ INSERT_PADDING_BYTES(0x3);
+};
+static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8,
+ "UserSelectionSettingsForSystemService has incorrect size.");
+
+struct UiSettingsDisplayOptions {
+ bool is_network_service_account_required;
+ bool is_skip_enabled;
+ bool is_system_or_launcher;
+ bool is_registration_permitted;
+ bool show_skip_button;
+ bool aditional_select;
+ bool show_user_selector;
+ bool is_unqualified_user_selectable;
+};
+static_assert(sizeof(UiSettingsDisplayOptions) == 0x8,
+ "UiSettingsDisplayOptions has incorrect size.");
+
+struct UiSettingsV1 {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+};
+static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size.");
+
+// This is nn::account::UiSettings
+struct UiSettings {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+ UserSelectionPurpose purpose;
+ INSERT_PADDING_BYTES(0x4);
+};
+static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size.");
+
+// This is nn::account::UiReturnArg
+struct UiReturnArg {
u64 result;
Common::UUID uuid_selected;
};
-static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size.");
+static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size.");
class ProfileSelect final : public Applet {
public:
@@ -49,7 +130,10 @@ public:
private:
const Core::Frontend::ProfileSelectApplet& frontend;
- UserSelectionConfig config;
+ UiSettings config;
+ UiSettingsV1 config_old;
+ ProfileSelectAppletVersion profile_select_version;
+
bool complete = false;
Result status = ResultSuccess;
std::vector<u8> final_data;