diff options
| author | 2024-01-02 18:29:03 -0500 | |
|---|---|---|
| committer | 2024-01-29 20:17:33 -0500 | |
| commit | 182137a9a4b09c8188d2cbffa312550c5dc83641 (patch) | |
| tree | af62d2ecf774e7790c227cb0984e5392deca5afe | |
| parent | am: retrieve main applet creation info from frontend (diff) | |
| download | yuzu-182137a9a4b09c8188d2cbffa312550c5dc83641.tar.gz yuzu-182137a9a4b09c8188d2cbffa312550c5dc83641.tar.xz yuzu-182137a9a4b09c8188d2cbffa312550c5dc83641.zip | |
am: migrate global state to per-applet state structure
41 files changed, 687 insertions, 748 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 8c04685a5..435ef6793 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -392,6 +392,7 @@ struct System::Impl { | |||
| 392 | // All threads are started, begin main process execution, now that we're in the clear. | 392 | // All threads are started, begin main process execution, now that we're in the clear. |
| 393 | main_process->Run(load_parameters->main_thread_priority, | 393 | main_process->Run(load_parameters->main_thread_priority, |
| 394 | load_parameters->main_thread_stack_size); | 394 | load_parameters->main_thread_stack_size); |
| 395 | main_process->Close(); | ||
| 395 | 396 | ||
| 396 | if (Settings::values.gamecard_inserted) { | 397 | if (Settings::values.gamecard_inserted) { |
| 397 | if (Settings::values.gamecard_current_game) { | 398 | if (Settings::values.gamecard_current_game) { |
| @@ -886,10 +887,6 @@ void System::SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set | |||
| 886 | impl->frontend_applets.SetFrontendAppletSet(std::move(set)); | 887 | impl->frontend_applets.SetFrontendAppletSet(std::move(set)); |
| 887 | } | 888 | } |
| 888 | 889 | ||
| 889 | void System::SetDefaultAppletFrontendSet() { | ||
| 890 | impl->frontend_applets.SetDefaultAppletFrontendSet(); | ||
| 891 | } | ||
| 892 | |||
| 893 | Service::AM::Frontend::FrontendAppletHolder& System::GetFrontendAppletHolder() { | 890 | Service::AM::Frontend::FrontendAppletHolder& System::GetFrontendAppletHolder() { |
| 894 | return impl->frontend_applets; | 891 | return impl->frontend_applets; |
| 895 | } | 892 | } |
| @@ -898,6 +895,10 @@ const Service::AM::Frontend::FrontendAppletHolder& System::GetFrontendAppletHold | |||
| 898 | return impl->frontend_applets; | 895 | return impl->frontend_applets; |
| 899 | } | 896 | } |
| 900 | 897 | ||
| 898 | Service::AM::AppletManager& System::GetAppletManager() { | ||
| 899 | return impl->applet_manager; | ||
| 900 | } | ||
| 901 | |||
| 901 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { | 902 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { |
| 902 | impl->content_provider = std::move(provider); | 903 | impl->content_provider = std::move(provider); |
| 903 | } | 904 | } |
diff --git a/src/core/core.h b/src/core/core.h index 97e2d4b50..90826bd3a 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -350,12 +350,13 @@ public: | |||
| 350 | u64 main_region_size); | 350 | u64 main_region_size); |
| 351 | 351 | ||
| 352 | void SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set); | 352 | void SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet&& set); |
| 353 | void SetDefaultAppletFrontendSet(); | ||
| 354 | 353 | ||
| 355 | [[nodiscard]] Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder(); | 354 | [[nodiscard]] Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder(); |
| 356 | [[nodiscard]] const Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder() | 355 | [[nodiscard]] const Service::AM::Frontend::FrontendAppletHolder& GetFrontendAppletHolder() |
| 357 | const; | 356 | const; |
| 358 | 357 | ||
| 358 | [[nodiscard]] Service::AM::AppletManager& GetAppletManager(); | ||
| 359 | |||
| 359 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); | 360 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); |
| 360 | 361 | ||
| 361 | [[nodiscard]] FileSys::ContentProvider& GetContentProvider(); | 362 | [[nodiscard]] FileSys::ContentProvider& GetContentProvider(); |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f3683cdcc..34b25be66 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -97,8 +97,14 @@ struct KernelCore::Impl { | |||
| 97 | RegisterHostThread(nullptr); | 97 | RegisterHostThread(nullptr); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | void TerminateApplicationProcess() { | 100 | void TerminateAllProcesses() { |
| 101 | application_process.load()->Terminate(); | 101 | std::scoped_lock lk{process_list_lock}; |
| 102 | for (auto& process : process_list) { | ||
| 103 | process->Terminate(); | ||
| 104 | process->Close(); | ||
| 105 | process = nullptr; | ||
| 106 | } | ||
| 107 | process_list.clear(); | ||
| 102 | } | 108 | } |
| 103 | 109 | ||
| 104 | void Shutdown() { | 110 | void Shutdown() { |
| @@ -107,18 +113,9 @@ struct KernelCore::Impl { | |||
| 107 | 113 | ||
| 108 | CloseServices(); | 114 | CloseServices(); |
| 109 | 115 | ||
| 110 | auto* old_process = application_process.exchange(nullptr); | 116 | if (application_process) { |
| 111 | if (old_process) { | 117 | application_process->Close(); |
| 112 | old_process->Close(); | 118 | application_process = nullptr; |
| 113 | } | ||
| 114 | |||
| 115 | { | ||
| 116 | std::scoped_lock lk{process_list_lock}; | ||
| 117 | for (auto* const process : process_list) { | ||
| 118 | process->Terminate(); | ||
| 119 | process->Close(); | ||
| 120 | } | ||
| 121 | process_list.clear(); | ||
| 122 | } | 119 | } |
| 123 | 120 | ||
| 124 | next_object_id = 0; | 121 | next_object_id = 0; |
| @@ -354,6 +351,7 @@ struct KernelCore::Impl { | |||
| 354 | 351 | ||
| 355 | void MakeApplicationProcess(KProcess* process) { | 352 | void MakeApplicationProcess(KProcess* process) { |
| 356 | application_process = process; | 353 | application_process = process; |
| 354 | application_process->Open(); | ||
| 357 | } | 355 | } |
| 358 | 356 | ||
| 359 | static inline thread_local u8 host_thread_id = UINT8_MAX; | 357 | static inline thread_local u8 host_thread_id = UINT8_MAX; |
| @@ -779,7 +777,7 @@ struct KernelCore::Impl { | |||
| 779 | // Lists all processes that exist in the current session. | 777 | // Lists all processes that exist in the current session. |
| 780 | std::mutex process_list_lock; | 778 | std::mutex process_list_lock; |
| 781 | std::vector<KProcess*> process_list; | 779 | std::vector<KProcess*> process_list; |
| 782 | std::atomic<KProcess*> application_process{}; | 780 | KProcess* application_process{}; |
| 783 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; | 781 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; |
| 784 | std::unique_ptr<Kernel::KHardwareTimer> hardware_timer; | 782 | std::unique_ptr<Kernel::KHardwareTimer> hardware_timer; |
| 785 | 783 | ||
| @@ -1243,7 +1241,7 @@ void KernelCore::SuspendApplication(bool suspended) { | |||
| 1243 | } | 1241 | } |
| 1244 | 1242 | ||
| 1245 | void KernelCore::ShutdownCores() { | 1243 | void KernelCore::ShutdownCores() { |
| 1246 | impl->TerminateApplicationProcess(); | 1244 | impl->TerminateAllProcesses(); |
| 1247 | 1245 | ||
| 1248 | KScopedSchedulerLock lk{*this}; | 1246 | KScopedSchedulerLock lk{*this}; |
| 1249 | 1247 | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 46bc4f703..8f90eba34 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/am.h" | 4 | #include "core/hle/service/am/am.h" |
| 5 | #include "core/hle/service/am/applet_ae.h" | 5 | #include "core/hle/service/am/applet_ae.h" |
| 6 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 7 | #include "core/hle/service/am/applet_oe.h" | 6 | #include "core/hle/service/am/applet_oe.h" |
| 8 | #include "core/hle/service/am/idle.h" | 7 | #include "core/hle/service/am/idle.h" |
| 9 | #include "core/hle/service/am/omm.h" | 8 | #include "core/hle/service/am/omm.h" |
| @@ -13,13 +12,12 @@ | |||
| 13 | namespace Service::AM { | 12 | namespace Service::AM { |
| 14 | 13 | ||
| 15 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 14 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { |
| 16 | auto message_queue = std::make_shared<AppletMessageQueue>(system); | ||
| 17 | auto server_manager = std::make_unique<ServerManager>(system); | 15 | auto server_manager = std::make_unique<ServerManager>(system); |
| 18 | 16 | ||
| 19 | server_manager->RegisterNamedService( | 17 | server_manager->RegisterNamedService("appletAE", |
| 20 | "appletAE", std::make_shared<AppletAE>(nvnflinger, message_queue, system)); | 18 | std::make_shared<AppletAE>(nvnflinger, system)); |
| 21 | server_manager->RegisterNamedService( | 19 | server_manager->RegisterNamedService("appletOE", |
| 22 | "appletOE", std::make_shared<AppletOE>(nvnflinger, message_queue, system)); | 20 | std::make_shared<AppletOE>(nvnflinger, system)); |
| 23 | server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system)); | 21 | server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system)); |
| 24 | server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system)); | 22 | server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system)); |
| 25 | server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system)); | 23 | server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system)); |
diff --git a/src/core/hle/service/am/am_results.h b/src/core/hle/service/am/am_results.h index 528b334ad..e82d391ad 100644 --- a/src/core/hle/service/am/am_results.h +++ b/src/core/hle/service/am/am_results.h | |||
| @@ -10,5 +10,6 @@ namespace Service::AM { | |||
| 10 | constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; | 10 | constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2}; |
| 11 | constexpr Result ResultNoMessages{ErrorModule::AM, 3}; | 11 | constexpr Result ResultNoMessages{ErrorModule::AM, 3}; |
| 12 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; | 12 | constexpr Result ResultInvalidOffset{ErrorModule::AM, 503}; |
| 13 | constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512}; | ||
| 13 | 14 | ||
| 14 | } // namespace Service::AM | 15 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index bd9e5f505..1b715dea6 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp | |||
| @@ -2,40 +2,15 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/applet_ae.h" | 4 | #include "core/hle/service/am/applet_ae.h" |
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 5 | #include "core/hle/service/am/library_applet_proxy.h" | 6 | #include "core/hle/service/am/library_applet_proxy.h" |
| 6 | #include "core/hle/service/am/system_applet_proxy.h" | 7 | #include "core/hle/service/am/system_applet_proxy.h" |
| 7 | #include "core/hle/service/ipc_helpers.h" | 8 | #include "core/hle/service/ipc_helpers.h" |
| 8 | 9 | ||
| 9 | namespace Service::AM { | 10 | namespace Service::AM { |
| 10 | 11 | ||
| 11 | void AppletAE::OpenSystemAppletProxy(HLERequestContext& ctx) { | 12 | AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_) |
| 12 | LOG_DEBUG(Service_AM, "called"); | 13 | : ServiceFramework{system_, "appletAE"}, nvnflinger{nvnflinger_} { |
| 13 | |||
| 14 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 15 | rb.Push(ResultSuccess); | ||
| 16 | rb.PushIpcInterface<ISystemAppletProxy>(nvnflinger, msg_queue, system); | ||
| 17 | } | ||
| 18 | |||
| 19 | void AppletAE::OpenLibraryAppletProxy(HLERequestContext& ctx) { | ||
| 20 | LOG_DEBUG(Service_AM, "called"); | ||
| 21 | |||
| 22 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 23 | rb.Push(ResultSuccess); | ||
| 24 | rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, msg_queue, system); | ||
| 25 | } | ||
| 26 | |||
| 27 | void AppletAE::OpenLibraryAppletProxyOld(HLERequestContext& ctx) { | ||
| 28 | LOG_DEBUG(Service_AM, "called"); | ||
| 29 | |||
| 30 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 31 | rb.Push(ResultSuccess); | ||
| 32 | rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, msg_queue, system); | ||
| 33 | } | ||
| 34 | |||
| 35 | AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 36 | std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_) | ||
| 37 | : ServiceFramework{system_, "appletAE"}, nvnflinger{nvnflinger_}, | ||
| 38 | msg_queue{std::move(msg_queue_)} { | ||
| 39 | // clang-format off | 14 | // clang-format off |
| 40 | static const FunctionInfo functions[] = { | 15 | static const FunctionInfo functions[] = { |
| 41 | {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, | 16 | {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, |
| @@ -54,8 +29,45 @@ AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, | |||
| 54 | 29 | ||
| 55 | AppletAE::~AppletAE() = default; | 30 | AppletAE::~AppletAE() = default; |
| 56 | 31 | ||
| 57 | const std::shared_ptr<AppletMessageQueue>& AppletAE::GetMessageQueue() const { | 32 | void AppletAE::OpenSystemAppletProxy(HLERequestContext& ctx) { |
| 58 | return msg_queue; | 33 | LOG_DEBUG(Service_AM, "called"); |
| 34 | |||
| 35 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 36 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 37 | rb.Push(ResultSuccess); | ||
| 38 | rb.PushIpcInterface<ISystemAppletProxy>(nvnflinger, applet, system); | ||
| 39 | } else { | ||
| 40 | UNIMPLEMENTED(); | ||
| 41 | |||
| 42 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 43 | rb.Push(ResultUnknown); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void AppletAE::OpenLibraryAppletProxy(HLERequestContext& ctx) { | ||
| 48 | LOG_DEBUG(Service_AM, "called"); | ||
| 49 | |||
| 50 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 51 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 52 | rb.Push(ResultSuccess); | ||
| 53 | rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, applet, system); | ||
| 54 | } else { | ||
| 55 | UNIMPLEMENTED(); | ||
| 56 | |||
| 57 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 58 | rb.Push(ResultUnknown); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | void AppletAE::OpenLibraryAppletProxyOld(HLERequestContext& ctx) { | ||
| 63 | LOG_DEBUG(Service_AM, "called"); | ||
| 64 | |||
| 65 | return OpenLibraryAppletProxy(ctx); | ||
| 66 | } | ||
| 67 | |||
| 68 | std::shared_ptr<Applet> AppletAE::GetAppletFromContext(HLERequestContext& ctx) { | ||
| 69 | const auto aruid = ctx.GetPID(); | ||
| 70 | return system.GetAppletManager().GetByAppletResourceUserId(aruid); | ||
| 59 | } | 71 | } |
| 60 | 72 | ||
| 61 | } // namespace Service::AM | 73 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h index 538ce2903..3d7961fa1 100644 --- a/src/core/hle/service/am/applet_ae.h +++ b/src/core/hle/service/am/applet_ae.h | |||
| @@ -18,23 +18,21 @@ class Nvnflinger; | |||
| 18 | 18 | ||
| 19 | namespace AM { | 19 | namespace AM { |
| 20 | 20 | ||
| 21 | class AppletMessageQueue; | 21 | struct Applet; |
| 22 | 22 | ||
| 23 | class AppletAE final : public ServiceFramework<AppletAE> { | 23 | class AppletAE final : public ServiceFramework<AppletAE> { |
| 24 | public: | 24 | public: |
| 25 | explicit AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, | 25 | explicit AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_); |
| 26 | std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_); | ||
| 27 | ~AppletAE() override; | 26 | ~AppletAE() override; |
| 28 | 27 | ||
| 29 | const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; | ||
| 30 | |||
| 31 | private: | 28 | private: |
| 32 | void OpenSystemAppletProxy(HLERequestContext& ctx); | 29 | void OpenSystemAppletProxy(HLERequestContext& ctx); |
| 33 | void OpenLibraryAppletProxy(HLERequestContext& ctx); | 30 | void OpenLibraryAppletProxy(HLERequestContext& ctx); |
| 34 | void OpenLibraryAppletProxyOld(HLERequestContext& ctx); | 31 | void OpenLibraryAppletProxyOld(HLERequestContext& ctx); |
| 35 | 32 | ||
| 33 | std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx); | ||
| 34 | |||
| 36 | Nvnflinger::Nvnflinger& nvnflinger; | 35 | Nvnflinger::Nvnflinger& nvnflinger; |
| 37 | std::shared_ptr<AppletMessageQueue> msg_queue; | ||
| 38 | }; | 36 | }; |
| 39 | 37 | ||
| 40 | } // namespace AM | 38 | } // namespace AM |
diff --git a/src/core/hle/service/am/applet_common_functions.cpp b/src/core/hle/service/am/applet_common_functions.cpp index 81c01a48b..a5c54ce87 100644 --- a/src/core/hle/service/am/applet_common_functions.cpp +++ b/src/core/hle/service/am/applet_common_functions.cpp | |||
| @@ -1,13 +1,15 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/applet.h" | ||
| 4 | #include "core/hle/service/am/applet_common_functions.h" | 5 | #include "core/hle/service/am/applet_common_functions.h" |
| 5 | #include "core/hle/service/ipc_helpers.h" | 6 | #include "core/hle/service/ipc_helpers.h" |
| 6 | 7 | ||
| 7 | namespace Service::AM { | 8 | namespace Service::AM { |
| 8 | 9 | ||
| 9 | IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_) | 10 | IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, |
| 10 | : ServiceFramework{system_, "IAppletCommonFunctions"} { | 11 | std::shared_ptr<Applet> applet_) |
| 12 | : ServiceFramework{system_, "IAppletCommonFunctions"}, applet{std::move(applet_)} { | ||
| 11 | // clang-format off | 13 | // clang-format off |
| 12 | static const FunctionInfo functions[] = { | 14 | static const FunctionInfo functions[] = { |
| 13 | {0, nullptr, "SetTerminateResult"}, | 15 | {0, nullptr, "SetTerminateResult"}, |
| @@ -40,6 +42,11 @@ IAppletCommonFunctions::~IAppletCommonFunctions() = default; | |||
| 40 | void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) { | 42 | void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) { |
| 41 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 43 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 42 | 44 | ||
| 45 | IPC::RequestParser rp{ctx}; | ||
| 46 | |||
| 47 | std::scoped_lock lk{applet->lock}; | ||
| 48 | applet->cpu_boost_request_priority = rp.Pop<s32>(); | ||
| 49 | |||
| 43 | IPC::ResponseBuilder rb{ctx, 2}; | 50 | IPC::ResponseBuilder rb{ctx, 2}; |
| 44 | rb.Push(ResultSuccess); | 51 | rb.Push(ResultSuccess); |
| 45 | } | 52 | } |
diff --git a/src/core/hle/service/am/applet_common_functions.h b/src/core/hle/service/am/applet_common_functions.h index be87b3820..229555669 100644 --- a/src/core/hle/service/am/applet_common_functions.h +++ b/src/core/hle/service/am/applet_common_functions.h | |||
| @@ -7,13 +7,17 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::AM { | 8 | namespace Service::AM { |
| 9 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 10 | class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> { | 12 | class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> { |
| 11 | public: | 13 | public: |
| 12 | explicit IAppletCommonFunctions(Core::System& system_); | 14 | explicit IAppletCommonFunctions(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 13 | ~IAppletCommonFunctions() override; | 15 | ~IAppletCommonFunctions() override; |
| 14 | 16 | ||
| 15 | private: | 17 | private: |
| 16 | void SetCpuBoostRequestPriority(HLERequestContext& ctx); | 18 | void SetCpuBoostRequestPriority(HLERequestContext& ctx); |
| 19 | |||
| 20 | const std::shared_ptr<Applet> applet; | ||
| 17 | }; | 21 | }; |
| 18 | 22 | ||
| 19 | } // namespace Service::AM | 23 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 4aac5dba7..efbd0108c 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp | |||
| @@ -294,8 +294,8 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( | |||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | // Applet was started by frontend, so it is foreground. | 296 | // Applet was started by frontend, so it is foreground. |
| 297 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | ||
| 298 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | 297 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); |
| 298 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | ||
| 299 | applet->focus_state = FocusState::InFocus; | 299 | applet->focus_state = FocusState::InFocus; |
| 300 | 300 | ||
| 301 | this->InsertApplet(std::move(applet)); | 301 | this->InsertApplet(std::move(applet)); |
diff --git a/src/core/hle/service/am/applet_message_queue.cpp b/src/core/hle/service/am/applet_message_queue.cpp index e4931031d..5ed996b70 100644 --- a/src/core/hle/service/am/applet_message_queue.cpp +++ b/src/core/hle/service/am/applet_message_queue.cpp | |||
| @@ -26,11 +26,15 @@ Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() { | |||
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void AppletMessageQueue::PushMessage(AppletMessage msg) { | 28 | void AppletMessageQueue::PushMessage(AppletMessage msg) { |
| 29 | messages.push(msg); | 29 | { |
| 30 | std::scoped_lock lk{lock}; | ||
| 31 | messages.push(msg); | ||
| 32 | } | ||
| 30 | on_new_message->Signal(); | 33 | on_new_message->Signal(); |
| 31 | } | 34 | } |
| 32 | 35 | ||
| 33 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | 36 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { |
| 37 | std::scoped_lock lk{lock}; | ||
| 34 | if (messages.empty()) { | 38 | if (messages.empty()) { |
| 35 | on_new_message->Clear(); | 39 | on_new_message->Clear(); |
| 36 | return AppletMessage::None; | 40 | return AppletMessage::None; |
| @@ -44,6 +48,7 @@ AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | |||
| 44 | } | 48 | } |
| 45 | 49 | ||
| 46 | std::size_t AppletMessageQueue::GetMessageCount() const { | 50 | std::size_t AppletMessageQueue::GetMessageCount() const { |
| 51 | std::scoped_lock lk{lock}; | ||
| 47 | return messages.size(); | 52 | return messages.size(); |
| 48 | } | 53 | } |
| 49 | 54 | ||
diff --git a/src/core/hle/service/am/applet_message_queue.h b/src/core/hle/service/am/applet_message_queue.h index 60145aae9..5cb236d47 100644 --- a/src/core/hle/service/am/applet_message_queue.h +++ b/src/core/hle/service/am/applet_message_queue.h | |||
| @@ -69,6 +69,7 @@ private: | |||
| 69 | Kernel::KEvent* on_new_message; | 69 | Kernel::KEvent* on_new_message; |
| 70 | Kernel::KEvent* on_operation_mode_changed; | 70 | Kernel::KEvent* on_operation_mode_changed; |
| 71 | 71 | ||
| 72 | mutable std::mutex lock; | ||
| 72 | std::queue<AppletMessage> messages; | 73 | std::queue<AppletMessage> messages; |
| 73 | }; | 74 | }; |
| 74 | 75 | ||
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index f373d1136..56bafd162 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp | |||
| @@ -2,24 +2,15 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/am.h" | 4 | #include "core/hle/service/am/am.h" |
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 5 | #include "core/hle/service/am/applet_oe.h" | 6 | #include "core/hle/service/am/applet_oe.h" |
| 6 | #include "core/hle/service/am/application_proxy.h" | 7 | #include "core/hle/service/am/application_proxy.h" |
| 7 | #include "core/hle/service/ipc_helpers.h" | 8 | #include "core/hle/service/ipc_helpers.h" |
| 8 | 9 | ||
| 9 | namespace Service::AM { | 10 | namespace Service::AM { |
| 10 | 11 | ||
| 11 | void AppletOE::OpenApplicationProxy(HLERequestContext& ctx) { | 12 | AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_) |
| 12 | LOG_DEBUG(Service_AM, "called"); | 13 | : ServiceFramework{system_, "appletOE"}, nvnflinger{nvnflinger_} { |
| 13 | |||
| 14 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 15 | rb.Push(ResultSuccess); | ||
| 16 | rb.PushIpcInterface<IApplicationProxy>(nvnflinger, msg_queue, system); | ||
| 17 | } | ||
| 18 | |||
| 19 | AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, | ||
| 20 | std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_) | ||
| 21 | : ServiceFramework{system_, "appletOE"}, nvnflinger{nvnflinger_}, | ||
| 22 | msg_queue{std::move(msg_queue_)} { | ||
| 23 | static const FunctionInfo functions[] = { | 14 | static const FunctionInfo functions[] = { |
| 24 | {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, | 15 | {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, |
| 25 | }; | 16 | }; |
| @@ -28,8 +19,24 @@ AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, | |||
| 28 | 19 | ||
| 29 | AppletOE::~AppletOE() = default; | 20 | AppletOE::~AppletOE() = default; |
| 30 | 21 | ||
| 31 | const std::shared_ptr<AppletMessageQueue>& AppletOE::GetMessageQueue() const { | 22 | void AppletOE::OpenApplicationProxy(HLERequestContext& ctx) { |
| 32 | return msg_queue; | 23 | LOG_DEBUG(Service_AM, "called"); |
| 24 | |||
| 25 | if (const auto applet = GetAppletFromContext(ctx)) { | ||
| 26 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 27 | rb.Push(ResultSuccess); | ||
| 28 | rb.PushIpcInterface<IApplicationProxy>(nvnflinger, applet, system); | ||
| 29 | } else { | ||
| 30 | UNIMPLEMENTED(); | ||
| 31 | |||
| 32 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 33 | rb.Push(ResultUnknown); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | std::shared_ptr<Applet> AppletOE::GetAppletFromContext(HLERequestContext& ctx) { | ||
| 38 | const auto aruid = ctx.GetPID(); | ||
| 39 | return system.GetAppletManager().GetByAppletResourceUserId(aruid); | ||
| 33 | } | 40 | } |
| 34 | 41 | ||
| 35 | } // namespace Service::AM | 42 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h index 39eccc4ab..f2ba1c924 100644 --- a/src/core/hle/service/am/applet_oe.h +++ b/src/core/hle/service/am/applet_oe.h | |||
| @@ -18,21 +18,19 @@ class Nvnflinger; | |||
| 18 | 18 | ||
| 19 | namespace AM { | 19 | namespace AM { |
| 20 | 20 | ||
| 21 | class AppletMessageQueue; | 21 | struct Applet; |
| 22 | 22 | ||
| 23 | class AppletOE final : public ServiceFramework<AppletOE> { | 23 | class AppletOE final : public ServiceFramework<AppletOE> { |
| 24 | public: | 24 | public: |
| 25 | explicit AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, | 25 | explicit AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_); |
| 26 | std::shared_ptr<AppletMessageQueue> msg_queue_, Core::System& system_); | ||
| 27 | ~AppletOE() override; | 26 | ~AppletOE() override; |
| 28 | 27 | ||
| 29 | const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const; | ||
| 30 | |||
| 31 | private: | 28 | private: |
| 32 | void OpenApplicationProxy(HLERequestContext& ctx); | 29 | void OpenApplicationProxy(HLERequestContext& ctx); |
| 33 | 30 | ||
| 31 | std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx); | ||
| 32 | |||
| 34 | Nvnflinger::Nvnflinger& nvnflinger; | 33 | Nvnflinger::Nvnflinger& nvnflinger; |
| 35 | std::shared_ptr<AppletMessageQueue> msg_queue; | ||
| 36 | }; | 34 | }; |
| 37 | 35 | ||
| 38 | } // namespace AM | 36 | } // namespace AM |
diff --git a/src/core/hle/service/am/application_functions.cpp b/src/core/hle/service/am/application_functions.cpp index fef45c732..51c5be2d1 100644 --- a/src/core/hle/service/am/application_functions.cpp +++ b/src/core/hle/service/am/application_functions.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/file_sys/savedata_factory.h" | 9 | #include "core/file_sys/savedata_factory.h" |
| 10 | #include "core/hle/service/acc/profile_manager.h" | 10 | #include "core/hle/service/acc/profile_manager.h" |
| 11 | #include "core/hle/service/am/am_results.h" | 11 | #include "core/hle/service/am/am_results.h" |
| 12 | #include "core/hle/service/am/applet.h" | ||
| 12 | #include "core/hle/service/am/application_functions.h" | 13 | #include "core/hle/service/am/application_functions.h" |
| 13 | #include "core/hle/service/am/storage.h" | 14 | #include "core/hle/service/am/storage.h" |
| 14 | #include "core/hle/service/filesystem/filesystem.h" | 15 | #include "core/hle/service/filesystem/filesystem.h" |
| @@ -24,19 +25,8 @@ enum class LaunchParameterKind : u32 { | |||
| 24 | AccountPreselectedUser = 2, | 25 | AccountPreselectedUser = 2, |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | constexpr u32 LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC = 0xC79497CA; | 28 | IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_) |
| 28 | 29 | : ServiceFramework{system_, "IApplicationFunctions"}, applet{std::move(applet_)} { | |
| 29 | struct LaunchParameterAccountPreselectedUser { | ||
| 30 | u32_le magic; | ||
| 31 | u32_le is_account_selected; | ||
| 32 | Common::UUID current_user; | ||
| 33 | INSERT_PADDING_BYTES(0x70); | ||
| 34 | }; | ||
| 35 | static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88); | ||
| 36 | |||
| 37 | IApplicationFunctions::IApplicationFunctions(Core::System& system_) | ||
| 38 | : ServiceFramework{system_, "IApplicationFunctions"}, | ||
| 39 | service_context{system, "IApplicationFunctions"} { | ||
| 40 | // clang-format off | 30 | // clang-format off |
| 41 | static const FunctionInfo functions[] = { | 31 | static const FunctionInfo functions[] = { |
| 42 | {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, | 32 | {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, |
| @@ -105,27 +95,16 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 105 | // clang-format on | 95 | // clang-format on |
| 106 | 96 | ||
| 107 | RegisterHandlers(functions); | 97 | RegisterHandlers(functions); |
| 108 | |||
| 109 | gpu_error_detected_event = | ||
| 110 | service_context.CreateEvent("IApplicationFunctions:GpuErrorDetectedSystemEvent"); | ||
| 111 | friend_invitation_storage_channel_event = | ||
| 112 | service_context.CreateEvent("IApplicationFunctions:FriendInvitationStorageChannelEvent"); | ||
| 113 | notification_storage_channel_event = | ||
| 114 | service_context.CreateEvent("IApplicationFunctions:NotificationStorageChannelEvent"); | ||
| 115 | health_warning_disappeared_system_event = | ||
| 116 | service_context.CreateEvent("IApplicationFunctions:HealthWarningDisappearedSystemEvent"); | ||
| 117 | } | 98 | } |
| 118 | 99 | ||
| 119 | IApplicationFunctions::~IApplicationFunctions() { | 100 | IApplicationFunctions::~IApplicationFunctions() = default; |
| 120 | service_context.CloseEvent(gpu_error_detected_event); | ||
| 121 | service_context.CloseEvent(friend_invitation_storage_channel_event); | ||
| 122 | service_context.CloseEvent(notification_storage_channel_event); | ||
| 123 | service_context.CloseEvent(health_warning_disappeared_system_event); | ||
| 124 | } | ||
| 125 | 101 | ||
| 126 | void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) { | 102 | void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) { |
| 127 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 103 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 128 | 104 | ||
| 105 | std::scoped_lock lk{applet->lock}; | ||
| 106 | applet->application_crash_report_enabled = true; | ||
| 107 | |||
| 129 | IPC::ResponseBuilder rb{ctx, 2}; | 108 | IPC::ResponseBuilder rb{ctx, 2}; |
| 130 | rb.Push(ResultSuccess); | 109 | rb.Push(ResultSuccess); |
| 131 | } | 110 | } |
| @@ -157,6 +136,10 @@ void IApplicationFunctions::SetApplicationCopyrightVisibility(HLERequestContext& | |||
| 157 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { | 136 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { |
| 158 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 137 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 159 | 138 | ||
| 139 | std::scoped_lock lk{applet->lock}; | ||
| 140 | applet->home_button_long_pressed_blocked = true; | ||
| 141 | applet->home_button_short_pressed_blocked = true; | ||
| 142 | |||
| 160 | IPC::ResponseBuilder rb{ctx, 2}; | 143 | IPC::ResponseBuilder rb{ctx, 2}; |
| 161 | rb.Push(ResultSuccess); | 144 | rb.Push(ResultSuccess); |
| 162 | } | 145 | } |
| @@ -164,6 +147,10 @@ void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLEReques | |||
| 164 | void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { | 147 | void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) { |
| 165 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 148 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 166 | 149 | ||
| 150 | std::scoped_lock lk{applet->lock}; | ||
| 151 | applet->home_button_long_pressed_blocked = false; | ||
| 152 | applet->home_button_short_pressed_blocked = false; | ||
| 153 | |||
| 167 | IPC::ResponseBuilder rb{ctx, 2}; | 154 | IPC::ResponseBuilder rb{ctx, 2}; |
| 168 | rb.Push(ResultSuccess); | 155 | rb.Push(ResultSuccess); |
| 169 | } | 156 | } |
| @@ -171,6 +158,11 @@ void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestC | |||
| 171 | void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) { | 158 | void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) { |
| 172 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 159 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 173 | 160 | ||
| 161 | std::scoped_lock lk{applet->lock}; | ||
| 162 | applet->home_button_long_pressed_blocked = true; | ||
| 163 | applet->home_button_short_pressed_blocked = true; | ||
| 164 | applet->home_button_double_click_enabled = true; | ||
| 165 | |||
| 174 | IPC::ResponseBuilder rb{ctx, 2}; | 166 | IPC::ResponseBuilder rb{ctx, 2}; |
| 175 | rb.Push(ResultSuccess); | 167 | rb.Push(ResultSuccess); |
| 176 | } | 168 | } |
| @@ -178,6 +170,11 @@ void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) { | |||
| 178 | void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) { | 170 | void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) { |
| 179 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 171 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 180 | 172 | ||
| 173 | std::scoped_lock lk{applet->lock}; | ||
| 174 | applet->home_button_long_pressed_blocked = false; | ||
| 175 | applet->home_button_short_pressed_blocked = false; | ||
| 176 | applet->home_button_double_click_enabled = false; | ||
| 177 | |||
| 181 | IPC::ResponseBuilder rb{ctx, 2}; | 178 | IPC::ResponseBuilder rb{ctx, 2}; |
| 182 | rb.Push(ResultSuccess); | 179 | rb.Push(ResultSuccess); |
| 183 | } | 180 | } |
| @@ -188,47 +185,25 @@ void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) { | |||
| 188 | 185 | ||
| 189 | LOG_INFO(Service_AM, "called, kind={:08X}", kind); | 186 | LOG_INFO(Service_AM, "called, kind={:08X}", kind); |
| 190 | 187 | ||
| 191 | if (kind == LaunchParameterKind::UserChannel) { | 188 | std::scoped_lock lk{applet->lock}; |
| 192 | auto channel = system.GetUserChannel(); | ||
| 193 | if (channel.empty()) { | ||
| 194 | LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!"); | ||
| 195 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 196 | rb.Push(AM::ResultNoDataInChannel); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | |||
| 200 | auto data = channel.back(); | ||
| 201 | channel.pop_back(); | ||
| 202 | |||
| 203 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 204 | rb.Push(ResultSuccess); | ||
| 205 | rb.PushIpcInterface<IStorage>(system, std::move(data)); | ||
| 206 | } else if (kind == LaunchParameterKind::AccountPreselectedUser && | ||
| 207 | !launch_popped_account_preselect) { | ||
| 208 | // TODO: Verify this is hw-accurate | ||
| 209 | LaunchParameterAccountPreselectedUser params{}; | ||
| 210 | |||
| 211 | params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC; | ||
| 212 | params.is_account_selected = 1; | ||
| 213 | |||
| 214 | Account::ProfileManager profile_manager{}; | ||
| 215 | const auto uuid = profile_manager.GetUser(static_cast<s32>(Settings::values.current_user)); | ||
| 216 | ASSERT(uuid.has_value() && uuid->IsValid()); | ||
| 217 | params.current_user = *uuid; | ||
| 218 | 189 | ||
| 219 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 190 | auto& channel = kind == LaunchParameterKind::UserChannel |
| 220 | rb.Push(ResultSuccess); | 191 | ? applet->user_channel_launch_parameter |
| 192 | : applet->preselected_user_launch_parameter; | ||
| 221 | 193 | ||
| 222 | std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser)); | 194 | if (channel.empty()) { |
| 223 | std::memcpy(buffer.data(), ¶ms, buffer.size()); | 195 | LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", kind); |
| 224 | |||
| 225 | rb.PushIpcInterface<IStorage>(system, std::move(buffer)); | ||
| 226 | launch_popped_account_preselect = true; | ||
| 227 | } else { | ||
| 228 | LOG_ERROR(Service_AM, "Unknown launch parameter kind."); | ||
| 229 | IPC::ResponseBuilder rb{ctx, 2}; | 196 | IPC::ResponseBuilder rb{ctx, 2}; |
| 230 | rb.Push(AM::ResultNoDataInChannel); | 197 | rb.Push(AM::ResultNoDataInChannel); |
| 198 | return; | ||
| 231 | } | 199 | } |
| 200 | |||
| 201 | auto data = channel.back(); | ||
| 202 | channel.pop_back(); | ||
| 203 | |||
| 204 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 205 | rb.Push(ResultSuccess); | ||
| 206 | rb.PushIpcInterface<IStorage>(system, std::move(data)); | ||
| 232 | } | 207 | } |
| 233 | 208 | ||
| 234 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { | 209 | void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) { |
| @@ -245,7 +220,7 @@ void IApplicationFunctions::EnsureSaveData(HLERequestContext& ctx) { | |||
| 245 | LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]); | 220 | LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]); |
| 246 | 221 | ||
| 247 | FileSys::SaveDataAttribute attribute{}; | 222 | FileSys::SaveDataAttribute attribute{}; |
| 248 | attribute.title_id = system.GetApplicationProcessProgramID(); | 223 | attribute.title_id = applet->program_id; |
| 249 | attribute.user_id = user_id; | 224 | attribute.user_id = user_id; |
| 250 | attribute.type = FileSys::SaveDataType::SaveData; | 225 | attribute.type = FileSys::SaveDataType::SaveData; |
| 251 | 226 | ||
| @@ -267,6 +242,9 @@ void IApplicationFunctions::SetTerminateResult(HLERequestContext& ctx) { | |||
| 267 | u32 result = rp.Pop<u32>(); | 242 | u32 result = rp.Pop<u32>(); |
| 268 | LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result); | 243 | LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result); |
| 269 | 244 | ||
| 245 | std::scoped_lock lk{applet->lock}; | ||
| 246 | applet->terminate_result = Result(result); | ||
| 247 | |||
| 270 | IPC::ResponseBuilder rb{ctx, 2}; | 248 | IPC::ResponseBuilder rb{ctx, 2}; |
| 271 | rb.Push(ResultSuccess); | 249 | rb.Push(ResultSuccess); |
| 272 | } | 250 | } |
| @@ -277,16 +255,14 @@ void IApplicationFunctions::GetDisplayVersion(HLERequestContext& ctx) { | |||
| 277 | std::array<u8, 0x10> version_string{}; | 255 | std::array<u8, 0x10> version_string{}; |
| 278 | 256 | ||
| 279 | const auto res = [this] { | 257 | const auto res = [this] { |
| 280 | const auto title_id = system.GetApplicationProcessProgramID(); | 258 | const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(), |
| 281 | |||
| 282 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 283 | system.GetContentProvider()}; | 259 | system.GetContentProvider()}; |
| 284 | auto metadata = pm.GetControlMetadata(); | 260 | auto metadata = pm.GetControlMetadata(); |
| 285 | if (metadata.first != nullptr) { | 261 | if (metadata.first != nullptr) { |
| 286 | return metadata; | 262 | return metadata; |
| 287 | } | 263 | } |
| 288 | 264 | ||
| 289 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id), | 265 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id), |
| 290 | system.GetFileSystemController(), | 266 | system.GetFileSystemController(), |
| 291 | system.GetContentProvider()}; | 267 | system.GetContentProvider()}; |
| 292 | return pm_update.GetControlMetadata(); | 268 | return pm_update.GetControlMetadata(); |
| @@ -314,16 +290,14 @@ void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) { | |||
| 314 | u32 supported_languages = 0; | 290 | u32 supported_languages = 0; |
| 315 | 291 | ||
| 316 | const auto res = [this] { | 292 | const auto res = [this] { |
| 317 | const auto title_id = system.GetApplicationProcessProgramID(); | 293 | const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(), |
| 318 | |||
| 319 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 320 | system.GetContentProvider()}; | 294 | system.GetContentProvider()}; |
| 321 | auto metadata = pm.GetControlMetadata(); | 295 | auto metadata = pm.GetControlMetadata(); |
| 322 | if (metadata.first != nullptr) { | 296 | if (metadata.first != nullptr) { |
| 323 | return metadata; | 297 | return metadata; |
| 324 | } | 298 | } |
| 325 | 299 | ||
| 326 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id), | 300 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id), |
| 327 | system.GetFileSystemController(), | 301 | system.GetFileSystemController(), |
| 328 | system.GetContentProvider()}; | 302 | system.GetContentProvider()}; |
| 329 | return pm_update.GetControlMetadata(); | 303 | return pm_update.GetControlMetadata(); |
| @@ -368,11 +342,9 @@ void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) { | |||
| 368 | void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) { | 342 | void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) { |
| 369 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 343 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 370 | 344 | ||
| 371 | constexpr bool gameplay_recording_supported = false; | ||
| 372 | |||
| 373 | IPC::ResponseBuilder rb{ctx, 3}; | 345 | IPC::ResponseBuilder rb{ctx, 3}; |
| 374 | rb.Push(ResultSuccess); | 346 | rb.Push(ResultSuccess); |
| 375 | rb.Push(gameplay_recording_supported); | 347 | rb.Push(applet->gameplay_recording_supported); |
| 376 | } | 348 | } |
| 377 | 349 | ||
| 378 | void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) { | 350 | void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) { |
| @@ -385,6 +357,11 @@ void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) | |||
| 385 | void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) { | 357 | void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) { |
| 386 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 358 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 387 | 359 | ||
| 360 | IPC::RequestParser rp{ctx}; | ||
| 361 | |||
| 362 | std::scoped_lock lk{applet->lock}; | ||
| 363 | applet->gameplay_recording_state = rp.PopRaw<GameplayRecordingState>(); | ||
| 364 | |||
| 388 | IPC::ResponseBuilder rb{ctx, 2}; | 365 | IPC::ResponseBuilder rb{ctx, 2}; |
| 389 | rb.Push(ResultSuccess); | 366 | rb.Push(ResultSuccess); |
| 390 | } | 367 | } |
| @@ -392,6 +369,9 @@ void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) { | |||
| 392 | void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) { | 369 | void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) { |
| 393 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 370 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 394 | 371 | ||
| 372 | std::scoped_lock lk{applet->lock}; | ||
| 373 | applet->is_running = true; | ||
| 374 | |||
| 395 | IPC::ResponseBuilder rb{ctx, 3}; | 375 | IPC::ResponseBuilder rb{ctx, 3}; |
| 396 | rb.Push(ResultSuccess); | 376 | rb.Push(ResultSuccess); |
| 397 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes | 377 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes |
| @@ -426,8 +406,7 @@ void IApplicationFunctions::ExtendSaveData(HLERequestContext& ctx) { | |||
| 426 | static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size); | 406 | static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size); |
| 427 | 407 | ||
| 428 | system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize( | 408 | system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize( |
| 429 | type, system.GetApplicationProcessProgramID(), user_id, | 409 | type, applet->program_id, user_id, {new_normal_size, new_journal_size}); |
| 430 | {new_normal_size, new_journal_size}); | ||
| 431 | 410 | ||
| 432 | IPC::ResponseBuilder rb{ctx, 4}; | 411 | IPC::ResponseBuilder rb{ctx, 4}; |
| 433 | rb.Push(ResultSuccess); | 412 | rb.Push(ResultSuccess); |
| @@ -451,7 +430,7 @@ void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) { | |||
| 451 | user_id[0]); | 430 | user_id[0]); |
| 452 | 431 | ||
| 453 | const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize( | 432 | const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize( |
| 454 | type, system.GetApplicationProcessProgramID(), user_id); | 433 | type, applet->program_id, user_id); |
| 455 | 434 | ||
| 456 | IPC::ResponseBuilder rb{ctx, 6}; | 435 | IPC::ResponseBuilder rb{ctx, 6}; |
| 457 | rb.Push(ResultSuccess); | 436 | rb.Push(ResultSuccess); |
| @@ -528,13 +507,15 @@ void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) { | |||
| 528 | IPC::ResponseBuilder rb{ctx, 2}; | 507 | IPC::ResponseBuilder rb{ctx, 2}; |
| 529 | rb.Push(ResultSuccess); | 508 | rb.Push(ResultSuccess); |
| 530 | 509 | ||
| 510 | // Swap user channel ownership into the system so that it will be preserved | ||
| 511 | system.GetUserChannel().swap(applet->user_channel_launch_parameter); | ||
| 531 | system.ExecuteProgram(program_index); | 512 | system.ExecuteProgram(program_index); |
| 532 | } | 513 | } |
| 533 | 514 | ||
| 534 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { | 515 | void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) { |
| 535 | LOG_DEBUG(Service_AM, "called"); | 516 | LOG_DEBUG(Service_AM, "called"); |
| 536 | 517 | ||
| 537 | system.GetUserChannel().clear(); | 518 | applet->user_channel_launch_parameter.clear(); |
| 538 | 519 | ||
| 539 | IPC::ResponseBuilder rb{ctx, 2}; | 520 | IPC::ResponseBuilder rb{ctx, 2}; |
| 540 | rb.Push(ResultSuccess); | 521 | rb.Push(ResultSuccess); |
| @@ -546,7 +527,7 @@ void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) { | |||
| 546 | IPC::RequestParser rp{ctx}; | 527 | IPC::RequestParser rp{ctx}; |
| 547 | const auto storage = rp.PopIpcInterface<IStorage>().lock(); | 528 | const auto storage = rp.PopIpcInterface<IStorage>().lock(); |
| 548 | if (storage) { | 529 | if (storage) { |
| 549 | system.GetUserChannel().push_back(storage->GetData()); | 530 | applet->user_channel_launch_parameter.push_back(storage->GetData()); |
| 550 | } | 531 | } |
| 551 | 532 | ||
| 552 | IPC::ResponseBuilder rb{ctx, 2}; | 533 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -558,7 +539,7 @@ void IApplicationFunctions::GetPreviousProgramIndex(HLERequestContext& ctx) { | |||
| 558 | 539 | ||
| 559 | IPC::ResponseBuilder rb{ctx, 3}; | 540 | IPC::ResponseBuilder rb{ctx, 3}; |
| 560 | rb.Push(ResultSuccess); | 541 | rb.Push(ResultSuccess); |
| 561 | rb.Push<s32>(previous_program_index); | 542 | rb.Push<s32>(applet->previous_program_index); |
| 562 | } | 543 | } |
| 563 | 544 | ||
| 564 | void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) { | 545 | void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) { |
| @@ -566,7 +547,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ct | |||
| 566 | 547 | ||
| 567 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 548 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 568 | rb.Push(ResultSuccess); | 549 | rb.Push(ResultSuccess); |
| 569 | rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent()); | 550 | rb.PushCopyObjects(applet->gpu_error_detected_event.GetHandle()); |
| 570 | } | 551 | } |
| 571 | 552 | ||
| 572 | void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) { | 553 | void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) { |
| @@ -574,7 +555,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestCon | |||
| 574 | 555 | ||
| 575 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 556 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 576 | rb.Push(ResultSuccess); | 557 | rb.Push(ResultSuccess); |
| 577 | rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent()); | 558 | rb.PushCopyObjects(applet->friend_invitation_storage_channel_event.GetHandle()); |
| 578 | } | 559 | } |
| 579 | 560 | ||
| 580 | void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) { | 561 | void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) { |
| @@ -589,7 +570,7 @@ void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext | |||
| 589 | 570 | ||
| 590 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 571 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 591 | rb.Push(ResultSuccess); | 572 | rb.Push(ResultSuccess); |
| 592 | rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent()); | 573 | rb.PushCopyObjects(applet->notification_storage_channel_event.GetHandle()); |
| 593 | } | 574 | } |
| 594 | 575 | ||
| 595 | void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) { | 576 | void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) { |
| @@ -597,12 +578,15 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestCon | |||
| 597 | 578 | ||
| 598 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 579 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 599 | rb.Push(ResultSuccess); | 580 | rb.Push(ResultSuccess); |
| 600 | rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent()); | 581 | rb.PushCopyObjects(applet->health_warning_disappeared_system_event.GetHandle()); |
| 601 | } | 582 | } |
| 602 | 583 | ||
| 603 | void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) { | 584 | void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) { |
| 604 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 585 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 605 | 586 | ||
| 587 | std::scoped_lock lk{applet->lock}; | ||
| 588 | applet->jit_service_launched = true; | ||
| 589 | |||
| 606 | IPC::ResponseBuilder rb{ctx, 2}; | 590 | IPC::ResponseBuilder rb{ctx, 2}; |
| 607 | rb.Push(ResultSuccess); | 591 | rb.Push(ResultSuccess); |
| 608 | } | 592 | } |
diff --git a/src/core/hle/service/am/application_functions.h b/src/core/hle/service/am/application_functions.h index 22aab1c8f..55eb21d39 100644 --- a/src/core/hle/service/am/application_functions.h +++ b/src/core/hle/service/am/application_functions.h | |||
| @@ -8,9 +8,11 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM { | 9 | namespace Service::AM { |
| 10 | 10 | ||
| 11 | struct Applet; | ||
| 12 | |||
| 11 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | 13 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { |
| 12 | public: | 14 | public: |
| 13 | explicit IApplicationFunctions(Core::System& system_); | 15 | explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 14 | ~IApplicationFunctions() override; | 16 | ~IApplicationFunctions() override; |
| 15 | 17 | ||
| 16 | private: | 18 | private: |
| @@ -50,14 +52,7 @@ private: | |||
| 50 | void GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx); | 52 | void GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx); |
| 51 | void PrepareForJit(HLERequestContext& ctx); | 53 | void PrepareForJit(HLERequestContext& ctx); |
| 52 | 54 | ||
| 53 | KernelHelpers::ServiceContext service_context; | 55 | const std::shared_ptr<Applet> applet; |
| 54 | |||
| 55 | bool launch_popped_account_preselect = false; | ||
| 56 | s32 previous_program_index{-1}; | ||
| 57 | Kernel::KEvent* gpu_error_detected_event; | ||
| 58 | Kernel::KEvent* friend_invitation_storage_channel_event; | ||
| 59 | Kernel::KEvent* notification_storage_channel_event; | ||
| 60 | Kernel::KEvent* health_warning_disappeared_system_event; | ||
| 61 | }; | 56 | }; |
| 62 | 57 | ||
| 63 | } // namespace Service::AM | 58 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/application_proxy.cpp b/src/core/hle/service/am/application_proxy.cpp index e9cd0aa71..99e97f4bc 100644 --- a/src/core/hle/service/am/application_proxy.cpp +++ b/src/core/hle/service/am/application_proxy.cpp | |||
| @@ -18,10 +18,9 @@ | |||
| 18 | namespace Service::AM { | 18 | namespace Service::AM { |
| 19 | 19 | ||
| 20 | IApplicationProxy::IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 20 | IApplicationProxy::IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 21 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 21 | std::shared_ptr<Applet> applet_, Core::System& system_) |
| 22 | Core::System& system_) | 22 | : ServiceFramework{system_, "IApplicationProxy"}, nvnflinger{nvnflinger_}, applet{std::move( |
| 23 | : ServiceFramework{system_, "IApplicationProxy"}, nvnflinger{nvnflinger_}, | 23 | applet_)} { |
| 24 | msg_queue{std::move(msg_queue_)} { | ||
| 25 | // clang-format off | 24 | // clang-format off |
| 26 | static const FunctionInfo functions[] = { | 25 | static const FunctionInfo functions[] = { |
| 27 | {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 26 | {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| @@ -39,6 +38,8 @@ IApplicationProxy::IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, | |||
| 39 | RegisterHandlers(functions); | 38 | RegisterHandlers(functions); |
| 40 | } | 39 | } |
| 41 | 40 | ||
| 41 | IApplicationProxy::~IApplicationProxy() = default; | ||
| 42 | |||
| 42 | void IApplicationProxy::GetAudioController(HLERequestContext& ctx) { | 43 | void IApplicationProxy::GetAudioController(HLERequestContext& ctx) { |
| 43 | LOG_DEBUG(Service_AM, "called"); | 44 | LOG_DEBUG(Service_AM, "called"); |
| 44 | 45 | ||
| @@ -60,7 +61,7 @@ void IApplicationProxy::GetProcessWindingController(HLERequestContext& ctx) { | |||
| 60 | 61 | ||
| 61 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 62 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 62 | rb.Push(ResultSuccess); | 63 | rb.Push(ResultSuccess); |
| 63 | rb.PushIpcInterface<IProcessWindingController>(system); | 64 | rb.PushIpcInterface<IProcessWindingController>(system, applet); |
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | void IApplicationProxy::GetDebugFunctions(HLERequestContext& ctx) { | 67 | void IApplicationProxy::GetDebugFunctions(HLERequestContext& ctx) { |
| @@ -76,7 +77,7 @@ void IApplicationProxy::GetWindowController(HLERequestContext& ctx) { | |||
| 76 | 77 | ||
| 77 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 78 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 78 | rb.Push(ResultSuccess); | 79 | rb.Push(ResultSuccess); |
| 79 | rb.PushIpcInterface<IWindowController>(system); | 80 | rb.PushIpcInterface<IWindowController>(system, applet); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| 82 | void IApplicationProxy::GetSelfController(HLERequestContext& ctx) { | 83 | void IApplicationProxy::GetSelfController(HLERequestContext& ctx) { |
| @@ -84,7 +85,7 @@ void IApplicationProxy::GetSelfController(HLERequestContext& ctx) { | |||
| 84 | 85 | ||
| 85 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 86 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 86 | rb.Push(ResultSuccess); | 87 | rb.Push(ResultSuccess); |
| 87 | rb.PushIpcInterface<ISelfController>(system, nvnflinger); | 88 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | void IApplicationProxy::GetCommonStateGetter(HLERequestContext& ctx) { | 91 | void IApplicationProxy::GetCommonStateGetter(HLERequestContext& ctx) { |
| @@ -92,7 +93,7 @@ void IApplicationProxy::GetCommonStateGetter(HLERequestContext& ctx) { | |||
| 92 | 93 | ||
| 93 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 94 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 94 | rb.Push(ResultSuccess); | 95 | rb.Push(ResultSuccess); |
| 95 | rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); | 96 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | void IApplicationProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | 99 | void IApplicationProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { |
| @@ -100,7 +101,7 @@ void IApplicationProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | |||
| 100 | 101 | ||
| 101 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 102 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 102 | rb.Push(ResultSuccess); | 103 | rb.Push(ResultSuccess); |
| 103 | rb.PushIpcInterface<ILibraryAppletCreator>(system); | 104 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | void IApplicationProxy::GetApplicationFunctions(HLERequestContext& ctx) { | 107 | void IApplicationProxy::GetApplicationFunctions(HLERequestContext& ctx) { |
| @@ -108,7 +109,7 @@ void IApplicationProxy::GetApplicationFunctions(HLERequestContext& ctx) { | |||
| 108 | 109 | ||
| 109 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 110 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 110 | rb.Push(ResultSuccess); | 111 | rb.Push(ResultSuccess); |
| 111 | rb.PushIpcInterface<IApplicationFunctions>(system); | 112 | rb.PushIpcInterface<IApplicationFunctions>(system, applet); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | } // namespace Service::AM | 115 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/application_proxy.h b/src/core/hle/service/am/application_proxy.h index 4f620242b..eb98b095c 100644 --- a/src/core/hle/service/am/application_proxy.h +++ b/src/core/hle/service/am/application_proxy.h | |||
| @@ -3,16 +3,17 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 7 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/service.h" |
| 8 | 7 | ||
| 9 | namespace Service::AM { | 8 | namespace Service::AM { |
| 10 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 11 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | 12 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { |
| 12 | public: | 13 | public: |
| 13 | explicit IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 14 | explicit IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 14 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 15 | std::shared_ptr<Applet> msg_queue_, Core::System& system_); |
| 15 | Core::System& system_); | 16 | ~IApplicationProxy(); |
| 16 | 17 | ||
| 17 | private: | 18 | private: |
| 18 | void GetAudioController(HLERequestContext& ctx); | 19 | void GetAudioController(HLERequestContext& ctx); |
| @@ -26,7 +27,7 @@ private: | |||
| 26 | void GetApplicationFunctions(HLERequestContext& ctx); | 27 | void GetApplicationFunctions(HLERequestContext& ctx); |
| 27 | 28 | ||
| 28 | Nvnflinger::Nvnflinger& nvnflinger; | 29 | Nvnflinger::Nvnflinger& nvnflinger; |
| 29 | std::shared_ptr<AppletMessageQueue> msg_queue; | 30 | std::shared_ptr<Applet> applet; |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | } // namespace Service::AM | 33 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/common_state_getter.cpp b/src/core/hle/service/am/common_state_getter.cpp index 0b54b769d..77f3fd868 100644 --- a/src/core/hle/service/am/common_state_getter.cpp +++ b/src/core/hle/service/am/common_state_getter.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include "common/settings.h" | 4 | #include "common/settings.h" |
| 5 | #include "core/hle/service/am/am_results.h" | 5 | #include "core/hle/service/am/am_results.h" |
| 6 | #include "core/hle/service/am/applet.h" | ||
| 6 | #include "core/hle/service/am/common_state_getter.h" | 7 | #include "core/hle/service/am/common_state_getter.h" |
| 7 | #include "core/hle/service/am/lock_accessor.h" | 8 | #include "core/hle/service/am/lock_accessor.h" |
| 8 | #include "core/hle/service/apm/apm_controller.h" | 9 | #include "core/hle/service/apm/apm_controller.h" |
| @@ -14,10 +15,8 @@ | |||
| 14 | 15 | ||
| 15 | namespace Service::AM { | 16 | namespace Service::AM { |
| 16 | 17 | ||
| 17 | ICommonStateGetter::ICommonStateGetter(Core::System& system_, | 18 | ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_) |
| 18 | std::shared_ptr<AppletMessageQueue> msg_queue_) | 19 | : ServiceFramework{system_, "ICommonStateGetter"}, applet{std::move(applet_)} { |
| 19 | : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)}, | ||
| 20 | service_context{system_, "ICommonStateGetter"} { | ||
| 21 | // clang-format off | 20 | // clang-format off |
| 22 | static const FunctionInfo functions[] = { | 21 | static const FunctionInfo functions[] = { |
| 23 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, | 22 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, |
| @@ -75,17 +74,9 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, | |||
| 75 | // clang-format on | 74 | // clang-format on |
| 76 | 75 | ||
| 77 | RegisterHandlers(functions); | 76 | RegisterHandlers(functions); |
| 78 | |||
| 79 | sleep_lock_event = service_context.CreateEvent("ICommonStateGetter::SleepLockEvent"); | ||
| 80 | |||
| 81 | // Configure applets to be in foreground state | ||
| 82 | msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | ||
| 83 | msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | ||
| 84 | } | 77 | } |
| 85 | 78 | ||
| 86 | ICommonStateGetter::~ICommonStateGetter() { | 79 | ICommonStateGetter::~ICommonStateGetter() = default; |
| 87 | service_context.CloseEvent(sleep_lock_event); | ||
| 88 | }; | ||
| 89 | 80 | ||
| 90 | void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) { | 81 | void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) { |
| 91 | LOG_DEBUG(Service_AM, "called"); | 82 | LOG_DEBUG(Service_AM, "called"); |
| @@ -96,17 +87,17 @@ void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) { | |||
| 96 | } | 87 | } |
| 97 | 88 | ||
| 98 | void ICommonStateGetter::GetEventHandle(HLERequestContext& ctx) { | 89 | void ICommonStateGetter::GetEventHandle(HLERequestContext& ctx) { |
| 99 | LOG_DEBUG(Service_AM, "called"); | 90 | LOG_DEBUG(Service_AM, "(STUBBED) called"); |
| 100 | 91 | ||
| 101 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 92 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 102 | rb.Push(ResultSuccess); | 93 | rb.Push(ResultSuccess); |
| 103 | rb.PushCopyObjects(msg_queue->GetMessageReceiveEvent()); | 94 | rb.PushCopyObjects(applet->message_queue.GetMessageReceiveEvent()); |
| 104 | } | 95 | } |
| 105 | 96 | ||
| 106 | void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) { | 97 | void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) { |
| 107 | LOG_DEBUG(Service_AM, "called"); | 98 | LOG_DEBUG(Service_AM, "called"); |
| 108 | 99 | ||
| 109 | const auto message = msg_queue->PopMessage(); | 100 | const auto message = applet->message_queue.PopMessage(); |
| 110 | IPC::ResponseBuilder rb{ctx, 3}; | 101 | IPC::ResponseBuilder rb{ctx, 3}; |
| 111 | 102 | ||
| 112 | if (message == AppletMessageQueue::AppletMessage::None) { | 103 | if (message == AppletMessageQueue::AppletMessage::None) { |
| @@ -123,9 +114,11 @@ void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) { | |||
| 123 | void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) { | 114 | void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) { |
| 124 | LOG_DEBUG(Service_AM, "(STUBBED) called"); | 115 | LOG_DEBUG(Service_AM, "(STUBBED) called"); |
| 125 | 116 | ||
| 117 | std::scoped_lock lk{applet->lock}; | ||
| 118 | |||
| 126 | IPC::ResponseBuilder rb{ctx, 3}; | 119 | IPC::ResponseBuilder rb{ctx, 3}; |
| 127 | rb.Push(ResultSuccess); | 120 | rb.Push(ResultSuccess); |
| 128 | rb.Push(static_cast<u8>(FocusState::InFocus)); | 121 | rb.Push(static_cast<u8>(applet->focus_state)); |
| 129 | } | 122 | } |
| 130 | 123 | ||
| 131 | void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) { | 124 | void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) { |
| @@ -149,7 +142,7 @@ void ICommonStateGetter::RequestToAcquireSleepLock(HLERequestContext& ctx) { | |||
| 149 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 142 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 150 | 143 | ||
| 151 | // Sleep lock is acquired immediately. | 144 | // Sleep lock is acquired immediately. |
| 152 | sleep_lock_event->Signal(); | 145 | applet->sleep_lock_event.Signal(); |
| 153 | 146 | ||
| 154 | IPC::ResponseBuilder rb{ctx, 2}; | 147 | IPC::ResponseBuilder rb{ctx, 2}; |
| 155 | rb.Push(ResultSuccess); | 148 | rb.Push(ResultSuccess); |
| @@ -172,22 +165,25 @@ void ICommonStateGetter::GetAcquiredSleepLockEvent(HLERequestContext& ctx) { | |||
| 172 | 165 | ||
| 173 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 166 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 174 | rb.Push(ResultSuccess); | 167 | rb.Push(ResultSuccess); |
| 175 | rb.PushCopyObjects(sleep_lock_event->GetReadableEvent()); | 168 | rb.PushCopyObjects(applet->sleep_lock_event.GetHandle()); |
| 176 | } | 169 | } |
| 177 | 170 | ||
| 178 | void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) { | 171 | void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) { |
| 179 | LOG_DEBUG(Service_AM, "called"); | 172 | LOG_DEBUG(Service_AM, "called"); |
| 180 | 173 | ||
| 174 | std::scoped_lock lk{applet->lock}; | ||
| 175 | |||
| 181 | IPC::ResponseBuilder rb{ctx, 3}; | 176 | IPC::ResponseBuilder rb{ctx, 3}; |
| 182 | rb.Push(ResultSuccess); | 177 | rb.Push(ResultSuccess); |
| 183 | rb.Push(vr_mode_state); | 178 | rb.Push(applet->vr_mode_enabled); |
| 184 | } | 179 | } |
| 185 | 180 | ||
| 186 | void ICommonStateGetter::SetVrModeEnabled(HLERequestContext& ctx) { | 181 | void ICommonStateGetter::SetVrModeEnabled(HLERequestContext& ctx) { |
| 187 | IPC::RequestParser rp{ctx}; | 182 | IPC::RequestParser rp{ctx}; |
| 188 | vr_mode_state = rp.Pop<bool>(); | ||
| 189 | 183 | ||
| 190 | LOG_WARNING(Service_AM, "VR Mode is {}", vr_mode_state ? "on" : "off"); | 184 | std::scoped_lock lk{applet->lock}; |
| 185 | applet->vr_mode_enabled = rp.Pop<bool>(); | ||
| 186 | LOG_WARNING(Service_AM, "VR Mode is {}", applet->vr_mode_enabled ? "on" : "off"); | ||
| 191 | 187 | ||
| 192 | IPC::ResponseBuilder rb{ctx, 2}; | 188 | IPC::ResponseBuilder rb{ctx, 2}; |
| 193 | rb.Push(ResultSuccess); | 189 | rb.Push(ResultSuccess); |
| @@ -207,6 +203,9 @@ void ICommonStateGetter::SetLcdBacklighOffEnabled(HLERequestContext& ctx) { | |||
| 207 | void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) { | 203 | void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) { |
| 208 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 204 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 209 | 205 | ||
| 206 | std::scoped_lock lk{applet->lock}; | ||
| 207 | applet->vr_mode_enabled = true; | ||
| 208 | |||
| 210 | IPC::ResponseBuilder rb{ctx, 2}; | 209 | IPC::ResponseBuilder rb{ctx, 2}; |
| 211 | rb.Push(ResultSuccess); | 210 | rb.Push(ResultSuccess); |
| 212 | } | 211 | } |
| @@ -214,6 +213,9 @@ void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) { | |||
| 214 | void ICommonStateGetter::EndVrModeEx(HLERequestContext& ctx) { | 213 | void ICommonStateGetter::EndVrModeEx(HLERequestContext& ctx) { |
| 215 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 214 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 216 | 215 | ||
| 216 | std::scoped_lock lk{applet->lock}; | ||
| 217 | applet->vr_mode_enabled = false; | ||
| 218 | |||
| 217 | IPC::ResponseBuilder rb{ctx, 2}; | 219 | IPC::ResponseBuilder rb{ctx, 2}; |
| 218 | rb.Push(ResultSuccess); | 220 | rb.Push(ResultSuccess); |
| 219 | } | 221 | } |
| @@ -223,7 +225,7 @@ void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(HLERequestContex | |||
| 223 | 225 | ||
| 224 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 226 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 225 | rb.Push(ResultSuccess); | 227 | rb.Push(ResultSuccess); |
| 226 | rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent()); | 228 | rb.PushCopyObjects(applet->message_queue.GetOperationModeChangedEvent()); |
| 227 | } | 229 | } |
| 228 | 230 | ||
| 229 | void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) { | 231 | void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) { |
| @@ -281,6 +283,9 @@ void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnable | |||
| 281 | HLERequestContext& ctx) { | 283 | HLERequestContext& ctx) { |
| 282 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 284 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 283 | 285 | ||
| 286 | std::scoped_lock lk{applet->lock}; | ||
| 287 | applet->request_exit_to_library_applet_at_execute_next_program_enabled = true; | ||
| 288 | |||
| 284 | IPC::ResponseBuilder rb{ctx, 2}; | 289 | IPC::ResponseBuilder rb{ctx, 2}; |
| 285 | rb.Push(ResultSuccess); | 290 | rb.Push(ResultSuccess); |
| 286 | } | 291 | } |
diff --git a/src/core/hle/service/am/common_state_getter.h b/src/core/hle/service/am/common_state_getter.h index 11d66f10a..643ca4dc5 100644 --- a/src/core/hle/service/am/common_state_getter.h +++ b/src/core/hle/service/am/common_state_getter.h | |||
| @@ -10,10 +10,11 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::AM { | 11 | namespace Service::AM { |
| 12 | 12 | ||
| 13 | struct Applet; | ||
| 14 | |||
| 13 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { | 15 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { |
| 14 | public: | 16 | public: |
| 15 | explicit ICommonStateGetter(Core::System& system_, | 17 | explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 16 | std::shared_ptr<AppletMessageQueue> msg_queue_); | ||
| 17 | ~ICommonStateGetter() override; | 18 | ~ICommonStateGetter() override; |
| 18 | 19 | ||
| 19 | private: | 20 | private: |
| @@ -69,10 +70,7 @@ private: | |||
| 69 | void GetSettingsPlatformRegion(HLERequestContext& ctx); | 70 | void GetSettingsPlatformRegion(HLERequestContext& ctx); |
| 70 | void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); | 71 | void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); |
| 71 | 72 | ||
| 72 | std::shared_ptr<AppletMessageQueue> msg_queue; | 73 | const std::shared_ptr<Applet> applet; |
| 73 | bool vr_mode_state{}; | ||
| 74 | Kernel::KEvent* sleep_lock_event; | ||
| 75 | KernelHelpers::ServiceContext service_context; | ||
| 76 | }; | 74 | }; |
| 77 | 75 | ||
| 78 | } // namespace Service::AM | 76 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index 4e8f806d7..38495ee19 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "core/hle/kernel/k_event.h" | 16 | #include "core/hle/kernel/k_event.h" |
| 17 | #include "core/hle/service/am/am.h" | 17 | #include "core/hle/service/am/am.h" |
| 18 | #include "core/hle/service/am/applet_ae.h" | 18 | #include "core/hle/service/am/applet_ae.h" |
| 19 | #include "core/hle/service/am/applet_manager.h" | ||
| 19 | #include "core/hle/service/am/applet_message_queue.h" | 20 | #include "core/hle/service/am/applet_message_queue.h" |
| 20 | #include "core/hle/service/am/applet_oe.h" | 21 | #include "core/hle/service/am/applet_oe.h" |
| 21 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 22 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
| @@ -122,21 +123,11 @@ void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& | |||
| 122 | void AppletDataBroker::SignalStateChanged() { | 123 | void AppletDataBroker::SignalStateChanged() { |
| 123 | state_changed_event->Signal(); | 124 | state_changed_event->Signal(); |
| 124 | 125 | ||
| 126 | // TODO proper window management | ||
| 125 | switch (applet_mode) { | 127 | switch (applet_mode) { |
| 126 | case LibraryAppletMode::AllForeground: | 128 | case LibraryAppletMode::AllForeground: |
| 127 | case LibraryAppletMode::AllForegroundInitiallyHidden: { | 129 | case LibraryAppletMode::AllForegroundInitiallyHidden: { |
| 128 | auto applet_oe = system.ServiceManager().GetService<AppletOE>("appletOE"); | 130 | system.GetAppletManager().FocusStateChanged(); |
| 129 | auto applet_ae = system.ServiceManager().GetService<AppletAE>("appletAE"); | ||
| 130 | |||
| 131 | if (applet_oe) { | ||
| 132 | applet_oe->GetMessageQueue()->FocusStateChanged(); | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (applet_ae) { | ||
| 137 | applet_ae->GetMessageQueue()->FocusStateChanged(); | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | break; | 131 | break; |
| 141 | } | 132 | } |
| 142 | default: | 133 | default: |
| @@ -255,11 +246,6 @@ void FrontendAppletHolder::SetCurrentAppletId(AppletId applet_id) { | |||
| 255 | current_applet_id = applet_id; | 246 | current_applet_id = applet_id; |
| 256 | } | 247 | } |
| 257 | 248 | ||
| 258 | void FrontendAppletHolder::SetDefaultAppletFrontendSet() { | ||
| 259 | ClearAll(); | ||
| 260 | SetDefaultAppletsIfMissing(); | ||
| 261 | } | ||
| 262 | |||
| 263 | void FrontendAppletHolder::SetDefaultAppletsIfMissing() { | 249 | void FrontendAppletHolder::SetDefaultAppletsIfMissing() { |
| 264 | if (frontend.cabinet == nullptr) { | 250 | if (frontend.cabinet == nullptr) { |
| 265 | frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>(); | 251 | frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>(); |
diff --git a/src/core/hle/service/am/frontend/applets.h b/src/core/hle/service/am/frontend/applets.h index f58147955..dec1d63b2 100644 --- a/src/core/hle/service/am/frontend/applets.h +++ b/src/core/hle/service/am/frontend/applets.h | |||
| @@ -188,7 +188,6 @@ public: | |||
| 188 | void SetFrontendAppletSet(FrontendAppletSet set); | 188 | void SetFrontendAppletSet(FrontendAppletSet set); |
| 189 | void SetCabinetMode(NFP::CabinetMode mode); | 189 | void SetCabinetMode(NFP::CabinetMode mode); |
| 190 | void SetCurrentAppletId(AppletId applet_id); | 190 | void SetCurrentAppletId(AppletId applet_id); |
| 191 | void SetDefaultAppletFrontendSet(); | ||
| 192 | void SetDefaultAppletsIfMissing(); | 191 | void SetDefaultAppletsIfMissing(); |
| 193 | void ClearAll(); | 192 | void ClearAll(); |
| 194 | 193 | ||
diff --git a/src/core/hle/service/am/library_applet_accessor.cpp b/src/core/hle/service/am/library_applet_accessor.cpp index dabbd6dbe..d3be493e6 100644 --- a/src/core/hle/service/am/library_applet_accessor.cpp +++ b/src/core/hle/service/am/library_applet_accessor.cpp | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/scope_exit.h" | ||
| 4 | #include "core/hle/service/am/am_results.h" | 5 | #include "core/hle/service/am/am_results.h" |
| 6 | #include "core/hle/service/am/frontend/applets.h" | ||
| 5 | #include "core/hle/service/am/library_applet_accessor.h" | 7 | #include "core/hle/service/am/library_applet_accessor.h" |
| 6 | #include "core/hle/service/am/storage.h" | 8 | #include "core/hle/service/am/storage.h" |
| 7 | #include "core/hle/service/ipc_helpers.h" | 9 | #include "core/hle/service/ipc_helpers.h" |
| @@ -9,8 +11,10 @@ | |||
| 9 | namespace Service::AM { | 11 | namespace Service::AM { |
| 10 | 12 | ||
| 11 | ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, | 13 | ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, |
| 12 | std::shared_ptr<Frontend::FrontendApplet> applet_) | 14 | std::shared_ptr<AppletStorageHolder> storage_, |
| 13 | : ServiceFramework{system_, "ILibraryAppletAccessor"}, applet{std::move(applet_)} { | 15 | std::shared_ptr<Applet> applet_) |
| 16 | : ServiceFramework{system_, "ILibraryAppletAccessor"}, storage{std::move(storage_)}, | ||
| 17 | applet{std::move(applet_)} { | ||
| 14 | // clang-format off | 18 | // clang-format off |
| 15 | static const FunctionInfo functions[] = { | 19 | static const FunctionInfo functions[] = { |
| 16 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, | 20 | {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, |
| @@ -38,27 +42,31 @@ ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, | |||
| 38 | RegisterHandlers(functions); | 42 | RegisterHandlers(functions); |
| 39 | } | 43 | } |
| 40 | 44 | ||
| 45 | ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; | ||
| 46 | |||
| 41 | void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) { | 47 | void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) { |
| 42 | LOG_DEBUG(Service_AM, "called"); | 48 | LOG_DEBUG(Service_AM, "called"); |
| 43 | 49 | ||
| 44 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 50 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 45 | rb.Push(ResultSuccess); | 51 | rb.Push(ResultSuccess); |
| 46 | rb.PushCopyObjects(applet->GetBroker().GetStateChangedEvent()); | 52 | rb.PushCopyObjects(storage->state_changed_event.GetHandle()); |
| 47 | } | 53 | } |
| 48 | 54 | ||
| 49 | void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { | 55 | void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { |
| 50 | LOG_DEBUG(Service_AM, "called"); | 56 | LOG_DEBUG(Service_AM, "called"); |
| 51 | 57 | ||
| 58 | std::scoped_lock lk{applet->lock}; | ||
| 59 | |||
| 52 | IPC::ResponseBuilder rb{ctx, 3}; | 60 | IPC::ResponseBuilder rb{ctx, 3}; |
| 53 | rb.Push(ResultSuccess); | 61 | rb.Push(ResultSuccess); |
| 54 | rb.Push<u32>(applet->TransactionComplete()); | 62 | rb.Push<u32>(applet->is_completed); |
| 55 | } | 63 | } |
| 56 | 64 | ||
| 57 | void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { | 65 | void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { |
| 58 | LOG_DEBUG(Service_AM, "called"); | 66 | LOG_DEBUG(Service_AM, "called"); |
| 59 | 67 | ||
| 60 | IPC::ResponseBuilder rb{ctx, 2}; | 68 | IPC::ResponseBuilder rb{ctx, 2}; |
| 61 | rb.Push(applet->GetStatus()); | 69 | rb.Push(applet->terminate_result); |
| 62 | } | 70 | } |
| 63 | 71 | ||
| 64 | void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) { | 72 | void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) { |
| @@ -71,10 +79,7 @@ void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestConte | |||
| 71 | void ILibraryAppletAccessor::Start(HLERequestContext& ctx) { | 79 | void ILibraryAppletAccessor::Start(HLERequestContext& ctx) { |
| 72 | LOG_DEBUG(Service_AM, "called"); | 80 | LOG_DEBUG(Service_AM, "called"); |
| 73 | 81 | ||
| 74 | ASSERT(applet != nullptr); | 82 | applet->process->Run(); |
| 75 | |||
| 76 | applet->Initialize(); | ||
| 77 | applet->Execute(); | ||
| 78 | 83 | ||
| 79 | IPC::ResponseBuilder rb{ctx, 2}; | 84 | IPC::ResponseBuilder rb{ctx, 2}; |
| 80 | rb.Push(ResultSuccess); | 85 | rb.Push(ResultSuccess); |
| @@ -84,16 +89,17 @@ void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) { | |||
| 84 | LOG_DEBUG(Service_AM, "called"); | 89 | LOG_DEBUG(Service_AM, "called"); |
| 85 | 90 | ||
| 86 | ASSERT(applet != nullptr); | 91 | ASSERT(applet != nullptr); |
| 92 | applet->message_queue.RequestExit(); | ||
| 87 | 93 | ||
| 88 | IPC::ResponseBuilder rb{ctx, 2}; | 94 | IPC::ResponseBuilder rb{ctx, 2}; |
| 89 | rb.Push(applet->RequestExit()); | 95 | rb.Push(ResultSuccess); |
| 90 | } | 96 | } |
| 91 | 97 | ||
| 92 | void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { | 98 | void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { |
| 93 | LOG_DEBUG(Service_AM, "called"); | 99 | LOG_DEBUG(Service_AM, "called"); |
| 94 | 100 | ||
| 95 | IPC::RequestParser rp{ctx}; | 101 | IPC::RequestParser rp{ctx}; |
| 96 | applet->GetBroker().PushNormalDataFromGame(rp.PopIpcInterface<IStorage>().lock()); | 102 | storage->in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); |
| 97 | 103 | ||
| 98 | IPC::ResponseBuilder rb{ctx, 2}; | 104 | IPC::ResponseBuilder rb{ctx, 2}; |
| 99 | rb.Push(ResultSuccess); | 105 | rb.Push(ResultSuccess); |
| @@ -102,29 +108,24 @@ void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { | |||
| 102 | void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) { | 108 | void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) { |
| 103 | LOG_DEBUG(Service_AM, "called"); | 109 | LOG_DEBUG(Service_AM, "called"); |
| 104 | 110 | ||
| 105 | auto storage = applet->GetBroker().PopNormalDataToGame(); | 111 | std::shared_ptr<IStorage> data; |
| 106 | if (storage == nullptr) { | 112 | const auto res = storage->out_data.PopData(&data); |
| 107 | LOG_DEBUG(Service_AM, | 113 | |
| 108 | "storage is a nullptr. There is no data in the current normal channel"); | 114 | if (res.IsSuccess()) { |
| 115 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 116 | rb.Push(res); | ||
| 117 | rb.PushIpcInterface(std::move(data)); | ||
| 118 | } else { | ||
| 109 | IPC::ResponseBuilder rb{ctx, 2}; | 119 | IPC::ResponseBuilder rb{ctx, 2}; |
| 110 | rb.Push(AM::ResultNoDataInChannel); | 120 | rb.Push(res); |
| 111 | return; | ||
| 112 | } | 121 | } |
| 113 | |||
| 114 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 115 | rb.Push(ResultSuccess); | ||
| 116 | rb.PushIpcInterface<IStorage>(std::move(storage)); | ||
| 117 | } | 122 | } |
| 118 | 123 | ||
| 119 | void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { | 124 | void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { |
| 120 | LOG_DEBUG(Service_AM, "called"); | 125 | LOG_DEBUG(Service_AM, "called"); |
| 121 | 126 | ||
| 122 | IPC::RequestParser rp{ctx}; | 127 | IPC::RequestParser rp{ctx}; |
| 123 | applet->GetBroker().PushInteractiveDataFromGame(rp.PopIpcInterface<IStorage>().lock()); | 128 | storage->interactive_in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); |
| 124 | |||
| 125 | ASSERT(applet->IsInitialized()); | ||
| 126 | applet->ExecuteInteractive(); | ||
| 127 | applet->Execute(); | ||
| 128 | 129 | ||
| 129 | IPC::ResponseBuilder rb{ctx, 2}; | 130 | IPC::ResponseBuilder rb{ctx, 2}; |
| 130 | rb.Push(ResultSuccess); | 131 | rb.Push(ResultSuccess); |
| @@ -133,18 +134,17 @@ void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { | |||
| 133 | void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) { | 134 | void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) { |
| 134 | LOG_DEBUG(Service_AM, "called"); | 135 | LOG_DEBUG(Service_AM, "called"); |
| 135 | 136 | ||
| 136 | auto storage = applet->GetBroker().PopInteractiveDataToGame(); | 137 | std::shared_ptr<IStorage> data; |
| 137 | if (storage == nullptr) { | 138 | const auto res = storage->interactive_out_data.PopData(&data); |
| 138 | LOG_DEBUG(Service_AM, | 139 | |
| 139 | "storage is a nullptr. There is no data in the current interactive channel"); | 140 | if (res.IsSuccess()) { |
| 141 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 142 | rb.Push(res); | ||
| 143 | rb.PushIpcInterface(std::move(data)); | ||
| 144 | } else { | ||
| 140 | IPC::ResponseBuilder rb{ctx, 2}; | 145 | IPC::ResponseBuilder rb{ctx, 2}; |
| 141 | rb.Push(AM::ResultNoDataInChannel); | 146 | rb.Push(res); |
| 142 | return; | ||
| 143 | } | 147 | } |
| 144 | |||
| 145 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 146 | rb.Push(ResultSuccess); | ||
| 147 | rb.PushIpcInterface<IStorage>(std::move(storage)); | ||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { | 150 | void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { |
| @@ -152,7 +152,7 @@ void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { | |||
| 152 | 152 | ||
| 153 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 153 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 154 | rb.Push(ResultSuccess); | 154 | rb.Push(ResultSuccess); |
| 155 | rb.PushCopyObjects(applet->GetBroker().GetNormalDataEvent()); | 155 | rb.PushCopyObjects(storage->out_data.GetEvent()); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { | 158 | void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { |
| @@ -160,7 +160,7 @@ void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ct | |||
| 160 | 160 | ||
| 161 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 161 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 162 | rb.Push(ResultSuccess); | 162 | rb.Push(ResultSuccess); |
| 163 | rb.PushCopyObjects(applet->GetBroker().GetInteractiveDataEvent()); | 163 | rb.PushCopyObjects(storage->interactive_out_data.GetEvent()); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { | 166 | void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/library_applet_accessor.h b/src/core/hle/service/am/library_applet_accessor.h index 77f62906c..c34a1cbca 100644 --- a/src/core/hle/service/am/library_applet_accessor.h +++ b/src/core/hle/service/am/library_applet_accessor.h | |||
| @@ -3,17 +3,21 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/am/frontend/applets.h" | ||
| 7 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/service.h" |
| 8 | 7 | ||
| 9 | namespace Service::AM { | 8 | namespace Service::AM { |
| 10 | 9 | ||
| 10 | struct AppletStorageHolder; | ||
| 11 | struct Applet; | ||
| 12 | |||
| 11 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | 13 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { |
| 12 | public: | 14 | public: |
| 13 | explicit ILibraryAppletAccessor(Core::System& system_, | 15 | explicit ILibraryAppletAccessor(Core::System& system_, |
| 14 | std::shared_ptr<Frontend::FrontendApplet> applet_); | 16 | std::shared_ptr<AppletStorageHolder> storage_, |
| 17 | std::shared_ptr<Applet> applet_); | ||
| 18 | ~ILibraryAppletAccessor(); | ||
| 15 | 19 | ||
| 16 | private: | 20 | protected: |
| 17 | void GetAppletStateChangedEvent(HLERequestContext& ctx); | 21 | void GetAppletStateChangedEvent(HLERequestContext& ctx); |
| 18 | void IsCompleted(HLERequestContext& ctx); | 22 | void IsCompleted(HLERequestContext& ctx); |
| 19 | void GetResult(HLERequestContext& ctx); | 23 | void GetResult(HLERequestContext& ctx); |
| @@ -28,7 +32,8 @@ private: | |||
| 28 | void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); | 32 | void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); |
| 29 | void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); | 33 | void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); |
| 30 | 34 | ||
| 31 | std::shared_ptr<Frontend::FrontendApplet> applet; | 35 | const std::shared_ptr<AppletStorageHolder> storage; |
| 36 | const std::shared_ptr<Applet> applet; | ||
| 32 | }; | 37 | }; |
| 33 | 38 | ||
| 34 | } // namespace Service::AM | 39 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp index f80887517..e4332e244 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/library_applet_creator.cpp | |||
| @@ -2,16 +2,112 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/kernel/k_transfer_memory.h" | 4 | #include "core/hle/kernel/k_transfer_memory.h" |
| 5 | #include "core/hle/service/am/applet_manager.h" | ||
| 5 | #include "core/hle/service/am/frontend/applets.h" | 6 | #include "core/hle/service/am/frontend/applets.h" |
| 6 | #include "core/hle/service/am/library_applet_accessor.h" | 7 | #include "core/hle/service/am/library_applet_accessor.h" |
| 7 | #include "core/hle/service/am/library_applet_creator.h" | 8 | #include "core/hle/service/am/library_applet_creator.h" |
| 8 | #include "core/hle/service/am/storage.h" | 9 | #include "core/hle/service/am/storage.h" |
| 9 | #include "core/hle/service/ipc_helpers.h" | 10 | #include "core/hle/service/ipc_helpers.h" |
| 11 | #include "core/hle/service/sm/sm.h" | ||
| 10 | 12 | ||
| 11 | namespace Service::AM { | 13 | namespace Service::AM { |
| 12 | 14 | ||
| 13 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_) | 15 | namespace { |
| 14 | : ServiceFramework{system_, "ILibraryAppletCreator"} { | 16 | |
| 17 | AppletProgramId AppletIdToProgramId(AppletId applet_id) { | ||
| 18 | switch (applet_id) { | ||
| 19 | case AppletId::OverlayDisplay: | ||
| 20 | return AppletProgramId::OverlayDisplay; | ||
| 21 | case AppletId::QLaunch: | ||
| 22 | return AppletProgramId::QLaunch; | ||
| 23 | case AppletId::Starter: | ||
| 24 | return AppletProgramId::Starter; | ||
| 25 | case AppletId::Auth: | ||
| 26 | return AppletProgramId::Auth; | ||
| 27 | case AppletId::Cabinet: | ||
| 28 | return AppletProgramId::Cabinet; | ||
| 29 | case AppletId::Controller: | ||
| 30 | return AppletProgramId::Controller; | ||
| 31 | case AppletId::DataErase: | ||
| 32 | return AppletProgramId::DataErase; | ||
| 33 | case AppletId::Error: | ||
| 34 | return AppletProgramId::Error; | ||
| 35 | case AppletId::NetConnect: | ||
| 36 | return AppletProgramId::NetConnect; | ||
| 37 | case AppletId::ProfileSelect: | ||
| 38 | return AppletProgramId::ProfileSelect; | ||
| 39 | case AppletId::SoftwareKeyboard: | ||
| 40 | return AppletProgramId::SoftwareKeyboard; | ||
| 41 | case AppletId::MiiEdit: | ||
| 42 | return AppletProgramId::MiiEdit; | ||
| 43 | case AppletId::Web: | ||
| 44 | return AppletProgramId::Web; | ||
| 45 | case AppletId::Shop: | ||
| 46 | return AppletProgramId::Shop; | ||
| 47 | case AppletId::PhotoViewer: | ||
| 48 | return AppletProgramId::PhotoViewer; | ||
| 49 | case AppletId::Settings: | ||
| 50 | return AppletProgramId::Settings; | ||
| 51 | case AppletId::OfflineWeb: | ||
| 52 | return AppletProgramId::OfflineWeb; | ||
| 53 | case AppletId::LoginShare: | ||
| 54 | return AppletProgramId::LoginShare; | ||
| 55 | case AppletId::WebAuth: | ||
| 56 | return AppletProgramId::WebAuth; | ||
| 57 | case AppletId::MyPage: | ||
| 58 | return AppletProgramId::MyPage; | ||
| 59 | default: | ||
| 60 | return static_cast<AppletProgramId>(0); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | ||
| 65 | std::shared_ptr<Applet> caller_applet, | ||
| 66 | AppletId applet_id, | ||
| 67 | LibraryAppletMode mode) { | ||
| 68 | const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); | ||
| 69 | if (program_id == 0) { | ||
| 70 | // Unknown applet | ||
| 71 | return {}; | ||
| 72 | } | ||
| 73 | |||
| 74 | auto process = std::make_unique<Process>(system); | ||
| 75 | if (!process->Initialize(program_id)) { | ||
| 76 | // Couldn't initialize the guest process | ||
| 77 | return {}; | ||
| 78 | } | ||
| 79 | |||
| 80 | const auto applet = std::make_shared<Applet>(system, std::move(process)); | ||
| 81 | applet->program_id = program_id; | ||
| 82 | applet->applet_id = applet_id; | ||
| 83 | applet->type = AppletType::LibraryApplet; | ||
| 84 | applet->library_applet_mode = mode; | ||
| 85 | |||
| 86 | // Library applet should be foreground | ||
| 87 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | ||
| 88 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | ||
| 89 | applet->focus_state = FocusState::InFocus; | ||
| 90 | |||
| 91 | auto storage = std::make_shared<AppletStorageHolder>(system); | ||
| 92 | applet->caller_applet = caller_applet; | ||
| 93 | applet->caller_applet_storage = storage; | ||
| 94 | |||
| 95 | system.GetAppletManager().InsertApplet(applet); | ||
| 96 | |||
| 97 | return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); | ||
| 98 | } | ||
| 99 | |||
| 100 | std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, | ||
| 101 | AppletId applet_id, | ||
| 102 | LibraryAppletMode mode) { | ||
| 103 | UNREACHABLE(); | ||
| 104 | return {}; | ||
| 105 | } | ||
| 106 | |||
| 107 | } // namespace | ||
| 108 | |||
| 109 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
| 110 | : ServiceFramework{system_, "ILibraryAppletCreator"}, applet{std::move(applet_)} { | ||
| 15 | static const FunctionInfo functions[] = { | 111 | static const FunctionInfo functions[] = { |
| 16 | {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"}, | 112 | {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"}, |
| 17 | {1, nullptr, "TerminateAllLibraryApplets"}, | 113 | {1, nullptr, "TerminateAllLibraryApplets"}, |
| @@ -34,10 +130,11 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { | |||
| 34 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, | 130 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, |
| 35 | applet_mode); | 131 | applet_mode); |
| 36 | 132 | ||
| 37 | const auto& holder{system.GetFrontendAppletHolder()}; | 133 | auto library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); |
| 38 | const auto applet = holder.GetApplet(applet_id, applet_mode); | 134 | if (!library_applet) { |
| 39 | 135 | library_applet = CreateFrontendApplet(system, applet_id, applet_mode); | |
| 40 | if (applet == nullptr) { | 136 | } |
| 137 | if (!library_applet) { | ||
| 41 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); | 138 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); |
| 42 | 139 | ||
| 43 | IPC::ResponseBuilder rb{ctx, 2}; | 140 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -45,10 +142,12 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { | |||
| 45 | return; | 142 | return; |
| 46 | } | 143 | } |
| 47 | 144 | ||
| 48 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 145 | // Applet is created, can now be launched. |
| 146 | applet->library_applet_launchable_event.Signal(); | ||
| 49 | 147 | ||
| 148 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 50 | rb.Push(ResultSuccess); | 149 | rb.Push(ResultSuccess); |
| 51 | rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet); | 150 | rb.PushIpcInterface<ILibraryAppletAccessor>(library_applet); |
| 52 | } | 151 | } |
| 53 | 152 | ||
| 54 | void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) { | 153 | void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/library_applet_creator.h b/src/core/hle/service/am/library_applet_creator.h index 97f236fbc..551f287bd 100644 --- a/src/core/hle/service/am/library_applet_creator.h +++ b/src/core/hle/service/am/library_applet_creator.h | |||
| @@ -7,9 +7,11 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::AM { | 8 | namespace Service::AM { |
| 9 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 10 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | 12 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { |
| 11 | public: | 13 | public: |
| 12 | explicit ILibraryAppletCreator(Core::System& system_); | 14 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 13 | ~ILibraryAppletCreator() override; | 15 | ~ILibraryAppletCreator() override; |
| 14 | 16 | ||
| 15 | private: | 17 | private: |
| @@ -17,6 +19,8 @@ private: | |||
| 17 | void CreateStorage(HLERequestContext& ctx); | 19 | void CreateStorage(HLERequestContext& ctx); |
| 18 | void CreateTransferMemoryStorage(HLERequestContext& ctx); | 20 | void CreateTransferMemoryStorage(HLERequestContext& ctx); |
| 19 | void CreateHandleStorage(HLERequestContext& ctx); | 21 | void CreateHandleStorage(HLERequestContext& ctx); |
| 22 | |||
| 23 | const std::shared_ptr<Applet> applet; | ||
| 20 | }; | 24 | }; |
| 21 | 25 | ||
| 22 | } // namespace Service::AM | 26 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/library_applet_proxy.cpp b/src/core/hle/service/am/library_applet_proxy.cpp index 047fc40f4..1d88dd78c 100644 --- a/src/core/hle/service/am/library_applet_proxy.cpp +++ b/src/core/hle/service/am/library_applet_proxy.cpp | |||
| @@ -19,10 +19,9 @@ | |||
| 19 | namespace Service::AM { | 19 | namespace Service::AM { |
| 20 | 20 | ||
| 21 | ILibraryAppletProxy::ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 21 | ILibraryAppletProxy::ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 22 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 22 | std::shared_ptr<Applet> applet_, Core::System& system_) |
| 23 | Core::System& system_) | 23 | : ServiceFramework{system_, "ILibraryAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move( |
| 24 | : ServiceFramework{system_, "ILibraryAppletProxy"}, nvnflinger{nvnflinger_}, | 24 | applet_)} { |
| 25 | msg_queue{std::move(msg_queue_)} { | ||
| 26 | // clang-format off | 25 | // clang-format off |
| 27 | static const FunctionInfo functions[] = { | 26 | static const FunctionInfo functions[] = { |
| 28 | {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 27 | {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| @@ -43,12 +42,14 @@ ILibraryAppletProxy::ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | |||
| 43 | RegisterHandlers(functions); | 42 | RegisterHandlers(functions); |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 45 | ILibraryAppletProxy::~ILibraryAppletProxy() = default; | ||
| 46 | |||
| 46 | void ILibraryAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { | 47 | void ILibraryAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { |
| 47 | LOG_DEBUG(Service_AM, "called"); | 48 | LOG_DEBUG(Service_AM, "called"); |
| 48 | 49 | ||
| 49 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 50 | rb.Push(ResultSuccess); | 51 | rb.Push(ResultSuccess); |
| 51 | rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); | 52 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | void ILibraryAppletProxy::GetSelfController(HLERequestContext& ctx) { | 55 | void ILibraryAppletProxy::GetSelfController(HLERequestContext& ctx) { |
| @@ -56,7 +57,7 @@ void ILibraryAppletProxy::GetSelfController(HLERequestContext& ctx) { | |||
| 56 | 57 | ||
| 57 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 58 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 58 | rb.Push(ResultSuccess); | 59 | rb.Push(ResultSuccess); |
| 59 | rb.PushIpcInterface<ISelfController>(system, nvnflinger); | 60 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); |
| 60 | } | 61 | } |
| 61 | 62 | ||
| 62 | void ILibraryAppletProxy::GetWindowController(HLERequestContext& ctx) { | 63 | void ILibraryAppletProxy::GetWindowController(HLERequestContext& ctx) { |
| @@ -64,7 +65,7 @@ void ILibraryAppletProxy::GetWindowController(HLERequestContext& ctx) { | |||
| 64 | 65 | ||
| 65 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 66 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 66 | rb.Push(ResultSuccess); | 67 | rb.Push(ResultSuccess); |
| 67 | rb.PushIpcInterface<IWindowController>(system); | 68 | rb.PushIpcInterface<IWindowController>(system, applet); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | void ILibraryAppletProxy::GetAudioController(HLERequestContext& ctx) { | 71 | void ILibraryAppletProxy::GetAudioController(HLERequestContext& ctx) { |
| @@ -88,7 +89,7 @@ void ILibraryAppletProxy::GetProcessWindingController(HLERequestContext& ctx) { | |||
| 88 | 89 | ||
| 89 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 90 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 90 | rb.Push(ResultSuccess); | 91 | rb.Push(ResultSuccess); |
| 91 | rb.PushIpcInterface<IProcessWindingController>(system); | 92 | rb.PushIpcInterface<IProcessWindingController>(system, applet); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | void ILibraryAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | 95 | void ILibraryAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { |
| @@ -96,7 +97,7 @@ void ILibraryAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | |||
| 96 | 97 | ||
| 97 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 98 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 98 | rb.Push(ResultSuccess); | 99 | rb.Push(ResultSuccess); |
| 99 | rb.PushIpcInterface<ILibraryAppletCreator>(system); | 100 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | void ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { | 103 | void ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { |
| @@ -104,7 +105,7 @@ void ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) | |||
| 104 | 105 | ||
| 105 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 106 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 106 | rb.Push(ResultSuccess); | 107 | rb.Push(ResultSuccess); |
| 107 | rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); | 108 | rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system, applet); |
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | void ILibraryAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { | 111 | void ILibraryAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { |
| @@ -112,7 +113,7 @@ void ILibraryAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { | |||
| 112 | 113 | ||
| 113 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 114 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 114 | rb.Push(ResultSuccess); | 115 | rb.Push(ResultSuccess); |
| 115 | rb.PushIpcInterface<IAppletCommonFunctions>(system); | 116 | rb.PushIpcInterface<IAppletCommonFunctions>(system, applet); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | void ILibraryAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { | 119 | void ILibraryAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/library_applet_proxy.h b/src/core/hle/service/am/library_applet_proxy.h index cd9e6d02b..8f7a25897 100644 --- a/src/core/hle/service/am/library_applet_proxy.h +++ b/src/core/hle/service/am/library_applet_proxy.h | |||
| @@ -3,16 +3,17 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/hle/service/am/applet_message_queue.h" | ||
| 7 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/service.h" |
| 8 | 7 | ||
| 9 | namespace Service::AM { | 8 | namespace Service::AM { |
| 10 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 11 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | 12 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { |
| 12 | public: | 13 | public: |
| 13 | explicit ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 14 | explicit ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 14 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 15 | std::shared_ptr<Applet> applet_, Core::System& system_); |
| 15 | Core::System& system_); | 16 | ~ILibraryAppletProxy(); |
| 16 | 17 | ||
| 17 | private: | 18 | private: |
| 18 | void GetCommonStateGetter(HLERequestContext& ctx); | 19 | void GetCommonStateGetter(HLERequestContext& ctx); |
| @@ -29,7 +30,7 @@ private: | |||
| 29 | void GetDebugFunctions(HLERequestContext& ctx); | 30 | void GetDebugFunctions(HLERequestContext& ctx); |
| 30 | 31 | ||
| 31 | Nvnflinger::Nvnflinger& nvnflinger; | 32 | Nvnflinger::Nvnflinger& nvnflinger; |
| 32 | std::shared_ptr<AppletMessageQueue> msg_queue; | 33 | std::shared_ptr<Applet> applet; |
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | } // namespace Service::AM | 36 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/library_applet_self_accessor.cpp b/src/core/hle/service/am/library_applet_self_accessor.cpp index c36f141f4..74ee33213 100644 --- a/src/core/hle/service/am/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/library_applet_self_accessor.cpp | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/scope_exit.h" | ||
| 4 | #include "core/core_timing.h" | 5 | #include "core/core_timing.h" |
| 5 | #include "core/hle/service/acc/profile_manager.h" | 6 | #include "core/hle/service/acc/profile_manager.h" |
| 6 | #include "core/hle/service/am/am_results.h" | 7 | #include "core/hle/service/am/am_results.h" |
| 8 | #include "core/hle/service/am/applet_manager.h" | ||
| 7 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 9 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
| 8 | #include "core/hle/service/am/frontend/applet_controller.h" | 10 | #include "core/hle/service/am/frontend/applet_controller.h" |
| 9 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" | 11 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" |
| @@ -16,16 +18,44 @@ | |||
| 16 | 18 | ||
| 17 | namespace Service::AM { | 19 | namespace Service::AM { |
| 18 | 20 | ||
| 19 | ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | 21 | namespace { |
| 20 | : ServiceFramework{system_, "ILibraryAppletSelfAccessor"} { | 22 | |
| 23 | struct AppletIdentityInfo { | ||
| 24 | AppletId applet_id; | ||
| 25 | INSERT_PADDING_BYTES(0x4); | ||
| 26 | u64 application_id; | ||
| 27 | }; | ||
| 28 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||
| 29 | |||
| 30 | AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) { | ||
| 31 | if (const auto caller_applet = applet->caller_applet.lock(); caller_applet) { | ||
| 32 | // TODO: is this actually the application ID? | ||
| 33 | return { | ||
| 34 | .applet_id = applet->applet_id, | ||
| 35 | .application_id = applet->program_id, | ||
| 36 | }; | ||
| 37 | } else { | ||
| 38 | return { | ||
| 39 | .applet_id = AppletId::QLaunch, | ||
| 40 | .application_id = 0x0100000000001000ull, | ||
| 41 | }; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | } // namespace | ||
| 46 | |||
| 47 | ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_, | ||
| 48 | std::shared_ptr<Applet> applet_) | ||
| 49 | : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)}, | ||
| 50 | storage{applet->caller_applet_storage} { | ||
| 21 | // clang-format off | 51 | // clang-format off |
| 22 | static const FunctionInfo functions[] = { | 52 | static const FunctionInfo functions[] = { |
| 23 | {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, | 53 | {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, |
| 24 | {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"}, | 54 | {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"}, |
| 25 | {2, nullptr, "PopInteractiveInData"}, | 55 | {2, &ILibraryAppletSelfAccessor::PopInteractiveInData, "PopInteractiveInData"}, |
| 26 | {3, nullptr, "PushInteractiveOutData"}, | 56 | {3, &ILibraryAppletSelfAccessor::PushInteractiveOutData, "PushInteractiveOutData"}, |
| 27 | {5, nullptr, "GetPopInDataEvent"}, | 57 | {5, &ILibraryAppletSelfAccessor::GetPopInDataEvent, "GetPopInDataEvent"}, |
| 28 | {6, nullptr, "GetPopInteractiveInDataEvent"}, | 58 | {6, &ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent, "GetPopInteractiveInDataEvent"}, |
| 29 | {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, | 59 | {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, |
| 30 | {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, | 60 | {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, |
| 31 | {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"}, | 61 | {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"}, |
| @@ -58,26 +88,6 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) | |||
| 58 | }; | 88 | }; |
| 59 | // clang-format on | 89 | // clang-format on |
| 60 | RegisterHandlers(functions); | 90 | RegisterHandlers(functions); |
| 61 | |||
| 62 | switch (system.GetFrontendAppletHolder().GetCurrentAppletId()) { | ||
| 63 | case AppletId::Cabinet: | ||
| 64 | PushInShowCabinetData(); | ||
| 65 | break; | ||
| 66 | case AppletId::MiiEdit: | ||
| 67 | PushInShowMiiEditData(); | ||
| 68 | break; | ||
| 69 | case AppletId::PhotoViewer: | ||
| 70 | PushInShowAlbum(); | ||
| 71 | break; | ||
| 72 | case AppletId::SoftwareKeyboard: | ||
| 73 | PushInShowSoftwareKeyboard(); | ||
| 74 | break; | ||
| 75 | case AppletId::Controller: | ||
| 76 | PushInShowController(); | ||
| 77 | break; | ||
| 78 | default: | ||
| 79 | break; | ||
| 80 | } | ||
| 81 | } | 91 | } |
| 82 | 92 | ||
| 83 | ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; | 93 | ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; |
| @@ -85,31 +95,81 @@ ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; | |||
| 85 | void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) { | 95 | void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) { |
| 86 | LOG_INFO(Service_AM, "called"); | 96 | LOG_INFO(Service_AM, "called"); |
| 87 | 97 | ||
| 88 | if (queue_data.empty()) { | 98 | std::shared_ptr<IStorage> data; |
| 99 | const auto res = storage->in_data.PopData(&data); | ||
| 100 | |||
| 101 | if (res.IsSuccess()) { | ||
| 102 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 103 | rb.Push(res); | ||
| 104 | rb.PushIpcInterface(std::move(data)); | ||
| 105 | } else { | ||
| 89 | IPC::ResponseBuilder rb{ctx, 2}; | 106 | IPC::ResponseBuilder rb{ctx, 2}; |
| 90 | rb.Push(AM::ResultNoDataInChannel); | 107 | rb.Push(res); |
| 91 | return; | ||
| 92 | } | 108 | } |
| 109 | } | ||
| 110 | |||
| 111 | void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) { | ||
| 112 | LOG_INFO(Service_AM, "called"); | ||
| 93 | 113 | ||
| 94 | auto data = queue_data.front(); | 114 | IPC::RequestParser rp{ctx}; |
| 95 | queue_data.pop_front(); | 115 | storage->out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); |
| 96 | 116 | ||
| 97 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 117 | IPC::ResponseBuilder rb{ctx, 2}; |
| 98 | rb.Push(ResultSuccess); | 118 | rb.Push(ResultSuccess); |
| 99 | rb.PushIpcInterface<IStorage>(system, std::move(data)); | ||
| 100 | } | 119 | } |
| 101 | 120 | ||
| 102 | void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) { | 121 | void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) { |
| 103 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 122 | LOG_INFO(Service_AM, "called"); |
| 123 | |||
| 124 | std::shared_ptr<IStorage> data; | ||
| 125 | const auto res = storage->interactive_in_data.PopData(&data); | ||
| 126 | |||
| 127 | if (res.IsSuccess()) { | ||
| 128 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 129 | rb.Push(res); | ||
| 130 | rb.PushIpcInterface(std::move(data)); | ||
| 131 | } else { | ||
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 133 | rb.Push(res); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx) { | ||
| 138 | LOG_INFO(Service_AM, "called"); | ||
| 139 | |||
| 140 | IPC::RequestParser rp{ctx}; | ||
| 141 | storage->interactive_out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); | ||
| 104 | 142 | ||
| 105 | IPC::ResponseBuilder rb{ctx, 2}; | 143 | IPC::ResponseBuilder rb{ctx, 2}; |
| 106 | rb.Push(ResultSuccess); | 144 | rb.Push(ResultSuccess); |
| 107 | } | 145 | } |
| 108 | 146 | ||
| 147 | void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) { | ||
| 148 | LOG_INFO(Service_AM, "called"); | ||
| 149 | |||
| 150 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 151 | rb.Push(ResultSuccess); | ||
| 152 | rb.PushCopyObjects(storage->in_data.GetEvent()); | ||
| 153 | } | ||
| 154 | |||
| 155 | void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) { | ||
| 156 | LOG_INFO(Service_AM, "called"); | ||
| 157 | |||
| 158 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 159 | rb.Push(ResultSuccess); | ||
| 160 | rb.PushCopyObjects(storage->interactive_in_data.GetEvent()); | ||
| 161 | } | ||
| 162 | |||
| 109 | void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { | 163 | void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { |
| 110 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 164 | LOG_INFO(Service_AM, "called"); |
| 165 | |||
| 166 | system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid); | ||
| 111 | 167 | ||
| 112 | system.Exit(); | 168 | { |
| 169 | std::scoped_lock lk{applet->lock}; | ||
| 170 | applet->is_completed = true; | ||
| 171 | storage->state_changed_event.Signal(); | ||
| 172 | } | ||
| 113 | 173 | ||
| 114 | IPC::ResponseBuilder rb{ctx, 2}; | 174 | IPC::ResponseBuilder rb{ctx, 2}; |
| 115 | rb.Push(ResultSuccess); | 175 | rb.Push(ResultSuccess); |
| @@ -124,8 +184,8 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { | |||
| 124 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 184 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 125 | 185 | ||
| 126 | const LibraryAppletInfo applet_info{ | 186 | const LibraryAppletInfo applet_info{ |
| 127 | .applet_id = system.GetFrontendAppletHolder().GetCurrentAppletId(), | 187 | .applet_id = applet->applet_id, |
| 128 | .library_applet_mode = LibraryAppletMode::AllForeground, | 188 | .library_applet_mode = applet->library_applet_mode, |
| 129 | }; | 189 | }; |
| 130 | 190 | ||
| 131 | IPC::ResponseBuilder rb{ctx, 4}; | 191 | IPC::ResponseBuilder rb{ctx, 4}; |
| @@ -134,13 +194,6 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { | |||
| 134 | } | 194 | } |
| 135 | 195 | ||
| 136 | void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) { | 196 | void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) { |
| 137 | struct AppletIdentityInfo { | ||
| 138 | AppletId applet_id; | ||
| 139 | INSERT_PADDING_BYTES(0x4); | ||
| 140 | u64 application_id; | ||
| 141 | }; | ||
| 142 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||
| 143 | |||
| 144 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 197 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 145 | 198 | ||
| 146 | const AppletIdentityInfo applet_info{ | 199 | const AppletIdentityInfo applet_info{ |
| @@ -154,22 +207,11 @@ void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ct | |||
| 154 | } | 207 | } |
| 155 | 208 | ||
| 156 | void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { | 209 | void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { |
| 157 | struct AppletIdentityInfo { | ||
| 158 | AppletId applet_id; | ||
| 159 | INSERT_PADDING_BYTES(0x4); | ||
| 160 | u64 application_id; | ||
| 161 | }; | ||
| 162 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | ||
| 163 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 210 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 164 | 211 | ||
| 165 | const AppletIdentityInfo applet_info{ | ||
| 166 | .applet_id = AppletId::QLaunch, | ||
| 167 | .application_id = 0x0100000000001000ull, | ||
| 168 | }; | ||
| 169 | |||
| 170 | IPC::ResponseBuilder rb{ctx, 6}; | 212 | IPC::ResponseBuilder rb{ctx, 6}; |
| 171 | rb.Push(ResultSuccess); | 213 | rb.Push(ResultSuccess); |
| 172 | rb.PushRaw(applet_info); | 214 | rb.PushRaw(GetCallerIdentity(applet)); |
| 173 | } | 215 | } |
| 174 | 216 | ||
| 175 | void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) { | 217 | void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) { |
| @@ -207,176 +249,4 @@ void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext | |||
| 207 | rb.Push<u8>(0); | 249 | rb.Push<u8>(0); |
| 208 | } | 250 | } |
| 209 | 251 | ||
| 210 | void ILibraryAppletSelfAccessor::PushInShowAlbum() { | ||
| 211 | const CommonArguments arguments{ | ||
| 212 | .arguments_version = CommonArgumentVersion::Version3, | ||
| 213 | .size = CommonArgumentSize::Version3, | ||
| 214 | .library_version = 1, | ||
| 215 | .theme_color = ThemeColor::BasicBlack, | ||
| 216 | .play_startup_sound = true, | ||
| 217 | .system_tick = system.CoreTiming().GetClockTicks(), | ||
| 218 | }; | ||
| 219 | |||
| 220 | std::vector<u8> argument_data(sizeof(arguments)); | ||
| 221 | std::vector<u8> settings_data{2}; | ||
| 222 | std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); | ||
| 223 | queue_data.emplace_back(std::move(argument_data)); | ||
| 224 | queue_data.emplace_back(std::move(settings_data)); | ||
| 225 | } | ||
| 226 | |||
| 227 | void ILibraryAppletSelfAccessor::PushInShowController() { | ||
| 228 | const CommonArguments common_args = { | ||
| 229 | .arguments_version = CommonArgumentVersion::Version3, | ||
| 230 | .size = CommonArgumentSize::Version3, | ||
| 231 | .library_version = static_cast<u32>(Frontend::ControllerAppletVersion::Version8), | ||
| 232 | .theme_color = ThemeColor::BasicBlack, | ||
| 233 | .play_startup_sound = true, | ||
| 234 | .system_tick = system.CoreTiming().GetClockTicks(), | ||
| 235 | }; | ||
| 236 | |||
| 237 | Frontend::ControllerSupportArgNew user_args = { | ||
| 238 | .header = {.player_count_min = 1, | ||
| 239 | .player_count_max = 4, | ||
| 240 | .enable_take_over_connection = true, | ||
| 241 | .enable_left_justify = false, | ||
| 242 | .enable_permit_joy_dual = true, | ||
| 243 | .enable_single_mode = false, | ||
| 244 | .enable_identification_color = false}, | ||
| 245 | .identification_colors = {}, | ||
| 246 | .enable_explain_text = false, | ||
| 247 | .explain_text = {}, | ||
| 248 | }; | ||
| 249 | |||
| 250 | Frontend::ControllerSupportArgPrivate private_args = { | ||
| 251 | .arg_private_size = sizeof(Frontend::ControllerSupportArgPrivate), | ||
| 252 | .arg_size = sizeof(Frontend::ControllerSupportArgNew), | ||
| 253 | .is_home_menu = true, | ||
| 254 | .flag_1 = true, | ||
| 255 | .mode = Frontend::ControllerSupportMode::ShowControllerSupport, | ||
| 256 | .caller = Frontend::ControllerSupportCaller:: | ||
| 257 | Application, // switchbrew: Always zero except with | ||
| 258 | // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem, | ||
| 259 | // which sets this to the input param | ||
| 260 | .style_set = Core::HID::NpadStyleSet::None, | ||
| 261 | .joy_hold_type = 0, | ||
| 262 | }; | ||
| 263 | std::vector<u8> common_args_data(sizeof(common_args)); | ||
| 264 | std::vector<u8> private_args_data(sizeof(private_args)); | ||
| 265 | std::vector<u8> user_args_data(sizeof(user_args)); | ||
| 266 | |||
| 267 | std::memcpy(common_args_data.data(), &common_args, sizeof(common_args)); | ||
| 268 | std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); | ||
| 269 | std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); | ||
| 270 | |||
| 271 | queue_data.emplace_back(std::move(common_args_data)); | ||
| 272 | queue_data.emplace_back(std::move(private_args_data)); | ||
| 273 | queue_data.emplace_back(std::move(user_args_data)); | ||
| 274 | } | ||
| 275 | |||
| 276 | void ILibraryAppletSelfAccessor::PushInShowCabinetData() { | ||
| 277 | const CommonArguments arguments{ | ||
| 278 | .arguments_version = CommonArgumentVersion::Version3, | ||
| 279 | .size = CommonArgumentSize::Version3, | ||
| 280 | .library_version = static_cast<u32>(Frontend::CabinetAppletVersion::Version1), | ||
| 281 | .theme_color = ThemeColor::BasicBlack, | ||
| 282 | .play_startup_sound = true, | ||
| 283 | .system_tick = system.CoreTiming().GetClockTicks(), | ||
| 284 | }; | ||
| 285 | |||
| 286 | const Frontend::StartParamForAmiiboSettings amiibo_settings{ | ||
| 287 | .param_1 = 0, | ||
| 288 | .applet_mode = system.GetFrontendAppletHolder().GetCabinetMode(), | ||
| 289 | .flags = Frontend::CabinetFlags::None, | ||
| 290 | .amiibo_settings_1 = 0, | ||
| 291 | .device_handle = 0, | ||
| 292 | .tag_info{}, | ||
| 293 | .register_info{}, | ||
| 294 | .amiibo_settings_3{}, | ||
| 295 | }; | ||
| 296 | |||
| 297 | std::vector<u8> argument_data(sizeof(arguments)); | ||
| 298 | std::vector<u8> settings_data(sizeof(amiibo_settings)); | ||
| 299 | std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); | ||
| 300 | std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings)); | ||
| 301 | queue_data.emplace_back(std::move(argument_data)); | ||
| 302 | queue_data.emplace_back(std::move(settings_data)); | ||
| 303 | } | ||
| 304 | |||
| 305 | void ILibraryAppletSelfAccessor::PushInShowMiiEditData() { | ||
| 306 | struct MiiEditV3 { | ||
| 307 | Frontend::MiiEditAppletInputCommon common; | ||
| 308 | Frontend::MiiEditAppletInputV3 input; | ||
| 309 | }; | ||
| 310 | static_assert(sizeof(MiiEditV3) == 0x100, "MiiEditV3 has incorrect size."); | ||
| 311 | |||
| 312 | MiiEditV3 mii_arguments{ | ||
| 313 | .common = | ||
| 314 | { | ||
| 315 | .version = Frontend::MiiEditAppletVersion::Version3, | ||
| 316 | .applet_mode = Frontend::MiiEditAppletMode::ShowMiiEdit, | ||
| 317 | }, | ||
| 318 | .input{}, | ||
| 319 | }; | ||
| 320 | |||
| 321 | std::vector<u8> argument_data(sizeof(mii_arguments)); | ||
| 322 | std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments)); | ||
| 323 | |||
| 324 | queue_data.emplace_back(std::move(argument_data)); | ||
| 325 | } | ||
| 326 | |||
| 327 | void ILibraryAppletSelfAccessor::PushInShowSoftwareKeyboard() { | ||
| 328 | const CommonArguments arguments{ | ||
| 329 | .arguments_version = CommonArgumentVersion::Version3, | ||
| 330 | .size = CommonArgumentSize::Version3, | ||
| 331 | .library_version = static_cast<u32>(Frontend::SwkbdAppletVersion::Version524301), | ||
| 332 | .theme_color = ThemeColor::BasicBlack, | ||
| 333 | .play_startup_sound = true, | ||
| 334 | .system_tick = system.CoreTiming().GetClockTicks(), | ||
| 335 | }; | ||
| 336 | |||
| 337 | std::vector<char16_t> initial_string(0); | ||
| 338 | |||
| 339 | const Frontend::SwkbdConfigCommon swkbd_config{ | ||
| 340 | .type = Frontend::SwkbdType::Qwerty, | ||
| 341 | .ok_text{}, | ||
| 342 | .left_optional_symbol_key{}, | ||
| 343 | .right_optional_symbol_key{}, | ||
| 344 | .use_prediction = false, | ||
| 345 | .key_disable_flags{}, | ||
| 346 | .initial_cursor_position = Frontend::SwkbdInitialCursorPosition::Start, | ||
| 347 | .header_text{}, | ||
| 348 | .sub_text{}, | ||
| 349 | .guide_text{}, | ||
| 350 | .max_text_length = 500, | ||
| 351 | .min_text_length = 0, | ||
| 352 | .password_mode = Frontend::SwkbdPasswordMode::Disabled, | ||
| 353 | .text_draw_type = Frontend::SwkbdTextDrawType::Box, | ||
| 354 | .enable_return_button = true, | ||
| 355 | .use_utf8 = false, | ||
| 356 | .use_blur_background = true, | ||
| 357 | .initial_string_offset{}, | ||
| 358 | .initial_string_length = static_cast<u32>(initial_string.size()), | ||
| 359 | .user_dictionary_offset{}, | ||
| 360 | .user_dictionary_entries{}, | ||
| 361 | .use_text_check = false, | ||
| 362 | }; | ||
| 363 | |||
| 364 | Frontend::SwkbdConfigNew swkbd_config_new{}; | ||
| 365 | |||
| 366 | std::vector<u8> argument_data(sizeof(arguments)); | ||
| 367 | std::vector<u8> swkbd_data(sizeof(swkbd_config) + sizeof(swkbd_config_new)); | ||
| 368 | std::vector<u8> work_buffer(swkbd_config.initial_string_length * sizeof(char16_t)); | ||
| 369 | |||
| 370 | std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); | ||
| 371 | std::memcpy(swkbd_data.data(), &swkbd_config, sizeof(swkbd_config)); | ||
| 372 | std::memcpy(swkbd_data.data() + sizeof(swkbd_config), &swkbd_config_new, | ||
| 373 | sizeof(Frontend::SwkbdConfigNew)); | ||
| 374 | std::memcpy(work_buffer.data(), initial_string.data(), | ||
| 375 | swkbd_config.initial_string_length * sizeof(char16_t)); | ||
| 376 | |||
| 377 | queue_data.emplace_back(std::move(argument_data)); | ||
| 378 | queue_data.emplace_back(std::move(swkbd_data)); | ||
| 379 | queue_data.emplace_back(std::move(work_buffer)); | ||
| 380 | } | ||
| 381 | |||
| 382 | } // namespace Service::AM | 252 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/library_applet_self_accessor.h b/src/core/hle/service/am/library_applet_self_accessor.h index 45b325b77..b15040539 100644 --- a/src/core/hle/service/am/library_applet_self_accessor.h +++ b/src/core/hle/service/am/library_applet_self_accessor.h | |||
| @@ -10,14 +10,21 @@ | |||
| 10 | 10 | ||
| 11 | namespace Service::AM { | 11 | namespace Service::AM { |
| 12 | 12 | ||
| 13 | struct AppletStorageHolder; | ||
| 14 | struct Applet; | ||
| 15 | |||
| 13 | class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { | 16 | class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { |
| 14 | public: | 17 | public: |
| 15 | explicit ILibraryAppletSelfAccessor(Core::System& system_); | 18 | explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 16 | ~ILibraryAppletSelfAccessor() override; | 19 | ~ILibraryAppletSelfAccessor() override; |
| 17 | 20 | ||
| 18 | private: | 21 | private: |
| 19 | void PopInData(HLERequestContext& ctx); | 22 | void PopInData(HLERequestContext& ctx); |
| 20 | void PushOutData(HLERequestContext& ctx); | 23 | void PushOutData(HLERequestContext& ctx); |
| 24 | void PopInteractiveInData(HLERequestContext& ctx); | ||
| 25 | void PushInteractiveOutData(HLERequestContext& ctx); | ||
| 26 | void GetPopInDataEvent(HLERequestContext& ctx); | ||
| 27 | void GetPopInteractiveInDataEvent(HLERequestContext& ctx); | ||
| 21 | void GetLibraryAppletInfo(HLERequestContext& ctx); | 28 | void GetLibraryAppletInfo(HLERequestContext& ctx); |
| 22 | void GetMainAppletIdentityInfo(HLERequestContext& ctx); | 29 | void GetMainAppletIdentityInfo(HLERequestContext& ctx); |
| 23 | void ExitProcessAndReturn(HLERequestContext& ctx); | 30 | void ExitProcessAndReturn(HLERequestContext& ctx); |
| @@ -26,13 +33,8 @@ private: | |||
| 26 | void GetMainAppletAvailableUsers(HLERequestContext& ctx); | 33 | void GetMainAppletAvailableUsers(HLERequestContext& ctx); |
| 27 | void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx); | 34 | void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx); |
| 28 | 35 | ||
| 29 | void PushInShowAlbum(); | 36 | const std::shared_ptr<Applet> applet; |
| 30 | void PushInShowCabinetData(); | 37 | const std::shared_ptr<AppletStorageHolder> storage; |
| 31 | void PushInShowMiiEditData(); | ||
| 32 | void PushInShowSoftwareKeyboard(); | ||
| 33 | void PushInShowController(); | ||
| 34 | |||
| 35 | std::deque<std::vector<u8>> queue_data; | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | } // namespace Service::AM | 40 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/process_winding_controller.cpp b/src/core/hle/service/am/process_winding_controller.cpp index 7954abd7a..f5ccc4643 100644 --- a/src/core/hle/service/am/process_winding_controller.cpp +++ b/src/core/hle/service/am/process_winding_controller.cpp | |||
| @@ -8,8 +8,9 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM { | 9 | namespace Service::AM { |
| 10 | 10 | ||
| 11 | IProcessWindingController::IProcessWindingController(Core::System& system_) | 11 | IProcessWindingController::IProcessWindingController(Core::System& system_, |
| 12 | : ServiceFramework{system_, "IProcessWindingController"} { | 12 | std::shared_ptr<Applet> applet_) |
| 13 | : ServiceFramework{system_, "IProcessWindingController"}, applet{std::move(applet_)} { | ||
| 13 | // clang-format off | 14 | // clang-format off |
| 14 | static const FunctionInfo functions[] = { | 15 | static const FunctionInfo functions[] = { |
| 15 | {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"}, | 16 | {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"}, |
| @@ -31,34 +32,15 @@ IProcessWindingController::~IProcessWindingController() = default; | |||
| 31 | void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) { | 32 | void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) { |
| 32 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 33 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 33 | 34 | ||
| 34 | struct AppletProcessLaunchReason { | ||
| 35 | u8 flag; | ||
| 36 | INSERT_PADDING_BYTES(3); | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(AppletProcessLaunchReason) == 0x4, | ||
| 39 | "AppletProcessLaunchReason is an invalid size"); | ||
| 40 | |||
| 41 | AppletProcessLaunchReason reason{ | ||
| 42 | .flag = 0, | ||
| 43 | }; | ||
| 44 | |||
| 45 | IPC::ResponseBuilder rb{ctx, 3}; | 35 | IPC::ResponseBuilder rb{ctx, 3}; |
| 46 | rb.Push(ResultSuccess); | 36 | rb.Push(ResultSuccess); |
| 47 | rb.PushRaw(reason); | 37 | rb.PushRaw(applet->launch_reason); |
| 48 | } | 38 | } |
| 49 | 39 | ||
| 50 | void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) { | 40 | void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) { |
| 51 | const auto applet_id = system.GetFrontendAppletHolder().GetCurrentAppletId(); | 41 | const auto caller_applet = applet->caller_applet.lock(); |
| 52 | const auto applet_mode = LibraryAppletMode::AllForeground; | 42 | if (caller_applet == nullptr) { |
| 53 | 43 | LOG_ERROR(Service_AM, "No calling applet available"); | |
| 54 | LOG_WARNING(Service_AM, "(STUBBED) called with applet_id={:08X}, applet_mode={:08X}", applet_id, | ||
| 55 | applet_mode); | ||
| 56 | |||
| 57 | const auto& holder{system.GetFrontendAppletHolder()}; | ||
| 58 | const auto applet = holder.GetApplet(applet_id, applet_mode); | ||
| 59 | |||
| 60 | if (applet == nullptr) { | ||
| 61 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); | ||
| 62 | 44 | ||
| 63 | IPC::ResponseBuilder rb{ctx, 2}; | 45 | IPC::ResponseBuilder rb{ctx, 2}; |
| 64 | rb.Push(ResultUnknown); | 46 | rb.Push(ResultUnknown); |
| @@ -67,7 +49,8 @@ void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) | |||
| 67 | 49 | ||
| 68 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 69 | rb.Push(ResultSuccess); | 51 | rb.Push(ResultSuccess); |
| 70 | rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet); | 52 | rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_storage, |
| 53 | caller_applet); | ||
| 71 | } | 54 | } |
| 72 | 55 | ||
| 73 | } // namespace Service::AM | 56 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/process_winding_controller.h b/src/core/hle/service/am/process_winding_controller.h index 9b9704201..71ae4c4f5 100644 --- a/src/core/hle/service/am/process_winding_controller.h +++ b/src/core/hle/service/am/process_winding_controller.h | |||
| @@ -7,14 +7,18 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::AM { | 8 | namespace Service::AM { |
| 9 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 10 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { | 12 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { |
| 11 | public: | 13 | public: |
| 12 | explicit IProcessWindingController(Core::System& system_); | 14 | explicit IProcessWindingController(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 13 | ~IProcessWindingController() override; | 15 | ~IProcessWindingController() override; |
| 14 | 16 | ||
| 15 | private: | 17 | private: |
| 16 | void GetLaunchReason(HLERequestContext& ctx); | 18 | void GetLaunchReason(HLERequestContext& ctx); |
| 17 | void OpenCallingLibraryApplet(HLERequestContext& ctx); | 19 | void OpenCallingLibraryApplet(HLERequestContext& ctx); |
| 20 | |||
| 21 | const std::shared_ptr<Applet> applet; | ||
| 18 | }; | 22 | }; |
| 19 | 23 | ||
| 20 | } // namespace Service::AM | 24 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp index d5de1bb2f..3ac967b4d 100644 --- a/src/core/hle/service/am/self_controller.cpp +++ b/src/core/hle/service/am/self_controller.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/am_results.h" | ||
| 4 | #include "core/hle/service/am/frontend/applets.h" | 5 | #include "core/hle/service/am/frontend/applets.h" |
| 5 | #include "core/hle/service/am/self_controller.h" | 6 | #include "core/hle/service/am/self_controller.h" |
| 6 | #include "core/hle/service/caps/caps_su.h" | 7 | #include "core/hle/service/caps/caps_su.h" |
| @@ -12,9 +13,10 @@ | |||
| 12 | 13 | ||
| 13 | namespace Service::AM { | 14 | namespace Service::AM { |
| 14 | 15 | ||
| 15 | ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_) | 16 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_, |
| 16 | : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, | 17 | Nvnflinger::Nvnflinger& nvnflinger_) |
| 17 | service_context{system, "ISelfController"} { | 18 | : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, applet{std::move( |
| 19 | applet_)} { | ||
| 18 | // clang-format off | 20 | // clang-format off |
| 19 | static const FunctionInfo functions[] = { | 21 | static const FunctionInfo functions[] = { |
| 20 | {0, &ISelfController::Exit, "Exit"}, | 22 | {0, &ISelfController::Exit, "Exit"}, |
| @@ -69,24 +71,9 @@ ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& | |||
| 69 | // clang-format on | 71 | // clang-format on |
| 70 | 72 | ||
| 71 | RegisterHandlers(functions); | 73 | RegisterHandlers(functions); |
| 72 | |||
| 73 | launchable_event = service_context.CreateEvent("ISelfController:LaunchableEvent"); | ||
| 74 | |||
| 75 | // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is | ||
| 76 | // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple | ||
| 77 | // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not | ||
| 78 | // suspended if the event has previously been created by a call to | ||
| 79 | // GetAccumulatedSuspendedTickChangedEvent. | ||
| 80 | |||
| 81 | accumulated_suspended_tick_changed_event = | ||
| 82 | service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent"); | ||
| 83 | accumulated_suspended_tick_changed_event->Signal(); | ||
| 84 | } | 74 | } |
| 85 | 75 | ||
| 86 | ISelfController::~ISelfController() { | 76 | ISelfController::~ISelfController() = default; |
| 87 | service_context.CloseEvent(launchable_event); | ||
| 88 | service_context.CloseEvent(accumulated_suspended_tick_changed_event); | ||
| 89 | } | ||
| 90 | 77 | ||
| 91 | void ISelfController::Exit(HLERequestContext& ctx) { | 78 | void ISelfController::Exit(HLERequestContext& ctx) { |
| 92 | LOG_DEBUG(Service_AM, "called"); | 79 | LOG_DEBUG(Service_AM, "called"); |
| @@ -94,6 +81,7 @@ void ISelfController::Exit(HLERequestContext& ctx) { | |||
| 94 | IPC::ResponseBuilder rb{ctx, 2}; | 81 | IPC::ResponseBuilder rb{ctx, 2}; |
| 95 | rb.Push(ResultSuccess); | 82 | rb.Push(ResultSuccess); |
| 96 | 83 | ||
| 84 | // TODO | ||
| 97 | system.Exit(); | 85 | system.Exit(); |
| 98 | } | 86 | } |
| 99 | 87 | ||
| @@ -120,8 +108,10 @@ void ISelfController::UnlockExit(HLERequestContext& ctx) { | |||
| 120 | } | 108 | } |
| 121 | 109 | ||
| 122 | void ISelfController::EnterFatalSection(HLERequestContext& ctx) { | 110 | void ISelfController::EnterFatalSection(HLERequestContext& ctx) { |
| 123 | ++num_fatal_sections_entered; | 111 | |
| 124 | LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", num_fatal_sections_entered); | 112 | std::scoped_lock lk{applet->lock}; |
| 113 | applet->fatal_section_count++; | ||
| 114 | LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", applet->fatal_section_count); | ||
| 125 | 115 | ||
| 126 | IPC::ResponseBuilder rb{ctx, 2}; | 116 | IPC::ResponseBuilder rb{ctx, 2}; |
| 127 | rb.Push(ResultSuccess); | 117 | rb.Push(ResultSuccess); |
| @@ -131,13 +121,14 @@ void ISelfController::LeaveFatalSection(HLERequestContext& ctx) { | |||
| 131 | LOG_DEBUG(Service_AM, "called."); | 121 | LOG_DEBUG(Service_AM, "called."); |
| 132 | 122 | ||
| 133 | // Entry and exit of fatal sections must be balanced. | 123 | // Entry and exit of fatal sections must be balanced. |
| 134 | if (num_fatal_sections_entered == 0) { | 124 | std::scoped_lock lk{applet->lock}; |
| 125 | if (applet->fatal_section_count == 0) { | ||
| 135 | IPC::ResponseBuilder rb{ctx, 2}; | 126 | IPC::ResponseBuilder rb{ctx, 2}; |
| 136 | rb.Push(Result{ErrorModule::AM, 512}); | 127 | rb.Push(AM::ResultFatalSectionCountImbalance); |
| 137 | return; | 128 | return; |
| 138 | } | 129 | } |
| 139 | 130 | ||
| 140 | --num_fatal_sections_entered; | 131 | applet->fatal_section_count--; |
| 141 | 132 | ||
| 142 | IPC::ResponseBuilder rb{ctx, 2}; | 133 | IPC::ResponseBuilder rb{ctx, 2}; |
| 143 | rb.Push(ResultSuccess); | 134 | rb.Push(ResultSuccess); |
| @@ -146,11 +137,11 @@ void ISelfController::LeaveFatalSection(HLERequestContext& ctx) { | |||
| 146 | void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) { | 137 | void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) { |
| 147 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 138 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 148 | 139 | ||
| 149 | launchable_event->Signal(); | 140 | applet->library_applet_launchable_event.Signal(); |
| 150 | 141 | ||
| 151 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 142 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 152 | rb.Push(ResultSuccess); | 143 | rb.Push(ResultSuccess); |
| 153 | rb.PushCopyObjects(launchable_event->GetReadableEvent()); | 144 | rb.PushCopyObjects(applet->library_applet_launchable_event.GetHandle()); |
| 154 | } | 145 | } |
| 155 | 146 | ||
| 156 | void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) { | 147 | void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) { |
| @@ -158,7 +149,8 @@ void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) { | |||
| 158 | const auto permission = rp.PopEnum<ScreenshotPermission>(); | 149 | const auto permission = rp.PopEnum<ScreenshotPermission>(); |
| 159 | LOG_DEBUG(Service_AM, "called, permission={}", permission); | 150 | LOG_DEBUG(Service_AM, "called, permission={}", permission); |
| 160 | 151 | ||
| 161 | screenshot_permission = permission; | 152 | std::scoped_lock lk{applet->lock}; |
| 153 | applet->screenshot_permission = permission; | ||
| 162 | 154 | ||
| 163 | IPC::ResponseBuilder rb{ctx, 2}; | 155 | IPC::ResponseBuilder rb{ctx, 2}; |
| 164 | rb.Push(ResultSuccess); | 156 | rb.Push(ResultSuccess); |
| @@ -167,8 +159,11 @@ void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) { | |||
| 167 | void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) { | 159 | void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) { |
| 168 | IPC::RequestParser rp{ctx}; | 160 | IPC::RequestParser rp{ctx}; |
| 169 | 161 | ||
| 170 | bool flag = rp.Pop<bool>(); | 162 | const bool notification_enabled = rp.Pop<bool>(); |
| 171 | LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); | 163 | LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled); |
| 164 | |||
| 165 | std::scoped_lock lk{applet->lock}; | ||
| 166 | applet->operation_mode_changed_notification_enabled = notification_enabled; | ||
| 172 | 167 | ||
| 173 | IPC::ResponseBuilder rb{ctx, 2}; | 168 | IPC::ResponseBuilder rb{ctx, 2}; |
| 174 | rb.Push(ResultSuccess); | 169 | rb.Push(ResultSuccess); |
| @@ -177,28 +172,27 @@ void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx | |||
| 177 | void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) { | 172 | void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) { |
| 178 | IPC::RequestParser rp{ctx}; | 173 | IPC::RequestParser rp{ctx}; |
| 179 | 174 | ||
| 180 | bool flag = rp.Pop<bool>(); | 175 | const bool notification_enabled = rp.Pop<bool>(); |
| 181 | LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); | 176 | LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled); |
| 177 | |||
| 178 | std::scoped_lock lk{applet->lock}; | ||
| 179 | applet->performance_mode_changed_notification_enabled = notification_enabled; | ||
| 182 | 180 | ||
| 183 | IPC::ResponseBuilder rb{ctx, 2}; | 181 | IPC::ResponseBuilder rb{ctx, 2}; |
| 184 | rb.Push(ResultSuccess); | 182 | rb.Push(ResultSuccess); |
| 185 | } | 183 | } |
| 186 | 184 | ||
| 187 | void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) { | 185 | void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) { |
| 188 | // Takes 3 input u8s with each field located immediately after the previous | ||
| 189 | // u8, these are bool flags. No output. | ||
| 190 | IPC::RequestParser rp{ctx}; | 186 | IPC::RequestParser rp{ctx}; |
| 191 | 187 | ||
| 192 | struct FocusHandlingModeParams { | 188 | const auto flags = rp.PopRaw<FocusHandlingMode>(); |
| 193 | u8 unknown0; | ||
| 194 | u8 unknown1; | ||
| 195 | u8 unknown2; | ||
| 196 | }; | ||
| 197 | const auto flags = rp.PopRaw<FocusHandlingModeParams>(); | ||
| 198 | 189 | ||
| 199 | LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}", | 190 | LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}", |
| 200 | flags.unknown0, flags.unknown1, flags.unknown2); | 191 | flags.unknown0, flags.unknown1, flags.unknown2); |
| 201 | 192 | ||
| 193 | std::scoped_lock lk{applet->lock}; | ||
| 194 | applet->focus_handling_mode = flags; | ||
| 195 | |||
| 202 | IPC::ResponseBuilder rb{ctx, 2}; | 196 | IPC::ResponseBuilder rb{ctx, 2}; |
| 203 | rb.Push(ResultSuccess); | 197 | rb.Push(ResultSuccess); |
| 204 | } | 198 | } |
| @@ -206,24 +200,35 @@ void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) { | |||
| 206 | void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) { | 200 | void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) { |
| 207 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 201 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 208 | 202 | ||
| 203 | std::scoped_lock lk{applet->lock}; | ||
| 204 | applet->restart_message_enabled = true; | ||
| 205 | |||
| 209 | IPC::ResponseBuilder rb{ctx, 2}; | 206 | IPC::ResponseBuilder rb{ctx, 2}; |
| 210 | rb.Push(ResultSuccess); | 207 | rb.Push(ResultSuccess); |
| 211 | } | 208 | } |
| 212 | 209 | ||
| 213 | void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) { | 210 | void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) { |
| 214 | // Takes 3 input u8s with each field located immediately after the previous | ||
| 215 | // u8, these are bool flags. No output. | ||
| 216 | IPC::RequestParser rp{ctx}; | 211 | IPC::RequestParser rp{ctx}; |
| 217 | 212 | ||
| 218 | bool enabled = rp.Pop<bool>(); | 213 | const bool enabled = rp.Pop<bool>(); |
| 219 | LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); | 214 | LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); |
| 220 | 215 | ||
| 216 | std::scoped_lock lk{applet->lock}; | ||
| 217 | ASSERT(applet->type == AppletType::Application); | ||
| 218 | applet->out_of_focus_suspension_enabled = enabled; | ||
| 219 | |||
| 221 | IPC::ResponseBuilder rb{ctx, 2}; | 220 | IPC::ResponseBuilder rb{ctx, 2}; |
| 222 | rb.Push(ResultSuccess); | 221 | rb.Push(ResultSuccess); |
| 223 | } | 222 | } |
| 224 | 223 | ||
| 225 | void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) { | 224 | void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) { |
| 226 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 225 | IPC::RequestParser rp{ctx}; |
| 226 | |||
| 227 | const auto orientation = rp.PopRaw<Capture::AlbumImageOrientation>(); | ||
| 228 | LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", static_cast<s32>(orientation)); | ||
| 229 | |||
| 230 | std::scoped_lock lk{applet->lock}; | ||
| 231 | applet->album_image_orientation = orientation; | ||
| 227 | 232 | ||
| 228 | IPC::ResponseBuilder rb{ctx, 2}; | 233 | IPC::ResponseBuilder rb{ctx, 2}; |
| 229 | rb.Push(ResultSuccess); | 234 | rb.Push(ResultSuccess); |
| @@ -232,14 +237,13 @@ void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) { | |||
| 232 | void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) { | 237 | void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) { |
| 233 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 238 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 234 | 239 | ||
| 235 | // TODO(Subv): Find out how AM determines the display to use, for now just | 240 | u64 layer_id{}; |
| 236 | // create the layer in the Default display. | 241 | applet->managed_layer_holder.Initialize(&nvnflinger); |
| 237 | const auto display_id = nvnflinger.OpenDisplay("Default"); | 242 | applet->managed_layer_holder.CreateManagedDisplayLayer(&layer_id); |
| 238 | const auto layer_id = nvnflinger.CreateLayer(*display_id); | ||
| 239 | 243 | ||
| 240 | IPC::ResponseBuilder rb{ctx, 4}; | 244 | IPC::ResponseBuilder rb{ctx, 4}; |
| 241 | rb.Push(ResultSuccess); | 245 | rb.Push(ResultSuccess); |
| 242 | rb.Push(*layer_id); | 246 | rb.Push(layer_id); |
| 243 | } | 247 | } |
| 244 | 248 | ||
| 245 | void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) { | 249 | void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) { |
| @@ -252,56 +256,46 @@ void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) { | |||
| 252 | void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) { | 256 | void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) { |
| 253 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 257 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 254 | 258 | ||
| 259 | u64 buffer_id, layer_id; | ||
| 260 | applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id); | ||
| 261 | |||
| 255 | IPC::ResponseBuilder rb{ctx, 6}; | 262 | IPC::ResponseBuilder rb{ctx, 6}; |
| 256 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); | 263 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); |
| 257 | rb.Push<s64>(system_shared_buffer_id); | 264 | rb.Push<s64>(buffer_id); |
| 258 | rb.Push<s64>(system_shared_layer_id); | 265 | rb.Push<s64>(layer_id); |
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) { | 268 | void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) { |
| 262 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 269 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 263 | 270 | ||
| 271 | u64 buffer_id, layer_id; | ||
| 272 | applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id); | ||
| 273 | |||
| 264 | IPC::ResponseBuilder rb{ctx, 4}; | 274 | IPC::ResponseBuilder rb{ctx, 4}; |
| 265 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); | 275 | rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess())); |
| 266 | rb.Push<s64>(system_shared_buffer_id); | 276 | rb.Push<s64>(buffer_id); |
| 267 | } | 277 | } |
| 268 | 278 | ||
| 269 | Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) { | 279 | Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) { |
| 270 | if (buffer_sharing_enabled) { | 280 | if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id)) { |
| 271 | return ResultSuccess; | 281 | return ResultSuccess; |
| 272 | } | 282 | } |
| 273 | 283 | ||
| 274 | if (system.GetFrontendAppletHolder().GetCurrentAppletId() <= AppletId::Application) { | 284 | return VI::ResultOperationFailed; |
| 275 | return VI::ResultOperationFailed; | ||
| 276 | } | ||
| 277 | |||
| 278 | const auto display_id = nvnflinger.OpenDisplay("Default"); | ||
| 279 | const auto result = nvnflinger.GetSystemBufferManager().Initialize( | ||
| 280 | &system_shared_buffer_id, &system_shared_layer_id, *display_id); | ||
| 281 | |||
| 282 | if (result.IsSuccess()) { | ||
| 283 | buffer_sharing_enabled = true; | ||
| 284 | } | ||
| 285 | |||
| 286 | return result; | ||
| 287 | } | 285 | } |
| 288 | 286 | ||
| 289 | void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) { | 287 | void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) { |
| 290 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 288 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 291 | 289 | ||
| 292 | // TODO(Subv): Find out how AM determines the display to use, for now just | 290 | u64 layer_id{}; |
| 293 | // create the layer in the Default display. | 291 | u64 recording_layer_id{}; |
| 294 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | 292 | applet->managed_layer_holder.Initialize(&nvnflinger); |
| 295 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | 293 | applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(&layer_id, &recording_layer_id); |
| 296 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 297 | // side effects. | ||
| 298 | // TODO: Support multiple layers | ||
| 299 | const auto display_id = nvnflinger.OpenDisplay("Default"); | ||
| 300 | const auto layer_id = nvnflinger.CreateLayer(*display_id); | ||
| 301 | 294 | ||
| 302 | IPC::ResponseBuilder rb{ctx, 4}; | 295 | IPC::ResponseBuilder rb{ctx, 6}; |
| 303 | rb.Push(ResultSuccess); | 296 | rb.Push(ResultSuccess); |
| 304 | rb.Push(*layer_id); | 297 | rb.Push(layer_id); |
| 298 | rb.Push(recording_layer_id); | ||
| 305 | } | 299 | } |
| 306 | 300 | ||
| 307 | void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) { | 301 | void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) { |
| @@ -320,9 +314,12 @@ void ISelfController::ApproveToDisplay(HLERequestContext& ctx) { | |||
| 320 | 314 | ||
| 321 | void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { | 315 | void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { |
| 322 | IPC::RequestParser rp{ctx}; | 316 | IPC::RequestParser rp{ctx}; |
| 323 | idle_time_detection_extension = rp.Pop<u32>(); | 317 | |
| 324 | LOG_DEBUG(Service_AM, "(STUBBED) called idle_time_detection_extension={}", | 318 | const auto extension = rp.PopRaw<IdleTimeDetectionExtension>(); |
| 325 | idle_time_detection_extension); | 319 | LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", extension); |
| 320 | |||
| 321 | std::scoped_lock lk{applet->lock}; | ||
| 322 | applet->idle_time_detection_extension = extension; | ||
| 326 | 323 | ||
| 327 | IPC::ResponseBuilder rb{ctx, 2}; | 324 | IPC::ResponseBuilder rb{ctx, 2}; |
| 328 | rb.Push(ResultSuccess); | 325 | rb.Push(ResultSuccess); |
| @@ -331,9 +328,11 @@ void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { | |||
| 331 | void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) { | 328 | void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) { |
| 332 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 329 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 333 | 330 | ||
| 331 | std::scoped_lock lk{applet->lock}; | ||
| 332 | |||
| 334 | IPC::ResponseBuilder rb{ctx, 3}; | 333 | IPC::ResponseBuilder rb{ctx, 3}; |
| 335 | rb.Push(ResultSuccess); | 334 | rb.Push(ResultSuccess); |
| 336 | rb.Push<u32>(idle_time_detection_extension); | 335 | rb.PushRaw<IdleTimeDetectionExtension>(applet->idle_time_detection_extension); |
| 337 | } | 336 | } |
| 338 | 337 | ||
| 339 | void ISelfController::ReportUserIsActive(HLERequestContext& ctx) { | 338 | void ISelfController::ReportUserIsActive(HLERequestContext& ctx) { |
| @@ -345,7 +344,9 @@ void ISelfController::ReportUserIsActive(HLERequestContext& ctx) { | |||
| 345 | 344 | ||
| 346 | void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) { | 345 | void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) { |
| 347 | IPC::RequestParser rp{ctx}; | 346 | IPC::RequestParser rp{ctx}; |
| 348 | is_auto_sleep_disabled = rp.Pop<bool>(); | 347 | |
| 348 | std::scoped_lock lk{applet->lock}; | ||
| 349 | applet->auto_sleep_disabled = rp.Pop<bool>(); | ||
| 349 | 350 | ||
| 350 | // On the system itself, if the previous state of is_auto_sleep_disabled | 351 | // On the system itself, if the previous state of is_auto_sleep_disabled |
| 351 | // differed from the current value passed in, it'd signify the internal | 352 | // differed from the current value passed in, it'd signify the internal |
| @@ -357,7 +358,7 @@ void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) { | |||
| 357 | // and it's sufficient to simply set the member variable for querying via | 358 | // and it's sufficient to simply set the member variable for querying via |
| 358 | // IsAutoSleepDisabled(). | 359 | // IsAutoSleepDisabled(). |
| 359 | 360 | ||
| 360 | LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled); | 361 | LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", applet->auto_sleep_disabled); |
| 361 | 362 | ||
| 362 | IPC::ResponseBuilder rb{ctx, 2}; | 363 | IPC::ResponseBuilder rb{ctx, 2}; |
| 363 | rb.Push(ResultSuccess); | 364 | rb.Push(ResultSuccess); |
| @@ -366,20 +367,23 @@ void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) { | |||
| 366 | void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) { | 367 | void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) { |
| 367 | LOG_DEBUG(Service_AM, "called."); | 368 | LOG_DEBUG(Service_AM, "called."); |
| 368 | 369 | ||
| 370 | std::scoped_lock lk{applet->lock}; | ||
| 371 | |||
| 369 | IPC::ResponseBuilder rb{ctx, 3}; | 372 | IPC::ResponseBuilder rb{ctx, 3}; |
| 370 | rb.Push(ResultSuccess); | 373 | rb.Push(ResultSuccess); |
| 371 | rb.Push(is_auto_sleep_disabled); | 374 | rb.Push(applet->auto_sleep_disabled); |
| 372 | } | 375 | } |
| 373 | 376 | ||
| 374 | void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) { | 377 | void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) { |
| 375 | LOG_DEBUG(Service_AM, "called."); | 378 | LOG_DEBUG(Service_AM, "called."); |
| 376 | 379 | ||
| 380 | std::scoped_lock lk{applet->lock}; | ||
| 377 | // This command returns the total number of system ticks since ISelfController creation | 381 | // This command returns the total number of system ticks since ISelfController creation |
| 378 | // where the game was suspended. Since Yuzu doesn't implement game suspension, this command | 382 | // where the game was suspended. Since Yuzu doesn't implement game suspension, this command |
| 379 | // can just always return 0 ticks. | 383 | // can just always return 0 ticks. |
| 380 | IPC::ResponseBuilder rb{ctx, 4}; | 384 | IPC::ResponseBuilder rb{ctx, 4}; |
| 381 | rb.Push(ResultSuccess); | 385 | rb.Push(ResultSuccess); |
| 382 | rb.Push<u64>(0); | 386 | rb.Push<u64>(applet->suspended_ticks); |
| 383 | } | 387 | } |
| 384 | 388 | ||
| 385 | void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) { | 389 | void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) { |
| @@ -387,7 +391,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& | |||
| 387 | 391 | ||
| 388 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 392 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 389 | rb.Push(ResultSuccess); | 393 | rb.Push(ResultSuccess); |
| 390 | rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent()); | 394 | rb.PushCopyObjects(applet->accumulated_suspended_tick_changed_event.GetHandle()); |
| 391 | } | 395 | } |
| 392 | 396 | ||
| 393 | void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) { | 397 | void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) { |
| @@ -396,10 +400,11 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& c | |||
| 396 | // This service call sets an internal flag whether a notification is shown when an image is | 400 | // This service call sets an internal flag whether a notification is shown when an image is |
| 397 | // captured. Currently we do not support capturing images via the capture button, so this can be | 401 | // captured. Currently we do not support capturing images via the capture button, so this can be |
| 398 | // stubbed for now. | 402 | // stubbed for now. |
| 399 | const bool album_image_taken_notification_enabled = rp.Pop<bool>(); | 403 | const bool enabled = rp.Pop<bool>(); |
| 404 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
| 400 | 405 | ||
| 401 | LOG_WARNING(Service_AM, "(STUBBED) called. album_image_taken_notification_enabled={}", | 406 | std::scoped_lock lk{applet->lock}; |
| 402 | album_image_taken_notification_enabled); | 407 | applet->album_image_taken_notification_enabled = enabled; |
| 403 | 408 | ||
| 404 | IPC::ResponseBuilder rb{ctx, 2}; | 409 | IPC::ResponseBuilder rb{ctx, 2}; |
| 405 | rb.Push(ResultSuccess); | 410 | rb.Push(ResultSuccess); |
| @@ -427,9 +432,11 @@ void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) { | |||
| 427 | void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) { | 432 | void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) { |
| 428 | IPC::RequestParser rp{ctx}; | 433 | IPC::RequestParser rp{ctx}; |
| 429 | 434 | ||
| 430 | const auto is_record_volume_muted = rp.Pop<bool>(); | 435 | const auto enabled = rp.Pop<bool>(); |
| 436 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
| 431 | 437 | ||
| 432 | LOG_WARNING(Service_AM, "(STUBBED) called. is_record_volume_muted={}", is_record_volume_muted); | 438 | std::scoped_lock lk{applet->lock}; |
| 439 | applet->record_volume_muted = enabled; | ||
| 433 | 440 | ||
| 434 | IPC::ResponseBuilder rb{ctx, 2}; | 441 | IPC::ResponseBuilder rb{ctx, 2}; |
| 435 | rb.Push(ResultSuccess); | 442 | rb.Push(ResultSuccess); |
diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h index f157bb826..6e6975264 100644 --- a/src/core/hle/service/am/self_controller.h +++ b/src/core/hle/service/am/self_controller.h | |||
| @@ -8,9 +8,12 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM { | 9 | namespace Service::AM { |
| 10 | 10 | ||
| 11 | struct Applet; | ||
| 12 | |||
| 11 | class ISelfController final : public ServiceFramework<ISelfController> { | 13 | class ISelfController final : public ServiceFramework<ISelfController> { |
| 12 | public: | 14 | public: |
| 13 | explicit ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_); | 15 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_, |
| 16 | Nvnflinger::Nvnflinger& nvnflinger_); | ||
| 14 | ~ISelfController() override; | 17 | ~ISelfController() override; |
| 15 | 18 | ||
| 16 | private: | 19 | private: |
| @@ -47,26 +50,8 @@ private: | |||
| 47 | 50 | ||
| 48 | Result EnsureBufferSharingEnabled(Kernel::KProcess* process); | 51 | Result EnsureBufferSharingEnabled(Kernel::KProcess* process); |
| 49 | 52 | ||
| 50 | enum class ScreenshotPermission : u32 { | ||
| 51 | Inherit = 0, | ||
| 52 | Enable = 1, | ||
| 53 | Disable = 2, | ||
| 54 | }; | ||
| 55 | |||
| 56 | Nvnflinger::Nvnflinger& nvnflinger; | 53 | Nvnflinger::Nvnflinger& nvnflinger; |
| 57 | 54 | const std::shared_ptr<Applet> applet; | |
| 58 | KernelHelpers::ServiceContext service_context; | ||
| 59 | |||
| 60 | Kernel::KEvent* launchable_event; | ||
| 61 | Kernel::KEvent* accumulated_suspended_tick_changed_event; | ||
| 62 | |||
| 63 | u32 idle_time_detection_extension = 0; | ||
| 64 | u64 num_fatal_sections_entered = 0; | ||
| 65 | u64 system_shared_buffer_id = 0; | ||
| 66 | u64 system_shared_layer_id = 0; | ||
| 67 | bool is_auto_sleep_disabled = false; | ||
| 68 | bool buffer_sharing_enabled = false; | ||
| 69 | ScreenshotPermission screenshot_permission = ScreenshotPermission::Inherit; | ||
| 70 | }; | 55 | }; |
| 71 | 56 | ||
| 72 | } // namespace Service::AM | 57 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/system_applet_proxy.cpp b/src/core/hle/service/am/system_applet_proxy.cpp index d51a2c8db..e3013271b 100644 --- a/src/core/hle/service/am/system_applet_proxy.cpp +++ b/src/core/hle/service/am/system_applet_proxy.cpp | |||
| @@ -20,10 +20,9 @@ | |||
| 20 | namespace Service::AM { | 20 | namespace Service::AM { |
| 21 | 21 | ||
| 22 | ISystemAppletProxy::ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 22 | ISystemAppletProxy::ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 23 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 23 | std::shared_ptr<Applet> applet_, Core::System& system_) |
| 24 | Core::System& system_) | 24 | : ServiceFramework{system_, "ISystemAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move( |
| 25 | : ServiceFramework{system_, "ISystemAppletProxy"}, nvnflinger{nvnflinger_}, | 25 | applet_)} { |
| 26 | msg_queue{std::move(msg_queue_)} { | ||
| 27 | // clang-format off | 26 | // clang-format off |
| 28 | static const FunctionInfo functions[] = { | 27 | static const FunctionInfo functions[] = { |
| 29 | {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 28 | {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| @@ -44,12 +43,14 @@ ISystemAppletProxy::ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | |||
| 44 | RegisterHandlers(functions); | 43 | RegisterHandlers(functions); |
| 45 | } | 44 | } |
| 46 | 45 | ||
| 46 | ISystemAppletProxy::~ISystemAppletProxy() = default; | ||
| 47 | |||
| 47 | void ISystemAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { | 48 | void ISystemAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) { |
| 48 | LOG_DEBUG(Service_AM, "called"); | 49 | LOG_DEBUG(Service_AM, "called"); |
| 49 | 50 | ||
| 50 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 51 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 51 | rb.Push(ResultSuccess); | 52 | rb.Push(ResultSuccess); |
| 52 | rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue); | 53 | rb.PushIpcInterface<ICommonStateGetter>(system, applet); |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | void ISystemAppletProxy::GetSelfController(HLERequestContext& ctx) { | 56 | void ISystemAppletProxy::GetSelfController(HLERequestContext& ctx) { |
| @@ -57,7 +58,7 @@ void ISystemAppletProxy::GetSelfController(HLERequestContext& ctx) { | |||
| 57 | 58 | ||
| 58 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 59 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 59 | rb.Push(ResultSuccess); | 60 | rb.Push(ResultSuccess); |
| 60 | rb.PushIpcInterface<ISelfController>(system, nvnflinger); | 61 | rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger); |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | void ISystemAppletProxy::GetWindowController(HLERequestContext& ctx) { | 64 | void ISystemAppletProxy::GetWindowController(HLERequestContext& ctx) { |
| @@ -65,7 +66,7 @@ void ISystemAppletProxy::GetWindowController(HLERequestContext& ctx) { | |||
| 65 | 66 | ||
| 66 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 67 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 67 | rb.Push(ResultSuccess); | 68 | rb.Push(ResultSuccess); |
| 68 | rb.PushIpcInterface<IWindowController>(system); | 69 | rb.PushIpcInterface<IWindowController>(system, applet); |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | void ISystemAppletProxy::GetAudioController(HLERequestContext& ctx) { | 72 | void ISystemAppletProxy::GetAudioController(HLERequestContext& ctx) { |
| @@ -89,7 +90,7 @@ void ISystemAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) { | |||
| 89 | 90 | ||
| 90 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 91 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 91 | rb.Push(ResultSuccess); | 92 | rb.Push(ResultSuccess); |
| 92 | rb.PushIpcInterface<ILibraryAppletCreator>(system); | 93 | rb.PushIpcInterface<ILibraryAppletCreator>(system, applet); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | void ISystemAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { | 96 | void ISystemAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) { |
| @@ -121,7 +122,7 @@ void ISystemAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) { | |||
| 121 | 122 | ||
| 122 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 123 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 123 | rb.Push(ResultSuccess); | 124 | rb.Push(ResultSuccess); |
| 124 | rb.PushIpcInterface<IAppletCommonFunctions>(system); | 125 | rb.PushIpcInterface<IAppletCommonFunctions>(system, applet); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | void ISystemAppletProxy::GetDebugFunctions(HLERequestContext& ctx) { | 128 | void ISystemAppletProxy::GetDebugFunctions(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/system_applet_proxy.h b/src/core/hle/service/am/system_applet_proxy.h index b8855b1d6..0390cd1e5 100644 --- a/src/core/hle/service/am/system_applet_proxy.h +++ b/src/core/hle/service/am/system_applet_proxy.h | |||
| @@ -8,11 +8,13 @@ | |||
| 8 | 8 | ||
| 9 | namespace Service::AM { | 9 | namespace Service::AM { |
| 10 | 10 | ||
| 11 | struct Applet; | ||
| 12 | |||
| 11 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | 13 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { |
| 12 | public: | 14 | public: |
| 13 | explicit ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, | 15 | explicit ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_, |
| 14 | std::shared_ptr<AppletMessageQueue> msg_queue_, | 16 | std::shared_ptr<Applet> applet_, Core::System& system_); |
| 15 | Core::System& system_); | 17 | ~ISystemAppletProxy(); |
| 16 | 18 | ||
| 17 | private: | 19 | private: |
| 18 | void GetCommonStateGetter(HLERequestContext& ctx); | 20 | void GetCommonStateGetter(HLERequestContext& ctx); |
| @@ -28,7 +30,7 @@ private: | |||
| 28 | void GetDebugFunctions(HLERequestContext& ctx); | 30 | void GetDebugFunctions(HLERequestContext& ctx); |
| 29 | 31 | ||
| 30 | Nvnflinger::Nvnflinger& nvnflinger; | 32 | Nvnflinger::Nvnflinger& nvnflinger; |
| 31 | std::shared_ptr<AppletMessageQueue> msg_queue; | 33 | std::shared_ptr<Applet> applet; |
| 32 | }; | 34 | }; |
| 33 | 35 | ||
| 34 | } // namespace Service::AM | 36 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/window_controller.cpp b/src/core/hle/service/am/window_controller.cpp index f2ba3c134..430ca180b 100644 --- a/src/core/hle/service/am/window_controller.cpp +++ b/src/core/hle/service/am/window_controller.cpp | |||
| @@ -1,13 +1,14 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/am/applet.h" | ||
| 4 | #include "core/hle/service/am/window_controller.h" | 5 | #include "core/hle/service/am/window_controller.h" |
| 5 | #include "core/hle/service/ipc_helpers.h" | 6 | #include "core/hle/service/ipc_helpers.h" |
| 6 | 7 | ||
| 7 | namespace Service::AM { | 8 | namespace Service::AM { |
| 8 | 9 | ||
| 9 | IWindowController::IWindowController(Core::System& system_) | 10 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_) |
| 10 | : ServiceFramework{system_, "IWindowController"} { | 11 | : ServiceFramework{system_, "IWindowController"}, applet{std::move(applet_)} { |
| 11 | // clang-format off | 12 | // clang-format off |
| 12 | static const FunctionInfo functions[] = { | 13 | static const FunctionInfo functions[] = { |
| 13 | {0, nullptr, "CreateWindow"}, | 14 | {0, nullptr, "CreateWindow"}, |
| @@ -27,23 +28,22 @@ IWindowController::IWindowController(Core::System& system_) | |||
| 27 | IWindowController::~IWindowController() = default; | 28 | IWindowController::~IWindowController() = default; |
| 28 | 29 | ||
| 29 | void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) { | 30 | void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) { |
| 30 | const u64 process_id = system.ApplicationProcess()->GetProcessId(); | ||
| 31 | |||
| 32 | LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id); | ||
| 33 | |||
| 34 | IPC::ResponseBuilder rb{ctx, 4}; | 31 | IPC::ResponseBuilder rb{ctx, 4}; |
| 35 | rb.Push(ResultSuccess); | 32 | rb.Push(ResultSuccess); |
| 36 | rb.Push<u64>(process_id); | 33 | rb.Push<u64>(applet->aruid); |
| 37 | } | 34 | } |
| 38 | 35 | ||
| 39 | void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) { | 36 | void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) { |
| 40 | const u64 process_id = 0; | 37 | u64 aruid = 0; |
| 38 | if (auto caller = applet->caller_applet.lock(); caller) { | ||
| 39 | aruid = caller->aruid; | ||
| 40 | } | ||
| 41 | 41 | ||
| 42 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 42 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 43 | 43 | ||
| 44 | IPC::ResponseBuilder rb{ctx, 4}; | 44 | IPC::ResponseBuilder rb{ctx, 4}; |
| 45 | rb.Push(ResultSuccess); | 45 | rb.Push(ResultSuccess); |
| 46 | rb.Push<u64>(process_id); | 46 | rb.Push<u64>(aruid); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { | 49 | void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/am/window_controller.h b/src/core/hle/service/am/window_controller.h index 07b0e0e17..d97f93737 100644 --- a/src/core/hle/service/am/window_controller.h +++ b/src/core/hle/service/am/window_controller.h | |||
| @@ -7,15 +7,19 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::AM { | 8 | namespace Service::AM { |
| 9 | 9 | ||
| 10 | struct Applet; | ||
| 11 | |||
| 10 | class IWindowController final : public ServiceFramework<IWindowController> { | 12 | class IWindowController final : public ServiceFramework<IWindowController> { |
| 11 | public: | 13 | public: |
| 12 | explicit IWindowController(Core::System& system_); | 14 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_); |
| 13 | ~IWindowController() override; | 15 | ~IWindowController() override; |
| 14 | 16 | ||
| 15 | private: | 17 | private: |
| 16 | void GetAppletResourceUserId(HLERequestContext& ctx); | 18 | void GetAppletResourceUserId(HLERequestContext& ctx); |
| 17 | void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx); | 19 | void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx); |
| 18 | void AcquireForegroundRights(HLERequestContext& ctx); | 20 | void AcquireForegroundRights(HLERequestContext& ctx); |
| 21 | |||
| 22 | const std::shared_ptr<Applet> applet; | ||
| 19 | }; | 23 | }; |
| 20 | 24 | ||
| 21 | } // namespace Service::AM | 25 | } // namespace Service::AM |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 1f3d82c57..73058db9a 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -535,6 +535,12 @@ public: | |||
| 535 | RegisterHandlers(functions); | 535 | RegisterHandlers(functions); |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | ~IApplicationDisplayService() { | ||
| 539 | for (const auto layer_id : stray_layer_ids) { | ||
| 540 | nvnflinger.DestroyLayer(layer_id); | ||
| 541 | } | ||
| 542 | } | ||
| 543 | |||
| 538 | private: | 544 | private: |
| 539 | enum class ConvertedScaleMode : u64 { | 545 | enum class ConvertedScaleMode : u64 { |
| 540 | Freeze = 0, | 546 | Freeze = 0, |
| @@ -770,6 +776,7 @@ private: | |||
| 770 | return; | 776 | return; |
| 771 | } | 777 | } |
| 772 | 778 | ||
| 779 | stray_layer_ids.push_back(*layer_id); | ||
| 773 | const auto buffer_queue_id = nvnflinger.FindBufferQueueId(display_id, *layer_id); | 780 | const auto buffer_queue_id = nvnflinger.FindBufferQueueId(display_id, *layer_id); |
| 774 | if (!buffer_queue_id) { | 781 | if (!buffer_queue_id) { |
| 775 | LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id); | 782 | LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id); |
| @@ -916,6 +923,7 @@ private: | |||
| 916 | 923 | ||
| 917 | Nvnflinger::Nvnflinger& nvnflinger; | 924 | Nvnflinger::Nvnflinger& nvnflinger; |
| 918 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server; | 925 | Nvnflinger::HosBinderDriverServer& hos_binder_driver_server; |
| 926 | std::vector<u64> stray_layer_ids; | ||
| 919 | bool vsync_event_fetched{false}; | 927 | bool vsync_event_fetched{false}; |
| 920 | }; | 928 | }; |
| 921 | 929 | ||
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 718534ba1..e28df10bd 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applet_ae.h" | 11 | #include "core/hle/service/am/applet_ae.h" |
| 12 | #include "core/hle/service/am/applet_manager.h" | ||
| 12 | #include "core/hle/service/am/applet_message_queue.h" | 13 | #include "core/hle/service/am/applet_message_queue.h" |
| 13 | #include "core/hle/service/am/applet_oe.h" | 14 | #include "core/hle/service/am/applet_oe.h" |
| 14 | #include "core/hle/service/sm/sm.h" | 15 | #include "core/hle/service/sm/sm.h" |
| @@ -48,22 +49,8 @@ void OnDockedModeChanged(bool last_state, bool new_state, Core::System& system) | |||
| 48 | if (!system.IsPoweredOn()) { | 49 | if (!system.IsPoweredOn()) { |
| 49 | return; | 50 | return; |
| 50 | } | 51 | } |
| 51 | Service::SM::ServiceManager& sm = system.ServiceManager(); | ||
| 52 | 52 | ||
| 53 | // Message queue is shared between these services, we just need to signal an operation | 53 | system.GetAppletManager().OperationModeChanged(); |
| 54 | // change to one and it will handle both automatically | ||
| 55 | auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE"); | ||
| 56 | auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE"); | ||
| 57 | bool has_signalled = false; | ||
| 58 | |||
| 59 | if (applet_oe != nullptr) { | ||
| 60 | applet_oe->GetMessageQueue()->OperationModeChanged(); | ||
| 61 | has_signalled = true; | ||
| 62 | } | ||
| 63 | |||
| 64 | if (applet_ae != nullptr && !has_signalled) { | ||
| 65 | applet_ae->GetMessageQueue()->OperationModeChanged(); | ||
| 66 | } | ||
| 67 | } | 54 | } |
| 68 | 55 | ||
| 69 | ConfigureInput::ConfigureInput(Core::System& system_, QWidget* parent) | 56 | ConfigureInput::ConfigureInput(Core::System& system_, QWidget* parent) |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 02508b20d..4e5c4da53 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -4783,36 +4783,12 @@ void GMainWindow::RequestGameExit() { | |||
| 4783 | return; | 4783 | return; |
| 4784 | } | 4784 | } |
| 4785 | 4785 | ||
| 4786 | auto& sm{system->ServiceManager()}; | ||
| 4787 | auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE"); | ||
| 4788 | auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE"); | ||
| 4789 | bool has_signalled = false; | ||
| 4790 | |||
| 4791 | system->SetExitRequested(true); | 4786 | system->SetExitRequested(true); |
| 4792 | 4787 | system->GetAppletManager().RequestExit(); | |
| 4793 | if (applet_oe != nullptr) { | ||
| 4794 | applet_oe->GetMessageQueue()->RequestExit(); | ||
| 4795 | has_signalled = true; | ||
| 4796 | } | ||
| 4797 | |||
| 4798 | if (applet_ae != nullptr && !has_signalled) { | ||
| 4799 | applet_ae->GetMessageQueue()->RequestExit(); | ||
| 4800 | } | ||
| 4801 | } | 4788 | } |
| 4802 | 4789 | ||
| 4803 | void GMainWindow::RequestGameResume() { | 4790 | void GMainWindow::RequestGameResume() { |
| 4804 | auto& sm{system->ServiceManager()}; | 4791 | system->GetAppletManager().RequestResume(); |
| 4805 | auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE"); | ||
| 4806 | auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE"); | ||
| 4807 | |||
| 4808 | if (applet_oe != nullptr) { | ||
| 4809 | applet_oe->GetMessageQueue()->RequestResume(); | ||
| 4810 | return; | ||
| 4811 | } | ||
| 4812 | |||
| 4813 | if (applet_ae != nullptr) { | ||
| 4814 | applet_ae->GetMessageQueue()->RequestResume(); | ||
| 4815 | } | ||
| 4816 | } | 4792 | } |
| 4817 | 4793 | ||
| 4818 | void GMainWindow::filterBarSetChecked(bool state) { | 4794 | void GMainWindow::filterBarSetChecked(bool state) { |