summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/acc/acc.cpp57
-rw-r--r--src/core/hle/service/acc/acc.h9
-rw-r--r--src/core/hle/service/acc/acc_aa.cpp5
-rw-r--r--src/core/hle/service/acc/acc_aa.h4
-rw-r--r--src/core/hle/service/acc/acc_su.cpp5
-rw-r--r--src/core/hle/service/acc/acc_su.h4
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp9
-rw-r--r--src/core/hle/service/acc/acc_u0.h4
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp5
-rw-r--r--src/core/hle/service/acc/acc_u1.h4
-rw-r--r--src/core/hle/service/am/am.cpp18
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/am/applets/applets.cpp34
-rw-r--r--src/core/hle/service/am/applets/applets.h16
-rw-r--r--src/core/hle/service/am/applets/error.cpp19
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp22
-rw-r--r--src/core/hle/service/am/applets/general_backend.h5
-rw-r--r--src/core/hle/service/audio/audout_u.cpp23
-rw-r--r--src/core/hle/service/fatal/fatal.cpp26
-rw-r--r--src/core/hle/service/ldr/ldr.cpp2
-rw-r--r--src/core/hle/service/prepo/prepo.cpp25
-rw-r--r--src/core/hle/service/service.cpp5
22 files changed, 218 insertions, 86 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index cb66e344b..0cd8158df 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -12,13 +12,17 @@
#include "common/swap.h"
#include "core/constants.h"
#include "core/core_timing.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/service/acc/acc.h"
#include "core/hle/service/acc/acc_aa.h"
#include "core/hle/service/acc/acc_su.h"
#include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h"
#include "core/hle/service/acc/profile_manager.h"
+#include "core/loader/loader.h"
namespace Service::Account {
@@ -90,7 +94,7 @@ private:
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
ctx.WriteBuffer(Core::Constants::ACCOUNT_BACKUP_JPEG);
- rb.Push<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size());
+ rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
return;
}
@@ -112,9 +116,9 @@ private:
if (!image.IsOpen()) {
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
- rb.Push<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size());
+ rb.Push(SanitizeJPEGSize(Core::Constants::ACCOUNT_BACKUP_JPEG.size()));
} else {
- rb.Push<u32>(SanitizeJPEGSize(image.GetSize()));
+ rb.Push(SanitizeJPEGSize(image.GetSize()));
}
}
@@ -213,7 +217,7 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
rb.Push(profile_manager->CanSystemRegisterUser());
}
-void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
+void Module::Interface::InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -226,6 +230,31 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
rb.PushIpcInterface<IManagerForApplication>();
}
+void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_ACC, "called");
+ FileSys::NACP nacp;
+ const auto res = system.GetAppLoader().ReadControlData(nacp);
+
+ bool is_locked = false;
+
+ if (res != Loader::ResultStatus::Success) {
+ FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
+ auto nacp_unique = pm.GetControlMetadata().first;
+
+ if (nacp_unique != nullptr) {
+ is_locked = nacp_unique->GetUserAccountSwitchLock();
+ } else {
+ LOG_ERROR(Service_ACC, "nacp_unique is null!");
+ }
+ } else {
+ is_locked = nacp.GetUserAccountSwitchLock();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(is_locked);
+}
+
void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
// A u8 is passed into this function which we can safely ignore. It's to determine if we have
@@ -251,19 +280,25 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
}
Module::Interface::Interface(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager, const char* name)
+ std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
+ const char* name)
: ServiceFramework(name), module(std::move(module)),
- profile_manager(std::move(profile_manager)) {}
+ profile_manager(std::move(profile_manager)), system(system) {}
Module::Interface::~Interface() = default;
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(Core::System& system) {
auto module = std::make_shared<Module>();
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);
+
+ std::make_shared<ACC_AA>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_SU>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_U0>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_U1>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
}
} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 89b2104fa..350f123a0 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -15,7 +15,8 @@ public:
class Interface : public ServiceFramework<Interface> {
public:
explicit Interface(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager, const char* name);
+ std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
+ const char* name);
~Interface() override;
void GetUserCount(Kernel::HLERequestContext& ctx);
@@ -24,18 +25,20 @@ public:
void ListOpenUsers(Kernel::HLERequestContext& ctx);
void GetLastOpenedUser(Kernel::HLERequestContext& ctx);
void GetProfile(Kernel::HLERequestContext& ctx);
- void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
+ void InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx);
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
+ void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
std::shared_ptr<ProfileManager> profile_manager;
+ Core::System& system;
};
};
/// Registers all ACC services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(Core::System& system);
} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_aa.cpp b/src/core/hle/service/acc/acc_aa.cpp
index e84d9f7cf..3bac6bcd1 100644
--- a/src/core/hle/service/acc/acc_aa.cpp
+++ b/src/core/hle/service/acc/acc_aa.cpp
@@ -6,8 +6,9 @@
namespace Service::Account {
-ACC_AA::ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
- : Module::Interface(std::move(module), std::move(profile_manager), "acc:aa") {
+ACC_AA::ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system)
+ : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:aa") {
static const FunctionInfo functions[] = {
{0, nullptr, "EnsureCacheAsync"},
{1, nullptr, "LoadCache"},
diff --git a/src/core/hle/service/acc/acc_aa.h b/src/core/hle/service/acc/acc_aa.h
index 9edb0421b..932c04890 100644
--- a/src/core/hle/service/acc/acc_aa.h
+++ b/src/core/hle/service/acc/acc_aa.h
@@ -10,8 +10,8 @@ namespace Service::Account {
class ACC_AA final : public Module::Interface {
public:
- explicit ACC_AA(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager);
+ explicit ACC_AA(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system);
~ACC_AA() override;
};
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index d66233cad..1b7ec3ed0 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -6,8 +6,9 @@
namespace Service::Account {
-ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
- : Module::Interface(std::move(module), std::move(profile_manager), "acc:su") {
+ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system)
+ : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:su") {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ACC_SU::GetUserCount, "GetUserCount"},
diff --git a/src/core/hle/service/acc/acc_su.h b/src/core/hle/service/acc/acc_su.h
index fcced063a..0a700d9bf 100644
--- a/src/core/hle/service/acc/acc_su.h
+++ b/src/core/hle/service/acc/acc_su.h
@@ -10,8 +10,8 @@ namespace Service::Account {
class ACC_SU final : public Module::Interface {
public:
- explicit ACC_SU(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager);
+ explicit ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system);
~ACC_SU() override;
};
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index 182f7c7e5..2f239e8c0 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -6,8 +6,9 @@
namespace Service::Account {
-ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
- : Module::Interface(std::move(module), std::move(profile_manager), "acc:u0") {
+ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system)
+ : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:u0") {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ACC_U0::GetUserCount, "GetUserCount"},
@@ -21,7 +22,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"},
- {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
+ {100, &ACC_U0::InitializeApplicationInfoOld, "InitializeApplicationInfoOld"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
{102, nullptr, "AuthenticateApplicationAsync"},
{103, nullptr, "CheckNetworkServiceAvailabilityAsync"},
@@ -32,7 +33,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{131, nullptr, "ListOpenContextStoredUsers"},
{140, nullptr, "InitializeApplicationInfo"},
{141, nullptr, "ListQualifiedUsers"},
- {150, nullptr, "IsUserAccountSwitchLocked"},
+ {150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
};
// clang-format on
diff --git a/src/core/hle/service/acc/acc_u0.h b/src/core/hle/service/acc/acc_u0.h
index a1290e0bd..3bd9c3164 100644
--- a/src/core/hle/service/acc/acc_u0.h
+++ b/src/core/hle/service/acc/acc_u0.h
@@ -10,8 +10,8 @@ namespace Service::Account {
class ACC_U0 final : public Module::Interface {
public:
- explicit ACC_U0(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager);
+ explicit ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system);
~ACC_U0() override;
};
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
index 2dd17d935..6520b3968 100644
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ b/src/core/hle/service/acc/acc_u1.cpp
@@ -6,8 +6,9 @@
namespace Service::Account {
-ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager)
- : Module::Interface(std::move(module), std::move(profile_manager), "acc:u1") {
+ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system)
+ : Module::Interface(std::move(module), std::move(profile_manager), system, "acc:u1") {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ACC_U1::GetUserCount, "GetUserCount"},
diff --git a/src/core/hle/service/acc/acc_u1.h b/src/core/hle/service/acc/acc_u1.h
index 9e79daee3..829f8a744 100644
--- a/src/core/hle/service/acc/acc_u1.h
+++ b/src/core/hle/service/acc/acc_u1.h
@@ -10,8 +10,8 @@ namespace Service::Account {
class ACC_U1 final : public Module::Interface {
public:
- explicit ACC_U1(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager);
+ explicit ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager,
+ Core::System& system);
~ACC_U1() override;
};
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 3f201c821..4a7bf4acb 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -271,7 +271,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
{71, nullptr, "GetCurrentIlluminanceEx"},
{80, nullptr, "SetWirelessPriorityMode"},
{90, nullptr, "GetAccumulatedSuspendedTickValue"},
- {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"},
+ {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
{100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
{1000, nullptr, "GetDebugStorageChannel"},
};
@@ -282,6 +282,11 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
auto& kernel = Core::System::GetInstance().Kernel();
launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"ISelfController:LaunchableEvent");
+
+ // TODO(ogniK): Figure out where, when and why this event gets signalled
+ accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair(
+ kernel, Kernel::ResetType::Manual, "ISelfController:AccumulatedSuspendedTickChangedEvent");
+ accumulated_suspended_tick_changed_event.writable->Signal(); // Is signalled on creation
}
ISelfController::~ISelfController() = default;
@@ -444,6 +449,17 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
rb.Push<u32>(idle_time_detection_extension);
}
+void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx) {
+ // The implementation of this function is fine as is, the reason we're labelling it as stubbed
+ // is because we're currently unsure when and where accumulated_suspended_tick_changed_event is
+ // actually signalled for the time being.
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushCopyObjects(accumulated_suspended_tick_changed_event.readable);
+}
+
AppletMessageQueue::AppletMessageQueue() {
auto& kernel = Core::System::GetInstance().Kernel();
on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 991b7d47c..1fa069e56 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -133,9 +133,12 @@ private:
void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
+ void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
Kernel::EventPair launchable_event;
+ Kernel::EventPair accumulated_suspended_tick_changed_event;
+
u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0;
};
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 14fa92318..e3e4ead03 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -35,12 +35,28 @@ AppletDataBroker::AppletDataBroker() {
AppletDataBroker::~AppletDataBroker() = default;
+AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
+ std::vector<std::vector<u8>> out_normal;
+
+ for (const auto& storage : in_channel) {
+ out_normal.push_back(storage->GetData());
+ }
+
+ std::vector<std::vector<u8>> out_interactive;
+
+ for (const auto& storage : in_interactive_channel) {
+ out_interactive.push_back(storage->GetData());
+ }
+
+ return {std::move(out_normal), std::move(out_interactive)};
+}
+
std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
if (out_channel.empty())
return nullptr;
auto out = std::move(out_channel.front());
- out_channel.pop();
+ out_channel.pop_front();
return out;
}
@@ -49,7 +65,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() {
return nullptr;
auto out = std::move(in_channel.front());
- in_channel.pop();
+ in_channel.pop_front();
return out;
}
@@ -58,7 +74,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
return nullptr;
auto out = std::move(out_interactive_channel.front());
- out_interactive_channel.pop();
+ out_interactive_channel.pop_front();
return out;
}
@@ -67,25 +83,25 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
return nullptr;
auto out = std::move(in_interactive_channel.front());
- in_interactive_channel.pop();
+ in_interactive_channel.pop_front();
return out;
}
void AppletDataBroker::PushNormalDataFromGame(IStorage storage) {
- in_channel.push(std::make_unique<IStorage>(storage));
+ in_channel.push_back(std::make_unique<IStorage>(storage));
}
void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) {
- out_channel.push(std::make_unique<IStorage>(storage));
+ out_channel.push_back(std::make_unique<IStorage>(storage));
pop_out_data_event.writable->Signal();
}
void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) {
- in_interactive_channel.push(std::make_unique<IStorage>(storage));
+ in_interactive_channel.push_back(std::make_unique<IStorage>(storage));
}
void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) {
- out_interactive_channel.push(std::make_unique<IStorage>(storage));
+ out_interactive_channel.push_back(std::make_unique<IStorage>(storage));
pop_interactive_out_data_event.writable->Signal();
}
@@ -204,7 +220,7 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id));
- return std::make_shared<StubApplet>();
+ return std::make_shared<StubApplet>(id);
}
}
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index b46e10a4a..05ae739ca 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -54,6 +54,14 @@ public:
AppletDataBroker();
~AppletDataBroker();
+ struct RawChannelData {
+ std::vector<std::vector<u8>> normal;
+ std::vector<std::vector<u8>> interactive;
+ };
+
+ // Retrieves but does not pop the data sent to applet.
+ RawChannelData PeekDataToAppletForDebug() const;
+
std::unique_ptr<IStorage> PopNormalDataToGame();
std::unique_ptr<IStorage> PopNormalDataToApplet();
@@ -76,16 +84,16 @@ private:
// Queues are named from applet's perspective
// PopNormalDataToApplet and PushNormalDataFromGame
- std::queue<std::unique_ptr<IStorage>> in_channel;
+ std::deque<std::unique_ptr<IStorage>> in_channel;
// PopNormalDataToGame and PushNormalDataFromApplet
- std::queue<std::unique_ptr<IStorage>> out_channel;
+ std::deque<std::unique_ptr<IStorage>> out_channel;
// PopInteractiveDataToApplet and PushInteractiveDataFromGame
- std::queue<std::unique_ptr<IStorage>> in_interactive_channel;
+ std::deque<std::unique_ptr<IStorage>> in_interactive_channel;
// PopInteractiveDataToGame and PushInteractiveDataFromApplet
- std::queue<std::unique_ptr<IStorage>> out_interactive_channel;
+ std::deque<std::unique_ptr<IStorage>> out_interactive_channel;
Kernel::EventPair state_changed_event;
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index 04774bedc..af3a900f8 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -9,8 +9,10 @@
#include "common/string_util.h"
#include "core/core.h"
#include "core/frontend/applets/error.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/error.h"
+#include "core/reporter.h"
namespace Service::AM::Applets {
@@ -143,9 +145,12 @@ void Error::Execute() {
}
const auto callback = [this] { DisplayCompleted(); };
+ const auto title_id = Core::CurrentProcess()->GetTitleID();
+ const auto& reporter{Core::System::GetInstance().GetReporter()};
switch (mode) {
case ErrorAppletMode::ShowError:
+ reporter.SaveErrorReport(title_id, error_code);
frontend.ShowError(error_code, callback);
break;
case ErrorAppletMode::ShowSystemError:
@@ -156,14 +161,18 @@ void Error::Execute() {
const auto& detail_text =
system ? args->system_error.detail_text : args->application_error.detail_text;
- frontend.ShowCustomErrorText(
- error_code,
- Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()),
- Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()),
- callback);
+ const auto main_text_string =
+ Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size());
+ const auto detail_text_string =
+ Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size());
+
+ reporter.SaveErrorReport(title_id, error_code, main_text_string, detail_text_string);
+ frontend.ShowCustomErrorText(error_code, main_text_string, detail_text_string, callback);
break;
}
case ErrorAppletMode::ShowErrorRecord:
+ reporter.SaveErrorReport(title_id, error_code,
+ fmt::format("{:016X}", args->error_record.posix_time));
frontend.ShowErrorWithTimestamp(
error_code, std::chrono::seconds{args->error_record.posix_time}, callback);
break;
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index c591b9ac2..54c155dd8 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <string>
+#include <string_view>
#include "common/assert.h"
#include "common/hex_util.h"
@@ -13,24 +13,25 @@
#include "core/hle/result.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/general_backend.h"
+#include "core/reporter.h"
namespace Service::AM::Applets {
-static void LogCurrentStorage(AppletDataBroker& broker, std::string prefix) {
+static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) {
std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
const auto data = storage->GetData();
LOG_INFO(Service_AM,
- "called (STUBBED), during {} recieved normal data with size={:08X}, data={}",
- prefix, data.size(), Common::HexVectorToString(data));
+ "called (STUBBED), during {} received normal data with size={:08X}, data={}",
+ prefix, data.size(), Common::HexToString(data));
}
storage = broker.PopInteractiveDataToApplet();
for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
const auto data = storage->GetData();
LOG_INFO(Service_AM,
- "called (STUBBED), during {} recieved interactive data with size={:08X}, data={}",
- prefix, data.size(), Common::HexVectorToString(data));
+ "called (STUBBED), during {} received interactive data with size={:08X}, data={}",
+ prefix, data.size(), Common::HexToString(data));
}
}
@@ -83,13 +84,20 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged();
}
-StubApplet::StubApplet() = default;
+StubApplet::StubApplet(AppletId id) : id(id) {}
StubApplet::~StubApplet() = default;
void StubApplet::Initialize() {
LOG_WARNING(Service_AM, "called (STUBBED)");
Applet::Initialize();
+
+ const auto data = broker.PeekDataToAppletForDebug();
+ Core::System::GetInstance().GetReporter().SaveUnimplementedAppletReport(
+ static_cast<u32>(id), common_args.arguments_version, common_args.library_version,
+ common_args.theme_color, common_args.play_startup_sound, common_args.system_tick,
+ data.normal, data.interactive);
+
LogCurrentStorage(broker, "Initialize");
}
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index 2dd255d7c..fb68a2543 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -34,7 +34,7 @@ private:
class StubApplet final : public Applet {
public:
- StubApplet();
+ explicit StubApplet(AppletId id);
~StubApplet() override;
void Initialize() override;
@@ -43,6 +43,9 @@ public:
ResultCode GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+
+private:
+ AppletId id;
};
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 6ba41b20a..7db6eb08d 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -58,8 +58,8 @@ public:
{9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
{10, nullptr, "GetAudioOutPlayedSampleCount"},
{11, nullptr, "FlushAudioOutBuffers"},
- {12, nullptr, "SetAudioOutVolume"},
- {13, nullptr, "GetAudioOutVolume"},
+ {12, &IAudioOut::SetAudioOutVolume, "SetAudioOutVolume"},
+ {13, &IAudioOut::GetAudioOutVolume, "GetAudioOutVolume"},
};
// clang-format on
RegisterHandlers(functions);
@@ -183,6 +183,25 @@ private:
rb.Push(static_cast<u32>(stream->GetQueueSize()));
}
+ void SetAudioOutVolume(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const float volume = rp.Pop<float>();
+ LOG_DEBUG(Service_Audio, "called, volume={}", volume);
+
+ stream->SetVolume(volume);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ void GetAudioOutVolume(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(stream->GetVolume());
+ }
+
AudioCore::AudioOut& audio_core;
AudioCore::StreamPtr stream;
std::string device_name;
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 2c229bcad..fe49c2161 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -16,6 +16,7 @@
#include "core/hle/service/fatal/fatal.h"
#include "core/hle/service/fatal/fatal_p.h"
#include "core/hle/service/fatal/fatal_u.h"
+#include "core/reporter.h"
namespace Service::Fatal {
@@ -100,27 +101,10 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
LOG_ERROR(Service_Fatal, "{}", crash_report);
- const std::string crashreport_dir =
- FileUtil::GetUserPath(FileUtil::UserPath::LogDir) + "crash_logs";
-
- if (!FileUtil::CreateFullPath(crashreport_dir)) {
- LOG_ERROR(
- Service_Fatal,
- "Unable to create crash report directory. Possible log directory permissions issue.");
- return;
- }
-
- const std::time_t t = std::time(nullptr);
- const std::string crashreport_filename =
- fmt::format("{}/{:016x}-{:%F-%H%M%S}.log", crashreport_dir, title_id, *std::localtime(&t));
-
- auto file = FileUtil::IOFile(crashreport_filename, "wb");
- if (file.IsOpen()) {
- file.WriteString(crash_report);
- LOG_ERROR(Service_Fatal, "Saving error report to {}", crashreport_filename);
- } else {
- LOG_ERROR(Service_Fatal, "Failed to save error report to {}", crashreport_filename);
- }
+ Core::System::GetInstance().GetReporter().SaveCrashReport(
+ title_id, error_code, info.set_flags, info.program_entry_point, info.sp, info.pc,
+ info.pstate, info.afsr0, info.afsr1, info.esr, info.far, info.registers, info.backtrace,
+ info.backtrace_size, info.ArchAsString(), info.unk10);
}
static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) {
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 5af925515..b839303ac 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -310,7 +310,7 @@ public:
if (!IsValidNROHash(hash)) {
LOG_ERROR(Service_LDR,
"NRO hash is not present in any currently loaded NRRs (hash={})!",
- Common::HexArrayToString(hash));
+ Common::HexToString(hash));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERROR_MISSING_NRR_HASH);
return;
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index e4fcee9f8..7e134f5c1 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -2,10 +2,18 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <json.hpp>
+#include "common/file_util.h"
+#include "common/hex_util.h"
#include "common/logging/log.h"
+#include "common/scm_rev.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
+#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/prepo/prepo.h"
#include "core/hle/service/service.h"
+#include "core/reporter.h"
+#include "core/settings.h"
namespace Service::PlayReport {
@@ -40,8 +48,21 @@ public:
private:
void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) {
- // TODO(ogniK): Do we want to add play report?
- LOG_WARNING(Service_PREPO, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ const auto user_id = rp.PopRaw<u128>();
+ const auto process_id = rp.PopRaw<u64>();
+
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = ctx.ReadBuffer(1);
+
+ LOG_DEBUG(
+ Service_PREPO,
+ "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}",
+ user_id[1], user_id[0], process_id, data1.size(), data2.size());
+
+ const auto& reporter{Core::System::GetInstance().GetReporter()};
+ reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), process_id, {data1, data2},
+ user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 00806b0ed..b2954eb34 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -68,6 +68,7 @@
#include "core/hle/service/usb/usb.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/wlan/wlan.h"
+#include "core/reporter.h"
namespace Service {
@@ -148,6 +149,8 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
}
buf.push_back('}');
+ Core::System::GetInstance().GetReporter().SaveUnimplementedFunctionReport(
+ ctx, ctx.GetCommand(), function_name, service_name);
UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
}
@@ -200,7 +203,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
SM::ServiceManager::InstallInterfaces(sm);
- Account::InstallInterfaces(*sm);
+ Account::InstallInterfaces(system);
AM::InstallInterfaces(*sm, nv_flinger);
AOC::InstallInterfaces(*sm);
APM::InstallInterfaces(*sm);