summaryrefslogtreecommitdiff
path: root/src/core/hle/service/am
diff options
context:
space:
mode:
authorGravatar Liam2024-02-11 20:12:09 -0500
committerGravatar Liam2024-02-12 09:16:02 -0500
commitc7e94e2175c02fe22846d89915b08d8b1802ef4f (patch)
tree674cbe3c536331516fa8995214104d6d9a01b7ec /src/core/hle/service/am
parentam: rewrite ILibraryAppletCreator (diff)
downloadyuzu-c7e94e2175c02fe22846d89915b08d8b1802ef4f.tar.gz
yuzu-c7e94e2175c02fe22846d89915b08d8b1802ef4f.tar.xz
yuzu-c7e94e2175c02fe22846d89915b08d8b1802ef4f.zip
am: rewrite ILibraryAppletSelfAccessor
Diffstat (limited to 'src/core/hle/service/am')
-rw-r--r--src/core/hle/service/am/library_applet_self_accessor.cpp338
-rw-r--r--src/core/hle/service/am/library_applet_self_accessor.h44
-rw-r--r--src/core/hle/service/am/service/application_proxy.cpp1
-rw-r--r--src/core/hle/service/am/service/library_applet_proxy.cpp2
-rw-r--r--src/core/hle/service/am/service/library_applet_self_accessor.cpp322
-rw-r--r--src/core/hle/service/am/service/library_applet_self_accessor.h83
-rw-r--r--src/core/hle/service/am/service/system_applet_proxy.cpp1
7 files changed, 406 insertions, 385 deletions
diff --git a/src/core/hle/service/am/library_applet_self_accessor.cpp b/src/core/hle/service/am/library_applet_self_accessor.cpp
deleted file mode 100644
index b560f580b..000000000
--- a/src/core/hle/service/am/library_applet_self_accessor.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/scope_exit.h"
5#include "core/core_timing.h"
6#include "core/file_sys/control_metadata.h"
7#include "core/file_sys/patch_manager.h"
8#include "core/file_sys/registered_cache.h"
9#include "core/hle/service/acc/profile_manager.h"
10#include "core/hle/service/am/am_results.h"
11#include "core/hle/service/am/applet_data_broker.h"
12#include "core/hle/service/am/applet_manager.h"
13#include "core/hle/service/am/frontend/applet_cabinet.h"
14#include "core/hle/service/am/frontend/applet_controller.h"
15#include "core/hle/service/am/frontend/applet_mii_edit_types.h"
16#include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
17#include "core/hle/service/am/frontend/applets.h"
18#include "core/hle/service/am/library_applet_self_accessor.h"
19#include "core/hle/service/am/storage.h"
20#include "core/hle/service/ipc_helpers.h"
21#include "core/hle/service/ns/ns.h"
22#include "core/hle/service/sm/sm.h"
23#include "hid_core/hid_types.h"
24
25namespace Service::AM {
26
27namespace {
28
29AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) {
30 if (const auto caller_applet = applet->caller_applet.lock(); caller_applet) {
31 // TODO: is this actually the application ID?
32 return {
33 .applet_id = caller_applet->applet_id,
34 .application_id = caller_applet->program_id,
35 };
36 } else {
37 return {
38 .applet_id = AppletId::QLaunch,
39 .application_id = 0x0100000000001000ull,
40 };
41 }
42}
43
44} // namespace
45
46ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
47 std::shared_ptr<Applet> applet_)
48 : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)},
49 broker{applet->caller_applet_broker} {
50 // clang-format off
51 static const FunctionInfo functions[] = {
52 {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
53 {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"},
54 {2, &ILibraryAppletSelfAccessor::PopInteractiveInData, "PopInteractiveInData"},
55 {3, &ILibraryAppletSelfAccessor::PushInteractiveOutData, "PushInteractiveOutData"},
56 {5, &ILibraryAppletSelfAccessor::GetPopInDataEvent, "GetPopInDataEvent"},
57 {6, &ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent, "GetPopInteractiveInDataEvent"},
58 {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
59 {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
60 {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
61 {13, &ILibraryAppletSelfAccessor::CanUseApplicationCore, "CanUseApplicationCore"},
62 {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
63 {15, nullptr, "GetMainAppletApplicationControlProperty"},
64 {16, nullptr, "GetMainAppletStorageId"},
65 {17, nullptr, "GetCallerAppletIdentityInfoStack"},
66 {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
67 {19, &ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout, "GetDesirableKeyboardLayout"},
68 {20, nullptr, "PopExtraStorage"},
69 {25, nullptr, "GetPopExtraStorageEvent"},
70 {30, nullptr, "UnpopInData"},
71 {31, nullptr, "UnpopExtraStorage"},
72 {40, nullptr, "GetIndirectLayerProducerHandle"},
73 {50, nullptr, "ReportVisibleError"},
74 {51, nullptr, "ReportVisibleErrorWithErrorContext"},
75 {60, &ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage, "GetMainAppletApplicationDesiredLanguage"},
76 {70, &ILibraryAppletSelfAccessor::GetCurrentApplicationId, "GetCurrentApplicationId"},
77 {80, nullptr, "RequestExitToSelf"},
78 {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
79 {100, nullptr, "CreateGameMovieTrimmer"},
80 {101, nullptr, "ReserveResourceForMovieOperation"},
81 {102, nullptr, "UnreserveResourceForMovieOperation"},
82 {110, &ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers, "GetMainAppletAvailableUsers"},
83 {120, nullptr, "GetLaunchStorageInfoForDebug"},
84 {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
85 {140, nullptr, "SetApplicationMemoryReservation"},
86 {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"},
87 {160, &ILibraryAppletSelfAccessor::Cmd160, "Cmd160"},
88 };
89 // clang-format on
90 RegisterHandlers(functions);
91}
92
93ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
94
95void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) {
96 LOG_INFO(Service_AM, "called");
97
98 std::shared_ptr<IStorage> data;
99 const auto res = broker->GetInData().Pop(&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 {
106 IPC::ResponseBuilder rb{ctx, 2};
107 rb.Push(res);
108 }
109}
110
111void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) {
112 LOG_INFO(Service_AM, "called");
113
114 IPC::RequestParser rp{ctx};
115 broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock());
116
117 IPC::ResponseBuilder rb{ctx, 2};
118 rb.Push(ResultSuccess);
119}
120
121void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) {
122 LOG_INFO(Service_AM, "called");
123
124 std::shared_ptr<IStorage> data;
125 const auto res = broker->GetInteractiveInData().Pop(&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
137void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx) {
138 LOG_INFO(Service_AM, "called");
139
140 IPC::RequestParser rp{ctx};
141 broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock());
142
143 IPC::ResponseBuilder rb{ctx, 2};
144 rb.Push(ResultSuccess);
145}
146
147void 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(broker->GetInData().GetEvent());
153}
154
155void 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(broker->GetInteractiveInData().GetEvent());
161}
162
163void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
164 LOG_INFO(Service_AM, "called");
165
166 system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid);
167 broker->SignalCompletion();
168
169 IPC::ResponseBuilder rb{ctx, 2};
170 rb.Push(ResultSuccess);
171}
172
173void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
174 struct LibraryAppletInfo {
175 AppletId applet_id;
176 LibraryAppletMode library_applet_mode;
177 };
178
179 LOG_WARNING(Service_AM, "(STUBBED) called");
180
181 const LibraryAppletInfo applet_info{
182 .applet_id = applet->applet_id,
183 .library_applet_mode = applet->library_applet_mode,
184 };
185
186 IPC::ResponseBuilder rb{ctx, 4};
187 rb.Push(ResultSuccess);
188 rb.PushRaw(applet_info);
189}
190
191void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
192 LOG_WARNING(Service_AM, "(STUBBED) called");
193
194 const AppletIdentityInfo applet_info{
195 .applet_id = AppletId::QLaunch,
196 .application_id = 0x0100000000001000ull,
197 };
198
199 IPC::ResponseBuilder rb{ctx, 6};
200 rb.Push(ResultSuccess);
201 rb.PushRaw(applet_info);
202}
203
204void ILibraryAppletSelfAccessor::CanUseApplicationCore(HLERequestContext& ctx) {
205 LOG_WARNING(Service_AM, "(STUBBED) called");
206
207 // TODO: This appears to read the NPDM from state and check the core mask of the applet.
208 IPC::ResponseBuilder rb{ctx, 3};
209 rb.Push(ResultSuccess);
210 rb.Push<u8>(0);
211}
212
213void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
214 LOG_WARNING(Service_AM, "(STUBBED) called");
215
216 IPC::ResponseBuilder rb{ctx, 6};
217 rb.Push(ResultSuccess);
218 rb.PushRaw(GetCallerIdentity(applet));
219}
220
221void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) {
222 LOG_WARNING(Service_AM, "(STUBBED) called");
223
224 IPC::ResponseBuilder rb{ctx, 3};
225 rb.Push(ResultSuccess);
226 rb.Push<u32>(0);
227}
228
229void ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx) {
230 // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage
231 auto identity = GetCallerIdentity(applet);
232
233 // TODO(bunnei): This should be configurable
234 LOG_DEBUG(Service_AM, "called");
235
236 // Get supported languages from NACP, if possible
237 // Default to 0 (all languages supported)
238 u32 supported_languages = 0;
239
240 const auto res = [this, identity] {
241 const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(),
242 system.GetContentProvider()};
243 auto metadata = pm.GetControlMetadata();
244 if (metadata.first != nullptr) {
245 return metadata;
246 }
247
248 const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id),
249 system.GetFileSystemController(),
250 system.GetContentProvider()};
251 return pm_update.GetControlMetadata();
252 }();
253
254 if (res.first != nullptr) {
255 supported_languages = res.first->GetSupportedLanguages();
256 }
257
258 // Call IApplicationManagerInterface implementation.
259 auto& service_manager = system.ServiceManager();
260 auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
261 auto app_man = ns_am2->GetApplicationManagerInterface();
262
263 // Get desired application language
264 u8 desired_language{};
265 const auto res_lang =
266 app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages);
267 if (res_lang != ResultSuccess) {
268 IPC::ResponseBuilder rb{ctx, 2};
269 rb.Push(res_lang);
270 return;
271 }
272
273 // Convert to settings language code.
274 u64 language_code{};
275 const auto res_code =
276 app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language);
277 if (res_code != ResultSuccess) {
278 IPC::ResponseBuilder rb{ctx, 2};
279 rb.Push(res_code);
280 return;
281 }
282
283 LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
284
285 IPC::ResponseBuilder rb{ctx, 4};
286 rb.Push(ResultSuccess);
287 rb.Push(language_code);
288}
289
290void ILibraryAppletSelfAccessor::GetCurrentApplicationId(HLERequestContext& ctx) {
291 LOG_WARNING(Service_AM, "(STUBBED) called");
292
293 u64 application_id = 0;
294 if (auto caller_applet = applet->caller_applet.lock(); caller_applet) {
295 application_id = caller_applet->program_id;
296 }
297
298 IPC::ResponseBuilder rb{ctx, 4};
299 rb.Push(ResultSuccess);
300 rb.Push(application_id);
301}
302
303void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) {
304 const Service::Account::ProfileManager manager{};
305 bool is_empty{true};
306 s32 user_count{-1};
307
308 LOG_INFO(Service_AM, "called");
309
310 if (manager.GetUserCount() > 0) {
311 is_empty = false;
312 user_count = static_cast<s32>(manager.GetUserCount());
313 ctx.WriteBuffer(manager.GetAllUsers());
314 }
315
316 IPC::ResponseBuilder rb{ctx, 4};
317 rb.Push(ResultSuccess);
318 rb.Push<u8>(is_empty);
319 rb.Push(user_count);
320}
321
322void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext& ctx) {
323 LOG_WARNING(Service_AM, "(STUBBED) called");
324
325 IPC::ResponseBuilder rb{ctx, 3};
326 rb.Push(ResultSuccess);
327 rb.Push<u8>(0);
328}
329
330void ILibraryAppletSelfAccessor::Cmd160(HLERequestContext& ctx) {
331 LOG_WARNING(Service_AM, "(STUBBED) called");
332
333 IPC::ResponseBuilder rb{ctx, 4};
334 rb.Push(ResultSuccess);
335 rb.Push<u64>(0);
336}
337
338} // 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
deleted file mode 100644
index 8717a989a..000000000
--- a/src/core/hle/service/am/library_applet_self_accessor.h
+++ /dev/null
@@ -1,44 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <deque>
7#include <vector>
8
9#include "core/hle/service/service.h"
10
11namespace Service::AM {
12
13class AppletDataBroker;
14struct Applet;
15
16class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
17public:
18 explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet_);
19 ~ILibraryAppletSelfAccessor() override;
20
21private:
22 void PopInData(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);
28 void GetLibraryAppletInfo(HLERequestContext& ctx);
29 void GetMainAppletIdentityInfo(HLERequestContext& ctx);
30 void CanUseApplicationCore(HLERequestContext& ctx);
31 void ExitProcessAndReturn(HLERequestContext& ctx);
32 void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
33 void GetDesirableKeyboardLayout(HLERequestContext& ctx);
34 void GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx);
35 void GetCurrentApplicationId(HLERequestContext& ctx);
36 void GetMainAppletAvailableUsers(HLERequestContext& ctx);
37 void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
38 void Cmd160(HLERequestContext& ctx);
39
40 const std::shared_ptr<Applet> applet;
41 const std::shared_ptr<AppletDataBroker> broker;
42};
43
44} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 26a818f14..c9b872887 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
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/library_applet_self_accessor.h"
5#include "core/hle/service/am/process_winding_controller.h" 4#include "core/hle/service/am/process_winding_controller.h"
6#include "core/hle/service/am/self_controller.h" 5#include "core/hle/service/am/self_controller.h"
7#include "core/hle/service/am/service/applet_common_functions.h" 6#include "core/hle/service/am/service/applet_common_functions.h"
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index f1a13a331..9506739e9 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
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/library_applet_self_accessor.h"
5#include "core/hle/service/am/process_winding_controller.h" 4#include "core/hle/service/am/process_winding_controller.h"
6#include "core/hle/service/am/self_controller.h" 5#include "core/hle/service/am/self_controller.h"
7#include "core/hle/service/am/service/applet_common_functions.h" 6#include "core/hle/service/am/service/applet_common_functions.h"
@@ -13,6 +12,7 @@
13#include "core/hle/service/am/service/home_menu_functions.h" 12#include "core/hle/service/am/service/home_menu_functions.h"
14#include "core/hle/service/am/service/library_applet_creator.h" 13#include "core/hle/service/am/service/library_applet_creator.h"
15#include "core/hle/service/am/service/library_applet_proxy.h" 14#include "core/hle/service/am/service/library_applet_proxy.h"
15#include "core/hle/service/am/service/library_applet_self_accessor.h"
16#include "core/hle/service/am/window_controller.h" 16#include "core/hle/service/am/window_controller.h"
17#include "core/hle/service/cmif_serialization.h" 17#include "core/hle/service/cmif_serialization.h"
18 18
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
new file mode 100644
index 000000000..a432a79ba
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
@@ -0,0 +1,322 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core_timing.h"
5#include "core/file_sys/control_metadata.h"
6#include "core/file_sys/patch_manager.h"
7#include "core/file_sys/registered_cache.h"
8#include "core/hle/service/acc/profile_manager.h"
9#include "core/hle/service/am/applet_data_broker.h"
10#include "core/hle/service/am/applet_manager.h"
11#include "core/hle/service/am/frontend/applets.h"
12#include "core/hle/service/am/service/library_applet_self_accessor.h"
13#include "core/hle/service/am/storage.h"
14#include "core/hle/service/cmif_serialization.h"
15#include "core/hle/service/filesystem/filesystem.h"
16#include "core/hle/service/glue/glue_manager.h"
17#include "core/hle/service/ns/ns.h"
18#include "core/hle/service/sm/sm.h"
19
20namespace Service::AM {
21
22namespace {
23
24AppletIdentityInfo GetCallerIdentity(Applet& applet) {
25 if (const auto caller_applet = applet.caller_applet.lock(); caller_applet) {
26 // TODO: is this actually the application ID?
27 return {
28 .applet_id = caller_applet->applet_id,
29 .application_id = caller_applet->program_id,
30 };
31 } else {
32 return {
33 .applet_id = AppletId::QLaunch,
34 .application_id = 0x0100000000001000ull,
35 };
36 }
37}
38
39} // namespace
40
41ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
42 std::shared_ptr<Applet> applet)
43 : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
44 m_broker{m_applet->caller_applet_broker} {
45 // clang-format off
46 static const FunctionInfo functions[] = {
47 {0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
48 {1, D<&ILibraryAppletSelfAccessor::PushOutData>, "PushOutData"},
49 {2, D<&ILibraryAppletSelfAccessor::PopInteractiveInData>, "PopInteractiveInData"},
50 {3, D<&ILibraryAppletSelfAccessor::PushInteractiveOutData>, "PushInteractiveOutData"},
51 {5, D<&ILibraryAppletSelfAccessor::GetPopInDataEvent>, "GetPopInDataEvent"},
52 {6, D<&ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent>, "GetPopInteractiveInDataEvent"},
53 {10, D<&ILibraryAppletSelfAccessor::ExitProcessAndReturn>, "ExitProcessAndReturn"},
54 {11, D<&ILibraryAppletSelfAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"},
55 {12, D<&ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo>, "GetMainAppletIdentityInfo"},
56 {13, D<&ILibraryAppletSelfAccessor::CanUseApplicationCore>, "CanUseApplicationCore"},
57 {14, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo>, "GetCallerAppletIdentityInfo"},
58 {15, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty>, "GetMainAppletApplicationControlProperty"},
59 {16, D<&ILibraryAppletSelfAccessor::GetMainAppletStorageId>, "GetMainAppletStorageId"},
60 {17, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack>, "GetCallerAppletIdentityInfoStack"},
61 {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
62 {19, D<&ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout>, "GetDesirableKeyboardLayout"},
63 {20, nullptr, "PopExtraStorage"},
64 {25, nullptr, "GetPopExtraStorageEvent"},
65 {30, nullptr, "UnpopInData"},
66 {31, nullptr, "UnpopExtraStorage"},
67 {40, nullptr, "GetIndirectLayerProducerHandle"},
68 {50, D<&ILibraryAppletSelfAccessor::ReportVisibleError>, "ReportVisibleError"},
69 {51, D<&ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext>, "ReportVisibleErrorWithErrorContext"},
70 {60, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage>, "GetMainAppletApplicationDesiredLanguage"},
71 {70, D<&ILibraryAppletSelfAccessor::GetCurrentApplicationId>, "GetCurrentApplicationId"},
72 {80, nullptr, "RequestExitToSelf"},
73 {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
74 {100, nullptr, "CreateGameMovieTrimmer"},
75 {101, nullptr, "ReserveResourceForMovieOperation"},
76 {102, nullptr, "UnreserveResourceForMovieOperation"},
77 {110, D<&ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers>, "GetMainAppletAvailableUsers"},
78 {120, nullptr, "GetLaunchStorageInfoForDebug"},
79 {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
80 {140, nullptr, "SetApplicationMemoryReservation"},
81 {150, D<&ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually>, "ShouldSetGpuTimeSliceManually"},
82 {160, D<&ILibraryAppletSelfAccessor::Cmd160>, "Cmd160"},
83 };
84 // clang-format on
85 RegisterHandlers(functions);
86}
87
88ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
89
90Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_storage) {
91 LOG_INFO(Service_AM, "called");
92 R_RETURN(m_broker->GetInData().Pop(out_storage));
93}
94
95Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
96 LOG_INFO(Service_AM, "called");
97 m_broker->GetOutData().Push(storage);
98 R_SUCCEED();
99}
100
101Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage) {
102 LOG_INFO(Service_AM, "called");
103 R_RETURN(m_broker->GetInteractiveInData().Pop(out_storage));
104}
105
106Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer<IStorage> storage) {
107 LOG_INFO(Service_AM, "called");
108 m_broker->GetInteractiveOutData().Push(storage);
109 R_SUCCEED();
110}
111
112Result ILibraryAppletSelfAccessor::GetPopInDataEvent(
113 OutCopyHandle<Kernel::KReadableEvent> out_event) {
114 LOG_INFO(Service_AM, "called");
115 *out_event = m_broker->GetInData().GetEvent();
116 R_SUCCEED();
117}
118
119Result ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(
120 OutCopyHandle<Kernel::KReadableEvent> out_event) {
121 LOG_INFO(Service_AM, "called");
122 *out_event = m_broker->GetInteractiveInData().GetEvent();
123 R_SUCCEED();
124}
125
126Result ILibraryAppletSelfAccessor::GetLibraryAppletInfo(
127 Out<LibraryAppletInfo> out_library_applet_info) {
128 LOG_INFO(Service_AM, "called");
129 *out_library_applet_info = {
130 .applet_id = m_applet->applet_id,
131 .library_applet_mode = m_applet->library_applet_mode,
132 };
133 R_SUCCEED();
134}
135
136Result ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(
137 Out<AppletIdentityInfo> out_identity_info) {
138 LOG_WARNING(Service_AM, "(STUBBED) called");
139 *out_identity_info = {
140 .applet_id = AppletId::QLaunch,
141 .application_id = 0x0100000000001000ull,
142 };
143 R_SUCCEED();
144}
145
146Result ILibraryAppletSelfAccessor::CanUseApplicationCore(Out<bool> out_can_use_application_core) {
147 // TODO: This appears to read the NPDM from state and check the core mask of the applet.
148 LOG_WARNING(Service_AM, "(STUBBED) called");
149 *out_can_use_application_core = false;
150 R_SUCCEED();
151}
152
153Result ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty(
154 OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp) {
155 LOG_WARNING(Service_AM, "(STUBBED) called");
156
157 // TODO: this should be the main applet, not the caller applet
158 const auto application = GetCallerIdentity(*m_applet);
159 std::vector<u8> nacp;
160 const auto result =
161 system.GetARPManager().GetControlProperty(&nacp, application.application_id);
162
163 if (R_SUCCEEDED(result)) {
164 std::memcpy(out_nacp->data(), nacp.data(), std::min(nacp.size(), out_nacp->size()));
165 }
166
167 R_RETURN(result);
168}
169
170Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id) {
171 LOG_INFO(Service_AM, "(STUBBED) called");
172 *out_storage_id = FileSys::StorageId::NandUser;
173 R_SUCCEED();
174}
175
176Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
177 LOG_INFO(Service_AM, "called");
178 system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid);
179 m_broker->SignalCompletion();
180 R_SUCCEED();
181}
182
183Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(
184 Out<AppletIdentityInfo> out_identity_info) {
185 LOG_INFO(Service_AM, "called");
186 *out_identity_info = GetCallerIdentity(*m_applet);
187 R_SUCCEED();
188}
189
190Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack(
191 Out<s32> out_count, OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info) {
192 LOG_INFO(Service_AM, "called");
193
194 std::shared_ptr<Applet> applet = m_applet;
195 *out_count = 0;
196
197 do {
198 if (*out_count >= static_cast<s32>(out_identity_info.size())) {
199 break;
200 }
201 out_identity_info[(*out_count)++] = GetCallerIdentity(*applet);
202 } while ((applet = applet->caller_applet.lock()));
203
204 R_SUCCEED();
205}
206
207Result ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(Out<u32> out_desirable_layout) {
208 LOG_WARNING(Service_AM, "(STUBBED) called");
209 *out_desirable_layout = 0;
210 R_SUCCEED();
211}
212
213Result ILibraryAppletSelfAccessor::ReportVisibleError(ErrorCode error_code) {
214 LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
215 error_code.number);
216 R_SUCCEED();
217}
218
219Result ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext(
220 ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context) {
221 LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
222 error_code.number);
223 R_SUCCEED();
224}
225
226Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(
227 Out<u64> out_desired_language) {
228 // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage
229 // FIXME: all of this stuff belongs to ns
230 auto identity = GetCallerIdentity(*m_applet);
231
232 // TODO(bunnei): This should be configurable
233 LOG_DEBUG(Service_AM, "called");
234
235 // Get supported languages from NACP, if possible
236 // Default to 0 (all languages supported)
237 u32 supported_languages = 0;
238
239 const auto res = [this, identity] {
240 const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(),
241 system.GetContentProvider()};
242 auto metadata = pm.GetControlMetadata();
243 if (metadata.first != nullptr) {
244 return metadata;
245 }
246
247 const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id),
248 system.GetFileSystemController(),
249 system.GetContentProvider()};
250 return pm_update.GetControlMetadata();
251 }();
252
253 if (res.first != nullptr) {
254 supported_languages = res.first->GetSupportedLanguages();
255 }
256
257 // Call IApplicationManagerInterface implementation.
258 auto& service_manager = system.ServiceManager();
259 auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
260 auto app_man = ns_am2->GetApplicationManagerInterface();
261
262 // Get desired application language
263 u8 desired_language{};
264 R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
265
266 // Convert to settings language code.
267 u64 language_code{};
268 R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language));
269
270 LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
271
272 *out_desired_language = language_code;
273 R_SUCCEED();
274}
275
276Result ILibraryAppletSelfAccessor::GetCurrentApplicationId(Out<u64> out_application_id) {
277 LOG_WARNING(Service_AM, "(STUBBED) called");
278
279 // TODO: this should be the main applet, not the caller applet
280 const auto main_applet = GetCallerIdentity(*m_applet);
281 *out_application_id = main_applet.application_id;
282
283 R_SUCCEED();
284}
285
286Result ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(
287 Out<bool> out_no_users_available, Out<s32> out_users_count,
288 OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users) {
289 const Service::Account::ProfileManager manager{};
290
291 *out_no_users_available = true;
292 *out_users_count = -1;
293
294 LOG_INFO(Service_AM, "called");
295
296 if (manager.GetUserCount() > 0) {
297 *out_no_users_available = false;
298 *out_users_count = static_cast<s32>(manager.GetUserCount());
299
300 const auto users = manager.GetAllUsers();
301 for (size_t i = 0; i < users.size() && i < out_users.size(); i++) {
302 out_users[i] = users[i];
303 }
304 }
305
306 R_SUCCEED();
307}
308
309Result ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(
310 Out<bool> out_should_set_gpu_time_slice_manually) {
311 LOG_INFO(Service_AM, "(STUBBED) called");
312 *out_should_set_gpu_time_slice_manually = false;
313 R_SUCCEED();
314}
315
316Result ILibraryAppletSelfAccessor::Cmd160(Out<u64> out_unknown0) {
317 LOG_WARNING(Service_AM, "(STUBBED) called");
318 *out_unknown0 = 0;
319 R_SUCCEED();
320}
321
322} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.h b/src/core/hle/service/am/service/library_applet_self_accessor.h
new file mode 100644
index 000000000..a9743569f
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_self_accessor.h
@@ -0,0 +1,83 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/uuid.h"
7#include "core/hle/service/am/am_types.h"
8#include "core/hle/service/cmif_types.h"
9#include "core/hle/service/service.h"
10
11namespace FileSys {
12enum class StorageId : u8;
13}
14
15namespace Kernel {
16class KReadableEvent;
17}
18
19namespace Service::AM {
20
21class AppletDataBroker;
22struct Applet;
23class IStorage;
24
25struct LibraryAppletInfo {
26 AppletId applet_id;
27 LibraryAppletMode library_applet_mode;
28};
29static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size.");
30
31struct ErrorCode {
32 u32 category;
33 u32 number;
34};
35static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size.");
36
37struct ErrorContext {
38 u8 type;
39 INSERT_PADDING_BYTES_NOINIT(0x7);
40 std::array<u8, 0x1f4> data;
41 Result result;
42};
43static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size.");
44
45class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
46public:
47 explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet);
48 ~ILibraryAppletSelfAccessor() override;
49
50private:
51 Result PopInData(Out<SharedPointer<IStorage>> out_storage);
52 Result PushOutData(SharedPointer<IStorage> storage);
53 Result PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage);
54 Result PushInteractiveOutData(SharedPointer<IStorage> storage);
55 Result GetPopInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
56 Result GetPopInteractiveInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
57 Result GetLibraryAppletInfo(Out<LibraryAppletInfo> out_library_applet_info);
58 Result GetMainAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
59 Result CanUseApplicationCore(Out<bool> out_can_use_application_core);
60 Result GetMainAppletApplicationControlProperty(
61 OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp);
62 Result GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id);
63 Result ExitProcessAndReturn();
64 Result GetCallerAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
65 Result GetCallerAppletIdentityInfoStack(
66 Out<s32> out_count,
67 OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info);
68 Result GetDesirableKeyboardLayout(Out<u32> out_desirable_layout);
69 Result ReportVisibleError(ErrorCode error_code);
70 Result ReportVisibleErrorWithErrorContext(
71 ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context);
72 Result GetMainAppletApplicationDesiredLanguage(Out<u64> out_desired_language);
73 Result GetCurrentApplicationId(Out<u64> out_application_id);
74 Result GetMainAppletAvailableUsers(Out<bool> out_no_users_available, Out<s32> out_users_count,
75 OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users);
76 Result ShouldSetGpuTimeSliceManually(Out<bool> out_should_set_gpu_time_slice_manually);
77 Result Cmd160(Out<u64> out_unknown0);
78
79 const std::shared_ptr<Applet> m_applet;
80 const std::shared_ptr<AppletDataBroker> m_broker;
81};
82
83} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 59d5b2a23..1e931dec7 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
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/application_creator.h" 4#include "core/hle/service/am/application_creator.h"
5#include "core/hle/service/am/library_applet_self_accessor.h"
6#include "core/hle/service/am/process_winding_controller.h" 5#include "core/hle/service/am/process_winding_controller.h"
7#include "core/hle/service/am/self_controller.h" 6#include "core/hle/service/am/self_controller.h"
8#include "core/hle/service/am/service/applet_common_functions.h" 7#include "core/hle/service/am/service/applet_common_functions.h"