Merge pull request #13115 from liamwhite/olsc-pctl
olsc, pctl: move to new ipc
This commit is contained in:
		| @@ -879,8 +879,20 @@ add_library(core STATIC | |||||||
|     hle/service/nvnflinger/ui/graphic_buffer.cpp |     hle/service/nvnflinger/ui/graphic_buffer.cpp | ||||||
|     hle/service/nvnflinger/ui/graphic_buffer.h |     hle/service/nvnflinger/ui/graphic_buffer.h | ||||||
|     hle/service/nvnflinger/window.h |     hle/service/nvnflinger/window.h | ||||||
|  |     hle/service/olsc/daemon_controller.cpp | ||||||
|  |     hle/service/olsc/daemon_controller.h | ||||||
|  |     hle/service/olsc/native_handle_holder.cpp | ||||||
|  |     hle/service/olsc/native_handle_holder.h | ||||||
|  |     hle/service/olsc/olsc_service_for_application.cpp | ||||||
|  |     hle/service/olsc/olsc_service_for_application.h | ||||||
|  |     hle/service/olsc/olsc_service_for_system_service.cpp | ||||||
|  |     hle/service/olsc/olsc_service_for_system_service.h | ||||||
|     hle/service/olsc/olsc.cpp |     hle/service/olsc/olsc.cpp | ||||||
|     hle/service/olsc/olsc.h |     hle/service/olsc/olsc.h | ||||||
|  |     hle/service/olsc/remote_storage_controller.cpp | ||||||
|  |     hle/service/olsc/remote_storage_controller.h | ||||||
|  |     hle/service/olsc/transfer_task_list_controller.cpp | ||||||
|  |     hle/service/olsc/transfer_task_list_controller.h | ||||||
|     hle/service/omm/omm.cpp |     hle/service/omm/omm.cpp | ||||||
|     hle/service/omm/omm.h |     hle/service/omm/omm.h | ||||||
|     hle/service/omm/operation_mode_manager.cpp |     hle/service/omm/operation_mode_manager.cpp | ||||||
| @@ -900,10 +912,14 @@ add_library(core STATIC | |||||||
|     hle/service/os/mutex.h |     hle/service/os/mutex.h | ||||||
|     hle/service/pcie/pcie.cpp |     hle/service/pcie/pcie.cpp | ||||||
|     hle/service/pcie/pcie.h |     hle/service/pcie/pcie.h | ||||||
|  |     hle/service/pctl/parental_control_service_factory.cpp | ||||||
|  |     hle/service/pctl/parental_control_service_factory.h | ||||||
|  |     hle/service/pctl/parental_control_service.cpp | ||||||
|  |     hle/service/pctl/parental_control_service.h | ||||||
|     hle/service/pctl/pctl.cpp |     hle/service/pctl/pctl.cpp | ||||||
|     hle/service/pctl/pctl.h |     hle/service/pctl/pctl.h | ||||||
|     hle/service/pctl/pctl_module.cpp |     hle/service/pctl/pctl_results.h | ||||||
|     hle/service/pctl/pctl_module.h |     hle/service/pctl/pctl_types.h | ||||||
|     hle/service/pcv/pcv.cpp |     hle/service/pcv/pcv.cpp | ||||||
|     hle/service/pcv/pcv.h |     hle/service/pcv/pcv.h | ||||||
|     hle/service/pm/pm.cpp |     hle/service/pm/pm.cpp | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								src/core/hle/service/olsc/daemon_controller.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/core/hle/service/olsc/daemon_controller.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/daemon_controller.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | IDaemonController::IDaemonController(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "IDaemonController"} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"}, | ||||||
|  |         {1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"}, | ||||||
|  |         {2, nullptr, "GetGlobalUploadEnabledForAccount"}, | ||||||
|  |         {3, nullptr, "SetGlobalUploadEnabledForAccount"}, | ||||||
|  |         {4, nullptr, "TouchAccount"}, | ||||||
|  |         {5, nullptr, "GetGlobalDownloadEnabledForAccount"}, | ||||||
|  |         {6, nullptr, "SetGlobalDownloadEnabledForAccount"}, | ||||||
|  |         {10, nullptr, "GetForbiddenSaveDataIndication"}, | ||||||
|  |         {11, nullptr, "GetStopperObject"}, | ||||||
|  |         {12, nullptr, "GetState"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IDaemonController::~IDaemonController() = default; | ||||||
|  |  | ||||||
|  | Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled, | ||||||
|  |                                                                          Common::UUID user_id, | ||||||
|  |                                                                          u64 application_id) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}", | ||||||
|  |                 user_id.FormattedString(), application_id); | ||||||
|  |     *out_is_enabled = false; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										20
									
								
								src/core/hle/service/olsc/daemon_controller.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/core/hle/service/olsc/daemon_controller.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "common/uuid.h" | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class IDaemonController final : public ServiceFramework<IDaemonController> { | ||||||
|  | public: | ||||||
|  |     explicit IDaemonController(Core::System& system_); | ||||||
|  |     ~IDaemonController() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled, | ||||||
|  |                                                           Common::UUID user_id, u64 application_id); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										28
									
								
								src/core/hle/service/olsc/native_handle_holder.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/core/hle/service/olsc/native_handle_holder.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/native_handle_holder.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | INativeHandleHolder::INativeHandleHolder(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "INativeHandleHolder"} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, D<&INativeHandleHolder::GetNativeHandle>, "GetNativeHandle"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | INativeHandleHolder::~INativeHandleHolder() = default; | ||||||
|  |  | ||||||
|  | Result INativeHandleHolder::GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called"); | ||||||
|  |     *out_event = nullptr; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										22
									
								
								src/core/hle/service/olsc/native_handle_holder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/core/hle/service/olsc/native_handle_holder.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Kernel { | ||||||
|  | class KReadableEvent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> { | ||||||
|  | public: | ||||||
|  |     explicit INativeHandleHolder(Core::System& system_); | ||||||
|  |     ~INativeHandleHolder() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result GetNativeHandle(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
| @@ -1,226 +1,27 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
| #include "core/hle/service/ipc_helpers.h" |  | ||||||
| #include "core/hle/service/olsc/olsc.h" | #include "core/hle/service/olsc/olsc.h" | ||||||
|  | #include "core/hle/service/olsc/olsc_service_for_application.h" | ||||||
|  | #include "core/hle/service/olsc/olsc_service_for_system_service.h" | ||||||
| #include "core/hle/service/server_manager.h" | #include "core/hle/service/server_manager.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
| namespace Service::OLSC { | namespace Service::OLSC { | ||||||
|  |  | ||||||
| class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> { |  | ||||||
| public: |  | ||||||
|     explicit IOlscServiceForApplication(Core::System& system_) |  | ||||||
|         : ServiceFramework{system_, "olsc:u"} { |  | ||||||
|         // clang-format off |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {0, &IOlscServiceForApplication::Initialize, "Initialize"}, |  | ||||||
|             {10, nullptr, "VerifySaveDataBackupLicenseAsync"}, |  | ||||||
|             {13, &IOlscServiceForApplication::GetSaveDataBackupSetting, "GetSaveDataBackupSetting"}, |  | ||||||
|             {14, &IOlscServiceForApplication::SetSaveDataBackupSettingEnabled, "SetSaveDataBackupSettingEnabled"}, |  | ||||||
|             {15, nullptr, "SetCustomData"}, |  | ||||||
|             {16, nullptr, "DeleteSaveDataBackupSetting"}, |  | ||||||
|             {18, nullptr, "GetSaveDataBackupInfoCache"}, |  | ||||||
|             {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"}, |  | ||||||
|             {22, nullptr, "DeleteSaveDataBackupAsync"}, |  | ||||||
|             {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"}, |  | ||||||
|             {26, nullptr, "DownloadSaveDataBackupAsync"}, |  | ||||||
|             {27, nullptr, "UploadSaveDataBackupAsync"}, |  | ||||||
|             {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"}, |  | ||||||
|             {9013, nullptr, "GetSaveDataBackupSettingForDebug"}, |  | ||||||
|             {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"}, |  | ||||||
|             {9015, nullptr, "SetCustomDataForDebug"}, |  | ||||||
|             {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"}, |  | ||||||
|             {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"}, |  | ||||||
|             {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"}, |  | ||||||
|             {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"}, |  | ||||||
|             {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"}, |  | ||||||
|             {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on |  | ||||||
|  |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     void Initialize(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_OLSC, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         initialized = true; |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetSaveDataBackupSetting(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_OLSC, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         // backup_setting is set to 0 since real value is unknown |  | ||||||
|         constexpr u64 backup_setting = 0; |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 4}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push(backup_setting); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void SetSaveDataBackupSettingEnabled(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_OLSC, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool initialized{}; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class INativeHandleHolder final : public ServiceFramework<INativeHandleHolder> { |  | ||||||
| public: |  | ||||||
|     explicit INativeHandleHolder(Core::System& system_) |  | ||||||
|         : ServiceFramework{system_, "INativeHandleHolder"} { |  | ||||||
|         // clang-format off |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {0, nullptr, "GetNativeHandle"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on |  | ||||||
|  |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> { |  | ||||||
| public: |  | ||||||
|     explicit ITransferTaskListController(Core::System& system_) |  | ||||||
|         : ServiceFramework{system_, "ITransferTaskListController"} { |  | ||||||
|         // clang-format off |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {0, nullptr, "Unknown0"}, |  | ||||||
|             {1, nullptr, "Unknown1"}, |  | ||||||
|             {2, nullptr, "Unknown2"}, |  | ||||||
|             {3, nullptr, "Unknown3"}, |  | ||||||
|             {4, nullptr, "Unknown4"}, |  | ||||||
|             {5, &ITransferTaskListController::GetNativeHandleHolder , "GetNativeHandleHolder"}, |  | ||||||
|             {6, nullptr, "Unknown6"}, |  | ||||||
|             {7, nullptr, "Unknown7"}, |  | ||||||
|             {8, nullptr, "GetRemoteStorageController"}, |  | ||||||
|             {9, &ITransferTaskListController::GetNativeHandleHolder, "GetNativeHandleHolder2"}, |  | ||||||
|             {10, nullptr, "Unknown10"}, |  | ||||||
|             {11, nullptr, "Unknown11"}, |  | ||||||
|             {12, nullptr, "Unknown12"}, |  | ||||||
|             {13, nullptr, "Unknown13"}, |  | ||||||
|             {14, nullptr, "Unknown14"}, |  | ||||||
|             {15, nullptr, "Unknown15"}, |  | ||||||
|             {16, nullptr, "Unknown16"}, |  | ||||||
|             {17, nullptr, "Unknown17"}, |  | ||||||
|             {18, nullptr, "Unknown18"}, |  | ||||||
|             {19, nullptr, "Unknown19"}, |  | ||||||
|             {20, nullptr, "Unknown20"}, |  | ||||||
|             {21, nullptr, "Unknown21"}, |  | ||||||
|             {22, nullptr, "Unknown22"}, |  | ||||||
|             {23, nullptr, "Unknown23"}, |  | ||||||
|             {24, nullptr, "Unknown24"}, |  | ||||||
|             {25, nullptr, "Unknown25"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on |  | ||||||
|  |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     void GetNativeHandleHolder(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_OLSC, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushIpcInterface<INativeHandleHolder>(system); |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> { |  | ||||||
| public: |  | ||||||
|     explicit IOlscServiceForSystemService(Core::System& system_) |  | ||||||
|         : ServiceFramework{system_, "olsc:s"} { |  | ||||||
|         // clang-format off |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {0, &IOlscServiceForSystemService::OpenTransferTaskListController, "OpenTransferTaskListController"}, |  | ||||||
|             {1, nullptr, "OpenRemoteStorageController"}, |  | ||||||
|             {2, nullptr, "OpenDaemonController"}, |  | ||||||
|             {10, nullptr, "Unknown10"}, |  | ||||||
|             {11, nullptr, "Unknown11"}, |  | ||||||
|             {12, nullptr, "Unknown12"}, |  | ||||||
|             {13, nullptr, "Unknown13"}, |  | ||||||
|             {100, nullptr, "ListLastTransferTaskErrorInfo"}, |  | ||||||
|             {101, nullptr, "GetLastErrorInfoCount"}, |  | ||||||
|             {102, nullptr, "RemoveLastErrorInfoOld"}, |  | ||||||
|             {103, nullptr, "GetLastErrorInfo"}, |  | ||||||
|             {104, nullptr, "GetLastErrorEventHolder"}, |  | ||||||
|             {105, nullptr, "GetLastTransferTaskErrorInfo"}, |  | ||||||
|             {200, nullptr, "GetDataTransferPolicyInfo"}, |  | ||||||
|             {201, nullptr, "RemoveDataTransferPolicyInfo"}, |  | ||||||
|             {202, nullptr, "UpdateDataTransferPolicyOld"}, |  | ||||||
|             {203, nullptr, "UpdateDataTransferPolicy"}, |  | ||||||
|             {204, nullptr, "CleanupDataTransferPolicyInfo"}, |  | ||||||
|             {205, nullptr, "RequestDataTransferPolicy"}, |  | ||||||
|             {300, nullptr, "GetAutoTransferSeriesInfo"}, |  | ||||||
|             {301, nullptr, "UpdateAutoTransferSeriesInfo"}, |  | ||||||
|             {400, nullptr, "CleanupSaveDataArchiveInfoType1"}, |  | ||||||
|             {900, nullptr, "CleanupTransferTask"}, |  | ||||||
|             {902, nullptr, "CleanupSeriesInfoType0"}, |  | ||||||
|             {903, nullptr, "CleanupSaveDataArchiveInfoType0"}, |  | ||||||
|             {904, nullptr, "CleanupApplicationAutoTransferSetting"}, |  | ||||||
|             {905, nullptr, "CleanupErrorHistory"}, |  | ||||||
|             {906, nullptr, "SetLastError"}, |  | ||||||
|             {907, nullptr, "AddSaveDataArchiveInfoType0"}, |  | ||||||
|             {908, nullptr, "RemoveSeriesInfoType0"}, |  | ||||||
|             {909, nullptr, "GetSeriesInfoType0"}, |  | ||||||
|             {910, nullptr, "RemoveLastErrorInfo"}, |  | ||||||
|             {911, nullptr, "CleanupSeriesInfoType1"}, |  | ||||||
|             {912, nullptr, "RemoveSeriesInfoType1"}, |  | ||||||
|             {913, nullptr, "GetSeriesInfoType1"}, |  | ||||||
|             {1000, nullptr, "UpdateIssueOld"}, |  | ||||||
|             {1010, nullptr, "Unknown1010"}, |  | ||||||
|             {1011, nullptr, "ListIssueInfoOld"}, |  | ||||||
|             {1012, nullptr, "GetIssueOld"}, |  | ||||||
|             {1013, nullptr, "GetIssue2Old"}, |  | ||||||
|             {1014, nullptr, "GetIssue3Old"}, |  | ||||||
|             {1020, nullptr, "RepairIssueOld"}, |  | ||||||
|             {1021, nullptr, "RepairIssueWithUserIdOld"}, |  | ||||||
|             {1022, nullptr, "RepairIssue2Old"}, |  | ||||||
|             {1023, nullptr, "RepairIssue3Old"}, |  | ||||||
|             {1024, nullptr, "Unknown1024"}, |  | ||||||
|             {1100, nullptr, "UpdateIssue"}, |  | ||||||
|             {1110, nullptr, "Unknown1110"}, |  | ||||||
|             {1111, nullptr, "ListIssueInfo"}, |  | ||||||
|             {1112, nullptr, "GetIssue"}, |  | ||||||
|             {1113, nullptr, "GetIssue2"}, |  | ||||||
|             {1114, nullptr, "GetIssue3"}, |  | ||||||
|             {1120, nullptr, "RepairIssue"}, |  | ||||||
|             {1121, nullptr, "RepairIssueWithUserId"}, |  | ||||||
|             {1122, nullptr, "RepairIssue2"}, |  | ||||||
|             {1123, nullptr, "RepairIssue3"}, |  | ||||||
|             {1124, nullptr, "Unknown1124"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on |  | ||||||
|  |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     void OpenTransferTaskListController(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_OLSC, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushIpcInterface<ITransferTaskListController>(system); |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| void LoopProcess(Core::System& system) { | void LoopProcess(Core::System& system) { | ||||||
|     auto server_manager = std::make_unique<ServerManager>(system); |     auto server_manager = std::make_unique<ServerManager>(system); | ||||||
|  |  | ||||||
|     server_manager->RegisterNamedService("olsc:u", |     const auto OlscFactoryForApplication = [&] { | ||||||
|                                          std::make_shared<IOlscServiceForApplication>(system)); |         return std::make_shared<IOlscServiceForApplication>(system); | ||||||
|     server_manager->RegisterNamedService("olsc:s", |     }; | ||||||
|                                          std::make_shared<IOlscServiceForSystemService>(system)); |  | ||||||
|  |     const auto OlscFactoryForSystemService = [&] { | ||||||
|  |         return std::make_shared<IOlscServiceForSystemService>(system); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     server_manager->RegisterNamedService("olsc:u", OlscFactoryForApplication); | ||||||
|  |     server_manager->RegisterNamedService("olsc:s", OlscFactoryForSystemService); | ||||||
|  |  | ||||||
|     ServerManager::RunServer(std::move(server_manager)); |     ServerManager::RunServer(std::move(server_manager)); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										63
									
								
								src/core/hle/service/olsc/olsc_service_for_application.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/core/hle/service/olsc/olsc_service_for_application.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/olsc_service_for_application.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | IOlscServiceForApplication::IOlscServiceForApplication(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "olsc:u"} { | ||||||
|  |     // clang-format off | ||||||
|  |         static const FunctionInfo functions[] = { | ||||||
|  |             {0, D<&IOlscServiceForApplication::Initialize>, "Initialize"}, | ||||||
|  |             {10, nullptr, "VerifySaveDataBackupLicenseAsync"}, | ||||||
|  |             {13, D<&IOlscServiceForApplication::GetSaveDataBackupSetting>, "GetSaveDataBackupSetting"}, | ||||||
|  |             {14, D<&IOlscServiceForApplication::SetSaveDataBackupSettingEnabled>, "SetSaveDataBackupSettingEnabled"}, | ||||||
|  |             {15, nullptr, "SetCustomData"}, | ||||||
|  |             {16, nullptr, "DeleteSaveDataBackupSetting"}, | ||||||
|  |             {18, nullptr, "GetSaveDataBackupInfoCache"}, | ||||||
|  |             {19, nullptr, "UpdateSaveDataBackupInfoCacheAsync"}, | ||||||
|  |             {22, nullptr, "DeleteSaveDataBackupAsync"}, | ||||||
|  |             {25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"}, | ||||||
|  |             {26, nullptr, "DownloadSaveDataBackupAsync"}, | ||||||
|  |             {27, nullptr, "UploadSaveDataBackupAsync"}, | ||||||
|  |             {9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"}, | ||||||
|  |             {9013, nullptr, "GetSaveDataBackupSettingForDebug"}, | ||||||
|  |             {9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"}, | ||||||
|  |             {9015, nullptr, "SetCustomDataForDebug"}, | ||||||
|  |             {9016, nullptr, "DeleteSaveDataBackupSettingForDebug"}, | ||||||
|  |             {9018, nullptr, "GetSaveDataBackupInfoCacheForDebug"}, | ||||||
|  |             {9019, nullptr, "UpdateSaveDataBackupInfoCacheAsyncForDebug"}, | ||||||
|  |             {9022, nullptr, "DeleteSaveDataBackupAsyncForDebug"}, | ||||||
|  |             {9025, nullptr, "ListDownloadableSaveDataBackupInfoAsyncForDebug"}, | ||||||
|  |             {9026, nullptr, "DownloadSaveDataBackupAsyncForDebug"}, | ||||||
|  |         }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IOlscServiceForApplication::~IOlscServiceForApplication() = default; | ||||||
|  |  | ||||||
|  | Result IOlscServiceForApplication::Initialize(ClientProcessId process_id) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called"); | ||||||
|  |     initialized = true; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForApplication::GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called"); | ||||||
|  |     // backup_setting is set to 0 since real value is unknown | ||||||
|  |     *out_save_data_backup_setting = 0; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForApplication::SetSaveDataBackupSettingEnabled(bool enabled, | ||||||
|  |                                                                    NS::Uid account_id) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called, enabled={}, account_id={}", enabled, | ||||||
|  |                 account_id.uuid.FormattedString()); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										23
									
								
								src/core/hle/service/olsc/olsc_service_for_application.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/core/hle/service/olsc/olsc_service_for_application.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/ns/ns_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class IOlscServiceForApplication final : public ServiceFramework<IOlscServiceForApplication> { | ||||||
|  | public: | ||||||
|  |     explicit IOlscServiceForApplication(Core::System& system_); | ||||||
|  |     ~IOlscServiceForApplication() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result Initialize(ClientProcessId process_id); | ||||||
|  |     Result GetSaveDataBackupSetting(Out<u8> out_save_data_backup_setting); | ||||||
|  |     Result SetSaveDataBackupSettingEnabled(bool enabled, NS::Uid account_id); | ||||||
|  |  | ||||||
|  |     bool initialized{}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										117
									
								
								src/core/hle/service/olsc/olsc_service_for_system_service.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/core/hle/service/olsc/olsc_service_for_system_service.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/daemon_controller.h" | ||||||
|  | #include "core/hle/service/olsc/olsc_service_for_system_service.h" | ||||||
|  | #include "core/hle/service/olsc/remote_storage_controller.h" | ||||||
|  | #include "core/hle/service/olsc/transfer_task_list_controller.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | IOlscServiceForSystemService::IOlscServiceForSystemService(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "olsc:s"} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, D<&IOlscServiceForSystemService::OpenTransferTaskListController>, "OpenTransferTaskListController"}, | ||||||
|  |         {1, D<&IOlscServiceForSystemService::OpenRemoteStorageController>, "OpenRemoteStorageController"}, | ||||||
|  |         {2, D<&IOlscServiceForSystemService::OpenDaemonController>, "OpenDaemonController"}, | ||||||
|  |         {10, nullptr, "Unknown10"}, | ||||||
|  |         {11, nullptr, "Unknown11"}, | ||||||
|  |         {12, nullptr, "Unknown12"}, | ||||||
|  |         {13, nullptr, "Unknown13"}, | ||||||
|  |         {100, nullptr, "ListLastTransferTaskErrorInfo"}, | ||||||
|  |         {101, nullptr, "GetLastErrorInfoCount"}, | ||||||
|  |         {102, nullptr, "RemoveLastErrorInfoOld"}, | ||||||
|  |         {103, nullptr, "GetLastErrorInfo"}, | ||||||
|  |         {104, nullptr, "GetLastErrorEventHolder"}, | ||||||
|  |         {105, nullptr, "GetLastTransferTaskErrorInfo"}, | ||||||
|  |         {200, D<&IOlscServiceForSystemService::GetDataTransferPolicyInfo>, "GetDataTransferPolicyInfo"}, | ||||||
|  |         {201, nullptr, "RemoveDataTransferPolicyInfo"}, | ||||||
|  |         {202, nullptr, "UpdateDataTransferPolicyOld"}, | ||||||
|  |         {203, nullptr, "UpdateDataTransferPolicy"}, | ||||||
|  |         {204, nullptr, "CleanupDataTransferPolicyInfo"}, | ||||||
|  |         {205, nullptr, "RequestDataTransferPolicy"}, | ||||||
|  |         {300, nullptr, "GetAutoTransferSeriesInfo"}, | ||||||
|  |         {301, nullptr, "UpdateAutoTransferSeriesInfo"}, | ||||||
|  |         {400, nullptr, "CleanupSaveDataArchiveInfoType1"}, | ||||||
|  |         {900, nullptr, "CleanupTransferTask"}, | ||||||
|  |         {902, nullptr, "CleanupSeriesInfoType0"}, | ||||||
|  |         {903, nullptr, "CleanupSaveDataArchiveInfoType0"}, | ||||||
|  |         {904, nullptr, "CleanupApplicationAutoTransferSetting"}, | ||||||
|  |         {905, nullptr, "CleanupErrorHistory"}, | ||||||
|  |         {906, nullptr, "SetLastError"}, | ||||||
|  |         {907, nullptr, "AddSaveDataArchiveInfoType0"}, | ||||||
|  |         {908, nullptr, "RemoveSeriesInfoType0"}, | ||||||
|  |         {909, nullptr, "GetSeriesInfoType0"}, | ||||||
|  |         {910, nullptr, "RemoveLastErrorInfo"}, | ||||||
|  |         {911, nullptr, "CleanupSeriesInfoType1"}, | ||||||
|  |         {912, nullptr, "RemoveSeriesInfoType1"}, | ||||||
|  |         {913, nullptr, "GetSeriesInfoType1"}, | ||||||
|  |         {1000, nullptr, "UpdateIssueOld"}, | ||||||
|  |         {1010, nullptr, "Unknown1010"}, | ||||||
|  |         {1011, nullptr, "ListIssueInfoOld"}, | ||||||
|  |         {1012, nullptr, "GetIssueOld"}, | ||||||
|  |         {1013, nullptr, "GetIssue2Old"}, | ||||||
|  |         {1014, nullptr, "GetIssue3Old"}, | ||||||
|  |         {1020, nullptr, "RepairIssueOld"}, | ||||||
|  |         {1021, nullptr, "RepairIssueWithUserIdOld"}, | ||||||
|  |         {1022, nullptr, "RepairIssue2Old"}, | ||||||
|  |         {1023, nullptr, "RepairIssue3Old"}, | ||||||
|  |         {1024, nullptr, "Unknown1024"}, | ||||||
|  |         {1100, nullptr, "UpdateIssue"}, | ||||||
|  |         {1110, nullptr, "Unknown1110"}, | ||||||
|  |         {1111, nullptr, "ListIssueInfo"}, | ||||||
|  |         {1112, nullptr, "GetIssue"}, | ||||||
|  |         {1113, nullptr, "GetIssue2"}, | ||||||
|  |         {1114, nullptr, "GetIssue3"}, | ||||||
|  |         {1120, nullptr, "RepairIssue"}, | ||||||
|  |         {1121, nullptr, "RepairIssueWithUserId"}, | ||||||
|  |         {1122, nullptr, "RepairIssue2"}, | ||||||
|  |         {1123, nullptr, "RepairIssue3"}, | ||||||
|  |         {1124, nullptr, "Unknown1124"}, | ||||||
|  |         {10000, D<&IOlscServiceForSystemService::CloneService>, "CloneService"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IOlscServiceForSystemService::~IOlscServiceForSystemService() = default; | ||||||
|  |  | ||||||
|  | Result IOlscServiceForSystemService::OpenTransferTaskListController( | ||||||
|  |     Out<SharedPointer<ITransferTaskListController>> out_interface) { | ||||||
|  |     LOG_INFO(Service_OLSC, "called"); | ||||||
|  |     *out_interface = std::make_shared<ITransferTaskListController>(system); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForSystemService::OpenRemoteStorageController( | ||||||
|  |     Out<SharedPointer<IRemoteStorageController>> out_interface) { | ||||||
|  |     LOG_INFO(Service_OLSC, "called"); | ||||||
|  |     *out_interface = std::make_shared<IRemoteStorageController>(system); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForSystemService::OpenDaemonController( | ||||||
|  |     Out<SharedPointer<IDaemonController>> out_interface) { | ||||||
|  |     LOG_INFO(Service_OLSC, "called"); | ||||||
|  |     *out_interface = std::make_shared<IDaemonController>(system); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(Out<u16> out_policy_info, | ||||||
|  |                                                                u64 application_id) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called"); | ||||||
|  |     *out_policy_info = 0; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IOlscServiceForSystemService::CloneService( | ||||||
|  |     Out<SharedPointer<IOlscServiceForSystemService>> out_interface) { | ||||||
|  |     LOG_INFO(Service_OLSC, "called"); | ||||||
|  |     *out_interface = std::static_pointer_cast<IOlscServiceForSystemService>(shared_from_this()); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										27
									
								
								src/core/hle/service/olsc/olsc_service_for_system_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/core/hle/service/olsc/olsc_service_for_system_service.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class IDaemonController; | ||||||
|  | class IRemoteStorageController; | ||||||
|  | class ITransferTaskListController; | ||||||
|  |  | ||||||
|  | class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> { | ||||||
|  | public: | ||||||
|  |     explicit IOlscServiceForSystemService(Core::System& system_); | ||||||
|  |     ~IOlscServiceForSystemService() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result OpenTransferTaskListController( | ||||||
|  |         Out<SharedPointer<ITransferTaskListController>> out_interface); | ||||||
|  |     Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface); | ||||||
|  |     Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface); | ||||||
|  |     Result GetDataTransferPolicyInfo(Out<u16> out_policy_info, u64 application_id); | ||||||
|  |     Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										54
									
								
								src/core/hle/service/olsc/remote_storage_controller.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/core/hle/service/olsc/remote_storage_controller.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/remote_storage_controller.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | IRemoteStorageController::IRemoteStorageController(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "IRemoteStorageController"} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, nullptr, "GetSaveDataArchiveInfoBySaveDataId"}, | ||||||
|  |         {1, nullptr, "GetSaveDataArchiveInfoByApplicationId"}, | ||||||
|  |         {3, nullptr, "GetSaveDataArchiveCount"}, | ||||||
|  |         {6, nullptr, "CleanupSaveDataArchives"}, | ||||||
|  |         {7, nullptr, "CreateSaveDataArchiveCacheUpdationTask"}, | ||||||
|  |         {8, nullptr, "CreateSaveDataArchiveCacheUpdationForSpecifiedApplicationTask"}, | ||||||
|  |         {9, nullptr, "Delete"}, | ||||||
|  |         {10, nullptr, "GetSeriesInfo"}, | ||||||
|  |         {11, nullptr, "CreateDeleteDataTask"}, | ||||||
|  |         {12, nullptr, "DeleteSeriesInfo"}, | ||||||
|  |         {13, nullptr, "CreateRegisterNotificationTokenTask"}, | ||||||
|  |         {14, nullptr, "UpdateSeriesInfo"}, | ||||||
|  |         {15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"}, | ||||||
|  |         {16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"}, | ||||||
|  |         {17, nullptr, "ListDataInfo"}, | ||||||
|  |         {18, nullptr, "GetDataInfo"}, | ||||||
|  |         {19, nullptr, "Unknown19"}, | ||||||
|  |         {20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"}, | ||||||
|  |         {21, nullptr, "ListSecondarySaves"}, | ||||||
|  |         {22, D<&IRemoteStorageController::GetSecondarySave>, "GetSecondarySave"}, | ||||||
|  |         {23, nullptr, "TouchSecondarySave"}, | ||||||
|  |         {24, nullptr, "GetSecondarySaveDataInfo"}, | ||||||
|  |         {25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"}, | ||||||
|  |         {900, nullptr, "Unknown900"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IRemoteStorageController::~IRemoteStorageController() = default; | ||||||
|  |  | ||||||
|  | Result IRemoteStorageController::GetSecondarySave(Out<bool> out_has_secondary_save, | ||||||
|  |                                                   Out<std::array<u64, 3>> out_unknown, | ||||||
|  |                                                   u64 application_id) { | ||||||
|  |     LOG_ERROR(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id); | ||||||
|  |     *out_has_secondary_save = false; | ||||||
|  |     *out_unknown = {}; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										19
									
								
								src/core/hle/service/olsc/remote_storage_controller.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/core/hle/service/olsc/remote_storage_controller.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class IRemoteStorageController final : public ServiceFramework<IRemoteStorageController> { | ||||||
|  | public: | ||||||
|  |     explicit IRemoteStorageController(Core::System& system_); | ||||||
|  |     ~IRemoteStorageController() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown, | ||||||
|  |                             u64 application_id); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										55
									
								
								src/core/hle/service/olsc/transfer_task_list_controller.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/core/hle/service/olsc/transfer_task_list_controller.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/olsc/native_handle_holder.h" | ||||||
|  | #include "core/hle/service/olsc/transfer_task_list_controller.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | ITransferTaskListController::ITransferTaskListController(Core::System& system_) | ||||||
|  |     : ServiceFramework{system_, "ITransferTaskListController"} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, nullptr, "Unknown0"}, | ||||||
|  |         {1, nullptr, "Unknown1"}, | ||||||
|  |         {2, nullptr, "Unknown2"}, | ||||||
|  |         {3, nullptr, "Unknown3"}, | ||||||
|  |         {4, nullptr, "Unknown4"}, | ||||||
|  |         {5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"}, | ||||||
|  |         {6, nullptr, "Unknown6"}, | ||||||
|  |         {7, nullptr, "Unknown7"}, | ||||||
|  |         {8, nullptr, "GetRemoteStorageController"}, | ||||||
|  |         {9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"}, | ||||||
|  |         {10, nullptr, "Unknown10"}, | ||||||
|  |         {11, nullptr, "Unknown11"}, | ||||||
|  |         {12, nullptr, "Unknown12"}, | ||||||
|  |         {13, nullptr, "Unknown13"}, | ||||||
|  |         {14, nullptr, "Unknown14"}, | ||||||
|  |         {15, nullptr, "Unknown15"}, | ||||||
|  |         {16, nullptr, "Unknown16"}, | ||||||
|  |         {17, nullptr, "Unknown17"}, | ||||||
|  |         {18, nullptr, "Unknown18"}, | ||||||
|  |         {19, nullptr, "Unknown19"}, | ||||||
|  |         {20, nullptr, "Unknown20"}, | ||||||
|  |         {21, nullptr, "Unknown21"}, | ||||||
|  |         {22, nullptr, "Unknown22"}, | ||||||
|  |         {23, nullptr, "Unknown23"}, | ||||||
|  |         {24, nullptr, "Unknown24"}, | ||||||
|  |         {25, nullptr, "Unknown25"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |  | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ITransferTaskListController::~ITransferTaskListController() = default; | ||||||
|  |  | ||||||
|  | Result ITransferTaskListController::GetNativeHandleHolder( | ||||||
|  |     Out<SharedPointer<INativeHandleHolder>> out_holder) { | ||||||
|  |     LOG_WARNING(Service_OLSC, "(STUBBED) called"); | ||||||
|  |     *out_holder = std::make_shared<INativeHandleHolder>(system); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										20
									
								
								src/core/hle/service/olsc/transfer_task_list_controller.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/core/hle/service/olsc/transfer_task_list_controller.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::OLSC { | ||||||
|  |  | ||||||
|  | class INativeHandleHolder; | ||||||
|  |  | ||||||
|  | class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> { | ||||||
|  | public: | ||||||
|  |     explicit ITransferTaskListController(Core::System& system_); | ||||||
|  |     ~ITransferTaskListController() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::OLSC | ||||||
							
								
								
									
										434
									
								
								src/core/hle/service/pctl/parental_control_service.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								src/core/hle/service/pctl/parental_control_service.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,434 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/core.h" | ||||||
|  | #include "core/file_sys/control_metadata.h" | ||||||
|  | #include "core/file_sys/patch_manager.h" | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/pctl/parental_control_service.h" | ||||||
|  | #include "core/hle/service/pctl/pctl_results.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | IParentalControlService::IParentalControlService(Core::System& system_, Capability capability_) | ||||||
|  |     : ServiceFramework{system_, "IParentalControlService"}, capability{capability_}, | ||||||
|  |       service_context{system_, "IParentalControlService"}, synchronization_event{service_context}, | ||||||
|  |       unlinked_event{service_context}, request_suspension_event{service_context} { | ||||||
|  |     // clang-format off | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {1, D<&IParentalControlService::Initialize>, "Initialize"}, | ||||||
|  |         {1001, D<&IParentalControlService::CheckFreeCommunicationPermission>, "CheckFreeCommunicationPermission"}, | ||||||
|  |         {1002, D<&IParentalControlService::ConfirmLaunchApplicationPermission>, "ConfirmLaunchApplicationPermission"}, | ||||||
|  |         {1003, D<&IParentalControlService::ConfirmResumeApplicationPermission>, "ConfirmResumeApplicationPermission"}, | ||||||
|  |         {1004, D<&IParentalControlService::ConfirmSnsPostPermission>, "ConfirmSnsPostPermission"}, | ||||||
|  |         {1005, nullptr, "ConfirmSystemSettingsPermission"}, | ||||||
|  |         {1006, D<&IParentalControlService::IsRestrictionTemporaryUnlocked>, "IsRestrictionTemporaryUnlocked"}, | ||||||
|  |         {1007, nullptr, "RevertRestrictionTemporaryUnlocked"}, | ||||||
|  |         {1008, nullptr, "EnterRestrictedSystemSettings"}, | ||||||
|  |         {1009, nullptr, "LeaveRestrictedSystemSettings"}, | ||||||
|  |         {1010, D<&IParentalControlService::IsRestrictedSystemSettingsEntered>, "IsRestrictedSystemSettingsEntered"}, | ||||||
|  |         {1011, nullptr, "RevertRestrictedSystemSettingsEntered"}, | ||||||
|  |         {1012, nullptr, "GetRestrictedFeatures"}, | ||||||
|  |         {1013, D<&IParentalControlService::ConfirmStereoVisionPermission>, "ConfirmStereoVisionPermission"}, | ||||||
|  |         {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, | ||||||
|  |         {1015, nullptr, "ConfirmPlayableApplicationVideo"}, | ||||||
|  |         {1016, nullptr, "ConfirmShowNewsPermission"}, | ||||||
|  |         {1017, D<&IParentalControlService::EndFreeCommunication>, "EndFreeCommunication"}, | ||||||
|  |         {1018, D<&IParentalControlService::IsFreeCommunicationAvailable>, "IsFreeCommunicationAvailable"}, | ||||||
|  |         {1031, D<&IParentalControlService::IsRestrictionEnabled>, "IsRestrictionEnabled"}, | ||||||
|  |         {1032, D<&IParentalControlService::GetSafetyLevel>, "GetSafetyLevel"}, | ||||||
|  |         {1033, nullptr, "SetSafetyLevel"}, | ||||||
|  |         {1034, nullptr, "GetSafetyLevelSettings"}, | ||||||
|  |         {1035, D<&IParentalControlService::GetCurrentSettings>, "GetCurrentSettings"}, | ||||||
|  |         {1036, nullptr, "SetCustomSafetyLevelSettings"}, | ||||||
|  |         {1037, nullptr, "GetDefaultRatingOrganization"}, | ||||||
|  |         {1038, nullptr, "SetDefaultRatingOrganization"}, | ||||||
|  |         {1039, D<&IParentalControlService::GetFreeCommunicationApplicationListCount>, "GetFreeCommunicationApplicationListCount"}, | ||||||
|  |         {1042, nullptr, "AddToFreeCommunicationApplicationList"}, | ||||||
|  |         {1043, nullptr, "DeleteSettings"}, | ||||||
|  |         {1044, nullptr, "GetFreeCommunicationApplicationList"}, | ||||||
|  |         {1045, nullptr, "UpdateFreeCommunicationApplicationList"}, | ||||||
|  |         {1046, nullptr, "DisableFeaturesForReset"}, | ||||||
|  |         {1047, nullptr, "NotifyApplicationDownloadStarted"}, | ||||||
|  |         {1048, nullptr, "NotifyNetworkProfileCreated"}, | ||||||
|  |         {1049, nullptr, "ResetFreeCommunicationApplicationList"}, | ||||||
|  |         {1061, D<&IParentalControlService::ConfirmStereoVisionRestrictionConfigurable>, "ConfirmStereoVisionRestrictionConfigurable"}, | ||||||
|  |         {1062, D<&IParentalControlService::GetStereoVisionRestriction>, "GetStereoVisionRestriction"}, | ||||||
|  |         {1063, D<&IParentalControlService::SetStereoVisionRestriction>, "SetStereoVisionRestriction"}, | ||||||
|  |         {1064, D<&IParentalControlService::ResetConfirmedStereoVisionPermission>, "ResetConfirmedStereoVisionPermission"}, | ||||||
|  |         {1065, D<&IParentalControlService::IsStereoVisionPermitted>, "IsStereoVisionPermitted"}, | ||||||
|  |         {1201, nullptr, "UnlockRestrictionTemporarily"}, | ||||||
|  |         {1202, nullptr, "UnlockSystemSettingsRestriction"}, | ||||||
|  |         {1203, nullptr, "SetPinCode"}, | ||||||
|  |         {1204, nullptr, "GenerateInquiryCode"}, | ||||||
|  |         {1205, nullptr, "CheckMasterKey"}, | ||||||
|  |         {1206, D<&IParentalControlService::GetPinCodeLength>, "GetPinCodeLength"}, | ||||||
|  |         {1207, nullptr, "GetPinCodeChangedEvent"}, | ||||||
|  |         {1208, nullptr, "GetPinCode"}, | ||||||
|  |         {1403, D<&IParentalControlService::IsPairingActive>, "IsPairingActive"}, | ||||||
|  |         {1406, nullptr, "GetSettingsLastUpdated"}, | ||||||
|  |         {1411, nullptr, "GetPairingAccountInfo"}, | ||||||
|  |         {1421, nullptr, "GetAccountNickname"}, | ||||||
|  |         {1424, nullptr, "GetAccountState"}, | ||||||
|  |         {1425, nullptr, "RequestPostEvents"}, | ||||||
|  |         {1426, nullptr, "GetPostEventInterval"}, | ||||||
|  |         {1427, nullptr, "SetPostEventInterval"}, | ||||||
|  |         {1432, D<&IParentalControlService::GetSynchronizationEvent>, "GetSynchronizationEvent"}, | ||||||
|  |         {1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"}, | ||||||
|  |         {1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"}, | ||||||
|  |         {1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"}, | ||||||
|  |         {1454, nullptr, "GetPlayTimerRemainingTime"}, | ||||||
|  |         {1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"}, | ||||||
|  |         {1456, D<&IParentalControlService::GetPlayTimerSettings>, "GetPlayTimerSettings"}, | ||||||
|  |         {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"}, | ||||||
|  |         {1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"}, | ||||||
|  |         {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"}, | ||||||
|  |         {1472, nullptr, "CancelNetworkRequest"}, | ||||||
|  |         {1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"}, | ||||||
|  |         {1474, nullptr, "ClearUnlinkedEvent"}, | ||||||
|  |         {1601, nullptr, "DisableAllFeatures"}, | ||||||
|  |         {1602, nullptr, "PostEnableAllFeatures"}, | ||||||
|  |         {1603, nullptr, "IsAllFeaturesDisabled"}, | ||||||
|  |         {1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"}, | ||||||
|  |         {1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"}, | ||||||
|  |         {1903, nullptr, "GetExemptApplicationListCountForDebug"}, | ||||||
|  |         {1904, nullptr, "GetExemptApplicationListForDebug"}, | ||||||
|  |         {1905, nullptr, "UpdateExemptApplicationListForDebug"}, | ||||||
|  |         {1906, nullptr, "AddToExemptApplicationListForDebug"}, | ||||||
|  |         {1907, nullptr, "DeleteFromExemptApplicationListForDebug"}, | ||||||
|  |         {1908, nullptr, "ClearExemptApplicationListForDebug"}, | ||||||
|  |         {1941, nullptr, "DeletePairing"}, | ||||||
|  |         {1951, nullptr, "SetPlayTimerSettingsForDebug"}, | ||||||
|  |         {1952, nullptr, "GetPlayTimerSpentTimeForTest"}, | ||||||
|  |         {1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"}, | ||||||
|  |         {2001, nullptr, "RequestPairingAsync"}, | ||||||
|  |         {2002, nullptr, "FinishRequestPairing"}, | ||||||
|  |         {2003, nullptr, "AuthorizePairingAsync"}, | ||||||
|  |         {2004, nullptr, "FinishAuthorizePairing"}, | ||||||
|  |         {2005, nullptr, "RetrievePairingInfoAsync"}, | ||||||
|  |         {2006, nullptr, "FinishRetrievePairingInfo"}, | ||||||
|  |         {2007, nullptr, "UnlinkPairingAsync"}, | ||||||
|  |         {2008, nullptr, "FinishUnlinkPairing"}, | ||||||
|  |         {2009, nullptr, "GetAccountMiiImageAsync"}, | ||||||
|  |         {2010, nullptr, "FinishGetAccountMiiImage"}, | ||||||
|  |         {2011, nullptr, "GetAccountMiiImageContentTypeAsync"}, | ||||||
|  |         {2012, nullptr, "FinishGetAccountMiiImageContentType"}, | ||||||
|  |         {2013, nullptr, "SynchronizeParentalControlSettingsAsync"}, | ||||||
|  |         {2014, nullptr, "FinishSynchronizeParentalControlSettings"}, | ||||||
|  |         {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"}, | ||||||
|  |         {2016, nullptr, "RequestUpdateExemptionListAsync"}, | ||||||
|  |     }; | ||||||
|  |     // clang-format on | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IParentalControlService::~IParentalControlService() = default; | ||||||
|  |  | ||||||
|  | bool IParentalControlService::CheckFreeCommunicationPermissionImpl() const { | ||||||
|  |     if (states.temporary_unlocked) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if ((states.application_info.parental_control_flag & 1) == 0) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if (pin_code[0] == '\0') { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if (!settings.is_free_communication_default_on) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here | ||||||
|  |     // but as we don't have multiproceses support yet, we can just assume our application is | ||||||
|  |     // valid for the time being | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool IParentalControlService::ConfirmStereoVisionPermissionImpl() const { | ||||||
|  |     if (states.temporary_unlocked) { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if (pin_code[0] == '\0') { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     if (!settings.is_stero_vision_restricted) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void IParentalControlService::SetStereoVisionRestrictionImpl(bool is_restricted) { | ||||||
|  |     if (settings.disabled) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (pin_code[0] == '\0') { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     settings.is_stero_vision_restricted = is_restricted; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::Initialize() { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (False(capability & (Capability::Application | Capability::System))) { | ||||||
|  |         LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability); | ||||||
|  |         R_THROW(PCTL::ResultNoCapability); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO(ogniK): Recovery flag initialization for pctl:r | ||||||
|  |  | ||||||
|  |     const auto program_id = system.GetApplicationProcessProgramID(); | ||||||
|  |     if (program_id != 0) { | ||||||
|  |         const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), | ||||||
|  |                                        system.GetContentProvider()}; | ||||||
|  |         const auto control = pm.GetControlMetadata(); | ||||||
|  |         if (control.first) { | ||||||
|  |             states.tid_from_event = 0; | ||||||
|  |             states.launch_time_valid = false; | ||||||
|  |             states.is_suspended = false; | ||||||
|  |             states.free_communication = false; | ||||||
|  |             states.stereo_vision = false; | ||||||
|  |             states.application_info = ApplicationInfo{ | ||||||
|  |                 .application_id = program_id, | ||||||
|  |                 .age_rating = control.first->GetRatingAge(), | ||||||
|  |                 .parental_control_flag = control.first->GetParentalControlFlag(), | ||||||
|  |                 .capability = capability, | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             if (False(capability & (Capability::System | Capability::Recovery))) { | ||||||
|  |                 // TODO(ogniK): Signal application launch event | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::CheckFreeCommunicationPermission() { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (!CheckFreeCommunicationPermissionImpl()) { | ||||||
|  |         R_THROW(PCTL::ResultNoFreeCommunication); | ||||||
|  |     } else { | ||||||
|  |         states.free_communication = true; | ||||||
|  |         R_SUCCEED(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ConfirmLaunchApplicationPermission( | ||||||
|  |     InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag, | ||||||
|  |                 application_id); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ConfirmResumeApplicationPermission( | ||||||
|  |     InBuffer<BufferAttr_HipcPointer> restriction_bitset, u64 nacp_flag, u64 application_id) { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, nacp_flag={:#x} application_id={:016X}", nacp_flag, | ||||||
|  |                 application_id); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ConfirmSnsPostPermission() { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |     R_THROW(PCTL::ResultNoFreeCommunication); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsRestrictionTemporaryUnlocked( | ||||||
|  |     Out<bool> out_is_temporary_unlocked) { | ||||||
|  |     *out_is_temporary_unlocked = false; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}", | ||||||
|  |                 *out_is_temporary_unlocked); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsRestrictedSystemSettingsEntered( | ||||||
|  |     Out<bool> out_is_restricted_system_settings_entered) { | ||||||
|  |     *out_is_restricted_system_settings_entered = false; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}", | ||||||
|  |                 *out_is_restricted_system_settings_entered); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ConfirmStereoVisionPermission() { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |     states.stereo_vision = true; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::EndFreeCommunication() { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsFreeCommunicationAvailable() { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |  | ||||||
|  |     if (!CheckFreeCommunicationPermissionImpl()) { | ||||||
|  |         R_THROW(PCTL::ResultNoFreeCommunication); | ||||||
|  |     } else { | ||||||
|  |         R_SUCCEED(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsRestrictionEnabled(Out<bool> out_restriction_enabled) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (False(capability & (Capability::Status | Capability::Recovery))) { | ||||||
|  |         LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!"); | ||||||
|  |         *out_restriction_enabled = false; | ||||||
|  |         R_THROW(PCTL::ResultNoCapability); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     *out_restriction_enabled = pin_code[0] != '\0'; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetSafetyLevel(Out<u32> out_safety_level) { | ||||||
|  |     *out_safety_level = 0; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", *out_safety_level); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetCurrentSettings(Out<RestrictionSettings> out_settings) { | ||||||
|  |     LOG_INFO(Service_PCTL, "called"); | ||||||
|  |     *out_settings = restriction_settings; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetFreeCommunicationApplicationListCount(Out<s32> out_count) { | ||||||
|  |     *out_count = 4; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", *out_count); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ConfirmStereoVisionRestrictionConfigurable() { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (False(capability & Capability::StereoVision)) { | ||||||
|  |         LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||||||
|  |         R_THROW(PCTL::ResultNoCapability); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (pin_code[0] == '\0') { | ||||||
|  |         R_THROW(PCTL::ResultNoRestrictionEnabled); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsStereoVisionPermitted(Out<bool> out_is_permitted) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (!ConfirmStereoVisionPermissionImpl()) { | ||||||
|  |         *out_is_permitted = false; | ||||||
|  |         R_THROW(PCTL::ResultStereoVisionRestricted); | ||||||
|  |     } else { | ||||||
|  |         *out_is_permitted = true; | ||||||
|  |         R_SUCCEED(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetPinCodeLength(Out<s32> out_length) { | ||||||
|  |     *out_length = 0; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, length={}", *out_length); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsPairingActive(Out<bool> out_is_pairing_active) { | ||||||
|  |     *out_is_pairing_active = false; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", *out_is_pairing_active); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetSynchronizationEvent( | ||||||
|  |     OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||||
|  |     LOG_INFO(Service_PCTL, "called"); | ||||||
|  |     *out_event = synchronization_event.GetHandle(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::StartPlayTimer() { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::StopPlayTimer() { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled) { | ||||||
|  |     *out_is_play_timer_enabled = false; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, enabled={}", *out_is_play_timer_enabled); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer) { | ||||||
|  |     *out_is_restricted_by_play_timer = false; | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called, restricted={}", *out_is_restricted_by_play_timer); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetPlayTimerSettings( | ||||||
|  |     Out<PlayTimerSettings> out_play_timer_settings) { | ||||||
|  |     LOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||||||
|  |     *out_play_timer_settings = {}; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetPlayTimerEventToRequestSuspension( | ||||||
|  |     OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||||
|  |     LOG_INFO(Service_PCTL, "called"); | ||||||
|  |     *out_event = request_suspension_event.GetHandle(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled) { | ||||||
|  |     *out_play_timer_alarm_disabled = false; | ||||||
|  |     LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}", | ||||||
|  |              *out_play_timer_alarm_disabled); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||||
|  |     LOG_INFO(Service_PCTL, "called"); | ||||||
|  |     *out_event = unlinked_event.GetHandle(); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::GetStereoVisionRestriction( | ||||||
|  |     Out<bool> out_stereo_vision_restriction) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     if (False(capability & Capability::StereoVision)) { | ||||||
|  |         LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||||||
|  |         *out_stereo_vision_restriction = false; | ||||||
|  |         R_THROW(PCTL::ResultNoCapability); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     *out_stereo_vision_restriction = settings.is_stero_vision_restricted; | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::SetStereoVisionRestriction(bool stereo_vision_restriction) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called, can_use={}", stereo_vision_restriction); | ||||||
|  |  | ||||||
|  |     if (False(capability & Capability::StereoVision)) { | ||||||
|  |         LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); | ||||||
|  |         R_THROW(PCTL::ResultNoCapability); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SetStereoVisionRestrictionImpl(stereo_vision_restriction); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlService::ResetConfirmedStereoVisionPermission() { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |  | ||||||
|  |     states.stereo_vision = false; | ||||||
|  |  | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
							
								
								
									
										86
									
								
								src/core/hle/service/pctl/parental_control_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/core/hle/service/pctl/parental_control_service.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/kernel_helpers.h" | ||||||
|  | #include "core/hle/service/os/event.h" | ||||||
|  | #include "core/hle/service/pctl/pctl_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | class IParentalControlService final : public ServiceFramework<IParentalControlService> { | ||||||
|  | public: | ||||||
|  |     explicit IParentalControlService(Core::System& system_, Capability capability_); | ||||||
|  |     ~IParentalControlService() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     bool CheckFreeCommunicationPermissionImpl() const; | ||||||
|  |     bool ConfirmStereoVisionPermissionImpl() const; | ||||||
|  |     void SetStereoVisionRestrictionImpl(bool is_restricted); | ||||||
|  |  | ||||||
|  |     Result Initialize(); | ||||||
|  |     Result CheckFreeCommunicationPermission(); | ||||||
|  |     Result ConfirmLaunchApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset, | ||||||
|  |                                               u64 nacp_flag, u64 application_id); | ||||||
|  |     Result ConfirmResumeApplicationPermission(InBuffer<BufferAttr_HipcPointer> restriction_bitset, | ||||||
|  |                                               u64 nacp_flag, u64 application_id); | ||||||
|  |     Result ConfirmSnsPostPermission(); | ||||||
|  |     Result IsRestrictionTemporaryUnlocked(Out<bool> out_is_temporary_unlocked); | ||||||
|  |     Result IsRestrictedSystemSettingsEntered(Out<bool> out_is_restricted_system_settings_entered); | ||||||
|  |     Result ConfirmStereoVisionPermission(); | ||||||
|  |     Result EndFreeCommunication(); | ||||||
|  |     Result IsFreeCommunicationAvailable(); | ||||||
|  |     Result IsRestrictionEnabled(Out<bool> out_restriction_enabled); | ||||||
|  |     Result GetSafetyLevel(Out<u32> out_safety_level); | ||||||
|  |     Result GetCurrentSettings(Out<RestrictionSettings> out_settings); | ||||||
|  |     Result GetFreeCommunicationApplicationListCount(Out<s32> out_count); | ||||||
|  |     Result ConfirmStereoVisionRestrictionConfigurable(); | ||||||
|  |     Result IsStereoVisionPermitted(Out<bool> out_is_permitted); | ||||||
|  |     Result GetPinCodeLength(Out<s32> out_length); | ||||||
|  |     Result IsPairingActive(Out<bool> out_is_pairing_active); | ||||||
|  |     Result GetSynchronizationEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||||||
|  |     Result StartPlayTimer(); | ||||||
|  |     Result StopPlayTimer(); | ||||||
|  |     Result IsPlayTimerEnabled(Out<bool> out_is_play_timer_enabled); | ||||||
|  |     Result IsRestrictedByPlayTimer(Out<bool> out_is_restricted_by_play_timer); | ||||||
|  |     Result GetPlayTimerSettings(Out<PlayTimerSettings> out_play_timer_settings); | ||||||
|  |     Result GetPlayTimerEventToRequestSuspension(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||||||
|  |     Result IsPlayTimerAlarmDisabled(Out<bool> out_play_timer_alarm_disabled); | ||||||
|  |     Result GetUnlinkedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||||||
|  |     Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction); | ||||||
|  |     Result SetStereoVisionRestriction(bool stereo_vision_restriction); | ||||||
|  |     Result ResetConfirmedStereoVisionPermission(); | ||||||
|  |  | ||||||
|  |     struct States { | ||||||
|  |         u64 current_tid{}; | ||||||
|  |         ApplicationInfo application_info{}; | ||||||
|  |         u64 tid_from_event{}; | ||||||
|  |         bool launch_time_valid{}; | ||||||
|  |         bool is_suspended{}; | ||||||
|  |         bool temporary_unlocked{}; | ||||||
|  |         bool free_communication{}; | ||||||
|  |         bool stereo_vision{}; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     struct ParentalControlSettings { | ||||||
|  |         bool is_stero_vision_restricted{}; | ||||||
|  |         bool is_free_communication_default_on{}; | ||||||
|  |         bool disabled{}; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     States states{}; | ||||||
|  |     ParentalControlSettings settings{}; | ||||||
|  |     RestrictionSettings restriction_settings{}; | ||||||
|  |     std::array<char, 8> pin_code{}; | ||||||
|  |     Capability capability{}; | ||||||
|  |  | ||||||
|  |     KernelHelpers::ServiceContext service_context; | ||||||
|  |     Event synchronization_event; | ||||||
|  |     Event unlinked_event; | ||||||
|  |     Event request_suspension_event; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_serialization.h" | ||||||
|  | #include "core/hle/service/pctl/parental_control_service.h" | ||||||
|  | #include "core/hle/service/pctl/parental_control_service_factory.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | IParentalControlServiceFactory::IParentalControlServiceFactory(Core::System& system_, | ||||||
|  |                                                                const char* name_, | ||||||
|  |                                                                Capability capability_) | ||||||
|  |     : ServiceFramework{system_, name_}, capability{capability_} { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|  |         {0, D<&IParentalControlServiceFactory::CreateService>, "CreateService"}, | ||||||
|  |         {1, D<&IParentalControlServiceFactory::CreateServiceWithoutInitialize>, | ||||||
|  |          "CreateServiceWithoutInitialize"}, | ||||||
|  |     }; | ||||||
|  |     RegisterHandlers(functions); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IParentalControlServiceFactory::~IParentalControlServiceFactory() = default; | ||||||
|  |  | ||||||
|  | Result IParentalControlServiceFactory::CreateService( | ||||||
|  |     Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |     // TODO(ogniK): Get application id from process | ||||||
|  |     *out_service = std::make_shared<IParentalControlService>(system, capability); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Result IParentalControlServiceFactory::CreateServiceWithoutInitialize( | ||||||
|  |     Out<SharedPointer<IParentalControlService>> out_service, ClientProcessId process_id) { | ||||||
|  |     LOG_DEBUG(Service_PCTL, "called"); | ||||||
|  |     // TODO(ogniK): Get application id from process | ||||||
|  |     *out_service = std::make_shared<IParentalControlService>(system, capability); | ||||||
|  |     R_SUCCEED(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
							
								
								
									
										31
									
								
								src/core/hle/service/pctl/parental_control_service_factory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/core/hle/service/pctl/parental_control_service_factory.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "core/hle/service/cmif_types.h" | ||||||
|  | #include "core/hle/service/pctl/pctl_types.h" | ||||||
|  | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | class IParentalControlService; | ||||||
|  |  | ||||||
|  | class IParentalControlServiceFactory : public ServiceFramework<IParentalControlServiceFactory> { | ||||||
|  | public: | ||||||
|  |     explicit IParentalControlServiceFactory(Core::System& system_, const char* name_, | ||||||
|  |                                             Capability capability_); | ||||||
|  |     ~IParentalControlServiceFactory() override; | ||||||
|  |  | ||||||
|  |     Result CreateService(Out<SharedPointer<IParentalControlService>> out_service, | ||||||
|  |                          ClientProcessId process_id); | ||||||
|  |     Result CreateServiceWithoutInitialize(Out<SharedPointer<IParentalControlService>> out_service, | ||||||
|  |                                           ClientProcessId process_id); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     Capability capability{}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void LoopProcess(Core::System& system); | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
| @@ -1,19 +1,28 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #include "core/hle/service/pctl/parental_control_service_factory.h" | ||||||
| #include "core/hle/service/pctl/pctl.h" | #include "core/hle/service/pctl/pctl.h" | ||||||
|  | #include "core/hle/service/server_manager.h" | ||||||
|  |  | ||||||
| namespace Service::PCTL { | namespace Service::PCTL { | ||||||
|  |  | ||||||
| PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, | void LoopProcess(Core::System& system) { | ||||||
|            Capability capability_) |     auto server_manager = std::make_unique<ServerManager>(system); | ||||||
|     : Interface{system_, std::move(module_), name, capability_} { |  | ||||||
|     static const FunctionInfo functions[] = { |     server_manager->RegisterNamedService("pctl", | ||||||
|         {0, &PCTL::CreateService, "CreateService"}, |                                          std::make_shared<IParentalControlServiceFactory>( | ||||||
|         {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, |                                              system, "pctl", | ||||||
|     }; |                                              Capability::Application | Capability::SnsPost | | ||||||
|     RegisterHandlers(functions); |                                                  Capability::Status | Capability::StereoVision)); | ||||||
|  |     // TODO(ogniK): Implement remaining capabilities | ||||||
|  |     server_manager->RegisterNamedService("pctl:a", std::make_shared<IParentalControlServiceFactory>( | ||||||
|  |                                                        system, "pctl:a", Capability::None)); | ||||||
|  |     server_manager->RegisterNamedService("pctl:r", std::make_shared<IParentalControlServiceFactory>( | ||||||
|  |                                                        system, "pctl:r", Capability::None)); | ||||||
|  |     server_manager->RegisterNamedService("pctl:s", std::make_shared<IParentalControlServiceFactory>( | ||||||
|  |                                                        system, "pctl:s", Capability::None)); | ||||||
|  |     ServerManager::RunServer(std::move(server_manager)); | ||||||
| } | } | ||||||
|  |  | ||||||
| PCTL::~PCTL() = default; |  | ||||||
| } // namespace Service::PCTL | } // namespace Service::PCTL | ||||||
|   | |||||||
| @@ -3,19 +3,12 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "core/hle/service/pctl/pctl_module.h" |  | ||||||
|  |  | ||||||
| namespace Core { | namespace Core { | ||||||
| class System; | class System; | ||||||
| } | } | ||||||
|  |  | ||||||
| namespace Service::PCTL { | namespace Service::PCTL { | ||||||
|  |  | ||||||
| class PCTL final : public Module::Interface { | void LoopProcess(Core::System& system); | ||||||
| public: |  | ||||||
|     explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name, |  | ||||||
|                   Capability capability_); |  | ||||||
|     ~PCTL() override; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| } // namespace Service::PCTL | } // namespace Service::PCTL | ||||||
|   | |||||||
| @@ -1,550 +0,0 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |  | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later |  | ||||||
|  |  | ||||||
| #include "common/logging/log.h" |  | ||||||
| #include "core/core.h" |  | ||||||
| #include "core/file_sys/control_metadata.h" |  | ||||||
| #include "core/file_sys/patch_manager.h" |  | ||||||
| #include "core/hle/service/ipc_helpers.h" |  | ||||||
| #include "core/hle/service/kernel_helpers.h" |  | ||||||
| #include "core/hle/service/pctl/pctl.h" |  | ||||||
| #include "core/hle/service/pctl/pctl_module.h" |  | ||||||
| #include "core/hle/service/server_manager.h" |  | ||||||
|  |  | ||||||
| namespace Service::PCTL { |  | ||||||
|  |  | ||||||
| namespace Error { |  | ||||||
|  |  | ||||||
| constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101}; |  | ||||||
| constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104}; |  | ||||||
| constexpr Result ResultNoCapability{ErrorModule::PCTL, 131}; |  | ||||||
| constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181}; |  | ||||||
|  |  | ||||||
| } // namespace Error |  | ||||||
|  |  | ||||||
| class IParentalControlService final : public ServiceFramework<IParentalControlService> { |  | ||||||
| public: |  | ||||||
|     explicit IParentalControlService(Core::System& system_, Capability capability_) |  | ||||||
|         : ServiceFramework{system_, "IParentalControlService"}, capability{capability_}, |  | ||||||
|           service_context{system_, "IParentalControlService"} { |  | ||||||
|         // clang-format off |  | ||||||
|         static const FunctionInfo functions[] = { |  | ||||||
|             {1, &IParentalControlService::Initialize, "Initialize"}, |  | ||||||
|             {1001, &IParentalControlService::CheckFreeCommunicationPermission, "CheckFreeCommunicationPermission"}, |  | ||||||
|             {1002, nullptr, "ConfirmLaunchApplicationPermission"}, |  | ||||||
|             {1003, nullptr, "ConfirmResumeApplicationPermission"}, |  | ||||||
|             {1004, &IParentalControlService::ConfirmSnsPostPermission, "ConfirmSnsPostPermission"}, |  | ||||||
|             {1005, nullptr, "ConfirmSystemSettingsPermission"}, |  | ||||||
|             {1006, &IParentalControlService::IsRestrictionTemporaryUnlocked, "IsRestrictionTemporaryUnlocked"}, |  | ||||||
|             {1007, nullptr, "RevertRestrictionTemporaryUnlocked"}, |  | ||||||
|             {1008, nullptr, "EnterRestrictedSystemSettings"}, |  | ||||||
|             {1009, nullptr, "LeaveRestrictedSystemSettings"}, |  | ||||||
|             {1010, nullptr, "IsRestrictedSystemSettingsEntered"}, |  | ||||||
|             {1011, nullptr, "RevertRestrictedSystemSettingsEntered"}, |  | ||||||
|             {1012, nullptr, "GetRestrictedFeatures"}, |  | ||||||
|             {1013, &IParentalControlService::ConfirmStereoVisionPermission, "ConfirmStereoVisionPermission"}, |  | ||||||
|             {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, |  | ||||||
|             {1015, nullptr, "ConfirmPlayableApplicationVideo"}, |  | ||||||
|             {1016, nullptr, "ConfirmShowNewsPermission"}, |  | ||||||
|             {1017, &IParentalControlService::EndFreeCommunication, "EndFreeCommunication"}, |  | ||||||
|             {1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"}, |  | ||||||
|             {1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"}, |  | ||||||
|             {1032, &IParentalControlService::GetSafetyLevel, "GetSafetyLevel"}, |  | ||||||
|             {1033, nullptr, "SetSafetyLevel"}, |  | ||||||
|             {1034, nullptr, "GetSafetyLevelSettings"}, |  | ||||||
|             {1035, &IParentalControlService::GetCurrentSettings, "GetCurrentSettings"}, |  | ||||||
|             {1036, nullptr, "SetCustomSafetyLevelSettings"}, |  | ||||||
|             {1037, nullptr, "GetDefaultRatingOrganization"}, |  | ||||||
|             {1038, nullptr, "SetDefaultRatingOrganization"}, |  | ||||||
|             {1039, &IParentalControlService::GetFreeCommunicationApplicationListCount, "GetFreeCommunicationApplicationListCount"}, |  | ||||||
|             {1042, nullptr, "AddToFreeCommunicationApplicationList"}, |  | ||||||
|             {1043, nullptr, "DeleteSettings"}, |  | ||||||
|             {1044, nullptr, "GetFreeCommunicationApplicationList"}, |  | ||||||
|             {1045, nullptr, "UpdateFreeCommunicationApplicationList"}, |  | ||||||
|             {1046, nullptr, "DisableFeaturesForReset"}, |  | ||||||
|             {1047, nullptr, "NotifyApplicationDownloadStarted"}, |  | ||||||
|             {1048, nullptr, "NotifyNetworkProfileCreated"}, |  | ||||||
|             {1049, nullptr, "ResetFreeCommunicationApplicationList"}, |  | ||||||
|             {1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"}, |  | ||||||
|             {1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"}, |  | ||||||
|             {1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"}, |  | ||||||
|             {1064, &IParentalControlService::ResetConfirmedStereoVisionPermission, "ResetConfirmedStereoVisionPermission"}, |  | ||||||
|             {1065, &IParentalControlService::IsStereoVisionPermitted, "IsStereoVisionPermitted"}, |  | ||||||
|             {1201, nullptr, "UnlockRestrictionTemporarily"}, |  | ||||||
|             {1202, nullptr, "UnlockSystemSettingsRestriction"}, |  | ||||||
|             {1203, nullptr, "SetPinCode"}, |  | ||||||
|             {1204, nullptr, "GenerateInquiryCode"}, |  | ||||||
|             {1205, nullptr, "CheckMasterKey"}, |  | ||||||
|             {1206, nullptr, "GetPinCodeLength"}, |  | ||||||
|             {1207, nullptr, "GetPinCodeChangedEvent"}, |  | ||||||
|             {1208, nullptr, "GetPinCode"}, |  | ||||||
|             {1403, &IParentalControlService::IsPairingActive, "IsPairingActive"}, |  | ||||||
|             {1406, nullptr, "GetSettingsLastUpdated"}, |  | ||||||
|             {1411, nullptr, "GetPairingAccountInfo"}, |  | ||||||
|             {1421, nullptr, "GetAccountNickname"}, |  | ||||||
|             {1424, nullptr, "GetAccountState"}, |  | ||||||
|             {1425, nullptr, "RequestPostEvents"}, |  | ||||||
|             {1426, nullptr, "GetPostEventInterval"}, |  | ||||||
|             {1427, nullptr, "SetPostEventInterval"}, |  | ||||||
|             {1432, &IParentalControlService::GetSynchronizationEvent, "GetSynchronizationEvent"}, |  | ||||||
|             {1451, nullptr, "StartPlayTimer"}, |  | ||||||
|             {1452, nullptr, "StopPlayTimer"}, |  | ||||||
|             {1453, nullptr, "IsPlayTimerEnabled"}, |  | ||||||
|             {1454, nullptr, "GetPlayTimerRemainingTime"}, |  | ||||||
|             {1455, nullptr, "IsRestrictedByPlayTimer"}, |  | ||||||
|             {1456, &IParentalControlService::GetPlayTimerSettings, "GetPlayTimerSettings"}, |  | ||||||
|             {1457, &IParentalControlService::GetPlayTimerEventToRequestSuspension, "GetPlayTimerEventToRequestSuspension"}, |  | ||||||
|             {1458, &IParentalControlService::IsPlayTimerAlarmDisabled, "IsPlayTimerAlarmDisabled"}, |  | ||||||
|             {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"}, |  | ||||||
|             {1472, nullptr, "CancelNetworkRequest"}, |  | ||||||
|             {1473, &IParentalControlService::GetUnlinkedEvent, "GetUnlinkedEvent"}, |  | ||||||
|             {1474, nullptr, "ClearUnlinkedEvent"}, |  | ||||||
|             {1601, nullptr, "DisableAllFeatures"}, |  | ||||||
|             {1602, nullptr, "PostEnableAllFeatures"}, |  | ||||||
|             {1603, nullptr, "IsAllFeaturesDisabled"}, |  | ||||||
|             {1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"}, |  | ||||||
|             {1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"}, |  | ||||||
|             {1903, nullptr, "GetExemptApplicationListCountForDebug"}, |  | ||||||
|             {1904, nullptr, "GetExemptApplicationListForDebug"}, |  | ||||||
|             {1905, nullptr, "UpdateExemptApplicationListForDebug"}, |  | ||||||
|             {1906, nullptr, "AddToExemptApplicationListForDebug"}, |  | ||||||
|             {1907, nullptr, "DeleteFromExemptApplicationListForDebug"}, |  | ||||||
|             {1908, nullptr, "ClearExemptApplicationListForDebug"}, |  | ||||||
|             {1941, nullptr, "DeletePairing"}, |  | ||||||
|             {1951, nullptr, "SetPlayTimerSettingsForDebug"}, |  | ||||||
|             {1952, nullptr, "GetPlayTimerSpentTimeForTest"}, |  | ||||||
|             {1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"}, |  | ||||||
|             {2001, nullptr, "RequestPairingAsync"}, |  | ||||||
|             {2002, nullptr, "FinishRequestPairing"}, |  | ||||||
|             {2003, nullptr, "AuthorizePairingAsync"}, |  | ||||||
|             {2004, nullptr, "FinishAuthorizePairing"}, |  | ||||||
|             {2005, nullptr, "RetrievePairingInfoAsync"}, |  | ||||||
|             {2006, nullptr, "FinishRetrievePairingInfo"}, |  | ||||||
|             {2007, nullptr, "UnlinkPairingAsync"}, |  | ||||||
|             {2008, nullptr, "FinishUnlinkPairing"}, |  | ||||||
|             {2009, nullptr, "GetAccountMiiImageAsync"}, |  | ||||||
|             {2010, nullptr, "FinishGetAccountMiiImage"}, |  | ||||||
|             {2011, nullptr, "GetAccountMiiImageContentTypeAsync"}, |  | ||||||
|             {2012, nullptr, "FinishGetAccountMiiImageContentType"}, |  | ||||||
|             {2013, nullptr, "SynchronizeParentalControlSettingsAsync"}, |  | ||||||
|             {2014, nullptr, "FinishSynchronizeParentalControlSettings"}, |  | ||||||
|             {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"}, |  | ||||||
|             {2016, nullptr, "RequestUpdateExemptionListAsync"}, |  | ||||||
|         }; |  | ||||||
|         // clang-format on |  | ||||||
|         RegisterHandlers(functions); |  | ||||||
|  |  | ||||||
|         synchronization_event = |  | ||||||
|             service_context.CreateEvent("IParentalControlService::SynchronizationEvent"); |  | ||||||
|         unlinked_event = service_context.CreateEvent("IParentalControlService::UnlinkedEvent"); |  | ||||||
|         request_suspension_event = |  | ||||||
|             service_context.CreateEvent("IParentalControlService::RequestSuspensionEvent"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ~IParentalControlService() { |  | ||||||
|         service_context.CloseEvent(synchronization_event); |  | ||||||
|         service_context.CloseEvent(unlinked_event); |  | ||||||
|         service_context.CloseEvent(request_suspension_event); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     bool CheckFreeCommunicationPermissionImpl() const { |  | ||||||
|         if (states.temporary_unlocked) { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if ((states.application_info.parental_control_flag & 1) == 0) { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if (pin_code[0] == '\0') { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if (!settings.is_free_communication_default_on) { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here |  | ||||||
|         // but as we don't have multiproceses support yet, we can just assume our application is |  | ||||||
|         // valid for the time being |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool ConfirmStereoVisionPermissionImpl() const { |  | ||||||
|         if (states.temporary_unlocked) { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if (pin_code[0] == '\0') { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if (!settings.is_stero_vision_restricted) { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void SetStereoVisionRestrictionImpl(bool is_restricted) { |  | ||||||
|         if (settings.disabled) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (pin_code[0] == '\0') { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         settings.is_stero_vision_restricted = is_restricted; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void Initialize(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|  |  | ||||||
|         if (False(capability & (Capability::Application | Capability::System))) { |  | ||||||
|             LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // TODO(ogniK): Recovery flag initialization for pctl:r |  | ||||||
|  |  | ||||||
|         const auto tid = system.GetApplicationProcessProgramID(); |  | ||||||
|         if (tid != 0) { |  | ||||||
|             const FileSys::PatchManager pm{tid, system.GetFileSystemController(), |  | ||||||
|                                            system.GetContentProvider()}; |  | ||||||
|             const auto control = pm.GetControlMetadata(); |  | ||||||
|             if (control.first) { |  | ||||||
|                 states.tid_from_event = 0; |  | ||||||
|                 states.launch_time_valid = false; |  | ||||||
|                 states.is_suspended = false; |  | ||||||
|                 states.free_communication = false; |  | ||||||
|                 states.stereo_vision = false; |  | ||||||
|                 states.application_info = ApplicationInfo{ |  | ||||||
|                     .tid = tid, |  | ||||||
|                     .age_rating = control.first->GetRatingAge(), |  | ||||||
|                     .parental_control_flag = control.first->GetParentalControlFlag(), |  | ||||||
|                     .capability = capability, |  | ||||||
|                 }; |  | ||||||
|  |  | ||||||
|                 if (False(capability & (Capability::System | Capability::Recovery))) { |  | ||||||
|                     // TODO(ogniK): Signal application launch event |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void CheckFreeCommunicationPermission(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         if (!CheckFreeCommunicationPermissionImpl()) { |  | ||||||
|             rb.Push(Error::ResultNoFreeCommunication); |  | ||||||
|         } else { |  | ||||||
|             rb.Push(ResultSuccess); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         states.free_communication = true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void ConfirmSnsPostPermission(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(Error::ResultNoFreeCommunication); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsRestrictionTemporaryUnlocked(HLERequestContext& ctx) { |  | ||||||
|         const bool is_temporary_unlocked = false; |  | ||||||
|  |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called, is_temporary_unlocked={}", |  | ||||||
|                     is_temporary_unlocked); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push<u8>(is_temporary_unlocked); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void ConfirmStereoVisionPermission(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|         states.stereo_vision = true; |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void EndFreeCommunication(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsFreeCommunicationAvailable(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         if (!CheckFreeCommunicationPermissionImpl()) { |  | ||||||
|             rb.Push(Error::ResultNoFreeCommunication); |  | ||||||
|         } else { |  | ||||||
|             rb.Push(ResultSuccess); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsRestrictionEnabled(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         if (False(capability & (Capability::Status | Capability::Recovery))) { |  | ||||||
|             LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!"); |  | ||||||
|             rb.Push(Error::ResultNoCapability); |  | ||||||
|             rb.Push(false); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         rb.Push(pin_code[0] != '\0'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetSafetyLevel(HLERequestContext& ctx) { |  | ||||||
|         const u32 safety_level = 0; |  | ||||||
|  |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called, safety_level={}", safety_level); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push(safety_level); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetCurrentSettings(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushRaw(restriction_settings); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetFreeCommunicationApplicationListCount(HLERequestContext& ctx) { |  | ||||||
|         const u32 count = 4; |  | ||||||
|  |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called, count={}", count); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push(count); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void ConfirmStereoVisionRestrictionConfigurable(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|  |  | ||||||
|         if (False(capability & Capability::StereoVision)) { |  | ||||||
|             LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); |  | ||||||
|             rb.Push(Error::ResultNoCapability); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (pin_code[0] == '\0') { |  | ||||||
|             rb.Push(Error::ResultNoRestrictionEnabled); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsStereoVisionPermitted(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         if (!ConfirmStereoVisionPermissionImpl()) { |  | ||||||
|             rb.Push(Error::ResultStereoVisionRestricted); |  | ||||||
|             rb.Push(false); |  | ||||||
|         } else { |  | ||||||
|             rb.Push(ResultSuccess); |  | ||||||
|             rb.Push(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsPairingActive(HLERequestContext& ctx) { |  | ||||||
|         const bool is_pairing_active = false; |  | ||||||
|  |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called, is_pairing_active={}", is_pairing_active); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push<u8>(is_pairing_active); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetSynchronizationEvent(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushCopyObjects(synchronization_event->GetReadableEvent()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetPlayTimerSettings(HLERequestContext& ctx) { |  | ||||||
|         LOG_WARNING(Service_PCTL, "(STUBBED) called"); |  | ||||||
|  |  | ||||||
|         const PlayTimerSettings timer_settings{}; |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 15}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushRaw(timer_settings); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetPlayTimerEventToRequestSuspension(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushCopyObjects(request_suspension_event->GetReadableEvent()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void IsPlayTimerAlarmDisabled(HLERequestContext& ctx) { |  | ||||||
|         const bool is_play_timer_alarm_disabled = false; |  | ||||||
|  |  | ||||||
|         LOG_INFO(Service_PCTL, "called, is_play_timer_alarm_disabled={}", |  | ||||||
|                  is_play_timer_alarm_disabled); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push<u8>(is_play_timer_alarm_disabled); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetUnlinkedEvent(HLERequestContext& ctx) { |  | ||||||
|         LOG_INFO(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.PushCopyObjects(unlinked_event->GetReadableEvent()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void SetStereoVisionRestriction(HLERequestContext& ctx) { |  | ||||||
|         IPC::RequestParser rp{ctx}; |  | ||||||
|         const auto can_use = rp.Pop<bool>(); |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         if (False(capability & Capability::StereoVision)) { |  | ||||||
|             LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); |  | ||||||
|             rb.Push(Error::ResultNoCapability); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         SetStereoVisionRestrictionImpl(can_use); |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void GetStereoVisionRestriction(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 3}; |  | ||||||
|         if (False(capability & Capability::StereoVision)) { |  | ||||||
|             LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!"); |  | ||||||
|             rb.Push(Error::ResultNoCapability); |  | ||||||
|             rb.Push(false); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|         rb.Push(settings.is_stero_vision_restricted); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void ResetConfirmedStereoVisionPermission(HLERequestContext& ctx) { |  | ||||||
|         LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|         states.stereo_vision = false; |  | ||||||
|  |  | ||||||
|         IPC::ResponseBuilder rb{ctx, 2}; |  | ||||||
|         rb.Push(ResultSuccess); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     struct ApplicationInfo { |  | ||||||
|         u64 tid{}; |  | ||||||
|         std::array<u8, 32> age_rating{}; |  | ||||||
|         u32 parental_control_flag{}; |  | ||||||
|         Capability capability{}; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     struct States { |  | ||||||
|         u64 current_tid{}; |  | ||||||
|         ApplicationInfo application_info{}; |  | ||||||
|         u64 tid_from_event{}; |  | ||||||
|         bool launch_time_valid{}; |  | ||||||
|         bool is_suspended{}; |  | ||||||
|         bool temporary_unlocked{}; |  | ||||||
|         bool free_communication{}; |  | ||||||
|         bool stereo_vision{}; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     struct ParentalControlSettings { |  | ||||||
|         bool is_stero_vision_restricted{}; |  | ||||||
|         bool is_free_communication_default_on{}; |  | ||||||
|         bool disabled{}; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     // This is nn::pctl::RestrictionSettings |  | ||||||
|     struct RestrictionSettings { |  | ||||||
|         u8 rating_age; |  | ||||||
|         bool sns_post_restriction; |  | ||||||
|         bool free_communication_restriction; |  | ||||||
|     }; |  | ||||||
|     static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size."); |  | ||||||
|  |  | ||||||
|     // This is nn::pctl::PlayTimerSettings |  | ||||||
|     struct PlayTimerSettings { |  | ||||||
|         std::array<u32, 13> settings; |  | ||||||
|     }; |  | ||||||
|     static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size."); |  | ||||||
|  |  | ||||||
|     States states{}; |  | ||||||
|     ParentalControlSettings settings{}; |  | ||||||
|     RestrictionSettings restriction_settings{}; |  | ||||||
|     std::array<char, 8> pin_code{}; |  | ||||||
|     Capability capability{}; |  | ||||||
|  |  | ||||||
|     Kernel::KEvent* synchronization_event; |  | ||||||
|     Kernel::KEvent* unlinked_event; |  | ||||||
|     Kernel::KEvent* request_suspension_event; |  | ||||||
|     KernelHelpers::ServiceContext service_context; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| void Module::Interface::CreateService(HLERequestContext& ctx) { |  | ||||||
|     LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |  | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
|     // TODO(ogniK): Get TID from process |  | ||||||
|  |  | ||||||
|     rb.PushIpcInterface<IParentalControlService>(system, capability); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void Module::Interface::CreateServiceWithoutInitialize(HLERequestContext& ctx) { |  | ||||||
|     LOG_DEBUG(Service_PCTL, "called"); |  | ||||||
|  |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |  | ||||||
|     rb.Push(ResultSuccess); |  | ||||||
|     rb.PushIpcInterface<IParentalControlService>(system, capability); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_, |  | ||||||
|                              const char* name_, Capability capability_) |  | ||||||
|     : ServiceFramework{system_, name_}, module{std::move(module_)}, capability{capability_} {} |  | ||||||
|  |  | ||||||
| Module::Interface::~Interface() = default; |  | ||||||
|  |  | ||||||
| void LoopProcess(Core::System& system) { |  | ||||||
|     auto server_manager = std::make_unique<ServerManager>(system); |  | ||||||
|  |  | ||||||
|     auto module = std::make_shared<Module>(); |  | ||||||
|     server_manager->RegisterNamedService( |  | ||||||
|         "pctl", std::make_shared<PCTL>(system, module, "pctl", |  | ||||||
|                                        Capability::Application | Capability::SnsPost | |  | ||||||
|                                            Capability::Status | Capability::StereoVision)); |  | ||||||
|     // TODO(ogniK): Implement remaining capabilities |  | ||||||
|     server_manager->RegisterNamedService( |  | ||||||
|         "pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None)); |  | ||||||
|     server_manager->RegisterNamedService( |  | ||||||
|         "pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None)); |  | ||||||
|     server_manager->RegisterNamedService( |  | ||||||
|         "pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None)); |  | ||||||
|     ServerManager::RunServer(std::move(server_manager)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace Service::PCTL |  | ||||||
| @@ -1,47 +0,0 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project |  | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "common/common_funcs.h" |  | ||||||
| #include "core/hle/service/service.h" |  | ||||||
|  |  | ||||||
| namespace Core { |  | ||||||
| class System; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| namespace Service::PCTL { |  | ||||||
|  |  | ||||||
| enum class Capability : u32 { |  | ||||||
|     None = 0, |  | ||||||
|     Application = 1 << 0, |  | ||||||
|     SnsPost = 1 << 1, |  | ||||||
|     Recovery = 1 << 6, |  | ||||||
|     Status = 1 << 8, |  | ||||||
|     StereoVision = 1 << 9, |  | ||||||
|     System = 1 << 15, |  | ||||||
| }; |  | ||||||
| DECLARE_ENUM_FLAG_OPERATORS(Capability); |  | ||||||
|  |  | ||||||
| class Module final { |  | ||||||
| public: |  | ||||||
|     class Interface : public ServiceFramework<Interface> { |  | ||||||
|     public: |  | ||||||
|         explicit Interface(Core::System& system_, std::shared_ptr<Module> module_, |  | ||||||
|                            const char* name_, Capability capability_); |  | ||||||
|         ~Interface() override; |  | ||||||
|  |  | ||||||
|         void CreateService(HLERequestContext& ctx); |  | ||||||
|         void CreateServiceWithoutInitialize(HLERequestContext& ctx); |  | ||||||
|  |  | ||||||
|     protected: |  | ||||||
|         std::shared_ptr<Module> module; |  | ||||||
|  |  | ||||||
|     private: |  | ||||||
|         Capability capability{}; |  | ||||||
|     }; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| void LoopProcess(Core::System& system); |  | ||||||
|  |  | ||||||
| } // namespace Service::PCTL |  | ||||||
							
								
								
									
										15
									
								
								src/core/hle/service/pctl/pctl_results.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/core/hle/service/pctl/pctl_results.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "core/hle/result.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | constexpr Result ResultNoFreeCommunication{ErrorModule::PCTL, 101}; | ||||||
|  | constexpr Result ResultStereoVisionRestricted{ErrorModule::PCTL, 104}; | ||||||
|  | constexpr Result ResultNoCapability{ErrorModule::PCTL, 131}; | ||||||
|  | constexpr Result ResultNoRestrictionEnabled{ErrorModule::PCTL, 181}; | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
							
								
								
									
										43
									
								
								src/core/hle/service/pctl/pctl_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/core/hle/service/pctl/pctl_types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "common/common_funcs.h" | ||||||
|  |  | ||||||
|  | namespace Service::PCTL { | ||||||
|  |  | ||||||
|  | enum class Capability : u32 { | ||||||
|  |     None = 0, | ||||||
|  |     Application = 1 << 0, | ||||||
|  |     SnsPost = 1 << 1, | ||||||
|  |     Recovery = 1 << 6, | ||||||
|  |     Status = 1 << 8, | ||||||
|  |     StereoVision = 1 << 9, | ||||||
|  |     System = 1 << 15, | ||||||
|  | }; | ||||||
|  | DECLARE_ENUM_FLAG_OPERATORS(Capability); | ||||||
|  |  | ||||||
|  | struct ApplicationInfo { | ||||||
|  |     u64 application_id{}; | ||||||
|  |     std::array<u8, 32> age_rating{}; | ||||||
|  |     u32 parental_control_flag{}; | ||||||
|  |     Capability capability{}; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(ApplicationInfo) == 0x30, "ApplicationInfo has incorrect size."); | ||||||
|  |  | ||||||
|  | // This is nn::pctl::RestrictionSettings | ||||||
|  | struct RestrictionSettings { | ||||||
|  |     u8 rating_age; | ||||||
|  |     bool sns_post_restriction; | ||||||
|  |     bool free_communication_restriction; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(RestrictionSettings) == 0x3, "RestrictionSettings has incorrect size."); | ||||||
|  |  | ||||||
|  | // This is nn::pctl::PlayTimerSettings | ||||||
|  | struct PlayTimerSettings { | ||||||
|  |     std::array<u32, 13> settings; | ||||||
|  | }; | ||||||
|  | static_assert(sizeof(PlayTimerSettings) == 0x34, "PlayTimerSettings has incorrect size."); | ||||||
|  |  | ||||||
|  | } // namespace Service::PCTL | ||||||
| @@ -46,7 +46,7 @@ | |||||||
| #include "core/hle/service/olsc/olsc.h" | #include "core/hle/service/olsc/olsc.h" | ||||||
| #include "core/hle/service/omm/omm.h" | #include "core/hle/service/omm/omm.h" | ||||||
| #include "core/hle/service/pcie/pcie.h" | #include "core/hle/service/pcie/pcie.h" | ||||||
| #include "core/hle/service/pctl/pctl_module.h" | #include "core/hle/service/pctl/pctl.h" | ||||||
| #include "core/hle/service/pcv/pcv.h" | #include "core/hle/service/pcv/pcv.h" | ||||||
| #include "core/hle/service/pm/pm.h" | #include "core/hle/service/pm/pm.h" | ||||||
| #include "core/hle/service/prepo/prepo.h" | #include "core/hle/service/prepo/prepo.h" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user