diff options
102 files changed, 5711 insertions, 925 deletions
@@ -1,7 +1,7 @@ | |||
1 | yuzu emulator early access | 1 | yuzu emulator early access |
2 | ============= | 2 | ============= |
3 | 3 | ||
4 | This is the source code for early-access 4134. | 4 | This is the source code for early-access 4136. |
5 | 5 | ||
6 | ## Legal Notice | 6 | ## Legal Notice |
7 | 7 | ||
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 4acc60956..a4d8454e8 100755 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
@@ -49,9 +49,7 @@ | |||
49 | #include "core/frontend/applets/profile_select.h" | 49 | #include "core/frontend/applets/profile_select.h" |
50 | #include "core/frontend/applets/software_keyboard.h" | 50 | #include "core/frontend/applets/software_keyboard.h" |
51 | #include "core/frontend/applets/web_browser.h" | 51 | #include "core/frontend/applets/web_browser.h" |
52 | #include "core/hle/service/am/applet_ae.h" | ||
53 | #include "core/hle/service/am/applet_manager.h" | 52 | #include "core/hle/service/am/applet_manager.h" |
54 | #include "core/hle/service/am/applet_oe.h" | ||
55 | #include "core/hle/service/am/frontend/applets.h" | 53 | #include "core/hle/service/am/frontend/applets.h" |
56 | #include "core/hle/service/filesystem/filesystem.h" | 54 | #include "core/hle/service/filesystem/filesystem.h" |
57 | #include "core/loader/loader.h" | 55 | #include "core/loader/loader.h" |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8c74878ab..3f7a30002 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
@@ -417,74 +417,72 @@ add_library(core STATIC | |||
417 | hle/service/am/am_types.h | 417 | hle/service/am/am_types.h |
418 | hle/service/am/applet.cpp | 418 | hle/service/am/applet.cpp |
419 | hle/service/am/applet.h | 419 | hle/service/am/applet.h |
420 | hle/service/am/applet_ae.cpp | ||
421 | hle/service/am/applet_ae.h | ||
422 | hle/service/am/applet_manager.cpp | 420 | hle/service/am/applet_manager.cpp |
423 | hle/service/am/applet_data_broker.cpp | 421 | hle/service/am/applet_data_broker.cpp |
424 | hle/service/am/applet_data_broker.h | 422 | hle/service/am/applet_data_broker.h |
425 | hle/service/am/applet_manager.h | 423 | hle/service/am/applet_manager.h |
426 | hle/service/am/applet_oe.cpp | ||
427 | hle/service/am/applet_oe.h | ||
428 | hle/service/am/applet_common_functions.cpp | ||
429 | hle/service/am/applet_common_functions.h | ||
430 | hle/service/am/applet_message_queue.cpp | 424 | hle/service/am/applet_message_queue.cpp |
431 | hle/service/am/applet_message_queue.h | 425 | hle/service/am/applet_message_queue.h |
432 | hle/service/am/application_creator.cpp | ||
433 | hle/service/am/application_creator.h | ||
434 | hle/service/am/application_functions.cpp | ||
435 | hle/service/am/application_functions.h | ||
436 | hle/service/am/application_proxy.cpp | ||
437 | hle/service/am/application_proxy.h | ||
438 | hle/service/am/audio_controller.cpp | ||
439 | hle/service/am/audio_controller.h | ||
440 | hle/service/am/common_state_getter.cpp | ||
441 | hle/service/am/common_state_getter.h | ||
442 | hle/service/am/debug_functions.cpp | ||
443 | hle/service/am/debug_functions.h | ||
444 | hle/service/am/display_controller.cpp | ||
445 | hle/service/am/display_controller.h | ||
446 | hle/service/am/global_state_controller.cpp | ||
447 | hle/service/am/global_state_controller.h | ||
448 | hle/service/am/hid_registration.cpp | 426 | hle/service/am/hid_registration.cpp |
449 | hle/service/am/hid_registration.h | 427 | hle/service/am/hid_registration.h |
450 | hle/service/am/home_menu_functions.cpp | ||
451 | hle/service/am/home_menu_functions.h | ||
452 | hle/service/am/idle.cpp | ||
453 | hle/service/am/idle.h | ||
454 | hle/service/am/library_applet_accessor.cpp | ||
455 | hle/service/am/library_applet_accessor.h | ||
456 | hle/service/am/library_applet_creator.cpp | ||
457 | hle/service/am/library_applet_creator.h | ||
458 | hle/service/am/library_applet_proxy.cpp | ||
459 | hle/service/am/library_applet_proxy.h | ||
460 | hle/service/am/library_applet_self_accessor.cpp | ||
461 | hle/service/am/library_applet_self_accessor.h | ||
462 | hle/service/am/library_applet_storage.cpp | 428 | hle/service/am/library_applet_storage.cpp |
463 | hle/service/am/library_applet_storage.h | 429 | hle/service/am/library_applet_storage.h |
464 | hle/service/am/lock_accessor.cpp | ||
465 | hle/service/am/lock_accessor.h | ||
466 | hle/service/am/managed_layer_holder.cpp | 430 | hle/service/am/managed_layer_holder.cpp |
467 | hle/service/am/managed_layer_holder.h | 431 | hle/service/am/managed_layer_holder.h |
468 | hle/service/am/omm.cpp | ||
469 | hle/service/am/omm.h | ||
470 | hle/service/am/process_winding_controller.cpp | ||
471 | hle/service/am/process_winding_controller.h | ||
472 | hle/service/am/process.cpp | 432 | hle/service/am/process.cpp |
473 | hle/service/am/process.h | 433 | hle/service/am/process.h |
474 | hle/service/am/self_controller.cpp | 434 | hle/service/am/service/all_system_applet_proxies_service.cpp |
475 | hle/service/am/self_controller.h | 435 | hle/service/am/service/all_system_applet_proxies_service.h |
476 | hle/service/am/system_applet_proxy.cpp | 436 | hle/service/am/service/applet_common_functions.cpp |
477 | hle/service/am/system_applet_proxy.h | 437 | hle/service/am/service/applet_common_functions.h |
438 | hle/service/am/service/application_accessor.cpp | ||
439 | hle/service/am/service/application_accessor.h | ||
440 | hle/service/am/service/application_creator.cpp | ||
441 | hle/service/am/service/application_creator.h | ||
442 | hle/service/am/service/application_functions.cpp | ||
443 | hle/service/am/service/application_functions.h | ||
444 | hle/service/am/service/application_proxy_service.cpp | ||
445 | hle/service/am/service/application_proxy_service.h | ||
446 | hle/service/am/service/application_proxy.cpp | ||
447 | hle/service/am/service/application_proxy.h | ||
448 | hle/service/am/service/audio_controller.cpp | ||
449 | hle/service/am/service/audio_controller.h | ||
450 | hle/service/am/service/common_state_getter.cpp | ||
451 | hle/service/am/service/common_state_getter.h | ||
452 | hle/service/am/service/cradle_firmware_updater.cpp | ||
453 | hle/service/am/service/cradle_firmware_updater.h | ||
454 | hle/service/am/service/debug_functions.cpp | ||
455 | hle/service/am/service/debug_functions.h | ||
456 | hle/service/am/service/display_controller.cpp | ||
457 | hle/service/am/service/display_controller.h | ||
458 | hle/service/am/service/global_state_controller.cpp | ||
459 | hle/service/am/service/global_state_controller.h | ||
460 | hle/service/am/service/home_menu_functions.cpp | ||
461 | hle/service/am/service/home_menu_functions.h | ||
462 | hle/service/am/service/library_applet_accessor.cpp | ||
463 | hle/service/am/service/library_applet_accessor.h | ||
464 | hle/service/am/service/library_applet_creator.cpp | ||
465 | hle/service/am/service/library_applet_creator.h | ||
466 | hle/service/am/service/library_applet_proxy.cpp | ||
467 | hle/service/am/service/library_applet_proxy.h | ||
468 | hle/service/am/service/library_applet_self_accessor.cpp | ||
469 | hle/service/am/service/library_applet_self_accessor.h | ||
470 | hle/service/am/service/lock_accessor.cpp | ||
471 | hle/service/am/service/lock_accessor.h | ||
472 | hle/service/am/service/process_winding_controller.cpp | ||
473 | hle/service/am/service/process_winding_controller.h | ||
474 | hle/service/am/service/self_controller.cpp | ||
475 | hle/service/am/service/self_controller.h | ||
476 | hle/service/am/service/storage_accessor.cpp | ||
477 | hle/service/am/service/storage_accessor.h | ||
478 | hle/service/am/service/storage.cpp | ||
479 | hle/service/am/service/storage.h | ||
480 | hle/service/am/service/system_applet_proxy.cpp | ||
481 | hle/service/am/service/system_applet_proxy.h | ||
482 | hle/service/am/service/window_controller.cpp | ||
483 | hle/service/am/service/window_controller.h | ||
478 | hle/service/am/system_buffer_manager.cpp | 484 | hle/service/am/system_buffer_manager.cpp |
479 | hle/service/am/system_buffer_manager.h | 485 | hle/service/am/system_buffer_manager.h |
480 | hle/service/am/spsm.cpp | ||
481 | hle/service/am/spsm.h | ||
482 | hle/service/am/storage_accessor.cpp | ||
483 | hle/service/am/storage_accessor.h | ||
484 | hle/service/am/storage.cpp | ||
485 | hle/service/am/storage.h | ||
486 | hle/service/am/window_controller.cpp | ||
487 | hle/service/am/window_controller.h | ||
488 | hle/service/aoc/aoc_u.cpp | 486 | hle/service/aoc/aoc_u.cpp |
489 | hle/service/aoc/aoc_u.h | 487 | hle/service/aoc/aoc_u.h |
490 | hle/service/apm/apm.cpp | 488 | hle/service/apm/apm.cpp |
@@ -668,6 +666,18 @@ add_library(core STATIC | |||
668 | hle/service/ldn/ldn.h | 666 | hle/service/ldn/ldn.h |
669 | hle/service/ldn/ldn_results.h | 667 | hle/service/ldn/ldn_results.h |
670 | hle/service/ldn/ldn_types.h | 668 | hle/service/ldn/ldn_types.h |
669 | hle/service/ldn/monitor_service.cpp | ||
670 | hle/service/ldn/monitor_service.h | ||
671 | hle/service/ldn/sf_monitor_service.cpp | ||
672 | hle/service/ldn/sf_monitor_service.h | ||
673 | hle/service/ldn/sf_service.cpp | ||
674 | hle/service/ldn/sf_service.h | ||
675 | hle/service/ldn/sf_service_monitor.cpp | ||
676 | hle/service/ldn/sf_service_monitor.h | ||
677 | hle/service/ldn/system_local_communication_service.cpp | ||
678 | hle/service/ldn/system_local_communication_service.h | ||
679 | hle/service/ldn/user_local_communication_service.cpp | ||
680 | hle/service/ldn/user_local_communication_service.h | ||
671 | hle/service/ldr/ldr.cpp | 681 | hle/service/ldr/ldr.cpp |
672 | hle/service/ldr/ldr.h | 682 | hle/service/ldr/ldr.h |
673 | hle/service/lm/lm.cpp | 683 | hle/service/lm/lm.cpp |
@@ -811,6 +821,14 @@ add_library(core STATIC | |||
811 | hle/service/nvnflinger/window.h | 821 | hle/service/nvnflinger/window.h |
812 | hle/service/olsc/olsc.cpp | 822 | hle/service/olsc/olsc.cpp |
813 | hle/service/olsc/olsc.h | 823 | hle/service/olsc/olsc.h |
824 | hle/service/omm/omm.cpp | ||
825 | hle/service/omm/omm.h | ||
826 | hle/service/omm/operation_mode_manager.cpp | ||
827 | hle/service/omm/operation_mode_manager.h | ||
828 | hle/service/omm/policy_manager_system.cpp | ||
829 | hle/service/omm/policy_manager_system.h | ||
830 | hle/service/omm/power_state_interface.cpp | ||
831 | hle/service/omm/power_state_interface.h | ||
814 | hle/service/os/event.cpp | 832 | hle/service/os/event.cpp |
815 | hle/service/os/event.h | 833 | hle/service/os/event.h |
816 | hle/service/os/multi_wait_holder.cpp | 834 | hle/service/os/multi_wait_holder.cpp |
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 6dfee806c..d636621de 100755 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc | |||
@@ -522,13 +522,17 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
522 | auto* memory_device_inter = registered_processes[asid.id]; | 522 | auto* memory_device_inter = registered_processes[asid.id]; |
523 | const auto release_pending = [&] { | 523 | const auto release_pending = [&] { |
524 | if (uncache_bytes > 0) { | 524 | if (uncache_bytes > 0) { |
525 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, | 525 | if (memory_device_inter != nullptr) { |
526 | uncache_bytes, false); | 526 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, |
527 | uncache_bytes, false); | ||
528 | } | ||
527 | uncache_bytes = 0; | 529 | uncache_bytes = 0; |
528 | } | 530 | } |
529 | if (cache_bytes > 0) { | 531 | if (cache_bytes > 0) { |
530 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, | 532 | if (memory_device_inter != nullptr) { |
531 | cache_bytes, true); | 533 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, |
534 | cache_bytes, true); | ||
535 | } | ||
532 | cache_bytes = 0; | 536 | cache_bytes = 0; |
533 | } | 537 | } |
534 | }; | 538 | }; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 0081cd3ad..1575b505d 100755 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
@@ -2,11 +2,8 @@ | |||
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_ae.h" | 5 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" |
6 | #include "core/hle/service/am/applet_oe.h" | 6 | #include "core/hle/service/am/service/application_proxy_service.h" |
7 | #include "core/hle/service/am/idle.h" | ||
8 | #include "core/hle/service/am/omm.h" | ||
9 | #include "core/hle/service/am/spsm.h" | ||
10 | #include "core/hle/service/server_manager.h" | 7 | #include "core/hle/service/server_manager.h" |
11 | 8 | ||
12 | namespace Service::AM { | 9 | namespace Service::AM { |
@@ -14,13 +11,10 @@ namespace Service::AM { | |||
14 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { | 11 | void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { |
15 | auto server_manager = std::make_unique<ServerManager>(system); | 12 | auto server_manager = std::make_unique<ServerManager>(system); |
16 | 13 | ||
17 | server_manager->RegisterNamedService("appletAE", | 14 | server_manager->RegisterNamedService( |
18 | std::make_shared<AppletAE>(nvnflinger, system)); | 15 | "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger)); |
19 | server_manager->RegisterNamedService("appletOE", | 16 | server_manager->RegisterNamedService( |
20 | std::make_shared<AppletOE>(nvnflinger, system)); | 17 | "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger)); |
21 | server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system)); | ||
22 | server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system)); | ||
23 | server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system)); | ||
24 | ServerManager::RunServer(std::move(server_manager)); | 18 | ServerManager::RunServer(std::move(server_manager)); |
25 | } | 19 | } |
26 | 20 | ||
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index 8c33feb15..46afb3996 100755 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h | |||
@@ -18,7 +18,7 @@ enum class AppletType { | |||
18 | SystemApplet, | 18 | SystemApplet, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | enum class GameplayRecordingState : u32 { | 21 | enum class GamePlayRecordingState : u32 { |
22 | Disabled, | 22 | Disabled, |
23 | Enabled, | 23 | Enabled, |
24 | }; | 24 | }; |
@@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 { | |||
67 | }; | 67 | }; |
68 | 68 | ||
69 | struct FocusHandlingMode { | 69 | struct FocusHandlingMode { |
70 | bool unknown0; | 70 | bool notify; |
71 | bool unknown1; | 71 | bool background; |
72 | bool unknown2; | 72 | bool suspend; |
73 | bool unknown3; | ||
74 | }; | 73 | }; |
75 | 74 | ||
76 | enum class IdleTimeDetectionExtension : u32 { | 75 | enum class IdleTimeDetectionExtension : u32 { |
@@ -128,6 +127,40 @@ enum class AppletProgramId : u64 { | |||
128 | MaxProgramId = 0x0100000000001FFFull, | 127 | MaxProgramId = 0x0100000000001FFFull, |
129 | }; | 128 | }; |
130 | 129 | ||
130 | // This is nn::am::AppletMessage | ||
131 | enum class AppletMessage : u32 { | ||
132 | None = 0, | ||
133 | ChangeIntoForeground = 1, | ||
134 | ChangeIntoBackground = 2, | ||
135 | Exit = 4, | ||
136 | ApplicationExited = 6, | ||
137 | FocusStateChanged = 15, | ||
138 | Resume = 16, | ||
139 | DetectShortPressingHomeButton = 20, | ||
140 | DetectLongPressingHomeButton = 21, | ||
141 | DetectShortPressingPowerButton = 22, | ||
142 | DetectMiddlePressingPowerButton = 23, | ||
143 | DetectLongPressingPowerButton = 24, | ||
144 | RequestToPrepareSleep = 25, | ||
145 | FinishedSleepSequence = 26, | ||
146 | SleepRequiredByHighTemperature = 27, | ||
147 | SleepRequiredByLowBattery = 28, | ||
148 | AutoPowerDown = 29, | ||
149 | OperationModeChanged = 30, | ||
150 | PerformanceModeChanged = 31, | ||
151 | DetectReceivingCecSystemStandby = 32, | ||
152 | SdCardRemoved = 33, | ||
153 | LaunchApplicationRequested = 50, | ||
154 | RequestToDisplay = 51, | ||
155 | ShowApplicationLogo = 55, | ||
156 | HideApplicationLogo = 56, | ||
157 | ForceHideApplicationLogo = 57, | ||
158 | FloatingApplicationDetected = 60, | ||
159 | DetectShortPressingCaptureButton = 90, | ||
160 | AlbumScreenShotTaken = 92, | ||
161 | AlbumRecordingSaved = 93, | ||
162 | }; | ||
163 | |||
131 | enum class LibraryAppletMode : u32 { | 164 | enum class LibraryAppletMode : u32 { |
132 | AllForeground = 0, | 165 | AllForeground = 0, |
133 | PartialForeground = 1, | 166 | PartialForeground = 1, |
@@ -136,6 +169,11 @@ enum class LibraryAppletMode : u32 { | |||
136 | AllForegroundInitiallyHidden = 4, | 169 | AllForegroundInitiallyHidden = 4, |
137 | }; | 170 | }; |
138 | 171 | ||
172 | enum class LaunchParameterKind : u32 { | ||
173 | UserChannel = 1, | ||
174 | AccountPreselectedUser = 2, | ||
175 | }; | ||
176 | |||
139 | enum class CommonArgumentVersion : u32 { | 177 | enum class CommonArgumentVersion : u32 { |
140 | Version0, | 178 | Version0, |
141 | Version1, | 179 | Version1, |
@@ -152,6 +190,22 @@ enum class ThemeColor : u32 { | |||
152 | BasicBlack = 3, | 190 | BasicBlack = 3, |
153 | }; | 191 | }; |
154 | 192 | ||
193 | enum class InputDetectionPolicy : u32 { | ||
194 | Unknown0 = 0, | ||
195 | Unknown1 = 1, | ||
196 | }; | ||
197 | |||
198 | enum class WindowOriginMode : u32 { | ||
199 | LowerLeft = 0, | ||
200 | UpperLeft = 1, | ||
201 | }; | ||
202 | |||
203 | enum class ProgramSpecifyKind : u32 { | ||
204 | ExecuteProgram = 0, | ||
205 | JumpToSubApplicationProgramForDevelopment = 1, | ||
206 | RestartProgram = 2, | ||
207 | }; | ||
208 | |||
155 | struct CommonArguments { | 209 | struct CommonArguments { |
156 | CommonArgumentVersion arguments_version; | 210 | CommonArgumentVersion arguments_version; |
157 | CommonArgumentSize size; | 211 | CommonArgumentSize size; |
@@ -169,6 +223,27 @@ struct AppletIdentityInfo { | |||
169 | }; | 223 | }; |
170 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); | 224 | static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size."); |
171 | 225 | ||
226 | struct AppletAttribute { | ||
227 | u8 flag; | ||
228 | INSERT_PADDING_BYTES_NOINIT(0x7F); | ||
229 | }; | ||
230 | static_assert(sizeof(AppletAttribute) == 0x80, "AppletAttribute has incorrect size."); | ||
231 | |||
232 | // This is nn::oe::DisplayVersion | ||
233 | struct DisplayVersion { | ||
234 | std::array<char, 0x10> string; | ||
235 | }; | ||
236 | static_assert(sizeof(DisplayVersion) == 0x10, "DisplayVersion has incorrect size."); | ||
237 | |||
238 | // This is nn::pdm::ApplicationPlayStatistics | ||
239 | struct ApplicationPlayStatistics { | ||
240 | u64 application_id; | ||
241 | u64 play_time_ns; | ||
242 | u64 launch_count; | ||
243 | }; | ||
244 | static_assert(sizeof(ApplicationPlayStatistics) == 0x18, | ||
245 | "ApplicationPlayStatistics has incorrect size."); | ||
246 | |||
172 | using AppletResourceUserId = u64; | 247 | using AppletResourceUserId = u64; |
173 | using ProgramId = u64; | 248 | using ProgramId = u64; |
174 | 249 | ||
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index b29ecdfed..4f34d4811 100755 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #pragma once | 4 | #pragma once |
5 | 5 | ||
6 | #include <list> | ||
7 | #include <mutex> | 6 | #include <mutex> |
8 | 7 | ||
9 | #include "common/math_util.h" | 8 | #include "common/math_util.h" |
@@ -18,7 +17,6 @@ | |||
18 | #include "core/hle/service/am/hid_registration.h" | 17 | #include "core/hle/service/am/hid_registration.h" |
19 | #include "core/hle/service/am/managed_layer_holder.h" | 18 | #include "core/hle/service/am/managed_layer_holder.h" |
20 | #include "core/hle/service/am/process.h" | 19 | #include "core/hle/service/am/process.h" |
21 | #include "core/hle/service/am/storage.h" | ||
22 | #include "core/hle/service/am/system_buffer_manager.h" | 20 | #include "core/hle/service/am/system_buffer_manager.h" |
23 | 21 | ||
24 | namespace Service::AM { | 22 | namespace Service::AM { |
@@ -76,8 +74,8 @@ struct Applet { | |||
76 | u32 application_core_usage_mode{}; | 74 | u32 application_core_usage_mode{}; |
77 | 75 | ||
78 | // Application functions | 76 | // Application functions |
79 | bool gameplay_recording_supported{}; | 77 | bool game_play_recording_supported{}; |
80 | GameplayRecordingState gameplay_recording_state{GameplayRecordingState::Disabled}; | 78 | GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; |
81 | bool jit_service_launched{}; | 79 | bool jit_service_launched{}; |
82 | bool is_running{}; | 80 | bool is_running{}; |
83 | bool application_crash_report_enabled{}; | 81 | bool application_crash_report_enabled{}; |
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 52200d5b2..4c7266f89 100755 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "core/hle/service/am/frontend/applet_controller.h" | 12 | #include "core/hle/service/am/frontend/applet_controller.h" |
13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" | 13 | #include "core/hle/service/am/frontend/applet_mii_edit_types.h" |
14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" | 14 | #include "core/hle/service/am/frontend/applet_software_keyboard_types.h" |
15 | #include "core/hle/service/am/service/storage.h" | ||
15 | #include "hid_core/hid_types.h" | 16 | #include "hid_core/hid_types.h" |
16 | 17 | ||
17 | namespace Service::AM { | 18 | namespace Service::AM { |
@@ -303,8 +304,8 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( | |||
303 | } | 304 | } |
304 | 305 | ||
305 | // Applet was started by frontend, so it is foreground. | 306 | // Applet was started by frontend, so it is foreground. |
306 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); | 307 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); |
307 | applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | 308 | applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); |
308 | applet->focus_state = FocusState::InFocus; | 309 | applet->focus_state = FocusState::InFocus; |
309 | 310 | ||
310 | this->InsertApplet(std::move(applet)); | 311 | 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 5ed996b70..83c3c5a55 100755 --- a/src/core/hle/service/am/applet_message_queue.cpp +++ b/src/core/hle/service/am/applet_message_queue.cpp | |||
@@ -33,7 +33,7 @@ void AppletMessageQueue::PushMessage(AppletMessage msg) { | |||
33 | on_new_message->Signal(); | 33 | on_new_message->Signal(); |
34 | } | 34 | } |
35 | 35 | ||
36 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | 36 | AppletMessage AppletMessageQueue::PopMessage() { |
37 | std::scoped_lock lk{lock}; | 37 | std::scoped_lock lk{lock}; |
38 | if (messages.empty()) { | 38 | if (messages.empty()) { |
39 | on_new_message->Clear(); | 39 | on_new_message->Clear(); |
diff --git a/src/core/hle/service/am/applet_message_queue.h b/src/core/hle/service/am/applet_message_queue.h index 5cb236d47..429b77d37 100755 --- a/src/core/hle/service/am/applet_message_queue.h +++ b/src/core/hle/service/am/applet_message_queue.h | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <queue> | 6 | #include <queue> |
7 | 7 | ||
8 | #include "core/hle/service/am/am_types.h" | ||
8 | #include "core/hle/service/kernel_helpers.h" | 9 | #include "core/hle/service/kernel_helpers.h" |
9 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
10 | 11 | ||
@@ -16,40 +17,6 @@ namespace Service::AM { | |||
16 | 17 | ||
17 | class AppletMessageQueue { | 18 | class AppletMessageQueue { |
18 | public: | 19 | public: |
19 | // This is nn::am::AppletMessage | ||
20 | enum class AppletMessage : u32 { | ||
21 | None = 0, | ||
22 | ChangeIntoForeground = 1, | ||
23 | ChangeIntoBackground = 2, | ||
24 | Exit = 4, | ||
25 | ApplicationExited = 6, | ||
26 | FocusStateChanged = 15, | ||
27 | Resume = 16, | ||
28 | DetectShortPressingHomeButton = 20, | ||
29 | DetectLongPressingHomeButton = 21, | ||
30 | DetectShortPressingPowerButton = 22, | ||
31 | DetectMiddlePressingPowerButton = 23, | ||
32 | DetectLongPressingPowerButton = 24, | ||
33 | RequestToPrepareSleep = 25, | ||
34 | FinishedSleepSequence = 26, | ||
35 | SleepRequiredByHighTemperature = 27, | ||
36 | SleepRequiredByLowBattery = 28, | ||
37 | AutoPowerDown = 29, | ||
38 | OperationModeChanged = 30, | ||
39 | PerformanceModeChanged = 31, | ||
40 | DetectReceivingCecSystemStandby = 32, | ||
41 | SdCardRemoved = 33, | ||
42 | LaunchApplicationRequested = 50, | ||
43 | RequestToDisplay = 51, | ||
44 | ShowApplicationLogo = 55, | ||
45 | HideApplicationLogo = 56, | ||
46 | ForceHideApplicationLogo = 57, | ||
47 | FloatingApplicationDetected = 60, | ||
48 | DetectShortPressingCaptureButton = 90, | ||
49 | AlbumScreenShotTaken = 92, | ||
50 | AlbumRecordingSaved = 93, | ||
51 | }; | ||
52 | |||
53 | explicit AppletMessageQueue(Core::System& system); | 20 | explicit AppletMessageQueue(Core::System& system); |
54 | ~AppletMessageQueue(); | 21 | ~AppletMessageQueue(); |
55 | 22 | ||
diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp index 0862c81b6..4cbc80d63 100755 --- a/src/core/hle/service/am/frontend/applet_cabinet.cpp +++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp | |||
@@ -9,7 +9,7 @@ | |||
9 | #include "core/hle/kernel/k_readable_event.h" | 9 | #include "core/hle/kernel/k_readable_event.h" |
10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
11 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 11 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
12 | #include "core/hle/service/am/storage.h" | 12 | #include "core/hle/service/am/service/storage.h" |
13 | #include "core/hle/service/mii/mii_manager.h" | 13 | #include "core/hle/service/mii/mii_manager.h" |
14 | #include "core/hle/service/nfc/common/device.h" | 14 | #include "core/hle/service/nfc/common/device.h" |
15 | #include "hid_core/hid_core.h" | 15 | #include "hid_core/hid_core.h" |
diff --git a/src/core/hle/service/am/frontend/applet_controller.cpp b/src/core/hle/service/am/frontend/applet_controller.cpp index bd3e49fc4..66f52686d 100755 --- a/src/core/hle/service/am/frontend/applet_controller.cpp +++ b/src/core/hle/service/am/frontend/applet_controller.cpp | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
13 | #include "core/hle/service/am/am.h" | 13 | #include "core/hle/service/am/am.h" |
14 | #include "core/hle/service/am/frontend/applet_controller.h" | 14 | #include "core/hle/service/am/frontend/applet_controller.h" |
15 | #include "core/hle/service/am/storage.h" | 15 | #include "core/hle/service/am/service/storage.h" |
16 | #include "hid_core/frontend/emulated_controller.h" | 16 | #include "hid_core/frontend/emulated_controller.h" |
17 | #include "hid_core/hid_core.h" | 17 | #include "hid_core/hid_core.h" |
18 | #include "hid_core/hid_types.h" | 18 | #include "hid_core/hid_types.h" |
diff --git a/src/core/hle/service/am/frontend/applet_error.cpp b/src/core/hle/service/am/frontend/applet_error.cpp index b97a5f3ea..34ec7013b 100755 --- a/src/core/hle/service/am/frontend/applet_error.cpp +++ b/src/core/hle/service/am/frontend/applet_error.cpp | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "core/frontend/applets/error.h" | 10 | #include "core/frontend/applets/error.h" |
11 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
12 | #include "core/hle/service/am/frontend/applet_error.h" | 12 | #include "core/hle/service/am/frontend/applet_error.h" |
13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
14 | #include "core/reporter.h" | 14 | #include "core/reporter.h" |
15 | 15 | ||
16 | namespace Service::AM::Frontend { | 16 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/frontend/applet_general.cpp b/src/core/hle/service/am/frontend/applet_general.cpp index 3c091a602..d2cabb7b5 100755 --- a/src/core/hle/service/am/frontend/applet_general.cpp +++ b/src/core/hle/service/am/frontend/applet_general.cpp | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "core/hle/service/am/am.h" | 10 | #include "core/hle/service/am/am.h" |
11 | #include "core/hle/service/am/applet_data_broker.h" | 11 | #include "core/hle/service/am/applet_data_broker.h" |
12 | #include "core/hle/service/am/frontend/applet_general.h" | 12 | #include "core/hle/service/am/frontend/applet_general.h" |
13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
14 | #include "core/reporter.h" | 14 | #include "core/reporter.h" |
15 | 15 | ||
16 | namespace Service::AM::Frontend { | 16 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/frontend/applet_mii_edit.cpp b/src/core/hle/service/am/frontend/applet_mii_edit.cpp index e3d19fb3d..0180ab761 100755 --- a/src/core/hle/service/am/frontend/applet_mii_edit.cpp +++ b/src/core/hle/service/am/frontend/applet_mii_edit.cpp | |||
@@ -7,7 +7,7 @@ | |||
7 | #include "core/frontend/applets/mii_edit.h" | 7 | #include "core/frontend/applets/mii_edit.h" |
8 | #include "core/hle/service/am/am.h" | 8 | #include "core/hle/service/am/am.h" |
9 | #include "core/hle/service/am/frontend/applet_mii_edit.h" | 9 | #include "core/hle/service/am/frontend/applet_mii_edit.h" |
10 | #include "core/hle/service/am/storage.h" | 10 | #include "core/hle/service/am/service/storage.h" |
11 | #include "core/hle/service/mii/mii.h" | 11 | #include "core/hle/service/mii/mii.h" |
12 | #include "core/hle/service/mii/mii_manager.h" | 12 | #include "core/hle/service/mii/mii_manager.h" |
13 | #include "core/hle/service/sm/sm.h" | 13 | #include "core/hle/service/sm/sm.h" |
diff --git a/src/core/hle/service/am/frontend/applet_profile_select.cpp b/src/core/hle/service/am/frontend/applet_profile_select.cpp index efb4053b8..89b5a1eab 100755 --- a/src/core/hle/service/am/frontend/applet_profile_select.cpp +++ b/src/core/hle/service/am/frontend/applet_profile_select.cpp | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "core/hle/service/acc/errors.h" | 10 | #include "core/hle/service/acc/errors.h" |
11 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
12 | #include "core/hle/service/am/frontend/applet_profile_select.h" | 12 | #include "core/hle/service/am/frontend/applet_profile_select.h" |
13 | #include "core/hle/service/am/storage.h" | 13 | #include "core/hle/service/am/service/storage.h" |
14 | 14 | ||
15 | namespace Service::AM::Frontend { | 15 | namespace Service::AM::Frontend { |
16 | 16 | ||
diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp index 034c62f32..d1bc03018 100755 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp | |||
@@ -6,7 +6,7 @@ | |||
6 | #include "core/frontend/applets/software_keyboard.h" | 6 | #include "core/frontend/applets/software_keyboard.h" |
7 | #include "core/hle/service/am/am.h" | 7 | #include "core/hle/service/am/am.h" |
8 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" | 8 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" |
9 | #include "core/hle/service/am/storage.h" | 9 | #include "core/hle/service/am/service/storage.h" |
10 | 10 | ||
11 | namespace Service::AM::Frontend { | 11 | namespace Service::AM::Frontend { |
12 | 12 | ||
diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp index 6ee4caf34..bb60260b4 100755 --- a/src/core/hle/service/am/frontend/applet_web_browser.cpp +++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "core/hle/result.h" | 20 | #include "core/hle/result.h" |
21 | #include "core/hle/service/am/am.h" | 21 | #include "core/hle/service/am/am.h" |
22 | #include "core/hle/service/am/frontend/applet_web_browser.h" | 22 | #include "core/hle/service/am/frontend/applet_web_browser.h" |
23 | #include "core/hle/service/am/storage.h" | 23 | #include "core/hle/service/am/service/storage.h" |
24 | #include "core/hle/service/filesystem/filesystem.h" | 24 | #include "core/hle/service/filesystem/filesystem.h" |
25 | #include "core/hle/service/ns/iplatform_service_manager.h" | 25 | #include "core/hle/service/ns/iplatform_service_manager.h" |
26 | #include "core/loader/loader.h" | 26 | #include "core/loader/loader.h" |
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index db2b04575..e662c6cd6 100755 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp | |||
@@ -15,11 +15,8 @@ | |||
15 | #include "core/frontend/applets/web_browser.h" | 15 | #include "core/frontend/applets/web_browser.h" |
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" | ||
19 | #include "core/hle/service/am/applet_data_broker.h" | 18 | #include "core/hle/service/am/applet_data_broker.h" |
20 | #include "core/hle/service/am/applet_manager.h" | 19 | #include "core/hle/service/am/applet_manager.h" |
21 | #include "core/hle/service/am/applet_message_queue.h" | ||
22 | #include "core/hle/service/am/applet_oe.h" | ||
23 | #include "core/hle/service/am/frontend/applet_cabinet.h" | 20 | #include "core/hle/service/am/frontend/applet_cabinet.h" |
24 | #include "core/hle/service/am/frontend/applet_controller.h" | 21 | #include "core/hle/service/am/frontend/applet_controller.h" |
25 | #include "core/hle/service/am/frontend/applet_error.h" | 22 | #include "core/hle/service/am/frontend/applet_error.h" |
@@ -29,7 +26,7 @@ | |||
29 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" | 26 | #include "core/hle/service/am/frontend/applet_software_keyboard.h" |
30 | #include "core/hle/service/am/frontend/applet_web_browser.h" | 27 | #include "core/hle/service/am/frontend/applet_web_browser.h" |
31 | #include "core/hle/service/am/frontend/applets.h" | 28 | #include "core/hle/service/am/frontend/applets.h" |
32 | #include "core/hle/service/am/storage.h" | 29 | #include "core/hle/service/am/service/storage.h" |
33 | #include "core/hle/service/sm/sm.h" | 30 | #include "core/hle/service/sm/sm.h" |
34 | 31 | ||
35 | namespace Service::AM::Frontend { | 32 | namespace Service::AM::Frontend { |
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp new file mode 100755 index 000000000..eebd90ba2 --- /dev/null +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | |||
@@ -0,0 +1,80 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/core.h" | ||
5 | #include "core/hle/service/am/applet_manager.h" | ||
6 | #include "core/hle/service/am/service/all_system_applet_proxies_service.h" | ||
7 | #include "core/hle/service/am/service/library_applet_proxy.h" | ||
8 | #include "core/hle/service/am/service/system_applet_proxy.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, | ||
14 | Nvnflinger::Nvnflinger& nvnflinger) | ||
15 | : ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} { | ||
16 | // clang-format off | ||
17 | static const FunctionInfo functions[] = { | ||
18 | {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, | ||
19 | {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"}, | ||
20 | {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"}, | ||
21 | {300, nullptr, "OpenOverlayAppletProxy"}, | ||
22 | {350, nullptr, "OpenSystemApplicationProxy"}, | ||
23 | {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, | ||
24 | {410, nullptr, "GetSystemAppletControllerForDebug"}, | ||
25 | {1000, nullptr, "GetDebugFunctions"}, | ||
26 | }; | ||
27 | // clang-format on | ||
28 | |||
29 | RegisterHandlers(functions); | ||
30 | } | ||
31 | |||
32 | IAllSystemAppletProxiesService::~IAllSystemAppletProxiesService() = default; | ||
33 | |||
34 | Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( | ||
35 | Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, ClientProcessId pid, | ||
36 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
37 | LOG_DEBUG(Service_AM, "called"); | ||
38 | |||
39 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | ||
40 | *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>( | ||
41 | system, applet, process_handle.Get(), m_nvnflinger); | ||
42 | R_SUCCEED(); | ||
43 | } else { | ||
44 | UNIMPLEMENTED(); | ||
45 | R_THROW(ResultUnknown); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( | ||
50 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
51 | InCopyHandle<Kernel::KProcess> process_handle, | ||
52 | InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute) { | ||
53 | LOG_DEBUG(Service_AM, "called"); | ||
54 | |||
55 | if (const auto applet = this->GetAppletFromProcessId(pid); applet) { | ||
56 | *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>( | ||
57 | system, applet, process_handle.Get(), m_nvnflinger); | ||
58 | R_SUCCEED(); | ||
59 | } else { | ||
60 | UNIMPLEMENTED(); | ||
61 | R_THROW(ResultUnknown); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( | ||
66 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
67 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
68 | LOG_DEBUG(Service_AM, "called"); | ||
69 | |||
70 | AppletAttribute attribute{}; | ||
71 | R_RETURN( | ||
72 | this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute)); | ||
73 | } | ||
74 | |||
75 | std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( | ||
76 | ProcessId process_id) { | ||
77 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | ||
78 | } | ||
79 | |||
80 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h new file mode 100755 index 000000000..38b1ca2ea --- /dev/null +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h | |||
@@ -0,0 +1,47 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service { | ||
10 | |||
11 | namespace Nvnflinger { | ||
12 | class Nvnflinger; | ||
13 | } | ||
14 | |||
15 | namespace AM { | ||
16 | |||
17 | struct Applet; | ||
18 | struct AppletAttribute; | ||
19 | class ILibraryAppletProxy; | ||
20 | class ISystemAppletProxy; | ||
21 | |||
22 | class IAllSystemAppletProxiesService final | ||
23 | : public ServiceFramework<IAllSystemAppletProxiesService> { | ||
24 | public: | ||
25 | explicit IAllSystemAppletProxiesService(Core::System& system_, | ||
26 | Nvnflinger::Nvnflinger& nvnflinger); | ||
27 | ~IAllSystemAppletProxiesService() override; | ||
28 | |||
29 | private: | ||
30 | Result OpenSystemAppletProxy(Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, | ||
31 | ClientProcessId pid, | ||
32 | InCopyHandle<Kernel::KProcess> process_handle); | ||
33 | Result OpenLibraryAppletProxy(Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, | ||
34 | ClientProcessId pid, | ||
35 | InCopyHandle<Kernel::KProcess> process_handle, | ||
36 | InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute); | ||
37 | Result OpenLibraryAppletProxyOld( | ||
38 | Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, | ||
39 | InCopyHandle<Kernel::KProcess> process_handle); | ||
40 | |||
41 | private: | ||
42 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | ||
43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
44 | }; | ||
45 | |||
46 | } // namespace AM | ||
47 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/service/applet_common_functions.cpp b/src/core/hle/service/am/service/applet_common_functions.cpp new file mode 100755 index 000000000..0f29ab285 --- /dev/null +++ b/src/core/hle/service/am/service/applet_common_functions.cpp | |||
@@ -0,0 +1,63 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/applet.h" | ||
5 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
6 | #include "core/hle/service/cmif_serialization.h" | ||
7 | |||
8 | namespace Service::AM { | ||
9 | |||
10 | IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, | ||
11 | std::shared_ptr<Applet> applet_) | ||
12 | : ServiceFramework{system_, "IAppletCommonFunctions"}, applet{std::move(applet_)} { | ||
13 | // clang-format off | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, nullptr, "SetTerminateResult"}, | ||
16 | {10, nullptr, "ReadThemeStorage"}, | ||
17 | {11, nullptr, "WriteThemeStorage"}, | ||
18 | {20, nullptr, "PushToAppletBoundChannel"}, | ||
19 | {21, nullptr, "TryPopFromAppletBoundChannel"}, | ||
20 | {40, nullptr, "GetDisplayLogicalResolution"}, | ||
21 | {42, nullptr, "SetDisplayMagnification"}, | ||
22 | {50, nullptr, "SetHomeButtonDoubleClickEnabled"}, | ||
23 | {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"}, | ||
24 | {52, nullptr, "IsHomeButtonShortPressedBlocked"}, | ||
25 | {60, nullptr, "IsVrModeCurtainRequired"}, | ||
26 | {61, nullptr, "IsSleepRequiredByHighTemperature"}, | ||
27 | {62, nullptr, "IsSleepRequiredByLowBattery"}, | ||
28 | {70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"}, | ||
29 | {80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"}, | ||
30 | {81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"}, | ||
31 | {90, nullptr, "OpenNamedChannelAsParent"}, | ||
32 | {91, nullptr, "OpenNamedChannelAsChild"}, | ||
33 | {100, nullptr, "SetApplicationCoreUsageMode"}, | ||
34 | {300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"}, | ||
35 | }; | ||
36 | // clang-format on | ||
37 | |||
38 | RegisterHandlers(functions); | ||
39 | } | ||
40 | |||
41 | IAppletCommonFunctions::~IAppletCommonFunctions() = default; | ||
42 | |||
43 | Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled( | ||
44 | Out<bool> out_home_button_double_click_enabled) { | ||
45 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
46 | *out_home_button_double_click_enabled = false; | ||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
50 | Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) { | ||
51 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
52 | std::scoped_lock lk{applet->lock}; | ||
53 | applet->cpu_boost_request_priority = priority; | ||
54 | R_SUCCEED(); | ||
55 | } | ||
56 | |||
57 | Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_id) { | ||
58 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
59 | *out_application_id = system.GetApplicationProcessProgramID() & ~0xFFFULL; | ||
60 | R_SUCCEED(); | ||
61 | } | ||
62 | |||
63 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/applet_common_functions.h b/src/core/hle/service/am/service/applet_common_functions.h new file mode 100755 index 000000000..4424fc83d --- /dev/null +++ b/src/core/hle/service/am/service/applet_common_functions.h | |||
@@ -0,0 +1,26 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | |||
13 | class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> { | ||
14 | public: | ||
15 | explicit IAppletCommonFunctions(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
16 | ~IAppletCommonFunctions() override; | ||
17 | |||
18 | private: | ||
19 | Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled); | ||
20 | Result SetCpuBoostRequestPriority(s32 priority); | ||
21 | Result GetCurrentApplicationId(Out<u64> out_application_id); | ||
22 | |||
23 | const std::shared_ptr<Applet> applet; | ||
24 | }; | ||
25 | |||
26 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_accessor.cpp b/src/core/hle/service/am/service/application_accessor.cpp new file mode 100755 index 000000000..6e7d110e8 --- /dev/null +++ b/src/core/hle/service/am/service/application_accessor.cpp | |||
@@ -0,0 +1,138 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/result.h" | ||
5 | #include "core/hle/service/am/am_types.h" | ||
6 | #include "core/hle/service/am/applet.h" | ||
7 | #include "core/hle/service/am/applet_data_broker.h" | ||
8 | #include "core/hle/service/am/applet_manager.h" | ||
9 | #include "core/hle/service/am/service/application_accessor.h" | ||
10 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
11 | #include "core/hle/service/am/service/storage.h" | ||
12 | #include "core/hle/service/cmif_serialization.h" | ||
13 | |||
14 | namespace Service::AM { | ||
15 | |||
16 | IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet) | ||
17 | : ServiceFramework{system_, "IApplicationAccessor"}, m_applet(std::move(applet)) { | ||
18 | // clang-format off | ||
19 | static const FunctionInfo functions[] = { | ||
20 | {0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, | ||
21 | {1, nullptr, "IsCompleted"}, | ||
22 | {10, D<&IApplicationAccessor::Start>, "Start"}, | ||
23 | {20, D<&IApplicationAccessor::RequestExit>, "RequestExit"}, | ||
24 | {25, D<&IApplicationAccessor::Terminate>, "Terminate"}, | ||
25 | {30, D<&IApplicationAccessor::GetResult>, "GetResult"}, | ||
26 | {101, D<&IApplicationAccessor::RequestForApplicationToGetForeground>, "RequestForApplicationToGetForeground"}, | ||
27 | {110, nullptr, "TerminateAllLibraryApplets"}, | ||
28 | {111, nullptr, "AreAnyLibraryAppletsLeft"}, | ||
29 | {112, D<&IApplicationAccessor::GetCurrentLibraryApplet>, "GetCurrentLibraryApplet"}, | ||
30 | {120, nullptr, "GetApplicationId"}, | ||
31 | {121, D<&IApplicationAccessor::PushLaunchParameter>, "PushLaunchParameter"}, | ||
32 | {122, D<&IApplicationAccessor::GetApplicationControlProperty>, "GetApplicationControlProperty"}, | ||
33 | {123, nullptr, "GetApplicationLaunchProperty"}, | ||
34 | {124, nullptr, "GetApplicationLaunchRequestInfo"}, | ||
35 | {130, D<&IApplicationAccessor::SetUsers>, "SetUsers"}, | ||
36 | {131, D<&IApplicationAccessor::CheckRightsEnvironmentAvailable>, "CheckRightsEnvironmentAvailable"}, | ||
37 | {132, D<&IApplicationAccessor::GetNsRightsEnvironmentHandle>, "GetNsRightsEnvironmentHandle"}, | ||
38 | {140, nullptr, "GetDesirableUids"}, | ||
39 | {150, D<&IApplicationAccessor::ReportApplicationExitTimeout>, "ReportApplicationExitTimeout"}, | ||
40 | {160, nullptr, "SetApplicationAttribute"}, | ||
41 | {170, nullptr, "HasSaveDataAccessPermission"}, | ||
42 | {180, nullptr, "PushToFriendInvitationStorageChannel"}, | ||
43 | {190, nullptr, "PushToNotificationStorageChannel"}, | ||
44 | {200, nullptr, "RequestApplicationSoftReset"}, | ||
45 | {201, nullptr, "RestartApplicationTimer"}, | ||
46 | }; | ||
47 | // clang-format on | ||
48 | |||
49 | RegisterHandlers(functions); | ||
50 | } | ||
51 | |||
52 | IApplicationAccessor::~IApplicationAccessor() = default; | ||
53 | |||
54 | Result IApplicationAccessor::Start() { | ||
55 | LOG_INFO(Service_AM, "called"); | ||
56 | m_applet->process->Run(); | ||
57 | R_SUCCEED(); | ||
58 | } | ||
59 | |||
60 | Result IApplicationAccessor::RequestExit() { | ||
61 | LOG_INFO(Service_AM, "called"); | ||
62 | m_applet->message_queue.RequestExit(); | ||
63 | R_SUCCEED(); | ||
64 | } | ||
65 | |||
66 | Result IApplicationAccessor::Terminate() { | ||
67 | LOG_INFO(Service_AM, "called"); | ||
68 | m_applet->process->Terminate(); | ||
69 | R_SUCCEED(); | ||
70 | } | ||
71 | |||
72 | Result IApplicationAccessor::GetResult() { | ||
73 | LOG_INFO(Service_AM, "called"); | ||
74 | R_SUCCEED(); | ||
75 | } | ||
76 | |||
77 | Result IApplicationAccessor::GetAppletStateChangedEvent( | ||
78 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
79 | LOG_INFO(Service_AM, "called"); | ||
80 | *out_event = m_applet->caller_applet_broker->GetStateChangedEvent().GetHandle(); | ||
81 | R_SUCCEED(); | ||
82 | } | ||
83 | |||
84 | Result IApplicationAccessor::PushLaunchParameter(LaunchParameterKind kind, | ||
85 | SharedPointer<IStorage> storage) { | ||
86 | LOG_INFO(Service_AM, "called, kind={}", kind); | ||
87 | |||
88 | switch (kind) { | ||
89 | case LaunchParameterKind::AccountPreselectedUser: | ||
90 | m_applet->preselected_user_launch_parameter.push_back(storage->GetData()); | ||
91 | R_SUCCEED(); | ||
92 | default: | ||
93 | R_THROW(ResultUnknown); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | Result IApplicationAccessor::GetApplicationControlProperty( | ||
98 | OutBuffer<BufferAttr_HipcMapAlias> out_control_property) { | ||
99 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
100 | R_THROW(ResultUnknown); | ||
101 | } | ||
102 | |||
103 | Result IApplicationAccessor::SetUsers(bool enable, | ||
104 | InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids) { | ||
105 | LOG_INFO(Service_AM, "called, enable={} user_id_count={}", enable, user_ids.size()); | ||
106 | R_SUCCEED(); | ||
107 | } | ||
108 | |||
109 | Result IApplicationAccessor::GetCurrentLibraryApplet( | ||
110 | Out<SharedPointer<ILibraryAppletAccessor>> out_accessor) { | ||
111 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
112 | *out_accessor = nullptr; | ||
113 | R_SUCCEED(); | ||
114 | } | ||
115 | |||
116 | Result IApplicationAccessor::RequestForApplicationToGetForeground() { | ||
117 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
118 | R_THROW(ResultUnknown); | ||
119 | } | ||
120 | |||
121 | Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) { | ||
122 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
123 | *out_is_available = true; | ||
124 | R_SUCCEED(); | ||
125 | } | ||
126 | |||
127 | Result IApplicationAccessor::GetNsRightsEnvironmentHandle(Out<u64> out_handle) { | ||
128 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
129 | *out_handle = 0xdeadbeef; | ||
130 | R_SUCCEED(); | ||
131 | } | ||
132 | |||
133 | Result IApplicationAccessor::ReportApplicationExitTimeout() { | ||
134 | LOG_ERROR(Service_AM, "called"); | ||
135 | R_SUCCEED(); | ||
136 | } | ||
137 | |||
138 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_accessor.h b/src/core/hle/service/am/service/application_accessor.h new file mode 100755 index 000000000..39a9b2153 --- /dev/null +++ b/src/core/hle/service/am/service/application_accessor.h | |||
@@ -0,0 +1,40 @@ | |||
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 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | struct Applet; | ||
14 | class ILibraryAppletAccessor; | ||
15 | class IStorage; | ||
16 | |||
17 | class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> { | ||
18 | public: | ||
19 | explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet); | ||
20 | ~IApplicationAccessor() override; | ||
21 | |||
22 | private: | ||
23 | Result Start(); | ||
24 | Result RequestExit(); | ||
25 | Result Terminate(); | ||
26 | Result GetResult(); | ||
27 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
28 | Result PushLaunchParameter(LaunchParameterKind kind, SharedPointer<IStorage> storage); | ||
29 | Result GetApplicationControlProperty(OutBuffer<BufferAttr_HipcMapAlias> out_control_property); | ||
30 | Result SetUsers(bool enable, InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids); | ||
31 | Result GetCurrentLibraryApplet(Out<SharedPointer<ILibraryAppletAccessor>> out_accessor); | ||
32 | Result RequestForApplicationToGetForeground(); | ||
33 | Result CheckRightsEnvironmentAvailable(Out<bool> out_is_available); | ||
34 | Result GetNsRightsEnvironmentHandle(Out<u64> out_handle); | ||
35 | Result ReportApplicationExitTimeout(); | ||
36 | |||
37 | const std::shared_ptr<Applet> m_applet; | ||
38 | }; | ||
39 | |||
40 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp new file mode 100755 index 000000000..568bb0122 --- /dev/null +++ b/src/core/hle/service/am/service/application_creator.cpp | |||
@@ -0,0 +1,35 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/am_types.h" | ||
5 | #include "core/hle/service/am/applet.h" | ||
6 | #include "core/hle/service/am/applet_manager.h" | ||
7 | #include "core/hle/service/am/service/application_accessor.h" | ||
8 | #include "core/hle/service/am/service/application_creator.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | IApplicationCreator::IApplicationCreator(Core::System& system_) | ||
14 | : ServiceFramework{system_, "IApplicationCreator"} { | ||
15 | // clang-format off | ||
16 | static const FunctionInfo functions[] = { | ||
17 | {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"}, | ||
18 | {1, nullptr, "PopLaunchRequestedApplication"}, | ||
19 | {10, nullptr, "CreateSystemApplication"}, | ||
20 | {100, nullptr, "PopFloatingApplicationForDevelopment"}, | ||
21 | }; | ||
22 | // clang-format on | ||
23 | |||
24 | RegisterHandlers(functions); | ||
25 | } | ||
26 | |||
27 | IApplicationCreator::~IApplicationCreator() = default; | ||
28 | |||
29 | Result IApplicationCreator::CreateApplication( | ||
30 | Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) { | ||
31 | LOG_ERROR(Service_NS, "called, application_id={:x}", application_id); | ||
32 | R_THROW(ResultUnknown); | ||
33 | } | ||
34 | |||
35 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_creator.h b/src/core/hle/service/am/service/application_creator.h new file mode 100755 index 000000000..9f939ebf6 --- /dev/null +++ b/src/core/hle/service/am/service/application_creator.h | |||
@@ -0,0 +1,23 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | class IApplicationAccessor; | ||
12 | struct Applet; | ||
13 | |||
14 | class IApplicationCreator final : public ServiceFramework<IApplicationCreator> { | ||
15 | public: | ||
16 | explicit IApplicationCreator(Core::System& system_); | ||
17 | ~IApplicationCreator() override; | ||
18 | |||
19 | private: | ||
20 | Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id); | ||
21 | }; | ||
22 | |||
23 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp new file mode 100755 index 000000000..b788fddd4 --- /dev/null +++ b/src/core/hle/service/am/service/application_functions.cpp | |||
@@ -0,0 +1,465 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "common/settings.h" | ||
5 | #include "common/uuid.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/file_sys/savedata_factory.h" | ||
10 | #include "core/hle/kernel/k_transfer_memory.h" | ||
11 | #include "core/hle/service/am/am_results.h" | ||
12 | #include "core/hle/service/am/applet.h" | ||
13 | #include "core/hle/service/am/service/application_functions.h" | ||
14 | #include "core/hle/service/am/service/storage.h" | ||
15 | #include "core/hle/service/cmif_serialization.h" | ||
16 | #include "core/hle/service/filesystem/filesystem.h" | ||
17 | #include "core/hle/service/filesystem/save_data_controller.h" | ||
18 | #include "core/hle/service/ns/ns.h" | ||
19 | #include "core/hle/service/sm/sm.h" | ||
20 | |||
21 | namespace Service::AM { | ||
22 | |||
23 | IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet) | ||
24 | : ServiceFramework{system_, "IApplicationFunctions"}, m_applet{std::move(applet)} { | ||
25 | // clang-format off | ||
26 | static const FunctionInfo functions[] = { | ||
27 | {1, D<&IApplicationFunctions::PopLaunchParameter>, "PopLaunchParameter"}, | ||
28 | {10, nullptr, "CreateApplicationAndPushAndRequestToStart"}, | ||
29 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, | ||
30 | {12, nullptr, "CreateApplicationAndRequestToStart"}, | ||
31 | {13, nullptr, "CreateApplicationAndRequestToStartForQuest"}, | ||
32 | {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"}, | ||
33 | {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"}, | ||
34 | {20, D<&IApplicationFunctions::EnsureSaveData>, "EnsureSaveData"}, | ||
35 | {21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"}, | ||
36 | {22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"}, | ||
37 | {23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"}, | ||
38 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, | ||
39 | {25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"}, | ||
40 | {26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"}, | ||
41 | {27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"}, | ||
42 | {28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"}, | ||
43 | {29, nullptr, "GetCacheStorageMax"}, | ||
44 | {30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"}, | ||
45 | {31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"}, | ||
46 | {32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"}, | ||
47 | {33, D<&IApplicationFunctions::EndBlockingHomeButton>, "EndBlockingHomeButton"}, | ||
48 | {34, nullptr, "SelectApplicationLicense"}, | ||
49 | {35, nullptr, "GetDeviceSaveDataSizeMax"}, | ||
50 | {36, nullptr, "GetLimitedApplicationLicense"}, | ||
51 | {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, | ||
52 | {40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"}, | ||
53 | {50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"}, | ||
54 | {60, nullptr, "SetMediaPlaybackStateForApplication"}, | ||
55 | {65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"}, | ||
56 | {66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"}, | ||
57 | {67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"}, | ||
58 | {68, nullptr, "RequestFlushGamePlayingMovieForDebug"}, | ||
59 | {70, nullptr, "RequestToShutdown"}, | ||
60 | {71, nullptr, "RequestToReboot"}, | ||
61 | {72, nullptr, "RequestToSleep"}, | ||
62 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, | ||
63 | {90, D<&IApplicationFunctions::EnableApplicationCrashReport>, "EnableApplicationCrashReport"}, | ||
64 | {100, D<&IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer>, "InitializeApplicationCopyrightFrameBuffer"}, | ||
65 | {101, D<&IApplicationFunctions::SetApplicationCopyrightImage>, "SetApplicationCopyrightImage"}, | ||
66 | {102, D<&IApplicationFunctions::SetApplicationCopyrightVisibility>, "SetApplicationCopyrightVisibility"}, | ||
67 | {110, D<&IApplicationFunctions::QueryApplicationPlayStatistics>, "QueryApplicationPlayStatistics"}, | ||
68 | {111, D<&IApplicationFunctions::QueryApplicationPlayStatisticsByUid>, "QueryApplicationPlayStatisticsByUid"}, | ||
69 | {120, D<&IApplicationFunctions::ExecuteProgram>, "ExecuteProgram"}, | ||
70 | {121, D<&IApplicationFunctions::ClearUserChannel>, "ClearUserChannel"}, | ||
71 | {122, D<&IApplicationFunctions::UnpopToUserChannel>, "UnpopToUserChannel"}, | ||
72 | {123, D<&IApplicationFunctions::GetPreviousProgramIndex>, "GetPreviousProgramIndex"}, | ||
73 | {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | ||
74 | {130, D<&IApplicationFunctions::GetGpuErrorDetectedSystemEvent>, "GetGpuErrorDetectedSystemEvent"}, | ||
75 | {131, nullptr, "SetDelayTimeToAbortOnGpuError"}, | ||
76 | {140, D<&IApplicationFunctions::GetFriendInvitationStorageChannelEvent>, "GetFriendInvitationStorageChannelEvent"}, | ||
77 | {141, D<&IApplicationFunctions::TryPopFromFriendInvitationStorageChannel>, "TryPopFromFriendInvitationStorageChannel"}, | ||
78 | {150, D<&IApplicationFunctions::GetNotificationStorageChannelEvent>, "GetNotificationStorageChannelEvent"}, | ||
79 | {151, nullptr, "TryPopFromNotificationStorageChannel"}, | ||
80 | {160, D<&IApplicationFunctions::GetHealthWarningDisappearedSystemEvent>, "GetHealthWarningDisappearedSystemEvent"}, | ||
81 | {170, nullptr, "SetHdcpAuthenticationActivated"}, | ||
82 | {180, nullptr, "GetLaunchRequiredVersion"}, | ||
83 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
84 | {190, nullptr, "SendServerMaintenanceOverlayNotification"}, | ||
85 | {200, nullptr, "GetLastApplicationExitReason"}, | ||
86 | {500, nullptr, "StartContinuousRecordingFlushForDebug"}, | ||
87 | {1000, nullptr, "CreateMovieMaker"}, | ||
88 | {1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"}, | ||
89 | }; | ||
90 | // clang-format on | ||
91 | |||
92 | RegisterHandlers(functions); | ||
93 | } | ||
94 | |||
95 | IApplicationFunctions::~IApplicationFunctions() = default; | ||
96 | |||
97 | Result IApplicationFunctions::PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage, | ||
98 | LaunchParameterKind launch_parameter_kind) { | ||
99 | LOG_INFO(Service_AM, "called, kind={}", launch_parameter_kind); | ||
100 | |||
101 | std::scoped_lock lk{m_applet->lock}; | ||
102 | |||
103 | auto& channel = launch_parameter_kind == LaunchParameterKind::UserChannel | ||
104 | ? m_applet->user_channel_launch_parameter | ||
105 | : m_applet->preselected_user_launch_parameter; | ||
106 | |||
107 | if (channel.empty()) { | ||
108 | LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", | ||
109 | launch_parameter_kind); | ||
110 | R_THROW(AM::ResultNoDataInChannel); | ||
111 | } | ||
112 | |||
113 | auto data = channel.back(); | ||
114 | channel.pop_back(); | ||
115 | |||
116 | *out_storage = std::make_shared<IStorage>(system, std::move(data)); | ||
117 | R_SUCCEED(); | ||
118 | } | ||
119 | |||
120 | Result IApplicationFunctions::EnsureSaveData(Out<u64> out_size, Common::UUID user_id) { | ||
121 | LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString()); | ||
122 | |||
123 | FileSys::SaveDataAttribute attribute{}; | ||
124 | attribute.title_id = m_applet->program_id; | ||
125 | attribute.user_id = user_id.AsU128(); | ||
126 | attribute.type = FileSys::SaveDataType::SaveData; | ||
127 | |||
128 | FileSys::VirtualDir save_data{}; | ||
129 | R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( | ||
130 | &save_data, FileSys::SaveDataSpaceId::NandUser, attribute)); | ||
131 | |||
132 | *out_size = 0; | ||
133 | R_SUCCEED(); | ||
134 | } | ||
135 | |||
136 | Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) { | ||
137 | // FIXME: all of this stuff belongs to ns | ||
138 | // TODO(bunnei): This should be configurable | ||
139 | LOG_DEBUG(Service_AM, "called"); | ||
140 | |||
141 | // Get supported languages from NACP, if possible | ||
142 | // Default to 0 (all languages supported) | ||
143 | u32 supported_languages = 0; | ||
144 | |||
145 | const auto res = [this] { | ||
146 | const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(), | ||
147 | system.GetContentProvider()}; | ||
148 | auto metadata = pm.GetControlMetadata(); | ||
149 | if (metadata.first != nullptr) { | ||
150 | return metadata; | ||
151 | } | ||
152 | |||
153 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id), | ||
154 | system.GetFileSystemController(), | ||
155 | system.GetContentProvider()}; | ||
156 | return pm_update.GetControlMetadata(); | ||
157 | }(); | ||
158 | |||
159 | if (res.first != nullptr) { | ||
160 | supported_languages = res.first->GetSupportedLanguages(); | ||
161 | } | ||
162 | |||
163 | // Call IApplicationManagerInterface implementation. | ||
164 | auto& service_manager = system.ServiceManager(); | ||
165 | auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); | ||
166 | auto app_man = ns_am2->GetApplicationManagerInterface(); | ||
167 | |||
168 | // Get desired application language | ||
169 | u8 desired_language{}; | ||
170 | R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); | ||
171 | |||
172 | // Convert to settings language code. | ||
173 | R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(out_language_code, desired_language)); | ||
174 | |||
175 | LOG_DEBUG(Service_AM, "got desired_language={:016X}", *out_language_code); | ||
176 | R_SUCCEED(); | ||
177 | } | ||
178 | |||
179 | Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { | ||
180 | LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(), | ||
181 | static_cast<u32>(terminate_result.GetModule()) + 2000, | ||
182 | terminate_result.GetDescription()); | ||
183 | |||
184 | std::scoped_lock lk{m_applet->lock}; | ||
185 | m_applet->terminate_result = terminate_result; | ||
186 | |||
187 | R_SUCCEED(); | ||
188 | } | ||
189 | |||
190 | Result IApplicationFunctions::GetDisplayVersion(Out<DisplayVersion> out_display_version) { | ||
191 | LOG_DEBUG(Service_AM, "called"); | ||
192 | |||
193 | const auto res = [this] { | ||
194 | const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(), | ||
195 | system.GetContentProvider()}; | ||
196 | auto metadata = pm.GetControlMetadata(); | ||
197 | if (metadata.first != nullptr) { | ||
198 | return metadata; | ||
199 | } | ||
200 | |||
201 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id), | ||
202 | system.GetFileSystemController(), | ||
203 | system.GetContentProvider()}; | ||
204 | return pm_update.GetControlMetadata(); | ||
205 | }(); | ||
206 | |||
207 | if (res.first != nullptr) { | ||
208 | const auto& version = res.first->GetVersionString(); | ||
209 | std::memcpy(out_display_version->string.data(), version.data(), | ||
210 | std::min(version.size(), out_display_version->string.size())); | ||
211 | } else { | ||
212 | static constexpr char default_version[]{"1.0.0"}; | ||
213 | std::memcpy(out_display_version->string.data(), default_version, sizeof(default_version)); | ||
214 | } | ||
215 | |||
216 | out_display_version->string[out_display_version->string.size() - 1] = '\0'; | ||
217 | R_SUCCEED(); | ||
218 | } | ||
219 | |||
220 | Result IApplicationFunctions::ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type, | ||
221 | Common::UUID user_id, u64 normal_size, | ||
222 | u64 journal_size) { | ||
223 | LOG_DEBUG(Service_AM, "called with type={} user_id={} normal={:#x} journal={:#x}", | ||
224 | static_cast<u8>(type), user_id.FormattedString(), normal_size, journal_size); | ||
225 | |||
226 | system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize( | ||
227 | type, m_applet->program_id, user_id.AsU128(), {normal_size, journal_size}); | ||
228 | |||
229 | // The following value is used to indicate the amount of space remaining on failure | ||
230 | // due to running out of space. Since we always succeed, this should be 0. | ||
231 | *out_required_size = 0; | ||
232 | |||
233 | R_SUCCEED(); | ||
234 | } | ||
235 | |||
236 | Result IApplicationFunctions::GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size, | ||
237 | FileSys::SaveDataType type, Common::UUID user_id) { | ||
238 | LOG_DEBUG(Service_AM, "called with type={} user_id={}", type, user_id.FormattedString()); | ||
239 | |||
240 | const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize( | ||
241 | type, m_applet->program_id, user_id.AsU128()); | ||
242 | |||
243 | *out_normal_size = size.normal; | ||
244 | *out_journal_size = size.journal; | ||
245 | R_SUCCEED(); | ||
246 | } | ||
247 | |||
248 | Result IApplicationFunctions::CreateCacheStorage(Out<u32> out_target_media, | ||
249 | Out<u64> out_required_size, u16 index, | ||
250 | u64 normal_size, u64 journal_size) { | ||
251 | LOG_WARNING(Service_AM, "(STUBBED) called with index={} size={:#x} journal_size={:#x}", index, | ||
252 | normal_size, journal_size); | ||
253 | |||
254 | *out_target_media = 1; // Nand | ||
255 | *out_required_size = 0; | ||
256 | |||
257 | R_SUCCEED(); | ||
258 | } | ||
259 | |||
260 | Result IApplicationFunctions::GetSaveDataSizeMax(Out<u64> out_max_normal_size, | ||
261 | Out<u64> out_max_journal_size) { | ||
262 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
263 | |||
264 | *out_max_normal_size = 0xFFFFFFF; | ||
265 | *out_max_journal_size = 0xFFFFFFF; | ||
266 | |||
267 | R_SUCCEED(); | ||
268 | } | ||
269 | |||
270 | Result IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(s64 unused) { | ||
271 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
272 | |||
273 | std::scoped_lock lk{m_applet->lock}; | ||
274 | m_applet->home_button_long_pressed_blocked = true; | ||
275 | m_applet->home_button_short_pressed_blocked = true; | ||
276 | |||
277 | R_SUCCEED(); | ||
278 | } | ||
279 | |||
280 | Result IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed() { | ||
281 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
282 | |||
283 | std::scoped_lock lk{m_applet->lock}; | ||
284 | m_applet->home_button_long_pressed_blocked = false; | ||
285 | m_applet->home_button_short_pressed_blocked = false; | ||
286 | |||
287 | R_SUCCEED(); | ||
288 | } | ||
289 | |||
290 | Result IApplicationFunctions::BeginBlockingHomeButton(s64 timeout_ns) { | ||
291 | LOG_WARNING(Service_AM, "(STUBBED) called, timeout_ns={}", timeout_ns); | ||
292 | |||
293 | std::scoped_lock lk{m_applet->lock}; | ||
294 | m_applet->home_button_long_pressed_blocked = true; | ||
295 | m_applet->home_button_short_pressed_blocked = true; | ||
296 | m_applet->home_button_double_click_enabled = true; | ||
297 | |||
298 | R_SUCCEED(); | ||
299 | } | ||
300 | |||
301 | Result IApplicationFunctions::EndBlockingHomeButton() { | ||
302 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
303 | |||
304 | std::scoped_lock lk{m_applet->lock}; | ||
305 | m_applet->home_button_long_pressed_blocked = false; | ||
306 | m_applet->home_button_short_pressed_blocked = false; | ||
307 | m_applet->home_button_double_click_enabled = false; | ||
308 | |||
309 | R_SUCCEED(); | ||
310 | } | ||
311 | |||
312 | Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) { | ||
313 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
314 | *out_became_running = true; | ||
315 | R_SUCCEED(); | ||
316 | } | ||
317 | |||
318 | Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) { | ||
319 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
320 | *out_pseudo_device_id = {}; | ||
321 | R_SUCCEED(); | ||
322 | } | ||
323 | |||
324 | Result IApplicationFunctions::IsGamePlayRecordingSupported( | ||
325 | Out<bool> out_is_game_play_recording_supported) { | ||
326 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
327 | *out_is_game_play_recording_supported = m_applet->game_play_recording_supported; | ||
328 | R_SUCCEED(); | ||
329 | } | ||
330 | |||
331 | Result IApplicationFunctions::InitializeGamePlayRecording( | ||
332 | u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
333 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
334 | R_SUCCEED(); | ||
335 | } | ||
336 | |||
337 | Result IApplicationFunctions::SetGamePlayRecordingState( | ||
338 | GamePlayRecordingState game_play_recording_state) { | ||
339 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
340 | |||
341 | std::scoped_lock lk{m_applet->lock}; | ||
342 | m_applet->game_play_recording_state = game_play_recording_state; | ||
343 | |||
344 | R_SUCCEED(); | ||
345 | } | ||
346 | |||
347 | Result IApplicationFunctions::EnableApplicationCrashReport(bool enabled) { | ||
348 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
349 | |||
350 | std::scoped_lock lk{m_applet->lock}; | ||
351 | m_applet->application_crash_report_enabled = enabled; | ||
352 | |||
353 | R_SUCCEED(); | ||
354 | } | ||
355 | |||
356 | Result IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( | ||
357 | s32 width, s32 height, u64 transfer_memory_size, | ||
358 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
359 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
360 | R_SUCCEED(); | ||
361 | } | ||
362 | |||
363 | Result IApplicationFunctions::SetApplicationCopyrightImage( | ||
364 | s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode, | ||
365 | InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data) { | ||
366 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
367 | R_SUCCEED(); | ||
368 | } | ||
369 | |||
370 | Result IApplicationFunctions::SetApplicationCopyrightVisibility(bool visible) { | ||
371 | LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", visible); | ||
372 | R_SUCCEED(); | ||
373 | } | ||
374 | |||
375 | Result IApplicationFunctions::QueryApplicationPlayStatistics( | ||
376 | Out<s32> out_entries, | ||
377 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
378 | InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
379 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
380 | *out_entries = 0; | ||
381 | R_SUCCEED(); | ||
382 | } | ||
383 | |||
384 | Result IApplicationFunctions::QueryApplicationPlayStatisticsByUid( | ||
385 | Out<s32> out_entries, | ||
386 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
387 | Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids) { | ||
388 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
389 | *out_entries = 0; | ||
390 | R_SUCCEED(); | ||
391 | } | ||
392 | |||
393 | Result IApplicationFunctions::ExecuteProgram(ProgramSpecifyKind kind, u64 value) { | ||
394 | LOG_WARNING(Service_AM, "(STUBBED) called, kind={}, value={}", kind, value); | ||
395 | ASSERT(kind == ProgramSpecifyKind::ExecuteProgram || | ||
396 | kind == ProgramSpecifyKind::RestartProgram); | ||
397 | |||
398 | // Copy user channel ownership into the system so that it will be preserved | ||
399 | system.GetUserChannel() = m_applet->user_channel_launch_parameter; | ||
400 | system.ExecuteProgram(value); | ||
401 | R_SUCCEED(); | ||
402 | } | ||
403 | |||
404 | Result IApplicationFunctions::ClearUserChannel() { | ||
405 | LOG_DEBUG(Service_AM, "called"); | ||
406 | m_applet->user_channel_launch_parameter.clear(); | ||
407 | R_SUCCEED(); | ||
408 | } | ||
409 | |||
410 | Result IApplicationFunctions::UnpopToUserChannel(SharedPointer<IStorage> storage) { | ||
411 | LOG_DEBUG(Service_AM, "called"); | ||
412 | m_applet->user_channel_launch_parameter.push_back(storage->GetData()); | ||
413 | R_SUCCEED(); | ||
414 | } | ||
415 | |||
416 | Result IApplicationFunctions::GetPreviousProgramIndex(Out<s32> out_previous_program_index) { | ||
417 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
418 | *out_previous_program_index = m_applet->previous_program_index; | ||
419 | R_SUCCEED(); | ||
420 | } | ||
421 | |||
422 | Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent( | ||
423 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
424 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
425 | *out_event = m_applet->gpu_error_detected_event.GetHandle(); | ||
426 | R_SUCCEED(); | ||
427 | } | ||
428 | |||
429 | Result IApplicationFunctions::GetFriendInvitationStorageChannelEvent( | ||
430 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
431 | LOG_DEBUG(Service_AM, "called"); | ||
432 | *out_event = m_applet->friend_invitation_storage_channel_event.GetHandle(); | ||
433 | R_SUCCEED(); | ||
434 | } | ||
435 | |||
436 | Result IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( | ||
437 | Out<SharedPointer<IStorage>> out_storage) { | ||
438 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
439 | R_THROW(AM::ResultNoDataInChannel); | ||
440 | } | ||
441 | |||
442 | Result IApplicationFunctions::GetNotificationStorageChannelEvent( | ||
443 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
444 | LOG_DEBUG(Service_AM, "called"); | ||
445 | *out_event = m_applet->notification_storage_channel_event.GetHandle(); | ||
446 | R_SUCCEED(); | ||
447 | } | ||
448 | |||
449 | Result IApplicationFunctions::GetHealthWarningDisappearedSystemEvent( | ||
450 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
451 | LOG_DEBUG(Service_AM, "called"); | ||
452 | *out_event = m_applet->health_warning_disappeared_system_event.GetHandle(); | ||
453 | R_SUCCEED(); | ||
454 | } | ||
455 | |||
456 | Result IApplicationFunctions::PrepareForJit() { | ||
457 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
458 | |||
459 | std::scoped_lock lk{m_applet->lock}; | ||
460 | m_applet->jit_service_launched = true; | ||
461 | |||
462 | R_SUCCEED(); | ||
463 | } | ||
464 | |||
465 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h new file mode 100755 index 000000000..3548202f8 --- /dev/null +++ b/src/core/hle/service/am/service/application_functions.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 | |||
11 | namespace FileSys { | ||
12 | enum class SaveDataType : u8; | ||
13 | } | ||
14 | |||
15 | namespace Kernel { | ||
16 | class KReadableEvent; | ||
17 | } | ||
18 | |||
19 | namespace Service::AM { | ||
20 | |||
21 | struct Applet; | ||
22 | class IStorage; | ||
23 | |||
24 | class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { | ||
25 | public: | ||
26 | explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet); | ||
27 | ~IApplicationFunctions() override; | ||
28 | |||
29 | private: | ||
30 | Result PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage, | ||
31 | LaunchParameterKind launch_parameter_kind); | ||
32 | Result EnsureSaveData(Out<u64> out_size, Common::UUID user_id); | ||
33 | Result GetDesiredLanguage(Out<u64> out_language_code); | ||
34 | Result SetTerminateResult(Result terminate_result); | ||
35 | Result GetDisplayVersion(Out<DisplayVersion> out_display_version); | ||
36 | Result ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type, | ||
37 | Common::UUID user_id, u64 normal_size, u64 journal_size); | ||
38 | Result GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size, | ||
39 | FileSys::SaveDataType type, Common::UUID user_id); | ||
40 | Result CreateCacheStorage(Out<u32> out_target_media, Out<u64> out_required_size, u16 index, | ||
41 | u64 normal_size, u64 journal_size); | ||
42 | Result GetSaveDataSizeMax(Out<u64> out_max_normal_size, Out<u64> out_max_journal_size); | ||
43 | Result BeginBlockingHomeButtonShortAndLongPressed(s64 unused); | ||
44 | Result EndBlockingHomeButtonShortAndLongPressed(); | ||
45 | Result BeginBlockingHomeButton(s64 timeout_ns); | ||
46 | Result EndBlockingHomeButton(); | ||
47 | Result NotifyRunning(Out<bool> out_became_running); | ||
48 | Result GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id); | ||
49 | Result IsGamePlayRecordingSupported(Out<bool> out_is_game_play_recording_supported); | ||
50 | Result InitializeGamePlayRecording( | ||
51 | u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
52 | Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state); | ||
53 | Result EnableApplicationCrashReport(bool enabled); | ||
54 | Result InitializeApplicationCopyrightFrameBuffer( | ||
55 | s32 width, s32 height, u64 transfer_memory_size, | ||
56 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
57 | Result SetApplicationCopyrightImage( | ||
58 | s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode, | ||
59 | InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data); | ||
60 | Result SetApplicationCopyrightVisibility(bool visible); | ||
61 | Result QueryApplicationPlayStatistics( | ||
62 | Out<s32> out_entries, | ||
63 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
64 | InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
65 | Result QueryApplicationPlayStatisticsByUid( | ||
66 | Out<s32> out_entries, | ||
67 | OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics, | ||
68 | Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids); | ||
69 | Result ExecuteProgram(ProgramSpecifyKind kind, u64 value); | ||
70 | Result ClearUserChannel(); | ||
71 | Result UnpopToUserChannel(SharedPointer<IStorage> storage); | ||
72 | Result GetPreviousProgramIndex(Out<s32> out_previous_program_index); | ||
73 | Result GetGpuErrorDetectedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
74 | Result GetFriendInvitationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
75 | Result TryPopFromFriendInvitationStorageChannel(Out<SharedPointer<IStorage>> out_storage); | ||
76 | Result GetNotificationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
77 | Result GetHealthWarningDisappearedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
78 | Result PrepareForJit(); | ||
79 | |||
80 | const std::shared_ptr<Applet> m_applet; | ||
81 | }; | ||
82 | |||
83 | } // 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 new file mode 100755 index 000000000..776f4552b --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy.cpp | |||
@@ -0,0 +1,106 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
5 | #include "core/hle/service/am/service/application_functions.h" | ||
6 | #include "core/hle/service/am/service/application_proxy.h" | ||
7 | #include "core/hle/service/am/service/audio_controller.h" | ||
8 | #include "core/hle/service/am/service/common_state_getter.h" | ||
9 | #include "core/hle/service/am/service/debug_functions.h" | ||
10 | #include "core/hle/service/am/service/display_controller.h" | ||
11 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
12 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
13 | #include "core/hle/service/am/service/self_controller.h" | ||
14 | #include "core/hle/service/am/service/window_controller.h" | ||
15 | #include "core/hle/service/cmif_serialization.h" | ||
16 | |||
17 | namespace Service::AM { | ||
18 | |||
19 | IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
20 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | ||
21 | : ServiceFramework{system_, "IApplicationProxy"}, | ||
22 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
23 | // clang-format off | ||
24 | static const FunctionInfo functions[] = { | ||
25 | {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
26 | {1, D<&IApplicationProxy::GetSelfController>, "GetSelfController"}, | ||
27 | {2, D<&IApplicationProxy::GetWindowController>, "GetWindowController"}, | ||
28 | {3, D<&IApplicationProxy::GetAudioController>, "GetAudioController"}, | ||
29 | {4, D<&IApplicationProxy::GetDisplayController>, "GetDisplayController"}, | ||
30 | {10, D<&IApplicationProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
31 | {11, D<&IApplicationProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
32 | {20, D<&IApplicationProxy::GetApplicationFunctions>, "GetApplicationFunctions"}, | ||
33 | {1000, D<&IApplicationProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
34 | }; | ||
35 | // clang-format on | ||
36 | |||
37 | RegisterHandlers(functions); | ||
38 | } | ||
39 | |||
40 | IApplicationProxy::~IApplicationProxy() = default; | ||
41 | |||
42 | Result IApplicationProxy::GetAudioController( | ||
43 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
44 | LOG_DEBUG(Service_AM, "called"); | ||
45 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
46 | R_SUCCEED(); | ||
47 | } | ||
48 | |||
49 | Result IApplicationProxy::GetDisplayController( | ||
50 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
51 | LOG_DEBUG(Service_AM, "called"); | ||
52 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
53 | R_SUCCEED(); | ||
54 | } | ||
55 | |||
56 | Result IApplicationProxy::GetProcessWindingController( | ||
57 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
58 | LOG_DEBUG(Service_AM, "called"); | ||
59 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
60 | R_SUCCEED(); | ||
61 | } | ||
62 | |||
63 | Result IApplicationProxy::GetDebugFunctions( | ||
64 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
65 | LOG_DEBUG(Service_AM, "called"); | ||
66 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
67 | R_SUCCEED(); | ||
68 | } | ||
69 | |||
70 | Result IApplicationProxy::GetWindowController( | ||
71 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
72 | LOG_DEBUG(Service_AM, "called"); | ||
73 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
74 | R_SUCCEED(); | ||
75 | } | ||
76 | |||
77 | Result IApplicationProxy::GetSelfController( | ||
78 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
79 | LOG_DEBUG(Service_AM, "called"); | ||
80 | *out_self_controller = | ||
81 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
82 | R_SUCCEED(); | ||
83 | } | ||
84 | |||
85 | Result IApplicationProxy::GetCommonStateGetter( | ||
86 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
87 | LOG_DEBUG(Service_AM, "called"); | ||
88 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
89 | R_SUCCEED(); | ||
90 | } | ||
91 | |||
92 | Result IApplicationProxy::GetLibraryAppletCreator( | ||
93 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
94 | LOG_DEBUG(Service_AM, "called"); | ||
95 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
96 | R_SUCCEED(); | ||
97 | } | ||
98 | |||
99 | Result IApplicationProxy::GetApplicationFunctions( | ||
100 | Out<SharedPointer<IApplicationFunctions>> out_application_functions) { | ||
101 | LOG_DEBUG(Service_AM, "called"); | ||
102 | *out_application_functions = std::make_shared<IApplicationFunctions>(system, m_applet); | ||
103 | R_SUCCEED(); | ||
104 | } | ||
105 | |||
106 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h new file mode 100755 index 000000000..1ebc593ba --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy.h | |||
@@ -0,0 +1,48 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | class IAudioController; | ||
13 | class IApplicationFunctions; | ||
14 | class ICommonStateGetter; | ||
15 | class IDebugFunctions; | ||
16 | class IDisplayController; | ||
17 | class ILibraryAppletCreator; | ||
18 | class IProcessWindingController; | ||
19 | class ISelfController; | ||
20 | class IWindowController; | ||
21 | |||
22 | class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { | ||
23 | public: | ||
24 | explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
25 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
26 | ~IApplicationProxy(); | ||
27 | |||
28 | private: | ||
29 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
30 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
31 | Result GetProcessWindingController( | ||
32 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
33 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
34 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
35 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
36 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
37 | Result GetLibraryAppletCreator( | ||
38 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
39 | Result GetApplicationFunctions( | ||
40 | Out<SharedPointer<IApplicationFunctions>> out_application_functions); | ||
41 | |||
42 | private: | ||
43 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
44 | Kernel::KProcess* const m_process; | ||
45 | const std::shared_ptr<Applet> m_applet; | ||
46 | }; | ||
47 | |||
48 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp new file mode 100755 index 000000000..36d4478df --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy_service.cpp | |||
@@ -0,0 +1,43 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/core.h" | ||
5 | #include "core/hle/service/am/am.h" | ||
6 | #include "core/hle/service/am/applet_manager.h" | ||
7 | #include "core/hle/service/am/service/application_proxy.h" | ||
8 | #include "core/hle/service/am/service/application_proxy_service.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | IApplicationProxyService::IApplicationProxyService(Core::System& system_, | ||
14 | Nvnflinger::Nvnflinger& nvnflinger) | ||
15 | : ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} { | ||
16 | static const FunctionInfo functions[] = { | ||
17 | {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, | ||
18 | }; | ||
19 | RegisterHandlers(functions); | ||
20 | } | ||
21 | |||
22 | IApplicationProxyService::~IApplicationProxyService() = default; | ||
23 | |||
24 | Result IApplicationProxyService::OpenApplicationProxy( | ||
25 | Out<SharedPointer<IApplicationProxy>> out_application_proxy, ClientProcessId pid, | ||
26 | InCopyHandle<Kernel::KProcess> process_handle) { | ||
27 | LOG_DEBUG(Service_AM, "called"); | ||
28 | |||
29 | if (const auto applet = this->GetAppletFromProcessId(pid)) { | ||
30 | *out_application_proxy = | ||
31 | std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger); | ||
32 | R_SUCCEED(); | ||
33 | } else { | ||
34 | UNIMPLEMENTED(); | ||
35 | R_THROW(ResultUnknown); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { | ||
40 | return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); | ||
41 | } | ||
42 | |||
43 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h new file mode 100755 index 000000000..1c1d32d0b --- /dev/null +++ b/src/core/hle/service/am/service/application_proxy_service.h | |||
@@ -0,0 +1,35 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service { | ||
10 | |||
11 | namespace Nvnflinger { | ||
12 | class Nvnflinger; | ||
13 | } | ||
14 | |||
15 | namespace AM { | ||
16 | |||
17 | struct Applet; | ||
18 | class IApplicationProxy; | ||
19 | |||
20 | class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { | ||
21 | public: | ||
22 | explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); | ||
23 | ~IApplicationProxyService() override; | ||
24 | |||
25 | private: | ||
26 | Result OpenApplicationProxy(Out<SharedPointer<IApplicationProxy>> out_application_proxy, | ||
27 | ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle); | ||
28 | |||
29 | private: | ||
30 | std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); | ||
31 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
32 | }; | ||
33 | |||
34 | } // namespace AM | ||
35 | } // namespace Service | ||
diff --git a/src/core/hle/service/am/service/audio_controller.cpp b/src/core/hle/service/am/service/audio_controller.cpp new file mode 100755 index 000000000..ad731c7bd --- /dev/null +++ b/src/core/hle/service/am/service/audio_controller.cpp | |||
@@ -0,0 +1,69 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/audio_controller.h" | ||
5 | #include "core/hle/service/cmif_serialization.h" | ||
6 | |||
7 | namespace Service::AM { | ||
8 | |||
9 | IAudioController::IAudioController(Core::System& system_) | ||
10 | : ServiceFramework{system_, "IAudioController"} { | ||
11 | // clang-format off | ||
12 | static const FunctionInfo functions[] = { | ||
13 | {0, D<&IAudioController::SetExpectedMasterVolume>, "SetExpectedMasterVolume"}, | ||
14 | {1, D<&IAudioController::GetMainAppletExpectedMasterVolume>, "GetMainAppletExpectedMasterVolume"}, | ||
15 | {2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"}, | ||
16 | {3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"}, | ||
17 | {4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"}, | ||
18 | }; | ||
19 | // clang-format on | ||
20 | |||
21 | RegisterHandlers(functions); | ||
22 | } | ||
23 | |||
24 | IAudioController::~IAudioController() = default; | ||
25 | |||
26 | Result IAudioController::SetExpectedMasterVolume(f32 main_applet_volume, | ||
27 | f32 library_applet_volume) { | ||
28 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}", | ||
29 | main_applet_volume, library_applet_volume); | ||
30 | |||
31 | // Ensure the volume values remain within the 0-100% range | ||
32 | m_main_applet_volume = std::clamp(main_applet_volume, MinAllowedVolume, MaxAllowedVolume); | ||
33 | m_library_applet_volume = std::clamp(library_applet_volume, MinAllowedVolume, MaxAllowedVolume); | ||
34 | |||
35 | R_SUCCEED(); | ||
36 | } | ||
37 | |||
38 | Result IAudioController::GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume) { | ||
39 | LOG_DEBUG(Service_AM, "called. main_applet_volume={}", m_main_applet_volume); | ||
40 | *out_main_applet_volume = m_main_applet_volume; | ||
41 | R_SUCCEED(); | ||
42 | } | ||
43 | |||
44 | Result IAudioController::GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume) { | ||
45 | LOG_DEBUG(Service_AM, "called. library_applet_volume={}", m_library_applet_volume); | ||
46 | *out_library_applet_volume = m_library_applet_volume; | ||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
50 | Result IAudioController::ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns) { | ||
51 | LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", volume, fade_time_ns); | ||
52 | |||
53 | m_main_applet_volume = std::clamp(volume, MinAllowedVolume, MaxAllowedVolume); | ||
54 | m_fade_time_ns = std::chrono::nanoseconds{fade_time_ns}; | ||
55 | |||
56 | R_SUCCEED(); | ||
57 | } | ||
58 | |||
59 | Result IAudioController::SetTransparentVolumeRate(f32 transparent_volume_rate) { | ||
60 | LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate); | ||
61 | |||
62 | // Clamp volume range to 0-100%. | ||
63 | m_transparent_volume_rate = | ||
64 | std::clamp(transparent_volume_rate, MinAllowedVolume, MaxAllowedVolume); | ||
65 | |||
66 | R_SUCCEED(); | ||
67 | } | ||
68 | |||
69 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/audio_controller.h b/src/core/hle/service/am/service/audio_controller.h new file mode 100755 index 000000000..4b0f3f9ae --- /dev/null +++ b/src/core/hle/service/am/service/audio_controller.h | |||
@@ -0,0 +1,37 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | class IAudioController final : public ServiceFramework<IAudioController> { | ||
12 | public: | ||
13 | explicit IAudioController(Core::System& system_); | ||
14 | ~IAudioController() override; | ||
15 | |||
16 | private: | ||
17 | Result SetExpectedMasterVolume(f32 main_applet_volume, f32 library_applet_volume); | ||
18 | Result GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume); | ||
19 | Result GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume); | ||
20 | Result ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns); | ||
21 | Result SetTransparentVolumeRate(f32 transparent_volume_rate); | ||
22 | |||
23 | static constexpr float MinAllowedVolume = 0.0f; | ||
24 | static constexpr float MaxAllowedVolume = 1.0f; | ||
25 | |||
26 | float m_main_applet_volume{0.25f}; | ||
27 | float m_library_applet_volume{MaxAllowedVolume}; | ||
28 | float m_transparent_volume_rate{MinAllowedVolume}; | ||
29 | |||
30 | // Volume transition fade time in nanoseconds. | ||
31 | // e.g. If the main applet volume was 0% and was changed to 50% | ||
32 | // with a fade of 50ns, then over the course of 50ns, | ||
33 | // the volume will gradually fade up to 50% | ||
34 | std::chrono::nanoseconds m_fade_time_ns{0}; | ||
35 | }; | ||
36 | |||
37 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp new file mode 100755 index 000000000..12d7e8cb1 --- /dev/null +++ b/src/core/hle/service/am/service/common_state_getter.cpp | |||
@@ -0,0 +1,277 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "common/settings.h" | ||
5 | #include "core/hle/service/am/am_results.h" | ||
6 | #include "core/hle/service/am/applet.h" | ||
7 | #include "core/hle/service/am/service/common_state_getter.h" | ||
8 | #include "core/hle/service/am/service/lock_accessor.h" | ||
9 | #include "core/hle/service/apm/apm_interface.h" | ||
10 | #include "core/hle/service/cmif_serialization.h" | ||
11 | #include "core/hle/service/pm/pm.h" | ||
12 | #include "core/hle/service/sm/sm.h" | ||
13 | #include "core/hle/service/vi/vi.h" | ||
14 | |||
15 | namespace Service::AM { | ||
16 | |||
17 | ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet) | ||
18 | : ServiceFramework{system_, "ICommonStateGetter"}, m_applet{std::move(applet)} { | ||
19 | // clang-format off | ||
20 | static const FunctionInfo functions[] = { | ||
21 | {0, D<&ICommonStateGetter::GetEventHandle>, "GetEventHandle"}, | ||
22 | {1, D<&ICommonStateGetter::ReceiveMessage>, "ReceiveMessage"}, | ||
23 | {2, nullptr, "GetThisAppletKind"}, | ||
24 | {3, nullptr, "AllowToEnterSleep"}, | ||
25 | {4, nullptr, "DisallowToEnterSleep"}, | ||
26 | {5, D<&ICommonStateGetter::GetOperationMode>, "GetOperationMode"}, | ||
27 | {6, D<&ICommonStateGetter::GetPerformanceMode>, "GetPerformanceMode"}, | ||
28 | {7, nullptr, "GetCradleStatus"}, | ||
29 | {8, D<&ICommonStateGetter::GetBootMode>, "GetBootMode"}, | ||
30 | {9, D<&ICommonStateGetter::GetCurrentFocusState>, "GetCurrentFocusState"}, | ||
31 | {10, D<&ICommonStateGetter::RequestToAcquireSleepLock>, "RequestToAcquireSleepLock"}, | ||
32 | {11, nullptr, "ReleaseSleepLock"}, | ||
33 | {12, nullptr, "ReleaseSleepLockTransiently"}, | ||
34 | {13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"}, | ||
35 | {14, nullptr, "GetWakeupCount"}, | ||
36 | {20, nullptr, "PushToGeneralChannel"}, | ||
37 | {30, nullptr, "GetHomeButtonReaderLockAccessor"}, | ||
38 | {31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"}, | ||
39 | {32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"}, | ||
40 | {40, nullptr, "GetCradleFwVersion"}, | ||
41 | {50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled"}, | ||
42 | {51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled"}, | ||
43 | {52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled"}, | ||
44 | {53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx"}, | ||
45 | {54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx"}, | ||
46 | {55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection"}, | ||
47 | {59, nullptr, "SetVrPositionForDebug"}, | ||
48 | {60, D<&ICommonStateGetter::GetDefaultDisplayResolution>, "GetDefaultDisplayResolution"}, | ||
49 | {61, D<&ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent>, "GetDefaultDisplayResolutionChangeEvent"}, | ||
50 | {62, nullptr, "GetHdcpAuthenticationState"}, | ||
51 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, | ||
52 | {64, nullptr, "SetTvPowerStateMatchingMode"}, | ||
53 | {65, nullptr, "GetApplicationIdByContentActionName"}, | ||
54 | {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, | ||
55 | {67, nullptr, "CancelCpuBoostMode"}, | ||
56 | {68, D<&ICommonStateGetter::GetBuiltInDisplayType>, "GetBuiltInDisplayType"}, | ||
57 | {80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"}, | ||
58 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | ||
59 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | ||
60 | {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"}, | ||
61 | {110, nullptr, "OpenMyGpuErrorHandler"}, | ||
62 | {120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"}, | ||
63 | {200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"}, | ||
64 | {300, D<&ICommonStateGetter::GetSettingsPlatformRegion>, "GetSettingsPlatformRegion"}, | ||
65 | {400, nullptr, "ActivateMigrationService"}, | ||
66 | {401, nullptr, "DeactivateMigrationService"}, | ||
67 | {500, nullptr, "DisableSleepTillShutdown"}, | ||
68 | {501, nullptr, "SuppressDisablingSleepTemporarily"}, | ||
69 | {502, nullptr, "IsSleepEnabled"}, | ||
70 | {503, nullptr, "IsDisablingSleepSuppressed"}, | ||
71 | {900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, | ||
72 | }; | ||
73 | // clang-format on | ||
74 | |||
75 | RegisterHandlers(functions); | ||
76 | } | ||
77 | |||
78 | ICommonStateGetter::~ICommonStateGetter() = default; | ||
79 | |||
80 | Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
81 | LOG_DEBUG(Service_AM, "called"); | ||
82 | *out_event = &m_applet->message_queue.GetMessageReceiveEvent(); | ||
83 | R_SUCCEED(); | ||
84 | } | ||
85 | |||
86 | Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) { | ||
87 | LOG_DEBUG(Service_AM, "called"); | ||
88 | |||
89 | *out_applet_message = m_applet->message_queue.PopMessage(); | ||
90 | if (*out_applet_message == AppletMessage::None) { | ||
91 | LOG_ERROR(Service_AM, "Tried to pop message but none was available!"); | ||
92 | R_THROW(AM::ResultNoMessages); | ||
93 | } | ||
94 | |||
95 | R_SUCCEED(); | ||
96 | } | ||
97 | |||
98 | Result ICommonStateGetter::GetCurrentFocusState(Out<FocusState> out_focus_state) { | ||
99 | LOG_DEBUG(Service_AM, "called"); | ||
100 | |||
101 | std::scoped_lock lk{m_applet->lock}; | ||
102 | *out_focus_state = m_applet->focus_state; | ||
103 | |||
104 | R_SUCCEED(); | ||
105 | } | ||
106 | |||
107 | Result ICommonStateGetter::RequestToAcquireSleepLock() { | ||
108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
109 | |||
110 | // Sleep lock is acquired immediately. | ||
111 | m_applet->sleep_lock_event.Signal(); | ||
112 | R_SUCCEED(); | ||
113 | } | ||
114 | |||
115 | Result ICommonStateGetter::GetAcquiredSleepLockEvent( | ||
116 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
117 | LOG_WARNING(Service_AM, "called"); | ||
118 | *out_event = m_applet->sleep_lock_event.GetHandle(); | ||
119 | R_SUCCEED(); | ||
120 | } | ||
121 | |||
122 | Result ICommonStateGetter::GetReaderLockAccessorEx( | ||
123 | Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) { | ||
124 | LOG_INFO(Service_AM, "called, button_type={}", button_type); | ||
125 | *out_lock_accessor = std::make_shared<ILockAccessor>(system); | ||
126 | R_SUCCEED(); | ||
127 | } | ||
128 | |||
129 | Result ICommonStateGetter::GetWriterLockAccessorEx( | ||
130 | Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) { | ||
131 | LOG_INFO(Service_AM, "called, button_type={}", button_type); | ||
132 | *out_lock_accessor = std::make_shared<ILockAccessor>(system); | ||
133 | R_SUCCEED(); | ||
134 | } | ||
135 | |||
136 | Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent( | ||
137 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
138 | LOG_DEBUG(Service_AM, "called"); | ||
139 | *out_event = &m_applet->message_queue.GetOperationModeChangedEvent(); | ||
140 | R_SUCCEED(); | ||
141 | } | ||
142 | |||
143 | Result ICommonStateGetter::GetOperationMode(Out<OperationMode> out_operation_mode) { | ||
144 | const bool use_docked_mode{Settings::IsDockedMode()}; | ||
145 | LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); | ||
146 | *out_operation_mode = use_docked_mode ? OperationMode::Docked : OperationMode::Handheld; | ||
147 | R_SUCCEED(); | ||
148 | } | ||
149 | |||
150 | Result ICommonStateGetter::GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode) { | ||
151 | LOG_DEBUG(Service_AM, "called"); | ||
152 | *out_performance_mode = system.GetAPMController().GetCurrentPerformanceMode(); | ||
153 | R_SUCCEED(); | ||
154 | } | ||
155 | |||
156 | Result ICommonStateGetter::GetBootMode(Out<PM::SystemBootMode> out_boot_mode) { | ||
157 | LOG_DEBUG(Service_AM, "called"); | ||
158 | *out_boot_mode = Service::PM::SystemBootMode::Normal; | ||
159 | R_SUCCEED(); | ||
160 | } | ||
161 | |||
162 | Result ICommonStateGetter::IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled) { | ||
163 | LOG_DEBUG(Service_AM, "called"); | ||
164 | |||
165 | std::scoped_lock lk{m_applet->lock}; | ||
166 | *out_is_vr_mode_enabled = m_applet->vr_mode_enabled; | ||
167 | R_SUCCEED(); | ||
168 | } | ||
169 | |||
170 | Result ICommonStateGetter::SetVrModeEnabled(bool is_vr_mode_enabled) { | ||
171 | std::scoped_lock lk{m_applet->lock}; | ||
172 | m_applet->vr_mode_enabled = is_vr_mode_enabled; | ||
173 | LOG_WARNING(Service_AM, "VR Mode is {}", m_applet->vr_mode_enabled ? "on" : "off"); | ||
174 | R_SUCCEED(); | ||
175 | } | ||
176 | |||
177 | Result ICommonStateGetter::SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled) { | ||
178 | LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}", | ||
179 | is_lcd_backlight_off_enabled); | ||
180 | R_SUCCEED(); | ||
181 | } | ||
182 | |||
183 | Result ICommonStateGetter::BeginVrModeEx() { | ||
184 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
185 | std::scoped_lock lk{m_applet->lock}; | ||
186 | m_applet->vr_mode_enabled = true; | ||
187 | R_SUCCEED(); | ||
188 | } | ||
189 | |||
190 | Result ICommonStateGetter::EndVrModeEx() { | ||
191 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
192 | std::scoped_lock lk{m_applet->lock}; | ||
193 | m_applet->vr_mode_enabled = false; | ||
194 | R_SUCCEED(); | ||
195 | } | ||
196 | |||
197 | Result ICommonStateGetter::IsInControllerFirmwareUpdateSection( | ||
198 | Out<bool> out_is_in_controller_firmware_update_section) { | ||
199 | LOG_INFO(Service_AM, "called"); | ||
200 | *out_is_in_controller_firmware_update_section = false; | ||
201 | R_SUCCEED(); | ||
202 | } | ||
203 | |||
204 | Result ICommonStateGetter::GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height) { | ||
205 | LOG_DEBUG(Service_AM, "called"); | ||
206 | |||
207 | if (Settings::IsDockedMode()) { | ||
208 | *out_width = static_cast<u32>(Service::VI::DisplayResolution::DockedWidth); | ||
209 | *out_height = static_cast<u32>(Service::VI::DisplayResolution::DockedHeight); | ||
210 | } else { | ||
211 | *out_width = static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth); | ||
212 | *out_height = static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight); | ||
213 | } | ||
214 | |||
215 | R_SUCCEED(); | ||
216 | } | ||
217 | |||
218 | void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) { | ||
219 | LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS"); | ||
220 | |||
221 | const auto& sm = system.ServiceManager(); | ||
222 | const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys"); | ||
223 | ASSERT(apm_sys != nullptr); | ||
224 | |||
225 | apm_sys->SetCpuBoostMode(ctx); | ||
226 | } | ||
227 | |||
228 | Result ICommonStateGetter::GetBuiltInDisplayType(Out<s32> out_display_type) { | ||
229 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
230 | *out_display_type = 0; | ||
231 | R_SUCCEED(); | ||
232 | } | ||
233 | |||
234 | Result ICommonStateGetter::PerformSystemButtonPressingIfInFocus(SystemButtonType type) { | ||
235 | LOG_WARNING(Service_AM, "(STUBBED) called, type={}", type); | ||
236 | R_SUCCEED(); | ||
237 | } | ||
238 | |||
239 | Result ICommonStateGetter::GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info) { | ||
240 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
241 | *out_operation_mode_system_info = 0; | ||
242 | R_SUCCEED(); | ||
243 | } | ||
244 | |||
245 | Result ICommonStateGetter::GetAppletLaunchedHistory( | ||
246 | Out<s32> out_count, OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids) { | ||
247 | LOG_INFO(Service_AM, "called"); | ||
248 | |||
249 | std::shared_ptr<Applet> current_applet = m_applet; | ||
250 | |||
251 | for (*out_count = 0; | ||
252 | *out_count < static_cast<s32>(out_applet_ids.size()) && current_applet != nullptr; | ||
253 | /* ... */) { | ||
254 | out_applet_ids[(*out_count)++] = current_applet->applet_id; | ||
255 | current_applet = current_applet->caller_applet.lock(); | ||
256 | } | ||
257 | |||
258 | R_SUCCEED(); | ||
259 | } | ||
260 | |||
261 | Result ICommonStateGetter::GetSettingsPlatformRegion( | ||
262 | Out<SysPlatformRegion> out_settings_platform_region) { | ||
263 | LOG_INFO(Service_AM, "called"); | ||
264 | *out_settings_platform_region = SysPlatformRegion::Global; | ||
265 | R_SUCCEED(); | ||
266 | } | ||
267 | |||
268 | Result ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled() { | ||
269 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
270 | |||
271 | std::scoped_lock lk{m_applet->lock}; | ||
272 | m_applet->request_exit_to_library_applet_at_execute_next_program_enabled = true; | ||
273 | |||
274 | R_SUCCEED(); | ||
275 | } | ||
276 | |||
277 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h new file mode 100755 index 000000000..5a8dca3d6 --- /dev/null +++ b/src/core/hle/service/am/service/common_state_getter.h | |||
@@ -0,0 +1,61 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/am/am_types.h" | ||
7 | #include "core/hle/service/apm/apm_controller.h" | ||
8 | #include "core/hle/service/cmif_types.h" | ||
9 | #include "core/hle/service/pm/pm.h" | ||
10 | #include "core/hle/service/service.h" | ||
11 | |||
12 | namespace Kernel { | ||
13 | class KReadableEvent; | ||
14 | } | ||
15 | |||
16 | namespace Service::AM { | ||
17 | |||
18 | struct Applet; | ||
19 | class ILockAccessor; | ||
20 | |||
21 | class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { | ||
22 | public: | ||
23 | explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
24 | ~ICommonStateGetter() override; | ||
25 | |||
26 | private: | ||
27 | Result GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
28 | Result ReceiveMessage(Out<AppletMessage> out_applet_message); | ||
29 | Result GetCurrentFocusState(Out<FocusState> out_focus_state); | ||
30 | Result RequestToAcquireSleepLock(); | ||
31 | Result GetAcquiredSleepLockEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
32 | Result GetReaderLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor, | ||
33 | u32 button_type); | ||
34 | Result GetWriterLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor, | ||
35 | u32 button_type); | ||
36 | Result GetDefaultDisplayResolutionChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
37 | Result GetOperationMode(Out<OperationMode> out_operation_mode); | ||
38 | Result GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode); | ||
39 | Result GetBootMode(Out<PM::SystemBootMode> out_boot_mode); | ||
40 | Result IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled); | ||
41 | Result SetVrModeEnabled(bool is_vr_mode_enabled); | ||
42 | Result SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled); | ||
43 | Result BeginVrModeEx(); | ||
44 | Result EndVrModeEx(); | ||
45 | Result IsInControllerFirmwareUpdateSection( | ||
46 | Out<bool> out_is_in_controller_firmware_update_section); | ||
47 | Result GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height); | ||
48 | Result GetBuiltInDisplayType(Out<s32> out_display_type); | ||
49 | Result PerformSystemButtonPressingIfInFocus(SystemButtonType type); | ||
50 | Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info); | ||
51 | Result GetAppletLaunchedHistory(Out<s32> out_count, | ||
52 | OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); | ||
53 | Result GetSettingsPlatformRegion(Out<SysPlatformRegion> out_settings_platform_region); | ||
54 | Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); | ||
55 | |||
56 | void SetCpuBoostMode(HLERequestContext& ctx); | ||
57 | |||
58 | const std::shared_ptr<Applet> m_applet; | ||
59 | }; | ||
60 | |||
61 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.cpp b/src/core/hle/service/am/service/cradle_firmware_updater.cpp new file mode 100755 index 000000000..0a8af0858 --- /dev/null +++ b/src/core/hle/service/am/service/cradle_firmware_updater.cpp | |||
@@ -0,0 +1,52 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/cradle_firmware_updater.h" | ||
5 | #include "core/hle/service/cmif_serialization.h" | ||
6 | |||
7 | namespace Service::AM { | ||
8 | |||
9 | ICradleFirmwareUpdater::ICradleFirmwareUpdater(Core::System& system_) | ||
10 | : ServiceFramework{system_, "ICradleFirmwareUpdater"}, | ||
11 | m_context{system, "ICradleFirmwareUpdater"}, m_cradle_device_info_event{m_context} { | ||
12 | // clang-format off | ||
13 | static const FunctionInfo functions[] = { | ||
14 | {0, D<&ICradleFirmwareUpdater::StartUpdate>, "StartUpdate"}, | ||
15 | {1, D<&ICradleFirmwareUpdater::FinishUpdate>, "FinishUpdate"}, | ||
16 | {2, D<&ICradleFirmwareUpdater::GetCradleDeviceInfo>, "GetCradleDeviceInfo"}, | ||
17 | {3, D<&ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent>, "GetCradleDeviceInfoChangeEvent"}, | ||
18 | {4, nullptr, "GetUpdateProgressInfo"}, | ||
19 | {5, nullptr, "GetLastInternalResult"}, | ||
20 | |||
21 | }; | ||
22 | // clang-format on | ||
23 | |||
24 | RegisterHandlers(functions); | ||
25 | } | ||
26 | |||
27 | ICradleFirmwareUpdater::~ICradleFirmwareUpdater() = default; | ||
28 | |||
29 | Result ICradleFirmwareUpdater::StartUpdate() { | ||
30 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
31 | R_SUCCEED(); | ||
32 | } | ||
33 | |||
34 | Result ICradleFirmwareUpdater::FinishUpdate() { | ||
35 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
36 | R_SUCCEED(); | ||
37 | } | ||
38 | |||
39 | Result ICradleFirmwareUpdater::GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info) { | ||
40 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
41 | *out_cradle_device_info = {}; | ||
42 | R_SUCCEED(); | ||
43 | } | ||
44 | |||
45 | Result ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent( | ||
46 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
47 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
48 | *out_event = m_cradle_device_info_event.GetHandle(); | ||
49 | R_SUCCEED(); | ||
50 | } | ||
51 | |||
52 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.h b/src/core/hle/service/am/service/cradle_firmware_updater.h new file mode 100755 index 000000000..3e803f0ae --- /dev/null +++ b/src/core/hle/service/am/service/cradle_firmware_updater.h | |||
@@ -0,0 +1,37 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/kernel_helpers.h" | ||
8 | #include "core/hle/service/os/event.h" | ||
9 | #include "core/hle/service/service.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | struct CradleDeviceInfo { | ||
14 | bool unknown0; | ||
15 | bool unknown1; | ||
16 | bool unknown2; | ||
17 | u64 unknown3; | ||
18 | }; | ||
19 | static_assert(sizeof(CradleDeviceInfo) == 0x10, "CradleDeviceInfo has incorrect size"); | ||
20 | |||
21 | class ICradleFirmwareUpdater final : public ServiceFramework<ICradleFirmwareUpdater> { | ||
22 | public: | ||
23 | explicit ICradleFirmwareUpdater(Core::System& system_); | ||
24 | ~ICradleFirmwareUpdater() override; | ||
25 | |||
26 | private: | ||
27 | Result StartUpdate(); | ||
28 | Result FinishUpdate(); | ||
29 | Result GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info); | ||
30 | Result GetCradleDeviceInfoChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
31 | |||
32 | private: | ||
33 | KernelHelpers::ServiceContext m_context; | ||
34 | Event m_cradle_device_info_event; | ||
35 | }; | ||
36 | |||
37 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/debug_functions.cpp b/src/core/hle/service/am/service/debug_functions.cpp new file mode 100755 index 000000000..fcac4776d --- /dev/null +++ b/src/core/hle/service/am/service/debug_functions.cpp | |||
@@ -0,0 +1,43 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/debug_functions.h" | ||
5 | |||
6 | namespace Service::AM { | ||
7 | |||
8 | IDebugFunctions::IDebugFunctions(Core::System& system_) | ||
9 | : ServiceFramework{system_, "IDebugFunctions"} { | ||
10 | // clang-format off | ||
11 | static const FunctionInfo functions[] = { | ||
12 | {0, nullptr, "NotifyMessageToHomeMenuForDebug"}, | ||
13 | {1, nullptr, "OpenMainApplication"}, | ||
14 | {10, nullptr, "PerformSystemButtonPressing"}, | ||
15 | {20, nullptr, "InvalidateTransitionLayer"}, | ||
16 | {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, | ||
17 | {31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"}, | ||
18 | {40, nullptr, "GetAppletResourceUsageInfo"}, | ||
19 | {50, nullptr, "AddSystemProgramIdAndAppletIdForDebug"}, | ||
20 | {51, nullptr, "AddOperationConfirmedLibraryAppletIdForDebug"}, | ||
21 | {100, nullptr, "SetCpuBoostModeForApplet"}, | ||
22 | {101, nullptr, "CancelCpuBoostModeForApplet"}, | ||
23 | {110, nullptr, "PushToAppletBoundChannelForDebug"}, | ||
24 | {111, nullptr, "TryPopFromAppletBoundChannelForDebug"}, | ||
25 | {120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"}, | ||
26 | {121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"}, | ||
27 | {122, nullptr, "AlarmSettingNotificationPushAppEventNotify"}, | ||
28 | {130, nullptr, "FriendInvitationSetApplicationParameter"}, | ||
29 | {131, nullptr, "FriendInvitationClearApplicationParameter"}, | ||
30 | {132, nullptr, "FriendInvitationPushApplicationParameter"}, | ||
31 | {140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"}, | ||
32 | {200, nullptr, "CreateFloatingLibraryAppletAccepterForDebug"}, | ||
33 | {300, nullptr, "TerminateAllRunningApplicationsForDebug"}, | ||
34 | {900, nullptr, "GetGrcProcessLaunchedSystemEvent"}, | ||
35 | }; | ||
36 | // clang-format on | ||
37 | |||
38 | RegisterHandlers(functions); | ||
39 | } | ||
40 | |||
41 | IDebugFunctions::~IDebugFunctions() = default; | ||
42 | |||
43 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/debug_functions.h b/src/core/hle/service/am/service/debug_functions.h new file mode 100755 index 000000000..d55968743 --- /dev/null +++ b/src/core/hle/service/am/service/debug_functions.h | |||
@@ -0,0 +1,16 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/service.h" | ||
7 | |||
8 | namespace Service::AM { | ||
9 | |||
10 | class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { | ||
11 | public: | ||
12 | explicit IDebugFunctions(Core::System& system_); | ||
13 | ~IDebugFunctions() override; | ||
14 | }; | ||
15 | |||
16 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/display_controller.cpp b/src/core/hle/service/am/service/display_controller.cpp new file mode 100755 index 000000000..249c73dfb --- /dev/null +++ b/src/core/hle/service/am/service/display_controller.cpp | |||
@@ -0,0 +1,105 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/result.h" | ||
5 | #include "core/hle/service/am/applet.h" | ||
6 | #include "core/hle/service/am/service/display_controller.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_) | ||
12 | : ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) { | ||
13 | // clang-format off | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, nullptr, "GetLastForegroundCaptureImage"}, | ||
16 | {1, nullptr, "UpdateLastForegroundCaptureImage"}, | ||
17 | {2, nullptr, "GetLastApplicationCaptureImage"}, | ||
18 | {3, nullptr, "GetCallerAppletCaptureImage"}, | ||
19 | {4, nullptr, "UpdateCallerAppletCaptureImage"}, | ||
20 | {5, nullptr, "GetLastForegroundCaptureImageEx"}, | ||
21 | {6, nullptr, "GetLastApplicationCaptureImageEx"}, | ||
22 | {7, D<&IDisplayController::GetCallerAppletCaptureImageEx>, "GetCallerAppletCaptureImageEx"}, | ||
23 | {8, D<&IDisplayController::TakeScreenShotOfOwnLayer>, "TakeScreenShotOfOwnLayer"}, | ||
24 | {9, nullptr, "CopyBetweenCaptureBuffers"}, | ||
25 | {10, nullptr, "AcquireLastApplicationCaptureBuffer"}, | ||
26 | {11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, | ||
27 | {12, nullptr, "AcquireLastForegroundCaptureBuffer"}, | ||
28 | {13, nullptr, "ReleaseLastForegroundCaptureBuffer"}, | ||
29 | {14, nullptr, "AcquireCallerAppletCaptureBuffer"}, | ||
30 | {15, nullptr, "ReleaseCallerAppletCaptureBuffer"}, | ||
31 | {16, nullptr, "AcquireLastApplicationCaptureBufferEx"}, | ||
32 | {17, nullptr, "AcquireLastForegroundCaptureBufferEx"}, | ||
33 | {18, nullptr, "AcquireCallerAppletCaptureBufferEx"}, | ||
34 | {20, D<&IDisplayController::ClearCaptureBuffer>, "ClearCaptureBuffer"}, | ||
35 | {21, nullptr, "ClearAppletTransitionBuffer"}, | ||
36 | {22, D<&IDisplayController::AcquireLastApplicationCaptureSharedBuffer>, "AcquireLastApplicationCaptureSharedBuffer"}, | ||
37 | {23, D<&IDisplayController::ReleaseLastApplicationCaptureSharedBuffer>, "ReleaseLastApplicationCaptureSharedBuffer"}, | ||
38 | {24, D<&IDisplayController::AcquireLastForegroundCaptureSharedBuffer>, "AcquireLastForegroundCaptureSharedBuffer"}, | ||
39 | {25, D<&IDisplayController::ReleaseLastForegroundCaptureSharedBuffer>, "ReleaseLastForegroundCaptureSharedBuffer"}, | ||
40 | {26, D<&IDisplayController::AcquireCallerAppletCaptureSharedBuffer>, "AcquireCallerAppletCaptureSharedBuffer"}, | ||
41 | {27, D<&IDisplayController::ReleaseCallerAppletCaptureSharedBuffer>, "ReleaseCallerAppletCaptureSharedBuffer"}, | ||
42 | {28, nullptr, "TakeScreenShotOfOwnLayerEx"}, | ||
43 | }; | ||
44 | // clang-format on | ||
45 | |||
46 | RegisterHandlers(functions); | ||
47 | } | ||
48 | |||
49 | IDisplayController::~IDisplayController() = default; | ||
50 | |||
51 | Result IDisplayController::GetCallerAppletCaptureImageEx( | ||
52 | Out<bool> out_was_written, OutBuffer<BufferAttr_HipcMapAlias> out_image_data) { | ||
53 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
54 | *out_was_written = true; | ||
55 | R_SUCCEED(); | ||
56 | } | ||
57 | |||
58 | Result IDisplayController::TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index) { | ||
59 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
60 | R_SUCCEED(); | ||
61 | } | ||
62 | |||
63 | Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color) { | ||
64 | LOG_WARNING(Service_AM, "(STUBBED) called, unknown0={} fbshare_layer_index={} color={:#x}", | ||
65 | unknown0, fbshare_layer_index, color); | ||
66 | R_SUCCEED(); | ||
67 | } | ||
68 | |||
69 | Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( | ||
70 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
71 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
72 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
73 | out_fbshare_layer_index)); | ||
74 | } | ||
75 | |||
76 | Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() { | ||
77 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
78 | R_SUCCEED(); | ||
79 | } | ||
80 | |||
81 | Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( | ||
82 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
83 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
84 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
85 | out_fbshare_layer_index)); | ||
86 | } | ||
87 | |||
88 | Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() { | ||
89 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
90 | R_SUCCEED(); | ||
91 | } | ||
92 | |||
93 | Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( | ||
94 | Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { | ||
95 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
96 | R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, | ||
97 | out_fbshare_layer_index)); | ||
98 | } | ||
99 | |||
100 | Result IDisplayController::ReleaseLastApplicationCaptureSharedBuffer() { | ||
101 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
102 | R_SUCCEED(); | ||
103 | } | ||
104 | |||
105 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/display_controller.h b/src/core/hle/service/am/service/display_controller.h new file mode 100755 index 000000000..406fae21a --- /dev/null +++ b/src/core/hle/service/am/service/display_controller.h | |||
@@ -0,0 +1,36 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | |||
13 | class IDisplayController final : public ServiceFramework<IDisplayController> { | ||
14 | public: | ||
15 | explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
16 | ~IDisplayController() override; | ||
17 | |||
18 | private: | ||
19 | Result GetCallerAppletCaptureImageEx(Out<bool> out_was_written, | ||
20 | OutBuffer<BufferAttr_HipcMapAlias> out_image_data); | ||
21 | Result TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index); | ||
22 | Result ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color); | ||
23 | Result AcquireLastForegroundCaptureSharedBuffer(Out<bool> out_was_written, | ||
24 | Out<s32> out_fbshare_layer_index); | ||
25 | Result ReleaseLastForegroundCaptureSharedBuffer(); | ||
26 | Result AcquireCallerAppletCaptureSharedBuffer(Out<bool> out_was_written, | ||
27 | Out<s32> out_fbshare_layer_index); | ||
28 | Result ReleaseCallerAppletCaptureSharedBuffer(); | ||
29 | Result AcquireLastApplicationCaptureSharedBuffer(Out<bool> out_was_written, | ||
30 | Out<s32> out_fbshare_layer_index); | ||
31 | Result ReleaseLastApplicationCaptureSharedBuffer(); | ||
32 | |||
33 | const std::shared_ptr<Applet> applet; | ||
34 | }; | ||
35 | |||
36 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/global_state_controller.cpp b/src/core/hle/service/am/service/global_state_controller.cpp new file mode 100755 index 000000000..dba5d3613 --- /dev/null +++ b/src/core/hle/service/am/service/global_state_controller.cpp | |||
@@ -0,0 +1,61 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/cradle_firmware_updater.h" | ||
5 | #include "core/hle/service/am/service/global_state_controller.h" | ||
6 | #include "core/hle/service/cmif_serialization.h" | ||
7 | |||
8 | namespace Service::AM { | ||
9 | |||
10 | IGlobalStateController::IGlobalStateController(Core::System& system_) | ||
11 | : ServiceFramework{system_, "IGlobalStateController"}, | ||
12 | m_context{system_, "IGlobalStateController"}, m_hdcp_authentication_failed_event{m_context} { | ||
13 | // clang-format off | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, nullptr, "RequestToEnterSleep"}, | ||
16 | {1, nullptr, "EnterSleep"}, | ||
17 | {2, nullptr, "StartSleepSequence"}, | ||
18 | {3, nullptr, "StartShutdownSequence"}, | ||
19 | {4, nullptr, "StartRebootSequence"}, | ||
20 | {9, nullptr, "IsAutoPowerDownRequested"}, | ||
21 | {10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"}, | ||
22 | {11, nullptr, "NotifyCecSettingsChanged"}, | ||
23 | {12, nullptr, "SetDefaultHomeButtonLongPressTime"}, | ||
24 | {13, nullptr, "UpdateDefaultDisplayResolution"}, | ||
25 | {14, D<&IGlobalStateController::ShouldSleepOnBoot>, "ShouldSleepOnBoot"}, | ||
26 | {15, D<&IGlobalStateController::GetHdcpAuthenticationFailedEvent>, "GetHdcpAuthenticationFailedEvent"}, | ||
27 | {30, D<&IGlobalStateController::OpenCradleFirmwareUpdater>, "OpenCradleFirmwareUpdater"}, | ||
28 | }; | ||
29 | // clang-format on | ||
30 | |||
31 | RegisterHandlers(functions); | ||
32 | } | ||
33 | |||
34 | IGlobalStateController::~IGlobalStateController() = default; | ||
35 | |||
36 | Result IGlobalStateController::LoadAndApplyIdlePolicySettings() { | ||
37 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
38 | R_SUCCEED(); | ||
39 | } | ||
40 | |||
41 | Result IGlobalStateController::ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot) { | ||
42 | LOG_INFO(Service_AM, "called"); | ||
43 | *out_should_sleep_on_boot = false; | ||
44 | R_SUCCEED(); | ||
45 | } | ||
46 | |||
47 | Result IGlobalStateController::GetHdcpAuthenticationFailedEvent( | ||
48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
49 | LOG_INFO(Service_AM, "called"); | ||
50 | *out_event = m_hdcp_authentication_failed_event.GetHandle(); | ||
51 | R_SUCCEED(); | ||
52 | } | ||
53 | |||
54 | Result IGlobalStateController::OpenCradleFirmwareUpdater( | ||
55 | Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater) { | ||
56 | LOG_INFO(Service_AM, "called"); | ||
57 | *out_cradle_firmware_updater = std::make_shared<ICradleFirmwareUpdater>(system); | ||
58 | R_SUCCEED(); | ||
59 | } | ||
60 | |||
61 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/global_state_controller.h b/src/core/hle/service/am/service/global_state_controller.h new file mode 100755 index 000000000..67c753513 --- /dev/null +++ b/src/core/hle/service/am/service/global_state_controller.h | |||
@@ -0,0 +1,31 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/kernel_helpers.h" | ||
8 | #include "core/hle/service/os/event.h" | ||
9 | #include "core/hle/service/service.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | class ICradleFirmwareUpdater; | ||
14 | |||
15 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | ||
16 | public: | ||
17 | explicit IGlobalStateController(Core::System& system_); | ||
18 | ~IGlobalStateController() override; | ||
19 | |||
20 | private: | ||
21 | Result LoadAndApplyIdlePolicySettings(); | ||
22 | Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot); | ||
23 | Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
24 | Result OpenCradleFirmwareUpdater( | ||
25 | Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater); | ||
26 | |||
27 | KernelHelpers::ServiceContext m_context; | ||
28 | Event m_hdcp_authentication_failed_event; | ||
29 | }; | ||
30 | |||
31 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.cpp b/src/core/hle/service/am/service/home_menu_functions.cpp new file mode 100755 index 000000000..0c4d24b58 --- /dev/null +++ b/src/core/hle/service/am/service/home_menu_functions.cpp | |||
@@ -0,0 +1,74 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/result.h" | ||
5 | #include "core/hle/service/am/applet_manager.h" | ||
6 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet) | ||
12 | : ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)}, | ||
13 | m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} { | ||
14 | // clang-format off | ||
15 | static const FunctionInfo functions[] = { | ||
16 | {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, | ||
17 | {11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"}, | ||
18 | {12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"}, | ||
19 | {20, nullptr, "PopFromGeneralChannel"}, | ||
20 | {21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"}, | ||
21 | {30, nullptr, "GetHomeButtonWriterLockAccessor"}, | ||
22 | {31, nullptr, "GetWriterLockAccessorEx"}, | ||
23 | {40, nullptr, "IsSleepEnabled"}, | ||
24 | {41, D<&IHomeMenuFunctions::IsRebootEnabled>, "IsRebootEnabled"}, | ||
25 | {50, nullptr, "LaunchSystemApplet"}, | ||
26 | {51, nullptr, "LaunchStarter"}, | ||
27 | {100, nullptr, "PopRequestLaunchApplicationForDebug"}, | ||
28 | {110, D<&IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug>, "IsForceTerminateApplicationDisabledForDebug"}, | ||
29 | {200, nullptr, "LaunchDevMenu"}, | ||
30 | {1000, nullptr, "SetLastApplicationExitReason"}, | ||
31 | }; | ||
32 | // clang-format on | ||
33 | |||
34 | RegisterHandlers(functions); | ||
35 | } | ||
36 | |||
37 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; | ||
38 | |||
39 | Result IHomeMenuFunctions::RequestToGetForeground() { | ||
40 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
41 | R_SUCCEED(); | ||
42 | } | ||
43 | |||
44 | Result IHomeMenuFunctions::LockForeground() { | ||
45 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
46 | R_SUCCEED(); | ||
47 | } | ||
48 | |||
49 | Result IHomeMenuFunctions::UnlockForeground() { | ||
50 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
51 | R_SUCCEED(); | ||
52 | } | ||
53 | |||
54 | Result IHomeMenuFunctions::GetPopFromGeneralChannelEvent( | ||
55 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
56 | LOG_INFO(Service_AM, "called"); | ||
57 | *out_event = m_pop_from_general_channel_event.GetHandle(); | ||
58 | R_SUCCEED(); | ||
59 | } | ||
60 | |||
61 | Result IHomeMenuFunctions::IsRebootEnabled(Out<bool> out_is_reboot_enbaled) { | ||
62 | LOG_INFO(Service_AM, "called"); | ||
63 | *out_is_reboot_enbaled = true; | ||
64 | R_SUCCEED(); | ||
65 | } | ||
66 | |||
67 | Result IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug( | ||
68 | Out<bool> out_is_force_terminate_application_disabled_for_debug) { | ||
69 | LOG_INFO(Service_AM, "called"); | ||
70 | *out_is_force_terminate_application_disabled_for_debug = false; | ||
71 | R_SUCCEED(); | ||
72 | } | ||
73 | |||
74 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/home_menu_functions.h b/src/core/hle/service/am/service/home_menu_functions.h new file mode 100755 index 000000000..caf6fbaab --- /dev/null +++ b/src/core/hle/service/am/service/home_menu_functions.h | |||
@@ -0,0 +1,34 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/kernel_helpers.h" | ||
8 | #include "core/hle/service/os/event.h" | ||
9 | #include "core/hle/service/service.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | struct Applet; | ||
14 | |||
15 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | ||
16 | public: | ||
17 | explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet); | ||
18 | ~IHomeMenuFunctions() override; | ||
19 | |||
20 | private: | ||
21 | Result RequestToGetForeground(); | ||
22 | Result LockForeground(); | ||
23 | Result UnlockForeground(); | ||
24 | Result GetPopFromGeneralChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
25 | Result IsRebootEnabled(Out<bool> out_is_reboot_enbaled); | ||
26 | Result IsForceTerminateApplicationDisabledForDebug( | ||
27 | Out<bool> out_is_force_terminate_application_disabled_for_debug); | ||
28 | |||
29 | const std::shared_ptr<Applet> m_applet; | ||
30 | KernelHelpers::ServiceContext m_context; | ||
31 | Event m_pop_from_general_channel_event; | ||
32 | }; | ||
33 | |||
34 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp new file mode 100755 index 000000000..0c2426d4b --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp | |||
@@ -0,0 +1,157 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/applet_data_broker.h" | ||
5 | #include "core/hle/service/am/applet_manager.h" | ||
6 | #include "core/hle/service/am/frontend/applets.h" | ||
7 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
8 | #include "core/hle/service/am/service/storage.h" | ||
9 | #include "core/hle/service/cmif_serialization.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, | ||
14 | std::shared_ptr<AppletDataBroker> broker, | ||
15 | std::shared_ptr<Applet> applet) | ||
16 | : ServiceFramework{system_, "ILibraryAppletAccessor"}, m_broker{std::move(broker)}, | ||
17 | m_applet{std::move(applet)} { | ||
18 | // clang-format off | ||
19 | static const FunctionInfo functions[] = { | ||
20 | {0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, | ||
21 | {1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"}, | ||
22 | {10, D<&ILibraryAppletAccessor::Start>, "Start"}, | ||
23 | {20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"}, | ||
24 | {25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"}, | ||
25 | {30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"}, | ||
26 | {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, | ||
27 | {60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero"}, | ||
28 | {100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"}, | ||
29 | {101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"}, | ||
30 | {102, nullptr, "PushExtraStorage"}, | ||
31 | {103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"}, | ||
32 | {104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"}, | ||
33 | {105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"}, | ||
34 | {106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"}, | ||
35 | {110, nullptr, "NeedsToExitProcess"}, | ||
36 | {120, nullptr, "GetLibraryAppletInfo"}, | ||
37 | {150, nullptr, "RequestForAppletToGetForeground"}, | ||
38 | {160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, | ||
39 | }; | ||
40 | // clang-format on | ||
41 | |||
42 | RegisterHandlers(functions); | ||
43 | } | ||
44 | |||
45 | ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; | ||
46 | |||
47 | Result ILibraryAppletAccessor::GetAppletStateChangedEvent( | ||
48 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
49 | LOG_DEBUG(Service_AM, "called"); | ||
50 | *out_event = m_broker->GetStateChangedEvent().GetHandle(); | ||
51 | R_SUCCEED(); | ||
52 | } | ||
53 | |||
54 | Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) { | ||
55 | LOG_DEBUG(Service_AM, "called"); | ||
56 | *out_is_completed = m_broker->IsCompleted(); | ||
57 | R_SUCCEED(); | ||
58 | } | ||
59 | |||
60 | Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) { | ||
61 | LOG_DEBUG(Service_AM, "called"); | ||
62 | *out_result = m_applet->terminate_result; | ||
63 | R_SUCCEED(); | ||
64 | } | ||
65 | |||
66 | Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() { | ||
67 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
68 | R_SUCCEED(); | ||
69 | } | ||
70 | |||
71 | Result ILibraryAppletAccessor::Start() { | ||
72 | LOG_DEBUG(Service_AM, "called"); | ||
73 | m_applet->process->Run(); | ||
74 | FrontendExecute(); | ||
75 | R_SUCCEED(); | ||
76 | } | ||
77 | |||
78 | Result ILibraryAppletAccessor::RequestExit() { | ||
79 | LOG_DEBUG(Service_AM, "called"); | ||
80 | m_applet->message_queue.RequestExit(); | ||
81 | FrontendRequestExit(); | ||
82 | R_SUCCEED(); | ||
83 | } | ||
84 | |||
85 | Result ILibraryAppletAccessor::Terminate() { | ||
86 | LOG_DEBUG(Service_AM, "called"); | ||
87 | m_applet->process->Terminate(); | ||
88 | FrontendRequestExit(); | ||
89 | R_SUCCEED(); | ||
90 | } | ||
91 | |||
92 | Result ILibraryAppletAccessor::PushInData(SharedPointer<IStorage> storage) { | ||
93 | LOG_DEBUG(Service_AM, "called"); | ||
94 | m_broker->GetInData().Push(storage); | ||
95 | R_SUCCEED(); | ||
96 | } | ||
97 | |||
98 | Result ILibraryAppletAccessor::PopOutData(Out<SharedPointer<IStorage>> out_storage) { | ||
99 | LOG_DEBUG(Service_AM, "called"); | ||
100 | R_RETURN(m_broker->GetOutData().Pop(out_storage.Get())); | ||
101 | } | ||
102 | |||
103 | Result ILibraryAppletAccessor::PushInteractiveInData(SharedPointer<IStorage> storage) { | ||
104 | LOG_DEBUG(Service_AM, "called"); | ||
105 | m_broker->GetInteractiveInData().Push(storage); | ||
106 | FrontendExecuteInteractive(); | ||
107 | R_SUCCEED(); | ||
108 | } | ||
109 | |||
110 | Result ILibraryAppletAccessor::PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage) { | ||
111 | LOG_DEBUG(Service_AM, "called"); | ||
112 | R_RETURN(m_broker->GetInteractiveOutData().Pop(out_storage.Get())); | ||
113 | } | ||
114 | |||
115 | Result ILibraryAppletAccessor::GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
116 | LOG_DEBUG(Service_AM, "called"); | ||
117 | *out_event = m_broker->GetOutData().GetEvent(); | ||
118 | R_SUCCEED(); | ||
119 | } | ||
120 | |||
121 | Result ILibraryAppletAccessor::GetPopInteractiveOutDataEvent( | ||
122 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
123 | LOG_DEBUG(Service_AM, "called"); | ||
124 | *out_event = m_broker->GetInteractiveOutData().GetEvent(); | ||
125 | R_SUCCEED(); | ||
126 | } | ||
127 | |||
128 | Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out<u64> out_handle) { | ||
129 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
130 | |||
131 | // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is | ||
132 | // actually used anywhere | ||
133 | *out_handle = 0xdeadbeef; | ||
134 | R_SUCCEED(); | ||
135 | } | ||
136 | |||
137 | void ILibraryAppletAccessor::FrontendExecute() { | ||
138 | if (m_applet->frontend) { | ||
139 | m_applet->frontend->Initialize(); | ||
140 | m_applet->frontend->Execute(); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void ILibraryAppletAccessor::FrontendExecuteInteractive() { | ||
145 | if (m_applet->frontend) { | ||
146 | m_applet->frontend->ExecuteInteractive(); | ||
147 | m_applet->frontend->Execute(); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | void ILibraryAppletAccessor::FrontendRequestExit() { | ||
152 | if (m_applet->frontend) { | ||
153 | m_applet->frontend->RequestExit(); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_accessor.h b/src/core/hle/service/am/service/library_applet_accessor.h new file mode 100755 index 000000000..97d3b6c8a --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_accessor.h | |||
@@ -0,0 +1,45 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | class AppletDataBroker; | ||
12 | struct Applet; | ||
13 | class IStorage; | ||
14 | |||
15 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | ||
16 | public: | ||
17 | explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<AppletDataBroker> broker, | ||
18 | std::shared_ptr<Applet> applet); | ||
19 | ~ILibraryAppletAccessor(); | ||
20 | |||
21 | private: | ||
22 | Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
23 | Result IsCompleted(Out<bool> out_is_completed); | ||
24 | Result GetResult(Out<Result> out_result); | ||
25 | Result PresetLibraryAppletGpuTimeSliceZero(); | ||
26 | Result Start(); | ||
27 | Result RequestExit(); | ||
28 | Result Terminate(); | ||
29 | Result PushInData(SharedPointer<IStorage> storage); | ||
30 | Result PopOutData(Out<SharedPointer<IStorage>> out_storage); | ||
31 | Result PushInteractiveInData(SharedPointer<IStorage> storage); | ||
32 | Result PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage); | ||
33 | Result GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
34 | Result GetPopInteractiveOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
35 | Result GetIndirectLayerConsumerHandle(Out<u64> out_handle); | ||
36 | |||
37 | void FrontendExecute(); | ||
38 | void FrontendExecuteInteractive(); | ||
39 | void FrontendRequestExit(); | ||
40 | |||
41 | const std::shared_ptr<AppletDataBroker> m_broker; | ||
42 | const std::shared_ptr<Applet> m_applet; | ||
43 | }; | ||
44 | |||
45 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp new file mode 100755 index 000000000..166637d60 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_creator.cpp | |||
@@ -0,0 +1,268 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "common/settings.h" | ||
5 | #include "core/hle/kernel/k_transfer_memory.h" | ||
6 | #include "core/hle/service/am/applet_data_broker.h" | ||
7 | #include "core/hle/service/am/applet_manager.h" | ||
8 | #include "core/hle/service/am/frontend/applets.h" | ||
9 | #include "core/hle/service/am/library_applet_storage.h" | ||
10 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
11 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
12 | #include "core/hle/service/am/service/storage.h" | ||
13 | #include "core/hle/service/cmif_serialization.h" | ||
14 | #include "core/hle/service/sm/sm.h" | ||
15 | |||
16 | namespace Service::AM { | ||
17 | |||
18 | namespace { | ||
19 | |||
20 | bool ShouldCreateGuestApplet(AppletId applet_id) { | ||
21 | #define X(Name, name) \ | ||
22 | if (applet_id == AppletId::Name && \ | ||
23 | Settings::values.name##_applet_mode.GetValue() != Settings::AppletMode::LLE) { \ | ||
24 | return false; \ | ||
25 | } | ||
26 | |||
27 | X(Cabinet, cabinet) | ||
28 | X(Controller, controller) | ||
29 | X(DataErase, data_erase) | ||
30 | X(Error, error) | ||
31 | X(NetConnect, net_connect) | ||
32 | X(ProfileSelect, player_select) | ||
33 | X(SoftwareKeyboard, swkbd) | ||
34 | X(MiiEdit, mii_edit) | ||
35 | X(Web, web) | ||
36 | X(Shop, shop) | ||
37 | X(PhotoViewer, photo_viewer) | ||
38 | X(OfflineWeb, offline_web) | ||
39 | X(LoginShare, login_share) | ||
40 | X(WebAuth, wifi_web_auth) | ||
41 | X(MyPage, my_page) | ||
42 | |||
43 | #undef X | ||
44 | |||
45 | return true; | ||
46 | } | ||
47 | |||
48 | AppletProgramId AppletIdToProgramId(AppletId applet_id) { | ||
49 | switch (applet_id) { | ||
50 | case AppletId::OverlayDisplay: | ||
51 | return AppletProgramId::OverlayDisplay; | ||
52 | case AppletId::QLaunch: | ||
53 | return AppletProgramId::QLaunch; | ||
54 | case AppletId::Starter: | ||
55 | return AppletProgramId::Starter; | ||
56 | case AppletId::Auth: | ||
57 | return AppletProgramId::Auth; | ||
58 | case AppletId::Cabinet: | ||
59 | return AppletProgramId::Cabinet; | ||
60 | case AppletId::Controller: | ||
61 | return AppletProgramId::Controller; | ||
62 | case AppletId::DataErase: | ||
63 | return AppletProgramId::DataErase; | ||
64 | case AppletId::Error: | ||
65 | return AppletProgramId::Error; | ||
66 | case AppletId::NetConnect: | ||
67 | return AppletProgramId::NetConnect; | ||
68 | case AppletId::ProfileSelect: | ||
69 | return AppletProgramId::ProfileSelect; | ||
70 | case AppletId::SoftwareKeyboard: | ||
71 | return AppletProgramId::SoftwareKeyboard; | ||
72 | case AppletId::MiiEdit: | ||
73 | return AppletProgramId::MiiEdit; | ||
74 | case AppletId::Web: | ||
75 | return AppletProgramId::Web; | ||
76 | case AppletId::Shop: | ||
77 | return AppletProgramId::Shop; | ||
78 | case AppletId::PhotoViewer: | ||
79 | return AppletProgramId::PhotoViewer; | ||
80 | case AppletId::Settings: | ||
81 | return AppletProgramId::Settings; | ||
82 | case AppletId::OfflineWeb: | ||
83 | return AppletProgramId::OfflineWeb; | ||
84 | case AppletId::LoginShare: | ||
85 | return AppletProgramId::LoginShare; | ||
86 | case AppletId::WebAuth: | ||
87 | return AppletProgramId::WebAuth; | ||
88 | case AppletId::MyPage: | ||
89 | return AppletProgramId::MyPage; | ||
90 | default: | ||
91 | return static_cast<AppletProgramId>(0); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, | ||
96 | std::shared_ptr<Applet> caller_applet, | ||
97 | AppletId applet_id, | ||
98 | LibraryAppletMode mode) { | ||
99 | const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); | ||
100 | if (program_id == 0) { | ||
101 | // Unknown applet | ||
102 | return {}; | ||
103 | } | ||
104 | |||
105 | // TODO: enable other versions of applets | ||
106 | enum : u8 { | ||
107 | Firmware1400 = 14, | ||
108 | Firmware1500 = 15, | ||
109 | Firmware1600 = 16, | ||
110 | Firmware1700 = 17, | ||
111 | }; | ||
112 | |||
113 | auto process = std::make_unique<Process>(system); | ||
114 | if (!process->Initialize(program_id, Firmware1400, Firmware1700)) { | ||
115 | // Couldn't initialize the guest process | ||
116 | return {}; | ||
117 | } | ||
118 | |||
119 | const auto applet = std::make_shared<Applet>(system, std::move(process)); | ||
120 | applet->program_id = program_id; | ||
121 | applet->applet_id = applet_id; | ||
122 | applet->type = AppletType::LibraryApplet; | ||
123 | applet->library_applet_mode = mode; | ||
124 | |||
125 | // Set focus state | ||
126 | switch (mode) { | ||
127 | case LibraryAppletMode::AllForeground: | ||
128 | case LibraryAppletMode::NoUi: | ||
129 | case LibraryAppletMode::PartialForeground: | ||
130 | case LibraryAppletMode::PartialForegroundIndirectDisplay: | ||
131 | applet->hid_registration.EnableAppletToGetInput(true); | ||
132 | applet->focus_state = FocusState::InFocus; | ||
133 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | ||
134 | break; | ||
135 | case LibraryAppletMode::AllForegroundInitiallyHidden: | ||
136 | applet->hid_registration.EnableAppletToGetInput(false); | ||
137 | applet->focus_state = FocusState::NotInFocus; | ||
138 | applet->system_buffer_manager.SetWindowVisibility(false); | ||
139 | applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); | ||
140 | break; | ||
141 | } | ||
142 | |||
143 | auto broker = std::make_shared<AppletDataBroker>(system); | ||
144 | applet->caller_applet = caller_applet; | ||
145 | applet->caller_applet_broker = broker; | ||
146 | |||
147 | system.GetAppletManager().InsertApplet(applet); | ||
148 | |||
149 | return std::make_shared<ILibraryAppletAccessor>(system, broker, applet); | ||
150 | } | ||
151 | |||
152 | std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, | ||
153 | std::shared_ptr<Applet> caller_applet, | ||
154 | AppletId applet_id, | ||
155 | LibraryAppletMode mode) { | ||
156 | const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); | ||
157 | |||
158 | auto process = std::make_unique<Process>(system); | ||
159 | auto applet = std::make_shared<Applet>(system, std::move(process)); | ||
160 | applet->program_id = program_id; | ||
161 | applet->applet_id = applet_id; | ||
162 | applet->type = AppletType::LibraryApplet; | ||
163 | applet->library_applet_mode = mode; | ||
164 | |||
165 | auto storage = std::make_shared<AppletDataBroker>(system); | ||
166 | applet->caller_applet = caller_applet; | ||
167 | applet->caller_applet_broker = storage; | ||
168 | applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); | ||
169 | |||
170 | return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); | ||
171 | } | ||
172 | |||
173 | } // namespace | ||
174 | |||
175 | ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet) | ||
176 | : ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} { | ||
177 | static const FunctionInfo functions[] = { | ||
178 | {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, | ||
179 | {1, nullptr, "TerminateAllLibraryApplets"}, | ||
180 | {2, nullptr, "AreAnyLibraryAppletsLeft"}, | ||
181 | {10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"}, | ||
182 | {11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"}, | ||
183 | {12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"}, | ||
184 | }; | ||
185 | RegisterHandlers(functions); | ||
186 | } | ||
187 | |||
188 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; | ||
189 | |||
190 | Result ILibraryAppletCreator::CreateLibraryApplet( | ||
191 | Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id, | ||
192 | LibraryAppletMode library_applet_mode) { | ||
193 | LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={}", applet_id, | ||
194 | library_applet_mode); | ||
195 | |||
196 | std::shared_ptr<ILibraryAppletAccessor> library_applet; | ||
197 | if (ShouldCreateGuestApplet(applet_id)) { | ||
198 | library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode); | ||
199 | } | ||
200 | if (!library_applet) { | ||
201 | library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode); | ||
202 | } | ||
203 | if (!library_applet) { | ||
204 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); | ||
205 | R_THROW(ResultUnknown); | ||
206 | } | ||
207 | |||
208 | // Applet is created, can now be launched. | ||
209 | m_applet->library_applet_launchable_event.Signal(); | ||
210 | *out_library_applet_accessor = library_applet; | ||
211 | R_SUCCEED(); | ||
212 | } | ||
213 | |||
214 | Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) { | ||
215 | LOG_DEBUG(Service_AM, "called, size={}", size); | ||
216 | |||
217 | if (size <= 0) { | ||
218 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
219 | R_THROW(ResultUnknown); | ||
220 | } | ||
221 | |||
222 | *out_storage = std::make_shared<IStorage>(system, AM::CreateStorage(std::vector<u8>(size))); | ||
223 | R_SUCCEED(); | ||
224 | } | ||
225 | |||
226 | Result ILibraryAppletCreator::CreateTransferMemoryStorage( | ||
227 | Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size, | ||
228 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
229 | LOG_DEBUG(Service_AM, "called, is_writable={} size={}", is_writable, size); | ||
230 | |||
231 | if (size <= 0) { | ||
232 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
233 | R_THROW(ResultUnknown); | ||
234 | } | ||
235 | |||
236 | if (!transfer_memory_handle) { | ||
237 | LOG_ERROR(Service_AM, "transfer_memory_handle is null"); | ||
238 | R_THROW(ResultUnknown); | ||
239 | } | ||
240 | |||
241 | *out_storage = std::make_shared<IStorage>( | ||
242 | system, AM::CreateTransferMemoryStorage(transfer_memory_handle->GetOwner()->GetMemory(), | ||
243 | transfer_memory_handle.Get(), is_writable, size)); | ||
244 | R_SUCCEED(); | ||
245 | } | ||
246 | |||
247 | Result ILibraryAppletCreator::CreateHandleStorage( | ||
248 | Out<SharedPointer<IStorage>> out_storage, s64 size, | ||
249 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) { | ||
250 | LOG_DEBUG(Service_AM, "called, size={}", size); | ||
251 | |||
252 | if (size <= 0) { | ||
253 | LOG_ERROR(Service_AM, "size is less than or equal to 0"); | ||
254 | R_THROW(ResultUnknown); | ||
255 | } | ||
256 | |||
257 | if (!transfer_memory_handle) { | ||
258 | LOG_ERROR(Service_AM, "transfer_memory_handle is null"); | ||
259 | R_THROW(ResultUnknown); | ||
260 | } | ||
261 | |||
262 | *out_storage = std::make_shared<IStorage>( | ||
263 | system, AM::CreateHandleStorage(transfer_memory_handle->GetOwner()->GetMemory(), | ||
264 | transfer_memory_handle.Get(), size)); | ||
265 | R_SUCCEED(); | ||
266 | } | ||
267 | |||
268 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_creator.h b/src/core/hle/service/am/service/library_applet_creator.h new file mode 100755 index 000000000..fe6d40eb3 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_creator.h | |||
@@ -0,0 +1,35 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/am/am_types.h" | ||
7 | #include "core/hle/service/cmif_types.h" | ||
8 | #include "core/hle/service/service.h" | ||
9 | |||
10 | namespace Service::AM { | ||
11 | |||
12 | struct Applet; | ||
13 | class ILibraryAppletAccessor; | ||
14 | class IStorage; | ||
15 | |||
16 | class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { | ||
17 | public: | ||
18 | explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet); | ||
19 | ~ILibraryAppletCreator() override; | ||
20 | |||
21 | private: | ||
22 | Result CreateLibraryApplet( | ||
23 | Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id, | ||
24 | LibraryAppletMode library_applet_mode); | ||
25 | Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size); | ||
26 | Result CreateTransferMemoryStorage( | ||
27 | Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size, | ||
28 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
29 | Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size, | ||
30 | InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); | ||
31 | |||
32 | const std::shared_ptr<Applet> m_applet; | ||
33 | }; | ||
34 | |||
35 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp new file mode 100755 index 000000000..bcb44a71c --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp | |||
@@ -0,0 +1,134 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
5 | #include "core/hle/service/am/service/audio_controller.h" | ||
6 | #include "core/hle/service/am/service/common_state_getter.h" | ||
7 | #include "core/hle/service/am/service/debug_functions.h" | ||
8 | #include "core/hle/service/am/service/display_controller.h" | ||
9 | #include "core/hle/service/am/service/global_state_controller.h" | ||
10 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
11 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
12 | #include "core/hle/service/am/service/library_applet_proxy.h" | ||
13 | #include "core/hle/service/am/service/library_applet_self_accessor.h" | ||
14 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
15 | #include "core/hle/service/am/service/self_controller.h" | ||
16 | #include "core/hle/service/am/service/window_controller.h" | ||
17 | #include "core/hle/service/cmif_serialization.h" | ||
18 | |||
19 | namespace Service::AM { | ||
20 | |||
21 | ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
22 | Kernel::KProcess* process, | ||
23 | Nvnflinger::Nvnflinger& nvnflinger) | ||
24 | : ServiceFramework{system_, "ILibraryAppletProxy"}, | ||
25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
26 | // clang-format off | ||
27 | static const FunctionInfo functions[] = { | ||
28 | {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
29 | {1, D<&ILibraryAppletProxy::GetSelfController>, "GetSelfController"}, | ||
30 | {2, D<&ILibraryAppletProxy::GetWindowController>, "GetWindowController"}, | ||
31 | {3, D<&ILibraryAppletProxy::GetAudioController>, "GetAudioController"}, | ||
32 | {4, D<&ILibraryAppletProxy::GetDisplayController>, "GetDisplayController"}, | ||
33 | {10, D<&ILibraryAppletProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
34 | {11, D<&ILibraryAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
35 | {20, D<&ILibraryAppletProxy::OpenLibraryAppletSelfAccessor>, "OpenLibraryAppletSelfAccessor"}, | ||
36 | {21, D<&ILibraryAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"}, | ||
37 | {22, D<&ILibraryAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"}, | ||
38 | {23, D<&ILibraryAppletProxy::GetGlobalStateController>, "GetGlobalStateController"}, | ||
39 | {1000, D<&ILibraryAppletProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
40 | }; | ||
41 | // clang-format on | ||
42 | |||
43 | RegisterHandlers(functions); | ||
44 | } | ||
45 | |||
46 | ILibraryAppletProxy::~ILibraryAppletProxy() = default; | ||
47 | |||
48 | Result ILibraryAppletProxy::GetAudioController( | ||
49 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
50 | LOG_DEBUG(Service_AM, "called"); | ||
51 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
52 | R_SUCCEED(); | ||
53 | } | ||
54 | |||
55 | Result ILibraryAppletProxy::GetDisplayController( | ||
56 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
57 | LOG_DEBUG(Service_AM, "called"); | ||
58 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
59 | R_SUCCEED(); | ||
60 | } | ||
61 | |||
62 | Result ILibraryAppletProxy::GetProcessWindingController( | ||
63 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
64 | LOG_DEBUG(Service_AM, "called"); | ||
65 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
66 | R_SUCCEED(); | ||
67 | } | ||
68 | |||
69 | Result ILibraryAppletProxy::GetDebugFunctions( | ||
70 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
71 | LOG_DEBUG(Service_AM, "called"); | ||
72 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
73 | R_SUCCEED(); | ||
74 | } | ||
75 | |||
76 | Result ILibraryAppletProxy::GetWindowController( | ||
77 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
78 | LOG_DEBUG(Service_AM, "called"); | ||
79 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
80 | R_SUCCEED(); | ||
81 | } | ||
82 | |||
83 | Result ILibraryAppletProxy::GetSelfController( | ||
84 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
85 | LOG_DEBUG(Service_AM, "called"); | ||
86 | *out_self_controller = | ||
87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
88 | R_SUCCEED(); | ||
89 | } | ||
90 | |||
91 | Result ILibraryAppletProxy::GetCommonStateGetter( | ||
92 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
93 | LOG_DEBUG(Service_AM, "called"); | ||
94 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
95 | R_SUCCEED(); | ||
96 | } | ||
97 | |||
98 | Result ILibraryAppletProxy::GetLibraryAppletCreator( | ||
99 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
100 | LOG_DEBUG(Service_AM, "called"); | ||
101 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
102 | R_SUCCEED(); | ||
103 | } | ||
104 | |||
105 | Result ILibraryAppletProxy::OpenLibraryAppletSelfAccessor( | ||
106 | Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor) { | ||
107 | LOG_DEBUG(Service_AM, "called"); | ||
108 | *out_library_applet_self_accessor = | ||
109 | std::make_shared<ILibraryAppletSelfAccessor>(system, m_applet); | ||
110 | R_SUCCEED(); | ||
111 | } | ||
112 | |||
113 | Result ILibraryAppletProxy::GetAppletCommonFunctions( | ||
114 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) { | ||
115 | LOG_DEBUG(Service_AM, "called"); | ||
116 | *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet); | ||
117 | R_SUCCEED(); | ||
118 | } | ||
119 | |||
120 | Result ILibraryAppletProxy::GetHomeMenuFunctions( | ||
121 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | ||
122 | LOG_DEBUG(Service_AM, "called"); | ||
123 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | ||
124 | R_SUCCEED(); | ||
125 | } | ||
126 | |||
127 | Result ILibraryAppletProxy::GetGlobalStateController( | ||
128 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller) { | ||
129 | LOG_DEBUG(Service_AM, "called"); | ||
130 | *out_global_state_controller = std::make_shared<IGlobalStateController>(system); | ||
131 | R_SUCCEED(); | ||
132 | } | ||
133 | |||
134 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h new file mode 100755 index 000000000..23e64e295 --- /dev/null +++ b/src/core/hle/service/am/service/library_applet_proxy.h | |||
@@ -0,0 +1,55 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | class IAppletCommonFunctions; | ||
13 | class IAudioController; | ||
14 | class ICommonStateGetter; | ||
15 | class IDebugFunctions; | ||
16 | class IDisplayController; | ||
17 | class IHomeMenuFunctions; | ||
18 | class IGlobalStateController; | ||
19 | class ILibraryAppletCreator; | ||
20 | class ILibraryAppletSelfAccessor; | ||
21 | class IProcessWindingController; | ||
22 | class ISelfController; | ||
23 | class IWindowController; | ||
24 | |||
25 | class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { | ||
26 | public: | ||
27 | explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
29 | ~ILibraryAppletProxy(); | ||
30 | |||
31 | private: | ||
32 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
33 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
34 | Result GetProcessWindingController( | ||
35 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
36 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
37 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
38 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
39 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
40 | Result GetLibraryAppletCreator( | ||
41 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
42 | Result OpenLibraryAppletSelfAccessor( | ||
43 | Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor); | ||
44 | Result GetAppletCommonFunctions( | ||
45 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions); | ||
46 | Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions); | ||
47 | Result GetGlobalStateController( | ||
48 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | ||
49 | |||
50 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
51 | Kernel::KProcess* const m_process; | ||
52 | const std::shared_ptr<Applet> m_applet; | ||
53 | }; | ||
54 | |||
55 | } // namespace Service::AM | ||
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 100755 index 000000000..7a3a86e88 --- /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/service/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 | |||
20 | namespace Service::AM { | ||
21 | |||
22 | namespace { | ||
23 | |||
24 | AppletIdentityInfo 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 | |||
41 | ILibraryAppletSelfAccessor::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 | |||
88 | ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; | ||
89 | |||
90 | Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_storage) { | ||
91 | LOG_INFO(Service_AM, "called"); | ||
92 | R_RETURN(m_broker->GetInData().Pop(out_storage)); | ||
93 | } | ||
94 | |||
95 | Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) { | ||
96 | LOG_INFO(Service_AM, "called"); | ||
97 | m_broker->GetOutData().Push(storage); | ||
98 | R_SUCCEED(); | ||
99 | } | ||
100 | |||
101 | Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage) { | ||
102 | LOG_INFO(Service_AM, "called"); | ||
103 | R_RETURN(m_broker->GetInteractiveInData().Pop(out_storage)); | ||
104 | } | ||
105 | |||
106 | Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer<IStorage> storage) { | ||
107 | LOG_INFO(Service_AM, "called"); | ||
108 | m_broker->GetInteractiveOutData().Push(storage); | ||
109 | R_SUCCEED(); | ||
110 | } | ||
111 | |||
112 | Result 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 | |||
119 | Result 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 | |||
126 | Result 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 | |||
136 | Result 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 | |||
146 | Result 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 | |||
153 | Result 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 | |||
170 | Result 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 | |||
176 | Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() { | ||
177 | LOG_INFO(Service_AM, "called"); | ||
178 | system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid); | ||
179 | m_broker->SignalCompletion(); | ||
180 | R_SUCCEED(); | ||
181 | } | ||
182 | |||
183 | Result 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 | |||
190 | Result 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 | |||
207 | Result ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(Out<u32> out_desirable_layout) { | ||
208 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
209 | *out_desirable_layout = 0; | ||
210 | R_SUCCEED(); | ||
211 | } | ||
212 | |||
213 | Result 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 | |||
219 | Result 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 | |||
226 | Result 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 | |||
276 | Result 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 | |||
286 | Result 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 | |||
309 | Result 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 | |||
316 | Result 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 100755 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 | |||
11 | namespace FileSys { | ||
12 | enum class StorageId : u8; | ||
13 | } | ||
14 | |||
15 | namespace Kernel { | ||
16 | class KReadableEvent; | ||
17 | } | ||
18 | |||
19 | namespace Service::AM { | ||
20 | |||
21 | class AppletDataBroker; | ||
22 | struct Applet; | ||
23 | class IStorage; | ||
24 | |||
25 | struct LibraryAppletInfo { | ||
26 | AppletId applet_id; | ||
27 | LibraryAppletMode library_applet_mode; | ||
28 | }; | ||
29 | static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size."); | ||
30 | |||
31 | struct ErrorCode { | ||
32 | u32 category; | ||
33 | u32 number; | ||
34 | }; | ||
35 | static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size."); | ||
36 | |||
37 | struct ErrorContext { | ||
38 | u8 type; | ||
39 | INSERT_PADDING_BYTES_NOINIT(0x7); | ||
40 | std::array<u8, 0x1f4> data; | ||
41 | Result result; | ||
42 | }; | ||
43 | static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size."); | ||
44 | |||
45 | class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { | ||
46 | public: | ||
47 | explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet); | ||
48 | ~ILibraryAppletSelfAccessor() override; | ||
49 | |||
50 | private: | ||
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/lock_accessor.cpp b/src/core/hle/service/am/service/lock_accessor.cpp new file mode 100755 index 000000000..8e556fdd6 --- /dev/null +++ b/src/core/hle/service/am/service/lock_accessor.cpp | |||
@@ -0,0 +1,75 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/lock_accessor.h" | ||
5 | #include "core/hle/service/cmif_serialization.h" | ||
6 | |||
7 | namespace Service::AM { | ||
8 | |||
9 | ILockAccessor::ILockAccessor(Core::System& system_) | ||
10 | : ServiceFramework{system_, "ILockAccessor"}, m_context{system_, "ILockAccessor"}, | ||
11 | m_event{m_context} { | ||
12 | // clang-format off | ||
13 | static const FunctionInfo functions[] = { | ||
14 | {1, D<&ILockAccessor::TryLock>, "TryLock"}, | ||
15 | {2, D<&ILockAccessor::Unlock>, "Unlock"}, | ||
16 | {3, D<&ILockAccessor::GetEvent>, "GetEvent"}, | ||
17 | {4, D<&ILockAccessor::IsLocked>, "IsLocked"}, | ||
18 | }; | ||
19 | // clang-format on | ||
20 | |||
21 | RegisterHandlers(functions); | ||
22 | |||
23 | m_event.Signal(); | ||
24 | } | ||
25 | |||
26 | ILockAccessor::~ILockAccessor() = default; | ||
27 | |||
28 | Result ILockAccessor::TryLock(Out<bool> out_is_locked, | ||
29 | OutCopyHandle<Kernel::KReadableEvent> out_handle, | ||
30 | bool return_handle) { | ||
31 | LOG_INFO(Service_AM, "called, return_handle={}", return_handle); | ||
32 | |||
33 | { | ||
34 | std::scoped_lock lk{m_mutex}; | ||
35 | if (m_is_locked) { | ||
36 | *out_is_locked = false; | ||
37 | } else { | ||
38 | m_is_locked = true; | ||
39 | *out_is_locked = true; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | if (return_handle) { | ||
44 | *out_handle = m_event.GetHandle(); | ||
45 | } | ||
46 | |||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
50 | Result ILockAccessor::Unlock() { | ||
51 | LOG_INFO(Service_AM, "called"); | ||
52 | |||
53 | { | ||
54 | std::scoped_lock lk{m_mutex}; | ||
55 | m_is_locked = false; | ||
56 | } | ||
57 | |||
58 | m_event.Signal(); | ||
59 | R_SUCCEED(); | ||
60 | } | ||
61 | |||
62 | Result ILockAccessor::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle) { | ||
63 | LOG_INFO(Service_AM, "called"); | ||
64 | *out_handle = m_event.GetHandle(); | ||
65 | R_SUCCEED(); | ||
66 | } | ||
67 | |||
68 | Result ILockAccessor::IsLocked(Out<bool> out_is_locked) { | ||
69 | LOG_INFO(Service_AM, "called"); | ||
70 | std::scoped_lock lk{m_mutex}; | ||
71 | *out_is_locked = m_is_locked; | ||
72 | R_SUCCEED(); | ||
73 | } | ||
74 | |||
75 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/lock_accessor.h b/src/core/hle/service/am/service/lock_accessor.h new file mode 100755 index 000000000..9bfb5c050 --- /dev/null +++ b/src/core/hle/service/am/service/lock_accessor.h | |||
@@ -0,0 +1,32 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/kernel_helpers.h" | ||
8 | #include "core/hle/service/os/event.h" | ||
9 | #include "core/hle/service/service.h" | ||
10 | |||
11 | namespace Service::AM { | ||
12 | |||
13 | class ILockAccessor final : public ServiceFramework<ILockAccessor> { | ||
14 | public: | ||
15 | explicit ILockAccessor(Core::System& system_); | ||
16 | ~ILockAccessor() override; | ||
17 | |||
18 | private: | ||
19 | Result TryLock(Out<bool> out_is_locked, OutCopyHandle<Kernel::KReadableEvent> out_handle, | ||
20 | bool return_handle); | ||
21 | Result Unlock(); | ||
22 | Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle); | ||
23 | Result IsLocked(Out<bool> out_is_locked); | ||
24 | |||
25 | private: | ||
26 | KernelHelpers::ServiceContext m_context; | ||
27 | Event m_event; | ||
28 | std::mutex m_mutex{}; | ||
29 | bool m_is_locked{}; | ||
30 | }; | ||
31 | |||
32 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/process_winding_controller.cpp b/src/core/hle/service/am/service/process_winding_controller.cpp new file mode 100755 index 000000000..10df830d7 --- /dev/null +++ b/src/core/hle/service/am/service/process_winding_controller.cpp | |||
@@ -0,0 +1,54 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/frontend/applets.h" | ||
5 | #include "core/hle/service/am/service/library_applet_accessor.h" | ||
6 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | IProcessWindingController::IProcessWindingController(Core::System& system_, | ||
12 | std::shared_ptr<Applet> applet) | ||
13 | : ServiceFramework{system_, "IProcessWindingController"}, m_applet{std::move(applet)} { | ||
14 | // clang-format off | ||
15 | static const FunctionInfo functions[] = { | ||
16 | {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"}, | ||
17 | {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"}, | ||
18 | {21, nullptr, "PushContext"}, | ||
19 | {22, nullptr, "PopContext"}, | ||
20 | {23, nullptr, "CancelWindingReservation"}, | ||
21 | {30, nullptr, "WindAndDoReserved"}, | ||
22 | {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"}, | ||
23 | {41, nullptr, "ReserveToStartAndWait"}, | ||
24 | }; | ||
25 | // clang-format on | ||
26 | |||
27 | RegisterHandlers(functions); | ||
28 | } | ||
29 | |||
30 | IProcessWindingController::~IProcessWindingController() = default; | ||
31 | |||
32 | Result IProcessWindingController::GetLaunchReason( | ||
33 | Out<AppletProcessLaunchReason> out_launch_reason) { | ||
34 | LOG_INFO(Service_AM, "called"); | ||
35 | *out_launch_reason = m_applet->launch_reason; | ||
36 | R_SUCCEED(); | ||
37 | } | ||
38 | |||
39 | Result IProcessWindingController::OpenCallingLibraryApplet( | ||
40 | Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet) { | ||
41 | LOG_INFO(Service_AM, "called"); | ||
42 | |||
43 | const auto caller_applet = m_applet->caller_applet.lock(); | ||
44 | if (caller_applet == nullptr) { | ||
45 | LOG_ERROR(Service_AM, "No caller applet available"); | ||
46 | R_THROW(ResultUnknown); | ||
47 | } | ||
48 | |||
49 | *out_calling_library_applet = std::make_shared<ILibraryAppletAccessor>( | ||
50 | system, m_applet->caller_applet_broker, caller_applet); | ||
51 | R_SUCCEED(); | ||
52 | } | ||
53 | |||
54 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/process_winding_controller.h b/src/core/hle/service/am/service/process_winding_controller.h new file mode 100755 index 000000000..4408af1f1 --- /dev/null +++ b/src/core/hle/service/am/service/process_winding_controller.h | |||
@@ -0,0 +1,28 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/am/am_types.h" | ||
7 | #include "core/hle/service/cmif_types.h" | ||
8 | #include "core/hle/service/service.h" | ||
9 | |||
10 | namespace Service::AM { | ||
11 | |||
12 | struct Applet; | ||
13 | class ILibraryAppletAccessor; | ||
14 | |||
15 | class IProcessWindingController final : public ServiceFramework<IProcessWindingController> { | ||
16 | public: | ||
17 | explicit IProcessWindingController(Core::System& system_, std::shared_ptr<Applet> applet_); | ||
18 | ~IProcessWindingController() override; | ||
19 | |||
20 | private: | ||
21 | Result GetLaunchReason(Out<AppletProcessLaunchReason> out_launch_reason); | ||
22 | Result OpenCallingLibraryApplet( | ||
23 | Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet); | ||
24 | |||
25 | const std::shared_ptr<Applet> m_applet; | ||
26 | }; | ||
27 | |||
28 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp new file mode 100755 index 000000000..5c4c13de1 --- /dev/null +++ b/src/core/hle/service/am/service/self_controller.cpp | |||
@@ -0,0 +1,393 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "common/logging/log.h" | ||
5 | #include "core/hle/result.h" | ||
6 | #include "core/hle/service/am/am_results.h" | ||
7 | #include "core/hle/service/am/frontend/applets.h" | ||
8 | #include "core/hle/service/am/service/self_controller.h" | ||
9 | #include "core/hle/service/caps/caps_su.h" | ||
10 | #include "core/hle/service/cmif_serialization.h" | ||
11 | #include "core/hle/service/nvnflinger/nvnflinger.h" | ||
12 | #include "core/hle/service/sm/sm.h" | ||
13 | #include "core/hle/service/vi/vi_results.h" | ||
14 | |||
15 | namespace Service::AM { | ||
16 | |||
17 | ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | ||
18 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) | ||
19 | : ServiceFramework{system_, "ISelfController"}, | ||
20 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
21 | // clang-format off | ||
22 | static const FunctionInfo functions[] = { | ||
23 | {0, D<&ISelfController::Exit>, "Exit"}, | ||
24 | {1, D<&ISelfController::LockExit>, "LockExit"}, | ||
25 | {2, D<&ISelfController::UnlockExit>, "UnlockExit"}, | ||
26 | {3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"}, | ||
27 | {4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"}, | ||
28 | {9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"}, | ||
29 | {10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"}, | ||
30 | {11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"}, | ||
31 | {12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"}, | ||
32 | {13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"}, | ||
33 | {14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"}, | ||
34 | {15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"}, | ||
35 | {16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"}, | ||
36 | {17, nullptr, "SetControllerFirmwareUpdateSection"}, | ||
37 | {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"}, | ||
38 | {19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"}, | ||
39 | {20, nullptr, "SetDesirableKeyboardLayout"}, | ||
40 | {21, nullptr, "GetScreenShotProgramId"}, | ||
41 | {40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"}, | ||
42 | {41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"}, | ||
43 | {42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"}, | ||
44 | {43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"}, | ||
45 | {44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"}, | ||
46 | {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, | ||
47 | {46, nullptr, "SetRecordingLayerCompositionEnabled"}, | ||
48 | {50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"}, | ||
49 | {51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"}, | ||
50 | {60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"}, | ||
51 | {61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"}, | ||
52 | {62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"}, | ||
53 | {63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"}, | ||
54 | {64, nullptr, "SetInputDetectionSourceSet"}, | ||
55 | {65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"}, | ||
56 | {66, nullptr, "GetCurrentIlluminance"}, | ||
57 | {67, nullptr, "IsIlluminanceAvailable"}, | ||
58 | {68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"}, | ||
59 | {69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"}, | ||
60 | {70, nullptr, "ReportMultimediaError"}, | ||
61 | {71, nullptr, "GetCurrentIlluminanceEx"}, | ||
62 | {72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"}, | ||
63 | {80, nullptr, "SetWirelessPriorityMode"}, | ||
64 | {90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"}, | ||
65 | {91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"}, | ||
66 | {100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"}, | ||
67 | {110, nullptr, "SetApplicationAlbumUserData"}, | ||
68 | {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, | ||
69 | {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, | ||
70 | {1000, nullptr, "GetDebugStorageChannel"}, | ||
71 | }; | ||
72 | // clang-format on | ||
73 | |||
74 | RegisterHandlers(functions); | ||
75 | } | ||
76 | |||
77 | ISelfController::~ISelfController() = default; | ||
78 | |||
79 | Result ISelfController::Exit() { | ||
80 | LOG_DEBUG(Service_AM, "called"); | ||
81 | |||
82 | // TODO | ||
83 | system.Exit(); | ||
84 | |||
85 | R_SUCCEED(); | ||
86 | } | ||
87 | |||
88 | Result ISelfController::LockExit() { | ||
89 | LOG_DEBUG(Service_AM, "called"); | ||
90 | |||
91 | system.SetExitLocked(true); | ||
92 | |||
93 | R_SUCCEED(); | ||
94 | } | ||
95 | |||
96 | Result ISelfController::UnlockExit() { | ||
97 | LOG_DEBUG(Service_AM, "called"); | ||
98 | |||
99 | system.SetExitLocked(false); | ||
100 | |||
101 | if (system.GetExitRequested()) { | ||
102 | system.Exit(); | ||
103 | } | ||
104 | |||
105 | R_SUCCEED(); | ||
106 | } | ||
107 | |||
108 | Result ISelfController::EnterFatalSection() { | ||
109 | std::scoped_lock lk{m_applet->lock}; | ||
110 | |||
111 | m_applet->fatal_section_count++; | ||
112 | LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", m_applet->fatal_section_count); | ||
113 | |||
114 | R_SUCCEED(); | ||
115 | } | ||
116 | |||
117 | Result ISelfController::LeaveFatalSection() { | ||
118 | LOG_DEBUG(Service_AM, "called"); | ||
119 | |||
120 | // Entry and exit of fatal sections must be balanced. | ||
121 | std::scoped_lock lk{m_applet->lock}; | ||
122 | R_UNLESS(m_applet->fatal_section_count > 0, AM::ResultFatalSectionCountImbalance); | ||
123 | m_applet->fatal_section_count--; | ||
124 | |||
125 | R_SUCCEED(); | ||
126 | } | ||
127 | |||
128 | Result ISelfController::GetLibraryAppletLaunchableEvent( | ||
129 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
130 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
131 | |||
132 | m_applet->library_applet_launchable_event.Signal(); | ||
133 | *out_event = m_applet->library_applet_launchable_event.GetHandle(); | ||
134 | |||
135 | R_SUCCEED(); | ||
136 | } | ||
137 | |||
138 | Result ISelfController::SetScreenShotPermission(ScreenshotPermission screen_shot_permission) { | ||
139 | LOG_DEBUG(Service_AM, "called, permission={}", screen_shot_permission); | ||
140 | |||
141 | std::scoped_lock lk{m_applet->lock}; | ||
142 | m_applet->screenshot_permission = screen_shot_permission; | ||
143 | |||
144 | R_SUCCEED(); | ||
145 | } | ||
146 | |||
147 | Result ISelfController::SetOperationModeChangedNotification(bool enabled) { | ||
148 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
149 | |||
150 | std::scoped_lock lk{m_applet->lock}; | ||
151 | m_applet->operation_mode_changed_notification_enabled = enabled; | ||
152 | |||
153 | R_SUCCEED(); | ||
154 | } | ||
155 | |||
156 | Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) { | ||
157 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
158 | |||
159 | std::scoped_lock lk{m_applet->lock}; | ||
160 | m_applet->performance_mode_changed_notification_enabled = enabled; | ||
161 | |||
162 | R_SUCCEED(); | ||
163 | } | ||
164 | |||
165 | Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) { | ||
166 | LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify, | ||
167 | background, suspend); | ||
168 | |||
169 | std::scoped_lock lk{m_applet->lock}; | ||
170 | m_applet->focus_handling_mode = {notify, background, suspend}; | ||
171 | |||
172 | R_SUCCEED(); | ||
173 | } | ||
174 | |||
175 | Result ISelfController::SetRestartMessageEnabled(bool enabled) { | ||
176 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
177 | |||
178 | std::scoped_lock lk{m_applet->lock}; | ||
179 | m_applet->restart_message_enabled = enabled; | ||
180 | |||
181 | R_SUCCEED(); | ||
182 | } | ||
183 | |||
184 | Result ISelfController::SetScreenShotAppletIdentityInfo( | ||
185 | AppletIdentityInfo screen_shot_applet_identity_info) { | ||
186 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
187 | |||
188 | std::scoped_lock lk{m_applet->lock}; | ||
189 | m_applet->screen_shot_identity = screen_shot_applet_identity_info; | ||
190 | |||
191 | R_SUCCEED(); | ||
192 | } | ||
193 | |||
194 | Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) { | ||
195 | LOG_INFO(Service_AM, "called, enabled={}", enabled); | ||
196 | |||
197 | std::scoped_lock lk{m_applet->lock}; | ||
198 | m_applet->out_of_focus_suspension_enabled = enabled; | ||
199 | |||
200 | R_SUCCEED(); | ||
201 | } | ||
202 | |||
203 | Result ISelfController::SetAlbumImageOrientation( | ||
204 | Capture::AlbumImageOrientation album_image_orientation) { | ||
205 | LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", album_image_orientation); | ||
206 | |||
207 | std::scoped_lock lk{m_applet->lock}; | ||
208 | m_applet->album_image_orientation = album_image_orientation; | ||
209 | |||
210 | R_SUCCEED(); | ||
211 | } | ||
212 | |||
213 | Result ISelfController::IsSystemBufferSharingEnabled() { | ||
214 | LOG_INFO(Service_AM, "called"); | ||
215 | R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize( | ||
216 | &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode)); | ||
217 | R_THROW(VI::ResultOperationFailed); | ||
218 | } | ||
219 | |||
220 | Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { | ||
221 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
222 | |||
223 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
224 | |||
225 | u64 layer_id; | ||
226 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id); | ||
227 | R_SUCCEED(); | ||
228 | } | ||
229 | |||
230 | Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { | ||
231 | LOG_INFO(Service_AM, "(STUBBED) called"); | ||
232 | |||
233 | R_TRY(this->IsSystemBufferSharingEnabled()); | ||
234 | |||
235 | m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id); | ||
236 | R_SUCCEED(); | ||
237 | } | ||
238 | |||
239 | Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { | ||
240 | LOG_INFO(Service_AM, "called"); | ||
241 | |||
242 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | ||
243 | m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id); | ||
244 | |||
245 | R_SUCCEED(); | ||
246 | } | ||
247 | |||
248 | Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | ||
249 | Out<u64> out_recording_layer_id) { | ||
250 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
251 | |||
252 | m_applet->managed_layer_holder.Initialize(&m_nvnflinger); | ||
253 | m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id, | ||
254 | out_recording_layer_id); | ||
255 | |||
256 | R_SUCCEED(); | ||
257 | } | ||
258 | |||
259 | Result ISelfController::SetHandlesRequestToDisplay(bool enable) { | ||
260 | LOG_WARNING(Service_AM, "(STUBBED) called, enable={}", enable); | ||
261 | R_SUCCEED(); | ||
262 | } | ||
263 | |||
264 | Result ISelfController::ApproveToDisplay() { | ||
265 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
266 | R_SUCCEED(); | ||
267 | } | ||
268 | |||
269 | Result ISelfController::SetMediaPlaybackState(bool state) { | ||
270 | LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state); | ||
271 | R_SUCCEED(); | ||
272 | } | ||
273 | |||
274 | Result ISelfController::OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d) { | ||
275 | LOG_WARNING(Service_AM, "(STUBBED) called, a={}, b={}, c={}, d={}", a, b, c, d); | ||
276 | R_SUCCEED(); | ||
277 | } | ||
278 | |||
279 | Result ISelfController::SetIdleTimeDetectionExtension( | ||
280 | IdleTimeDetectionExtension idle_time_detection_extension) { | ||
281 | LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", idle_time_detection_extension); | ||
282 | |||
283 | std::scoped_lock lk{m_applet->lock}; | ||
284 | m_applet->idle_time_detection_extension = idle_time_detection_extension; | ||
285 | |||
286 | R_SUCCEED(); | ||
287 | } | ||
288 | |||
289 | Result ISelfController::GetIdleTimeDetectionExtension( | ||
290 | Out<IdleTimeDetectionExtension> out_idle_time_detection_extension) { | ||
291 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
292 | |||
293 | std::scoped_lock lk{m_applet->lock}; | ||
294 | *out_idle_time_detection_extension = m_applet->idle_time_detection_extension; | ||
295 | |||
296 | R_SUCCEED(); | ||
297 | } | ||
298 | |||
299 | Result ISelfController::ReportUserIsActive() { | ||
300 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
301 | R_SUCCEED(); | ||
302 | } | ||
303 | |||
304 | Result ISelfController::SetAutoSleepDisabled(bool is_auto_sleep_disabled) { | ||
305 | LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled); | ||
306 | |||
307 | // On the system itself, if the previous state of is_auto_sleep_disabled | ||
308 | // differed from the current value passed in, it'd signify the internal | ||
309 | // window manager to update (and also increment some statistics like update counts) | ||
310 | // | ||
311 | // It'd also indicate this change to an idle handling context. | ||
312 | // | ||
313 | // However, given we're emulating this behavior, most of this can be ignored | ||
314 | // and it's sufficient to simply set the member variable for querying via | ||
315 | // IsAutoSleepDisabled(). | ||
316 | |||
317 | std::scoped_lock lk{m_applet->lock}; | ||
318 | m_applet->auto_sleep_disabled = is_auto_sleep_disabled; | ||
319 | |||
320 | R_SUCCEED(); | ||
321 | } | ||
322 | |||
323 | Result ISelfController::IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled) { | ||
324 | LOG_DEBUG(Service_AM, "called."); | ||
325 | |||
326 | std::scoped_lock lk{m_applet->lock}; | ||
327 | *out_is_auto_sleep_disabled = m_applet->auto_sleep_disabled; | ||
328 | |||
329 | R_SUCCEED(); | ||
330 | } | ||
331 | |||
332 | Result ISelfController::SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy) { | ||
333 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
334 | R_SUCCEED(); | ||
335 | } | ||
336 | |||
337 | Result ISelfController::GetAccumulatedSuspendedTickValue( | ||
338 | Out<u64> out_accumulated_suspended_tick_value) { | ||
339 | LOG_DEBUG(Service_AM, "called."); | ||
340 | |||
341 | // This command returns the total number of system ticks since ISelfController creation | ||
342 | // where the game was suspended. Since Yuzu doesn't implement game suspension, this command | ||
343 | // can just always return 0 ticks. | ||
344 | std::scoped_lock lk{m_applet->lock}; | ||
345 | *out_accumulated_suspended_tick_value = m_applet->suspended_ticks; | ||
346 | |||
347 | R_SUCCEED(); | ||
348 | } | ||
349 | |||
350 | Result ISelfController::GetAccumulatedSuspendedTickChangedEvent( | ||
351 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
352 | LOG_DEBUG(Service_AM, "called."); | ||
353 | |||
354 | *out_event = m_applet->accumulated_suspended_tick_changed_event.GetHandle(); | ||
355 | R_SUCCEED(); | ||
356 | } | ||
357 | |||
358 | Result ISelfController::SetAlbumImageTakenNotificationEnabled(bool enabled) { | ||
359 | LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled); | ||
360 | |||
361 | // This service call sets an internal flag whether a notification is shown when an image is | ||
362 | // captured. Currently we do not support capturing images via the capture button, so this can be | ||
363 | // stubbed for now. | ||
364 | std::scoped_lock lk{m_applet->lock}; | ||
365 | m_applet->album_image_taken_notification_enabled = enabled; | ||
366 | |||
367 | R_SUCCEED(); | ||
368 | } | ||
369 | |||
370 | Result ISelfController::SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option) { | ||
371 | LOG_INFO(Service_AM, "called, report_option={}", album_report_option); | ||
372 | |||
373 | const auto screenshot_service = | ||
374 | system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>( | ||
375 | "caps:su"); | ||
376 | |||
377 | if (screenshot_service) { | ||
378 | screenshot_service->CaptureAndSaveScreenshot(album_report_option); | ||
379 | } | ||
380 | |||
381 | R_SUCCEED(); | ||
382 | } | ||
383 | |||
384 | Result ISelfController::SetRecordVolumeMuted(bool muted) { | ||
385 | LOG_WARNING(Service_AM, "(STUBBED) called. muted={}", muted); | ||
386 | |||
387 | std::scoped_lock lk{m_applet->lock}; | ||
388 | m_applet->record_volume_muted = muted; | ||
389 | |||
390 | R_SUCCEED(); | ||
391 | } | ||
392 | |||
393 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h new file mode 100755 index 000000000..01fa381a3 --- /dev/null +++ b/src/core/hle/service/am/service/self_controller.h | |||
@@ -0,0 +1,72 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/am/am_types.h" | ||
7 | #include "core/hle/service/cmif_types.h" | ||
8 | #include "core/hle/service/service.h" | ||
9 | |||
10 | namespace Kernel { | ||
11 | class KReadableEvent; | ||
12 | } | ||
13 | |||
14 | namespace Service::Capture { | ||
15 | enum class AlbumImageOrientation; | ||
16 | enum class AlbumReportOption; | ||
17 | } // namespace Service::Capture | ||
18 | |||
19 | namespace Service::AM { | ||
20 | |||
21 | struct Applet; | ||
22 | |||
23 | class ISelfController final : public ServiceFramework<ISelfController> { | ||
24 | public: | ||
25 | explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, | ||
26 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
27 | ~ISelfController() override; | ||
28 | |||
29 | private: | ||
30 | Result Exit(); | ||
31 | Result LockExit(); | ||
32 | Result UnlockExit(); | ||
33 | Result EnterFatalSection(); | ||
34 | Result LeaveFatalSection(); | ||
35 | Result GetLibraryAppletLaunchableEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
36 | Result SetScreenShotPermission(ScreenshotPermission screen_shot_permission); | ||
37 | Result SetOperationModeChangedNotification(bool enabled); | ||
38 | Result SetPerformanceModeChangedNotification(bool enabled); | ||
39 | Result SetFocusHandlingMode(bool notify, bool background, bool suspend); | ||
40 | Result SetRestartMessageEnabled(bool enabled); | ||
41 | Result SetScreenShotAppletIdentityInfo(AppletIdentityInfo screen_shot_applet_identity_info); | ||
42 | Result SetOutOfFocusSuspendingEnabled(bool enabled); | ||
43 | Result SetAlbumImageOrientation(Capture::AlbumImageOrientation album_image_orientation); | ||
44 | Result IsSystemBufferSharingEnabled(); | ||
45 | Result GetSystemSharedBufferHandle(Out<u64> out_buffer_id); | ||
46 | Result GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id); | ||
47 | Result CreateManagedDisplayLayer(Out<u64> out_layer_id); | ||
48 | Result CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, | ||
49 | Out<u64> out_recording_layer_id); | ||
50 | Result SetHandlesRequestToDisplay(bool enable); | ||
51 | Result ApproveToDisplay(); | ||
52 | Result SetMediaPlaybackState(bool state); | ||
53 | Result OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d); | ||
54 | Result SetIdleTimeDetectionExtension(IdleTimeDetectionExtension idle_time_detection_extension); | ||
55 | Result GetIdleTimeDetectionExtension( | ||
56 | Out<IdleTimeDetectionExtension> out_idle_time_detection_extension); | ||
57 | Result ReportUserIsActive(); | ||
58 | Result SetAutoSleepDisabled(bool is_auto_sleep_disabled); | ||
59 | Result IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled); | ||
60 | Result SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy); | ||
61 | Result GetAccumulatedSuspendedTickValue(Out<u64> out_accumulated_suspended_tick_value); | ||
62 | Result GetAccumulatedSuspendedTickChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
63 | Result SetAlbumImageTakenNotificationEnabled(bool enabled); | ||
64 | Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); | ||
65 | Result SetRecordVolumeMuted(bool muted); | ||
66 | |||
67 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
68 | Kernel::KProcess* const m_process; | ||
69 | const std::shared_ptr<Applet> m_applet; | ||
70 | }; | ||
71 | |||
72 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/storage.cpp b/src/core/hle/service/am/service/storage.cpp new file mode 100755 index 000000000..25ee0afbd --- /dev/null +++ b/src/core/hle/service/am/service/storage.cpp | |||
@@ -0,0 +1,48 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/am_results.h" | ||
5 | #include "core/hle/service/am/library_applet_storage.h" | ||
6 | #include "core/hle/service/am/service/storage.h" | ||
7 | #include "core/hle/service/am/service/storage_accessor.h" | ||
8 | #include "core/hle/service/cmif_serialization.h" | ||
9 | |||
10 | namespace Service::AM { | ||
11 | |||
12 | IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) | ||
13 | : ServiceFramework{system_, "IStorage"}, m_impl{std::move(impl)} { | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, D<&IStorage::Open>, "Open"}, | ||
16 | {1, D<&IStorage::OpenTransferStorage>, "OpenTransferStorage"}, | ||
17 | }; | ||
18 | |||
19 | RegisterHandlers(functions); | ||
20 | } | ||
21 | |||
22 | IStorage::IStorage(Core::System& system_, std::vector<u8>&& data) | ||
23 | : IStorage(system_, CreateStorage(std::move(data))) {} | ||
24 | |||
25 | IStorage::~IStorage() = default; | ||
26 | |||
27 | Result IStorage::Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor) { | ||
28 | LOG_DEBUG(Service_AM, "called"); | ||
29 | |||
30 | R_UNLESS(m_impl->GetHandle() == nullptr, AM::ResultInvalidStorageType); | ||
31 | |||
32 | *out_storage_accessor = std::make_shared<IStorageAccessor>(system, m_impl); | ||
33 | R_SUCCEED(); | ||
34 | } | ||
35 | |||
36 | Result IStorage::OpenTransferStorage( | ||
37 | Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor) { | ||
38 | R_UNLESS(m_impl->GetHandle() != nullptr, AM::ResultInvalidStorageType); | ||
39 | |||
40 | *out_transfer_storage_accessor = std::make_shared<ITransferStorageAccessor>(system, m_impl); | ||
41 | R_SUCCEED(); | ||
42 | } | ||
43 | |||
44 | std::vector<u8> IStorage::GetData() const { | ||
45 | return m_impl->GetData(); | ||
46 | } | ||
47 | |||
48 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/storage.h b/src/core/hle/service/am/service/storage.h new file mode 100755 index 000000000..cde2ed0ea --- /dev/null +++ b/src/core/hle/service/am/service/storage.h | |||
@@ -0,0 +1,35 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | class LibraryAppletStorage; | ||
12 | class IStorageAccessor; | ||
13 | class ITransferStorageAccessor; | ||
14 | |||
15 | class IStorage final : public ServiceFramework<IStorage> { | ||
16 | public: | ||
17 | explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl); | ||
18 | explicit IStorage(Core::System& system_, std::vector<u8>&& buffer); | ||
19 | ~IStorage() override; | ||
20 | |||
21 | std::shared_ptr<LibraryAppletStorage> GetImpl() const { | ||
22 | return m_impl; | ||
23 | } | ||
24 | |||
25 | std::vector<u8> GetData() const; | ||
26 | |||
27 | private: | ||
28 | Result Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor); | ||
29 | Result OpenTransferStorage( | ||
30 | Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor); | ||
31 | |||
32 | const std::shared_ptr<LibraryAppletStorage> m_impl; | ||
33 | }; | ||
34 | |||
35 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/storage_accessor.cpp b/src/core/hle/service/am/service/storage_accessor.cpp new file mode 100755 index 000000000..84577fee4 --- /dev/null +++ b/src/core/hle/service/am/service/storage_accessor.cpp | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/kernel/k_transfer_memory.h" | ||
5 | #include "core/hle/service/am/library_applet_storage.h" | ||
6 | #include "core/hle/service/am/service/storage_accessor.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | IStorageAccessor::IStorageAccessor(Core::System& system_, | ||
12 | std::shared_ptr<LibraryAppletStorage> impl) | ||
13 | : ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} { | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, D<&IStorageAccessor::GetSize>, "GetSize"}, | ||
16 | {10, D<&IStorageAccessor::Write>, "Write"}, | ||
17 | {11, D<&IStorageAccessor::Read>, "Read"}, | ||
18 | }; | ||
19 | |||
20 | RegisterHandlers(functions); | ||
21 | } | ||
22 | |||
23 | IStorageAccessor::~IStorageAccessor() = default; | ||
24 | |||
25 | Result IStorageAccessor::GetSize(Out<s64> out_size) { | ||
26 | LOG_DEBUG(Service_AM, "called"); | ||
27 | *out_size = m_impl->GetSize(); | ||
28 | R_SUCCEED(); | ||
29 | } | ||
30 | |||
31 | Result IStorageAccessor::Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) { | ||
32 | LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size()); | ||
33 | R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size())); | ||
34 | } | ||
35 | |||
36 | Result IStorageAccessor::Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) { | ||
37 | LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size()); | ||
38 | R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size())); | ||
39 | } | ||
40 | |||
41 | ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_, | ||
42 | std::shared_ptr<LibraryAppletStorage> impl) | ||
43 | : ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} { | ||
44 | static const FunctionInfo functions[] = { | ||
45 | {0, D<&ITransferStorageAccessor::GetSize>, "GetSize"}, | ||
46 | {1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"}, | ||
47 | }; | ||
48 | |||
49 | RegisterHandlers(functions); | ||
50 | } | ||
51 | |||
52 | ITransferStorageAccessor::~ITransferStorageAccessor() = default; | ||
53 | |||
54 | Result ITransferStorageAccessor::GetSize(Out<s64> out_size) { | ||
55 | LOG_DEBUG(Service_AM, "called"); | ||
56 | *out_size = m_impl->GetSize(); | ||
57 | R_SUCCEED(); | ||
58 | } | ||
59 | |||
60 | Result ITransferStorageAccessor::GetHandle(Out<s64> out_size, | ||
61 | OutCopyHandle<Kernel::KTransferMemory> out_handle) { | ||
62 | LOG_INFO(Service_AM, "called"); | ||
63 | *out_size = m_impl->GetSize(); | ||
64 | *out_handle = m_impl->GetHandle(); | ||
65 | R_SUCCEED(); | ||
66 | } | ||
67 | |||
68 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/storage_accessor.h b/src/core/hle/service/am/service/storage_accessor.h new file mode 100755 index 000000000..1a01730e0 --- /dev/null +++ b/src/core/hle/service/am/service/storage_accessor.h | |||
@@ -0,0 +1,38 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/am/library_applet_storage.h" | ||
7 | #include "core/hle/service/cmif_types.h" | ||
8 | #include "core/hle/service/service.h" | ||
9 | |||
10 | namespace Service::AM { | ||
11 | |||
12 | class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { | ||
13 | public: | ||
14 | explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl); | ||
15 | ~IStorageAccessor() override; | ||
16 | |||
17 | private: | ||
18 | Result GetSize(Out<s64> out_size); | ||
19 | Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset); | ||
20 | Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset); | ||
21 | |||
22 | const std::shared_ptr<LibraryAppletStorage> m_impl; | ||
23 | }; | ||
24 | |||
25 | class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> { | ||
26 | public: | ||
27 | explicit ITransferStorageAccessor(Core::System& system_, | ||
28 | std::shared_ptr<LibraryAppletStorage> impl); | ||
29 | ~ITransferStorageAccessor() override; | ||
30 | |||
31 | private: | ||
32 | Result GetSize(Out<s64> out_size); | ||
33 | Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle); | ||
34 | |||
35 | const std::shared_ptr<LibraryAppletStorage> m_impl; | ||
36 | }; | ||
37 | |||
38 | } // 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 new file mode 100755 index 000000000..5ec509d2e --- /dev/null +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp | |||
@@ -0,0 +1,133 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/service/applet_common_functions.h" | ||
5 | #include "core/hle/service/am/service/application_creator.h" | ||
6 | #include "core/hle/service/am/service/audio_controller.h" | ||
7 | #include "core/hle/service/am/service/common_state_getter.h" | ||
8 | #include "core/hle/service/am/service/debug_functions.h" | ||
9 | #include "core/hle/service/am/service/display_controller.h" | ||
10 | #include "core/hle/service/am/service/global_state_controller.h" | ||
11 | #include "core/hle/service/am/service/home_menu_functions.h" | ||
12 | #include "core/hle/service/am/service/library_applet_creator.h" | ||
13 | #include "core/hle/service/am/service/process_winding_controller.h" | ||
14 | #include "core/hle/service/am/service/self_controller.h" | ||
15 | #include "core/hle/service/am/service/system_applet_proxy.h" | ||
16 | #include "core/hle/service/am/service/window_controller.h" | ||
17 | #include "core/hle/service/cmif_serialization.h" | ||
18 | |||
19 | namespace Service::AM { | ||
20 | |||
21 | ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, | ||
22 | Kernel::KProcess* process, | ||
23 | Nvnflinger::Nvnflinger& nvnflinger) | ||
24 | : ServiceFramework{system_, "ISystemAppletProxy"}, | ||
25 | m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { | ||
26 | // clang-format off | ||
27 | static const FunctionInfo functions[] = { | ||
28 | {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, | ||
29 | {1, D<&ISystemAppletProxy::GetSelfController>, "GetSelfController"}, | ||
30 | {2, D<&ISystemAppletProxy::GetWindowController>, "GetWindowController"}, | ||
31 | {3, D<&ISystemAppletProxy::GetAudioController>, "GetAudioController"}, | ||
32 | {4, D<&ISystemAppletProxy::GetDisplayController>, "GetDisplayController"}, | ||
33 | {10, D<&ISystemAppletProxy::GetProcessWindingController>, "GetProcessWindingController"}, | ||
34 | {11, D<&ISystemAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"}, | ||
35 | {20, D<&ISystemAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"}, | ||
36 | {21, D<&ISystemAppletProxy::GetGlobalStateController>, "GetGlobalStateController"}, | ||
37 | {22, D<&ISystemAppletProxy::GetApplicationCreator>, "GetApplicationCreator"}, | ||
38 | {23, D<&ISystemAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"}, | ||
39 | {1000, D<&ISystemAppletProxy::GetDebugFunctions>, "GetDebugFunctions"}, | ||
40 | }; | ||
41 | // clang-format on | ||
42 | |||
43 | RegisterHandlers(functions); | ||
44 | } | ||
45 | |||
46 | ISystemAppletProxy::~ISystemAppletProxy() = default; | ||
47 | |||
48 | Result ISystemAppletProxy::GetAudioController( | ||
49 | Out<SharedPointer<IAudioController>> out_audio_controller) { | ||
50 | LOG_DEBUG(Service_AM, "called"); | ||
51 | *out_audio_controller = std::make_shared<IAudioController>(system); | ||
52 | R_SUCCEED(); | ||
53 | } | ||
54 | |||
55 | Result ISystemAppletProxy::GetDisplayController( | ||
56 | Out<SharedPointer<IDisplayController>> out_display_controller) { | ||
57 | LOG_DEBUG(Service_AM, "called"); | ||
58 | *out_display_controller = std::make_shared<IDisplayController>(system, m_applet); | ||
59 | R_SUCCEED(); | ||
60 | } | ||
61 | |||
62 | Result ISystemAppletProxy::GetProcessWindingController( | ||
63 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) { | ||
64 | LOG_DEBUG(Service_AM, "called"); | ||
65 | *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet); | ||
66 | R_SUCCEED(); | ||
67 | } | ||
68 | |||
69 | Result ISystemAppletProxy::GetDebugFunctions( | ||
70 | Out<SharedPointer<IDebugFunctions>> out_debug_functions) { | ||
71 | LOG_DEBUG(Service_AM, "called"); | ||
72 | *out_debug_functions = std::make_shared<IDebugFunctions>(system); | ||
73 | R_SUCCEED(); | ||
74 | } | ||
75 | |||
76 | Result ISystemAppletProxy::GetWindowController( | ||
77 | Out<SharedPointer<IWindowController>> out_window_controller) { | ||
78 | LOG_DEBUG(Service_AM, "called"); | ||
79 | *out_window_controller = std::make_shared<IWindowController>(system, m_applet); | ||
80 | R_SUCCEED(); | ||
81 | } | ||
82 | |||
83 | Result ISystemAppletProxy::GetSelfController( | ||
84 | Out<SharedPointer<ISelfController>> out_self_controller) { | ||
85 | LOG_DEBUG(Service_AM, "called"); | ||
86 | *out_self_controller = | ||
87 | std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger); | ||
88 | R_SUCCEED(); | ||
89 | } | ||
90 | |||
91 | Result ISystemAppletProxy::GetCommonStateGetter( | ||
92 | Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) { | ||
93 | LOG_DEBUG(Service_AM, "called"); | ||
94 | *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet); | ||
95 | R_SUCCEED(); | ||
96 | } | ||
97 | |||
98 | Result ISystemAppletProxy::GetLibraryAppletCreator( | ||
99 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { | ||
100 | LOG_DEBUG(Service_AM, "called"); | ||
101 | *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); | ||
102 | R_SUCCEED(); | ||
103 | } | ||
104 | |||
105 | Result ISystemAppletProxy::GetApplicationCreator( | ||
106 | Out<SharedPointer<IApplicationCreator>> out_application_creator) { | ||
107 | LOG_DEBUG(Service_AM, "called"); | ||
108 | *out_application_creator = std::make_shared<IApplicationCreator>(system); | ||
109 | R_SUCCEED(); | ||
110 | } | ||
111 | |||
112 | Result ISystemAppletProxy::GetAppletCommonFunctions( | ||
113 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) { | ||
114 | LOG_DEBUG(Service_AM, "called"); | ||
115 | *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet); | ||
116 | R_SUCCEED(); | ||
117 | } | ||
118 | |||
119 | Result ISystemAppletProxy::GetHomeMenuFunctions( | ||
120 | Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { | ||
121 | LOG_DEBUG(Service_AM, "called"); | ||
122 | *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); | ||
123 | R_SUCCEED(); | ||
124 | } | ||
125 | |||
126 | Result ISystemAppletProxy::GetGlobalStateController( | ||
127 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller) { | ||
128 | LOG_DEBUG(Service_AM, "called"); | ||
129 | *out_global_state_controller = std::make_shared<IGlobalStateController>(system); | ||
130 | R_SUCCEED(); | ||
131 | } | ||
132 | |||
133 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h new file mode 100755 index 000000000..3d5040315 --- /dev/null +++ b/src/core/hle/service/am/service/system_applet_proxy.h | |||
@@ -0,0 +1,54 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | class IAppletCommonFunctions; | ||
13 | class IApplicationCreator; | ||
14 | class IAudioController; | ||
15 | class ICommonStateGetter; | ||
16 | class IDebugFunctions; | ||
17 | class IDisplayController; | ||
18 | class IHomeMenuFunctions; | ||
19 | class IGlobalStateController; | ||
20 | class ILibraryAppletCreator; | ||
21 | class IProcessWindingController; | ||
22 | class ISelfController; | ||
23 | class IWindowController; | ||
24 | |||
25 | class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { | ||
26 | public: | ||
27 | explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, | ||
28 | Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); | ||
29 | ~ISystemAppletProxy(); | ||
30 | |||
31 | private: | ||
32 | Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller); | ||
33 | Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller); | ||
34 | Result GetProcessWindingController( | ||
35 | Out<SharedPointer<IProcessWindingController>> out_process_winding_controller); | ||
36 | Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions); | ||
37 | Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller); | ||
38 | Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller); | ||
39 | Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter); | ||
40 | Result GetLibraryAppletCreator( | ||
41 | Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator); | ||
42 | Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator); | ||
43 | Result GetAppletCommonFunctions( | ||
44 | Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions); | ||
45 | Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions); | ||
46 | Result GetGlobalStateController( | ||
47 | Out<SharedPointer<IGlobalStateController>> out_global_state_controller); | ||
48 | |||
49 | Nvnflinger::Nvnflinger& m_nvnflinger; | ||
50 | Kernel::KProcess* const m_process; | ||
51 | const std::shared_ptr<Applet> m_applet; | ||
52 | }; | ||
53 | |||
54 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp new file mode 100755 index 000000000..b874ecb91 --- /dev/null +++ b/src/core/hle/service/am/service/window_controller.cpp | |||
@@ -0,0 +1,86 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/am/applet.h" | ||
5 | #include "core/hle/service/am/applet_manager.h" | ||
6 | #include "core/hle/service/am/service/window_controller.h" | ||
7 | #include "core/hle/service/cmif_serialization.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet) | ||
12 | : ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} { | ||
13 | // clang-format off | ||
14 | static const FunctionInfo functions[] = { | ||
15 | {0, nullptr, "CreateWindow"}, | ||
16 | {1, D<&IWindowController::GetAppletResourceUserId>, "GetAppletResourceUserId"}, | ||
17 | {2, D<&IWindowController::GetAppletResourceUserIdOfCallerApplet>, "GetAppletResourceUserIdOfCallerApplet"}, | ||
18 | {10, D<&IWindowController::AcquireForegroundRights>, "AcquireForegroundRights"}, | ||
19 | {11, D<&IWindowController::ReleaseForegroundRights>, "ReleaseForegroundRights"}, | ||
20 | {12, D<&IWindowController::RejectToChangeIntoBackground>, "RejectToChangeIntoBackground"}, | ||
21 | {20, D<&IWindowController::SetAppletWindowVisibility>, "SetAppletWindowVisibility"}, | ||
22 | {21, D<&IWindowController::SetAppletGpuTimeSlice>, "SetAppletGpuTimeSlice"}, | ||
23 | }; | ||
24 | // clang-format on | ||
25 | |||
26 | RegisterHandlers(functions); | ||
27 | } | ||
28 | |||
29 | IWindowController::~IWindowController() = default; | ||
30 | |||
31 | Result IWindowController::GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid) { | ||
32 | LOG_INFO(Service_AM, "called"); | ||
33 | *out_aruid = m_applet->aruid; | ||
34 | R_SUCCEED(); | ||
35 | } | ||
36 | |||
37 | Result IWindowController::GetAppletResourceUserIdOfCallerApplet( | ||
38 | Out<AppletResourceUserId> out_aruid) { | ||
39 | LOG_INFO(Service_AM, "called"); | ||
40 | |||
41 | if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet != nullptr) { | ||
42 | *out_aruid = caller_applet->aruid; | ||
43 | } else { | ||
44 | *out_aruid = AppletResourceUserId{}; | ||
45 | } | ||
46 | |||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
50 | Result IWindowController::AcquireForegroundRights() { | ||
51 | LOG_INFO(Service_AM, "called"); | ||
52 | R_SUCCEED(); | ||
53 | } | ||
54 | |||
55 | Result IWindowController::ReleaseForegroundRights() { | ||
56 | LOG_INFO(Service_AM, "called"); | ||
57 | R_SUCCEED(); | ||
58 | } | ||
59 | |||
60 | Result IWindowController::RejectToChangeIntoBackground() { | ||
61 | LOG_INFO(Service_AM, "called"); | ||
62 | R_SUCCEED(); | ||
63 | } | ||
64 | |||
65 | Result IWindowController::SetAppletWindowVisibility(bool visible) { | ||
66 | m_applet->system_buffer_manager.SetWindowVisibility(visible); | ||
67 | m_applet->hid_registration.EnableAppletToGetInput(visible); | ||
68 | |||
69 | if (visible) { | ||
70 | m_applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground); | ||
71 | m_applet->focus_state = FocusState::InFocus; | ||
72 | } else { | ||
73 | m_applet->focus_state = FocusState::NotInFocus; | ||
74 | } | ||
75 | |||
76 | m_applet->message_queue.PushMessage(AppletMessage::FocusStateChanged); | ||
77 | |||
78 | R_SUCCEED(); | ||
79 | } | ||
80 | |||
81 | Result IWindowController::SetAppletGpuTimeSlice(s64 time_slice) { | ||
82 | LOG_WARNING(Service_AM, "(STUBBED) called, time_slice={}", time_slice); | ||
83 | R_SUCCEED(); | ||
84 | } | ||
85 | |||
86 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/service/window_controller.h b/src/core/hle/service/am/service/window_controller.h new file mode 100755 index 000000000..bfbad9bcc --- /dev/null +++ b/src/core/hle/service/am/service/window_controller.h | |||
@@ -0,0 +1,30 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Service::AM { | ||
10 | |||
11 | struct Applet; | ||
12 | |||
13 | class IWindowController final : public ServiceFramework<IWindowController> { | ||
14 | public: | ||
15 | explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet); | ||
16 | ~IWindowController() override; | ||
17 | |||
18 | private: | ||
19 | Result GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid); | ||
20 | Result GetAppletResourceUserIdOfCallerApplet(Out<AppletResourceUserId> out_aruid); | ||
21 | Result AcquireForegroundRights(); | ||
22 | Result ReleaseForegroundRights(); | ||
23 | Result RejectToChangeIntoBackground(); | ||
24 | Result SetAppletWindowVisibility(bool visible); | ||
25 | Result SetAppletGpuTimeSlice(s64 time_slice); | ||
26 | |||
27 | const std::shared_ptr<Applet> m_applet; | ||
28 | }; | ||
29 | |||
30 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp index 478557dda..74c6942a4 100755 --- a/src/core/hle/service/ldn/lan_discovery.cpp +++ b/src/core/hle/service/ldn/lan_discovery.cpp | |||
@@ -85,15 +85,14 @@ Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network) const { | |||
85 | } | 85 | } |
86 | 86 | ||
87 | Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network, | 87 | Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network, |
88 | std::vector<NodeLatestUpdate>& out_updates, | 88 | std::span<NodeLatestUpdate> out_updates) { |
89 | std::size_t buffer_count) { | 89 | if (out_updates.size() > NodeCountMax) { |
90 | if (buffer_count > NodeCountMax) { | ||
91 | return ResultInvalidBufferCount; | 90 | return ResultInvalidBufferCount; |
92 | } | 91 | } |
93 | 92 | ||
94 | if (state == State::AccessPointCreated || state == State::StationConnected) { | 93 | if (state == State::AccessPointCreated || state == State::StationConnected) { |
95 | std::memcpy(&out_network, &network_info, sizeof(network_info)); | 94 | std::memcpy(&out_network, &network_info, sizeof(network_info)); |
96 | for (std::size_t i = 0; i < buffer_count; i++) { | 95 | for (std::size_t i = 0; i < out_updates.size(); i++) { |
97 | out_updates[i].state_change = node_changes[i].state_change; | 96 | out_updates[i].state_change = node_changes[i].state_change; |
98 | node_changes[i].state_change = NodeStateChange::None; | 97 | node_changes[i].state_change = NodeStateChange::None; |
99 | } | 98 | } |
@@ -107,15 +106,8 @@ DisconnectReason LANDiscovery::GetDisconnectReason() const { | |||
107 | return disconnect_reason; | 106 | return disconnect_reason; |
108 | } | 107 | } |
109 | 108 | ||
110 | Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | 109 | Result LANDiscovery::Scan(std::span<NetworkInfo> out_networks, s16& out_count, |
111 | const ScanFilter& filter) { | 110 | const ScanFilter& filter) { |
112 | if (!IsFlagSet(filter.flag, ScanFilterFlag::NetworkType) || | ||
113 | filter.network_type <= NetworkType::All) { | ||
114 | if (!IsFlagSet(filter.flag, ScanFilterFlag::Ssid) && filter.ssid.length >= SsidLengthMax) { | ||
115 | return ResultBadInput; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | { | 111 | { |
120 | std::scoped_lock lock{packet_mutex}; | 112 | std::scoped_lock lock{packet_mutex}; |
121 | scan_results.clear(); | 113 | scan_results.clear(); |
@@ -128,7 +120,7 @@ Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | |||
128 | 120 | ||
129 | std::scoped_lock lock{packet_mutex}; | 121 | std::scoped_lock lock{packet_mutex}; |
130 | for (const auto& [key, info] : scan_results) { | 122 | for (const auto& [key, info] : scan_results) { |
131 | if (count >= networks.size()) { | 123 | if (out_count >= static_cast<s16>(out_networks.size())) { |
132 | break; | 124 | break; |
133 | } | 125 | } |
134 | 126 | ||
@@ -159,7 +151,7 @@ Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count, | |||
159 | } | 151 | } |
160 | } | 152 | } |
161 | 153 | ||
162 | networks[count++] = info; | 154 | out_networks[out_count++] = info; |
163 | } | 155 | } |
164 | 156 | ||
165 | return ResultSuccess; | 157 | return ResultSuccess; |
diff --git a/src/core/hle/service/ldn/lan_discovery.h b/src/core/hle/service/ldn/lan_discovery.h index d2860d6a8..8fd54e8b8 100755 --- a/src/core/hle/service/ldn/lan_discovery.h +++ b/src/core/hle/service/ldn/lan_discovery.h | |||
@@ -54,11 +54,10 @@ public: | |||
54 | void SetState(State new_state); | 54 | void SetState(State new_state); |
55 | 55 | ||
56 | Result GetNetworkInfo(NetworkInfo& out_network) const; | 56 | Result GetNetworkInfo(NetworkInfo& out_network) const; |
57 | Result GetNetworkInfo(NetworkInfo& out_network, std::vector<NodeLatestUpdate>& out_updates, | 57 | Result GetNetworkInfo(NetworkInfo& out_network, std::span<NodeLatestUpdate> out_updates); |
58 | std::size_t buffer_count); | ||
59 | 58 | ||
60 | DisconnectReason GetDisconnectReason() const; | 59 | DisconnectReason GetDisconnectReason() const; |
61 | Result Scan(std::vector<NetworkInfo>& networks, u16& count, const ScanFilter& filter); | 60 | Result Scan(std::span<NetworkInfo> out_networks, s16& out_count, const ScanFilter& filter); |
62 | Result SetAdvertiseData(std::span<const u8> data); | 61 | Result SetAdvertiseData(std::span<const u8> data); |
63 | 62 | ||
64 | Result OpenAccessPoint(); | 63 | Result OpenAccessPoint(); |
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index c3ba38e72..3f1881119 100755 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp | |||
@@ -1,36 +1,24 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2018 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 <memory> | ||
5 | |||
6 | #include "core/core.h" | 4 | #include "core/core.h" |
7 | #include "core/hle/service/ldn/lan_discovery.h" | 5 | #include "core/hle/service/cmif_serialization.h" |
8 | #include "core/hle/service/ldn/ldn.h" | 6 | #include "core/hle/service/ldn/ldn.h" |
9 | #include "core/hle/service/ldn/ldn_results.h" | 7 | #include "core/hle/service/ldn/monitor_service.h" |
10 | #include "core/hle/service/ldn/ldn_types.h" | 8 | #include "core/hle/service/ldn/sf_monitor_service.h" |
11 | #include "core/hle/service/server_manager.h" | 9 | #include "core/hle/service/ldn/sf_service.h" |
12 | #include "core/internal_network/network.h" | 10 | #include "core/hle/service/ldn/sf_service_monitor.h" |
13 | #include "core/internal_network/network_interface.h" | 11 | #include "core/hle/service/ldn/system_local_communication_service.h" |
14 | #include "network/network.h" | 12 | #include "core/hle/service/ldn/user_local_communication_service.h" |
15 | |||
16 | // This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent | ||
17 | #undef CreateEvent | ||
18 | 13 | ||
19 | namespace Service::LDN { | 14 | namespace Service::LDN { |
20 | 15 | ||
21 | class IMonitorService final : public ServiceFramework<IMonitorService> { | 16 | class IMonitorServiceCreator final : public ServiceFramework<IMonitorServiceCreator> { |
22 | public: | 17 | public: |
23 | explicit IMonitorService(Core::System& system_) : ServiceFramework{system_, "IMonitorService"} { | 18 | explicit IMonitorServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:m"} { |
24 | // clang-format off | 19 | // clang-format off |
25 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
26 | {0, &IMonitorService::GetStateForMonitor, "GetStateForMonitor"}, | 21 | {0, C<&IMonitorServiceCreator::CreateMonitorService>, "CreateMonitorService"} |
27 | {1, nullptr, "GetNetworkInfoForMonitor"}, | ||
28 | {2, nullptr, "GetIpv4AddressForMonitor"}, | ||
29 | {3, nullptr, "GetDisconnectReasonForMonitor"}, | ||
30 | {4, nullptr, "GetSecurityParameterForMonitor"}, | ||
31 | {5, nullptr, "GetNetworkConfigForMonitor"}, | ||
32 | {100, &IMonitorService::InitializeMonitor, "InitializeMonitor"}, | ||
33 | {101, nullptr, "FinalizeMonitor"}, | ||
34 | }; | 22 | }; |
35 | // clang-format on | 23 | // clang-format on |
36 | 24 | ||
@@ -38,84 +26,20 @@ public: | |||
38 | } | 26 | } |
39 | 27 | ||
40 | private: | 28 | private: |
41 | void GetStateForMonitor(HLERequestContext& ctx) { | 29 | Result CreateMonitorService(OutInterface<IMonitorService> out_interface) { |
42 | LOG_INFO(Service_LDN, "called"); | ||
43 | |||
44 | IPC::ResponseBuilder rb{ctx, 3}; | ||
45 | rb.Push(ResultSuccess); | ||
46 | rb.PushEnum(state); | ||
47 | } | ||
48 | |||
49 | void InitializeMonitor(HLERequestContext& ctx) { | ||
50 | LOG_INFO(Service_LDN, "called"); | ||
51 | |||
52 | state = State::Initialized; | ||
53 | |||
54 | IPC::ResponseBuilder rb{ctx, 2}; | ||
55 | rb.Push(ResultSuccess); | ||
56 | } | ||
57 | |||
58 | State state{State::None}; | ||
59 | }; | ||
60 | |||
61 | class LDNM final : public ServiceFramework<LDNM> { | ||
62 | public: | ||
63 | explicit LDNM(Core::System& system_) : ServiceFramework{system_, "ldn:m"} { | ||
64 | // clang-format off | ||
65 | static const FunctionInfo functions[] = { | ||
66 | {0, &LDNM::CreateMonitorService, "CreateMonitorService"} | ||
67 | }; | ||
68 | // clang-format on | ||
69 | |||
70 | RegisterHandlers(functions); | ||
71 | } | ||
72 | |||
73 | void CreateMonitorService(HLERequestContext& ctx) { | ||
74 | LOG_DEBUG(Service_LDN, "called"); | 30 | LOG_DEBUG(Service_LDN, "called"); |
75 | 31 | ||
76 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 32 | *out_interface = std::make_shared<IMonitorService>(system); |
77 | rb.Push(ResultSuccess); | 33 | R_SUCCEED(); |
78 | rb.PushIpcInterface<IMonitorService>(system); | ||
79 | } | 34 | } |
80 | }; | 35 | }; |
81 | 36 | ||
82 | class ISystemLocalCommunicationService final | 37 | class ISystemServiceCreator final : public ServiceFramework<ISystemServiceCreator> { |
83 | : public ServiceFramework<ISystemLocalCommunicationService> { | ||
84 | public: | 38 | public: |
85 | explicit ISystemLocalCommunicationService(Core::System& system_) | 39 | explicit ISystemServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:s"} { |
86 | : ServiceFramework{system_, "ISystemLocalCommunicationService"} { | ||
87 | // clang-format off | 40 | // clang-format off |
88 | static const FunctionInfo functions[] = { | 41 | static const FunctionInfo functions[] = { |
89 | {0, nullptr, "GetState"}, | 42 | {0, C<&ISystemServiceCreator::CreateSystemLocalCommunicationService>, "CreateSystemLocalCommunicationService"}, |
90 | {1, nullptr, "GetNetworkInfo"}, | ||
91 | {2, nullptr, "GetIpv4Address"}, | ||
92 | {3, nullptr, "GetDisconnectReason"}, | ||
93 | {4, nullptr, "GetSecurityParameter"}, | ||
94 | {5, nullptr, "GetNetworkConfig"}, | ||
95 | {100, nullptr, "AttachStateChangeEvent"}, | ||
96 | {101, nullptr, "GetNetworkInfoLatestUpdate"}, | ||
97 | {102, nullptr, "Scan"}, | ||
98 | {103, nullptr, "ScanPrivate"}, | ||
99 | {104, nullptr, "SetWirelessControllerRestriction"}, | ||
100 | {200, nullptr, "OpenAccessPoint"}, | ||
101 | {201, nullptr, "CloseAccessPoint"}, | ||
102 | {202, nullptr, "CreateNetwork"}, | ||
103 | {203, nullptr, "CreateNetworkPrivate"}, | ||
104 | {204, nullptr, "DestroyNetwork"}, | ||
105 | {205, nullptr, "Reject"}, | ||
106 | {206, nullptr, "SetAdvertiseData"}, | ||
107 | {207, nullptr, "SetStationAcceptPolicy"}, | ||
108 | {208, nullptr, "AddAcceptFilterEntry"}, | ||
109 | {209, nullptr, "ClearAcceptFilter"}, | ||
110 | {300, nullptr, "OpenStation"}, | ||
111 | {301, nullptr, "CloseStation"}, | ||
112 | {302, nullptr, "Connect"}, | ||
113 | {303, nullptr, "ConnectPrivate"}, | ||
114 | {304, nullptr, "Disconnect"}, | ||
115 | {400, nullptr, "InitializeSystem"}, | ||
116 | {401, nullptr, "FinalizeSystem"}, | ||
117 | {402, nullptr, "SetOperationMode"}, | ||
118 | {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"}, | ||
119 | }; | 43 | }; |
120 | // clang-format on | 44 | // clang-format on |
121 | 45 | ||
@@ -123,687 +47,78 @@ public: | |||
123 | } | 47 | } |
124 | 48 | ||
125 | private: | 49 | private: |
126 | void InitializeSystem2(HLERequestContext& ctx) { | 50 | Result CreateSystemLocalCommunicationService( |
127 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | 51 | OutInterface<ISystemLocalCommunicationService> out_interface) { |
128 | |||
129 | IPC::ResponseBuilder rb{ctx, 2}; | ||
130 | rb.Push(ResultSuccess); | ||
131 | } | ||
132 | }; | ||
133 | |||
134 | class IUserLocalCommunicationService final | ||
135 | : public ServiceFramework<IUserLocalCommunicationService> { | ||
136 | public: | ||
137 | explicit IUserLocalCommunicationService(Core::System& system_) | ||
138 | : ServiceFramework{system_, "IUserLocalCommunicationService"}, | ||
139 | service_context{system, "IUserLocalCommunicationService"}, | ||
140 | room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { | ||
141 | // clang-format off | ||
142 | static const FunctionInfo functions[] = { | ||
143 | {0, &IUserLocalCommunicationService::GetState, "GetState"}, | ||
144 | {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"}, | ||
145 | {2, &IUserLocalCommunicationService::GetIpv4Address, "GetIpv4Address"}, | ||
146 | {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"}, | ||
147 | {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"}, | ||
148 | {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"}, | ||
149 | {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"}, | ||
150 | {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"}, | ||
151 | {102, &IUserLocalCommunicationService::Scan, "Scan"}, | ||
152 | {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"}, | ||
153 | {104, &IUserLocalCommunicationService::SetWirelessControllerRestriction, "SetWirelessControllerRestriction"}, | ||
154 | {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"}, | ||
155 | {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"}, | ||
156 | {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"}, | ||
157 | {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"}, | ||
158 | {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"}, | ||
159 | {205, nullptr, "Reject"}, | ||
160 | {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"}, | ||
161 | {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"}, | ||
162 | {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"}, | ||
163 | {209, nullptr, "ClearAcceptFilter"}, | ||
164 | {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"}, | ||
165 | {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"}, | ||
166 | {302, &IUserLocalCommunicationService::Connect, "Connect"}, | ||
167 | {303, nullptr, "ConnectPrivate"}, | ||
168 | {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"}, | ||
169 | {400, &IUserLocalCommunicationService::Initialize, "Initialize"}, | ||
170 | {401, &IUserLocalCommunicationService::Finalize, "Finalize"}, | ||
171 | {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, | ||
172 | }; | ||
173 | // clang-format on | ||
174 | |||
175 | RegisterHandlers(functions); | ||
176 | |||
177 | state_change_event = | ||
178 | service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); | ||
179 | } | ||
180 | |||
181 | ~IUserLocalCommunicationService() { | ||
182 | if (is_initialized) { | ||
183 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
184 | room_member->Unbind(ldn_packet_received); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | service_context.CloseEvent(state_change_event); | ||
189 | } | ||
190 | |||
191 | /// Callback to parse and handle a received LDN packet. | ||
192 | void OnLDNPacketReceived(const Network::LDNPacket& packet) { | ||
193 | lan_discovery.ReceivePacket(packet); | ||
194 | } | ||
195 | |||
196 | void OnEventFired() { | ||
197 | state_change_event->Signal(); | ||
198 | } | ||
199 | |||
200 | void GetState(HLERequestContext& ctx) { | ||
201 | State state = State::Error; | ||
202 | |||
203 | if (is_initialized) { | ||
204 | state = lan_discovery.GetState(); | ||
205 | } | ||
206 | |||
207 | IPC::ResponseBuilder rb{ctx, 3}; | ||
208 | rb.Push(ResultSuccess); | ||
209 | rb.PushEnum(state); | ||
210 | } | ||
211 | |||
212 | void GetNetworkInfo(HLERequestContext& ctx) { | ||
213 | const auto write_buffer_size = ctx.GetWriteBufferSize(); | ||
214 | |||
215 | if (write_buffer_size != sizeof(NetworkInfo)) { | ||
216 | LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); | ||
217 | IPC::ResponseBuilder rb{ctx, 2}; | ||
218 | rb.Push(ResultBadInput); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | NetworkInfo network_info{}; | ||
223 | const auto rc = lan_discovery.GetNetworkInfo(network_info); | ||
224 | if (rc.IsError()) { | ||
225 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
226 | IPC::ResponseBuilder rb{ctx, 2}; | ||
227 | rb.Push(rc); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | ctx.WriteBuffer<NetworkInfo>(network_info); | ||
232 | IPC::ResponseBuilder rb{ctx, 2}; | ||
233 | rb.Push(ResultSuccess); | ||
234 | } | ||
235 | |||
236 | void GetIpv4Address(HLERequestContext& ctx) { | ||
237 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
238 | |||
239 | if (!network_interface) { | ||
240 | LOG_ERROR(Service_LDN, "No network interface available"); | ||
241 | IPC::ResponseBuilder rb{ctx, 2}; | ||
242 | rb.Push(ResultNoIpAddress); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | Ipv4Address current_address{Network::TranslateIPv4(network_interface->ip_address)}; | ||
247 | Ipv4Address subnet_mask{Network::TranslateIPv4(network_interface->subnet_mask)}; | ||
248 | |||
249 | // When we're connected to a room, spoof the hosts IP address | ||
250 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
251 | if (room_member->IsConnected()) { | ||
252 | current_address = room_member->GetFakeIpAddress(); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | std::reverse(std::begin(current_address), std::end(current_address)); // ntohl | ||
257 | std::reverse(std::begin(subnet_mask), std::end(subnet_mask)); // ntohl | ||
258 | |||
259 | IPC::ResponseBuilder rb{ctx, 4}; | ||
260 | rb.Push(ResultSuccess); | ||
261 | rb.PushRaw(current_address); | ||
262 | rb.PushRaw(subnet_mask); | ||
263 | } | ||
264 | |||
265 | void GetDisconnectReason(HLERequestContext& ctx) { | ||
266 | IPC::ResponseBuilder rb{ctx, 3}; | ||
267 | rb.Push(ResultSuccess); | ||
268 | rb.PushEnum(lan_discovery.GetDisconnectReason()); | ||
269 | } | ||
270 | |||
271 | void GetSecurityParameter(HLERequestContext& ctx) { | ||
272 | SecurityParameter security_parameter{}; | ||
273 | NetworkInfo info{}; | ||
274 | const Result rc = lan_discovery.GetNetworkInfo(info); | ||
275 | |||
276 | if (rc.IsError()) { | ||
277 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
278 | IPC::ResponseBuilder rb{ctx, 2}; | ||
279 | rb.Push(rc); | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | security_parameter.session_id = info.network_id.session_id; | ||
284 | std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), | ||
285 | sizeof(SecurityParameter::data)); | ||
286 | |||
287 | IPC::ResponseBuilder rb{ctx, 10}; | ||
288 | rb.Push(rc); | ||
289 | rb.PushRaw<SecurityParameter>(security_parameter); | ||
290 | } | ||
291 | |||
292 | void GetNetworkConfig(HLERequestContext& ctx) { | ||
293 | NetworkConfig config{}; | ||
294 | NetworkInfo info{}; | ||
295 | const Result rc = lan_discovery.GetNetworkInfo(info); | ||
296 | |||
297 | if (rc.IsError()) { | ||
298 | LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); | ||
299 | IPC::ResponseBuilder rb{ctx, 2}; | ||
300 | rb.Push(rc); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | config.intent_id = info.network_id.intent_id; | ||
305 | config.channel = info.common.channel; | ||
306 | config.node_count_max = info.ldn.node_count_max; | ||
307 | config.local_communication_version = info.ldn.nodes[0].local_communication_version; | ||
308 | |||
309 | IPC::ResponseBuilder rb{ctx, 10}; | ||
310 | rb.Push(rc); | ||
311 | rb.PushRaw<NetworkConfig>(config); | ||
312 | } | ||
313 | |||
314 | void AttachStateChangeEvent(HLERequestContext& ctx) { | ||
315 | LOG_INFO(Service_LDN, "called"); | ||
316 | |||
317 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
318 | rb.Push(ResultSuccess); | ||
319 | rb.PushCopyObjects(state_change_event->GetReadableEvent()); | ||
320 | } | ||
321 | |||
322 | void GetNetworkInfoLatestUpdate(HLERequestContext& ctx) { | ||
323 | const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); | ||
324 | const std::size_t node_buffer_count = ctx.GetWriteBufferNumElements<NodeLatestUpdate>(1); | ||
325 | |||
326 | if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { | ||
327 | LOG_ERROR(Service_LDN, "Invalid buffer, size = {}, count = {}", network_buffer_size, | ||
328 | node_buffer_count); | ||
329 | IPC::ResponseBuilder rb{ctx, 2}; | ||
330 | rb.Push(ResultBadInput); | ||
331 | return; | ||
332 | } | ||
333 | |||
334 | NetworkInfo info{}; | ||
335 | std::vector<NodeLatestUpdate> latest_update(node_buffer_count); | ||
336 | |||
337 | const auto rc = lan_discovery.GetNetworkInfo(info, latest_update, latest_update.size()); | ||
338 | if (rc.IsError()) { | ||
339 | LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); | ||
340 | IPC::ResponseBuilder rb{ctx, 2}; | ||
341 | rb.Push(rc); | ||
342 | return; | ||
343 | } | ||
344 | |||
345 | ctx.WriteBuffer(info, 0); | ||
346 | ctx.WriteBuffer(latest_update, 1); | ||
347 | |||
348 | IPC::ResponseBuilder rb{ctx, 2}; | ||
349 | rb.Push(ResultSuccess); | ||
350 | } | ||
351 | |||
352 | void Scan(HLERequestContext& ctx) { | ||
353 | ScanImpl(ctx); | ||
354 | } | ||
355 | |||
356 | void ScanPrivate(HLERequestContext& ctx) { | ||
357 | ScanImpl(ctx, true); | ||
358 | } | ||
359 | |||
360 | void ScanImpl(HLERequestContext& ctx, bool is_private = false) { | ||
361 | IPC::RequestParser rp{ctx}; | ||
362 | const auto channel{rp.PopEnum<WifiChannel>()}; | ||
363 | const auto scan_filter{rp.PopRaw<ScanFilter>()}; | ||
364 | |||
365 | const std::size_t network_info_size = ctx.GetWriteBufferNumElements<NetworkInfo>(); | ||
366 | |||
367 | if (network_info_size == 0) { | ||
368 | LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); | ||
369 | IPC::ResponseBuilder rb{ctx, 2}; | ||
370 | rb.Push(ResultBadInput); | ||
371 | return; | ||
372 | } | ||
373 | |||
374 | u16 count = 0; | ||
375 | std::vector<NetworkInfo> network_infos(network_info_size); | ||
376 | Result rc = lan_discovery.Scan(network_infos, count, scan_filter); | ||
377 | |||
378 | LOG_INFO(Service_LDN, | ||
379 | "called, channel={}, filter_scan_flag={}, filter_network_type={}, is_private={}", | ||
380 | channel, scan_filter.flag, scan_filter.network_type, is_private); | ||
381 | |||
382 | ctx.WriteBuffer(network_infos); | ||
383 | |||
384 | IPC::ResponseBuilder rb{ctx, 3}; | ||
385 | rb.Push(rc); | ||
386 | rb.Push<u32>(count); | ||
387 | } | ||
388 | |||
389 | void SetWirelessControllerRestriction(HLERequestContext& ctx) { | ||
390 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
391 | |||
392 | IPC::ResponseBuilder rb{ctx, 2}; | ||
393 | rb.Push(ResultSuccess); | ||
394 | } | ||
395 | |||
396 | void OpenAccessPoint(HLERequestContext& ctx) { | ||
397 | LOG_INFO(Service_LDN, "called"); | ||
398 | |||
399 | IPC::ResponseBuilder rb{ctx, 2}; | ||
400 | rb.Push(lan_discovery.OpenAccessPoint()); | ||
401 | } | ||
402 | |||
403 | void CloseAccessPoint(HLERequestContext& ctx) { | ||
404 | LOG_INFO(Service_LDN, "called"); | ||
405 | |||
406 | IPC::ResponseBuilder rb{ctx, 2}; | ||
407 | rb.Push(lan_discovery.CloseAccessPoint()); | ||
408 | } | ||
409 | |||
410 | void CreateNetwork(HLERequestContext& ctx) { | ||
411 | LOG_INFO(Service_LDN, "called"); | ||
412 | |||
413 | CreateNetworkImpl(ctx); | ||
414 | } | ||
415 | |||
416 | void CreateNetworkPrivate(HLERequestContext& ctx) { | ||
417 | LOG_INFO(Service_LDN, "called"); | ||
418 | |||
419 | CreateNetworkImpl(ctx, true); | ||
420 | } | ||
421 | |||
422 | void CreateNetworkImpl(HLERequestContext& ctx, bool is_private = false) { | ||
423 | IPC::RequestParser rp{ctx}; | ||
424 | |||
425 | const auto security_config{rp.PopRaw<SecurityConfig>()}; | ||
426 | [[maybe_unused]] const auto security_parameter{is_private ? rp.PopRaw<SecurityParameter>() | ||
427 | : SecurityParameter{}}; | ||
428 | const auto user_config{rp.PopRaw<UserConfig>()}; | ||
429 | rp.Pop<u32>(); // Padding | ||
430 | const auto network_Config{rp.PopRaw<NetworkConfig>()}; | ||
431 | |||
432 | IPC::ResponseBuilder rb{ctx, 2}; | ||
433 | rb.Push(lan_discovery.CreateNetwork(security_config, user_config, network_Config)); | ||
434 | } | ||
435 | |||
436 | void DestroyNetwork(HLERequestContext& ctx) { | ||
437 | LOG_INFO(Service_LDN, "called"); | ||
438 | |||
439 | IPC::ResponseBuilder rb{ctx, 2}; | ||
440 | rb.Push(lan_discovery.DestroyNetwork()); | ||
441 | } | ||
442 | |||
443 | void SetAdvertiseData(HLERequestContext& ctx) { | ||
444 | const auto read_buffer = ctx.ReadBuffer(); | ||
445 | |||
446 | IPC::ResponseBuilder rb{ctx, 2}; | ||
447 | rb.Push(lan_discovery.SetAdvertiseData(read_buffer)); | ||
448 | } | ||
449 | |||
450 | void SetStationAcceptPolicy(HLERequestContext& ctx) { | ||
451 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
452 | |||
453 | IPC::ResponseBuilder rb{ctx, 2}; | ||
454 | rb.Push(ResultSuccess); | ||
455 | } | ||
456 | |||
457 | void AddAcceptFilterEntry(HLERequestContext& ctx) { | ||
458 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
459 | |||
460 | IPC::ResponseBuilder rb{ctx, 2}; | ||
461 | rb.Push(ResultSuccess); | ||
462 | } | ||
463 | |||
464 | void OpenStation(HLERequestContext& ctx) { | ||
465 | LOG_INFO(Service_LDN, "called"); | ||
466 | |||
467 | IPC::ResponseBuilder rb{ctx, 2}; | ||
468 | rb.Push(lan_discovery.OpenStation()); | ||
469 | } | ||
470 | |||
471 | void CloseStation(HLERequestContext& ctx) { | ||
472 | LOG_INFO(Service_LDN, "called"); | ||
473 | |||
474 | IPC::ResponseBuilder rb{ctx, 2}; | ||
475 | rb.Push(lan_discovery.CloseStation()); | ||
476 | } | ||
477 | |||
478 | void Connect(HLERequestContext& ctx) { | ||
479 | IPC::RequestParser rp{ctx}; | ||
480 | struct Parameters { | ||
481 | SecurityConfig security_config; | ||
482 | UserConfig user_config; | ||
483 | u32 local_communication_version; | ||
484 | u32 option; | ||
485 | }; | ||
486 | static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); | ||
487 | |||
488 | const auto parameters{rp.PopRaw<Parameters>()}; | ||
489 | |||
490 | LOG_INFO(Service_LDN, | ||
491 | "called, passphrase_size={}, security_mode={}, " | ||
492 | "local_communication_version={}", | ||
493 | parameters.security_config.passphrase_size, | ||
494 | parameters.security_config.security_mode, parameters.local_communication_version); | ||
495 | |||
496 | const auto read_buffer = ctx.ReadBuffer(); | ||
497 | if (read_buffer.size() != sizeof(NetworkInfo)) { | ||
498 | LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); | ||
499 | IPC::ResponseBuilder rb{ctx, 2}; | ||
500 | rb.Push(ResultBadInput); | ||
501 | return; | ||
502 | } | ||
503 | |||
504 | NetworkInfo network_info{}; | ||
505 | std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); | ||
506 | |||
507 | IPC::ResponseBuilder rb{ctx, 2}; | ||
508 | rb.Push(lan_discovery.Connect(network_info, parameters.user_config, | ||
509 | static_cast<u16>(parameters.local_communication_version))); | ||
510 | } | ||
511 | |||
512 | void Disconnect(HLERequestContext& ctx) { | ||
513 | LOG_INFO(Service_LDN, "called"); | ||
514 | |||
515 | IPC::ResponseBuilder rb{ctx, 2}; | ||
516 | rb.Push(lan_discovery.Disconnect()); | ||
517 | } | ||
518 | |||
519 | void Initialize(HLERequestContext& ctx) { | ||
520 | const auto rc = InitializeImpl(ctx); | ||
521 | if (rc.IsError()) { | ||
522 | LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); | ||
523 | } | ||
524 | |||
525 | IPC::ResponseBuilder rb{ctx, 2}; | ||
526 | rb.Push(rc); | ||
527 | } | ||
528 | |||
529 | void Finalize(HLERequestContext& ctx) { | ||
530 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
531 | room_member->Unbind(ldn_packet_received); | ||
532 | } | ||
533 | |||
534 | is_initialized = false; | ||
535 | |||
536 | IPC::ResponseBuilder rb{ctx, 2}; | ||
537 | rb.Push(lan_discovery.Finalize()); | ||
538 | } | ||
539 | |||
540 | void Initialize2(HLERequestContext& ctx) { | ||
541 | const auto rc = InitializeImpl(ctx); | ||
542 | if (rc.IsError()) { | ||
543 | LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); | ||
544 | } | ||
545 | |||
546 | IPC::ResponseBuilder rb{ctx, 2}; | ||
547 | rb.Push(rc); | ||
548 | } | ||
549 | |||
550 | Result InitializeImpl(HLERequestContext& ctx) { | ||
551 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
552 | if (!network_interface) { | ||
553 | LOG_ERROR(Service_LDN, "No network interface is set"); | ||
554 | return ResultAirplaneModeEnabled; | ||
555 | } | ||
556 | |||
557 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
558 | ldn_packet_received = room_member->BindOnLdnPacketReceived( | ||
559 | [this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); }); | ||
560 | } else { | ||
561 | LOG_ERROR(Service_LDN, "Couldn't bind callback!"); | ||
562 | return ResultAirplaneModeEnabled; | ||
563 | } | ||
564 | |||
565 | lan_discovery.Initialize([&]() { OnEventFired(); }); | ||
566 | is_initialized = true; | ||
567 | return ResultSuccess; | ||
568 | } | ||
569 | |||
570 | KernelHelpers::ServiceContext service_context; | ||
571 | Kernel::KEvent* state_change_event; | ||
572 | Network::RoomNetwork& room_network; | ||
573 | LANDiscovery lan_discovery; | ||
574 | |||
575 | // Callback identifier for the OnLDNPacketReceived event. | ||
576 | Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received; | ||
577 | |||
578 | bool is_initialized{}; | ||
579 | }; | ||
580 | |||
581 | class LDNS final : public ServiceFramework<LDNS> { | ||
582 | public: | ||
583 | explicit LDNS(Core::System& system_) : ServiceFramework{system_, "ldn:s"} { | ||
584 | // clang-format off | ||
585 | static const FunctionInfo functions[] = { | ||
586 | {0, &LDNS::CreateSystemLocalCommunicationService, "CreateSystemLocalCommunicationService"}, | ||
587 | }; | ||
588 | // clang-format on | ||
589 | |||
590 | RegisterHandlers(functions); | ||
591 | } | ||
592 | |||
593 | void CreateSystemLocalCommunicationService(HLERequestContext& ctx) { | ||
594 | LOG_DEBUG(Service_LDN, "called"); | 52 | LOG_DEBUG(Service_LDN, "called"); |
595 | 53 | ||
596 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 54 | *out_interface = std::make_shared<ISystemLocalCommunicationService>(system); |
597 | rb.Push(ResultSuccess); | 55 | R_SUCCEED(); |
598 | rb.PushIpcInterface<ISystemLocalCommunicationService>(system); | ||
599 | } | 56 | } |
600 | }; | 57 | }; |
601 | 58 | ||
602 | class LDNU final : public ServiceFramework<LDNU> { | 59 | class IUserServiceCreator final : public ServiceFramework<IUserServiceCreator> { |
603 | public: | 60 | public: |
604 | explicit LDNU(Core::System& system_) : ServiceFramework{system_, "ldn:u"} { | 61 | explicit IUserServiceCreator(Core::System& system_) : ServiceFramework{system_, "ldn:u"} { |
605 | // clang-format off | 62 | // clang-format off |
606 | static const FunctionInfo functions[] = { | 63 | static const FunctionInfo functions[] = { |
607 | {0, &LDNU::CreateUserLocalCommunicationService, "CreateUserLocalCommunicationService"}, | 64 | {0, C<&IUserServiceCreator::CreateUserLocalCommunicationService>, "CreateUserLocalCommunicationService"}, |
608 | }; | 65 | }; |
609 | // clang-format on | 66 | // clang-format on |
610 | 67 | ||
611 | RegisterHandlers(functions); | 68 | RegisterHandlers(functions); |
612 | } | 69 | } |
613 | 70 | ||
614 | void CreateUserLocalCommunicationService(HLERequestContext& ctx) { | 71 | private: |
72 | Result CreateUserLocalCommunicationService( | ||
73 | OutInterface<IUserLocalCommunicationService> out_interface) { | ||
615 | LOG_DEBUG(Service_LDN, "called"); | 74 | LOG_DEBUG(Service_LDN, "called"); |
616 | 75 | ||
617 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 76 | *out_interface = std::make_shared<IUserLocalCommunicationService>(system); |
618 | rb.Push(ResultSuccess); | 77 | R_SUCCEED(); |
619 | rb.PushIpcInterface<IUserLocalCommunicationService>(system); | ||
620 | } | 78 | } |
621 | }; | 79 | }; |
622 | 80 | ||
623 | class INetworkService final : public ServiceFramework<INetworkService> { | 81 | class ISfServiceCreator final : public ServiceFramework<ISfServiceCreator> { |
624 | public: | 82 | public: |
625 | explicit INetworkService(Core::System& system_) : ServiceFramework{system_, "INetworkService"} { | 83 | explicit ISfServiceCreator(Core::System& system_, bool is_system_, const char* name_) |
84 | : ServiceFramework{system_, name_}, is_system{is_system_} { | ||
626 | // clang-format off | 85 | // clang-format off |
627 | static const FunctionInfo functions[] = { | 86 | static const FunctionInfo functions[] = { |
628 | {0, nullptr, "Initialize"}, | 87 | {0, C<&ISfServiceCreator::CreateNetworkService>, "CreateNetworkService"}, |
629 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | 88 | {8, C<&ISfServiceCreator::CreateNetworkServiceMonitor>, "CreateNetworkServiceMonitor"}, |
630 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
631 | {272, nullptr, "GetRole"}, | ||
632 | {280, nullptr, "GetAdvertiseData"}, | ||
633 | {288, nullptr, "GetGroupInfo"}, | ||
634 | {296, nullptr, "GetGroupInfo2"}, | ||
635 | {304, nullptr, "GetGroupOwner"}, | ||
636 | {312, nullptr, "GetIpConfig"}, | ||
637 | {320, nullptr, "GetLinkLevel"}, | ||
638 | {512, nullptr, "Scan"}, | ||
639 | {768, nullptr, "CreateGroup"}, | ||
640 | {776, nullptr, "DestroyGroup"}, | ||
641 | {784, nullptr, "SetAdvertiseData"}, | ||
642 | {1536, nullptr, "SendToOtherGroup"}, | ||
643 | {1544, nullptr, "RecvFromOtherGroup"}, | ||
644 | {1552, nullptr, "AddAcceptableGroupId"}, | ||
645 | {1560, nullptr, "ClearAcceptableGroupId"}, | ||
646 | }; | 89 | }; |
647 | // clang-format on | 90 | // clang-format on |
648 | 91 | ||
649 | RegisterHandlers(functions); | 92 | RegisterHandlers(functions); |
650 | } | 93 | } |
651 | }; | ||
652 | |||
653 | class INetworkServiceMonitor final : public ServiceFramework<INetworkServiceMonitor> { | ||
654 | public: | ||
655 | explicit INetworkServiceMonitor(Core::System& system_) | ||
656 | : ServiceFramework{system_, "INetworkServiceMonitor"} { | ||
657 | // clang-format off | ||
658 | static const FunctionInfo functions[] = { | ||
659 | {0, &INetworkServiceMonitor::Initialize, "Initialize"}, | ||
660 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
661 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
662 | {272, nullptr, "GetRole"}, | ||
663 | {280, nullptr, "GetAdvertiseData"}, | ||
664 | {281, nullptr, "GetAdvertiseData2"}, | ||
665 | {288, nullptr, "GetGroupInfo"}, | ||
666 | {296, nullptr, "GetGroupInfo2"}, | ||
667 | {304, nullptr, "GetGroupOwner"}, | ||
668 | {312, nullptr, "GetIpConfig"}, | ||
669 | {320, nullptr, "GetLinkLevel"}, | ||
670 | {328, nullptr, "AttachJoinEvent"}, | ||
671 | {336, nullptr, "GetMembers"}, | ||
672 | }; | ||
673 | // clang-format on | ||
674 | |||
675 | RegisterHandlers(functions); | ||
676 | } | ||
677 | |||
678 | void Initialize(HLERequestContext& ctx) { | ||
679 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
680 | |||
681 | IPC::ResponseBuilder rb{ctx, 2}; | ||
682 | rb.Push(ResultDisabled); | ||
683 | } | ||
684 | }; | ||
685 | |||
686 | class LP2PAPP final : public ServiceFramework<LP2PAPP> { | ||
687 | public: | ||
688 | explicit LP2PAPP(Core::System& system_) : ServiceFramework{system_, "lp2p:app"} { | ||
689 | // clang-format off | ||
690 | static const FunctionInfo functions[] = { | ||
691 | {0, &LP2PAPP::CreateMonitorService, "CreateNetworkService"}, | ||
692 | {8, &LP2PAPP::CreateMonitorService, "CreateNetworkServiceMonitor"}, | ||
693 | }; | ||
694 | // clang-format on | ||
695 | |||
696 | RegisterHandlers(functions); | ||
697 | } | ||
698 | |||
699 | void CreateNetworkervice(HLERequestContext& ctx) { | ||
700 | IPC::RequestParser rp{ctx}; | ||
701 | const u64 reserved_input = rp.Pop<u64>(); | ||
702 | const u32 input = rp.Pop<u32>(); | ||
703 | |||
704 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, | ||
705 | input); | ||
706 | |||
707 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
708 | rb.Push(ResultSuccess); | ||
709 | rb.PushIpcInterface<INetworkService>(system); | ||
710 | } | ||
711 | |||
712 | void CreateMonitorService(HLERequestContext& ctx) { | ||
713 | IPC::RequestParser rp{ctx}; | ||
714 | const u64 reserved_input = rp.Pop<u64>(); | ||
715 | |||
716 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); | ||
717 | |||
718 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
719 | rb.Push(ResultSuccess); | ||
720 | rb.PushIpcInterface<INetworkServiceMonitor>(system); | ||
721 | } | ||
722 | }; | ||
723 | |||
724 | class LP2PSYS final : public ServiceFramework<LP2PSYS> { | ||
725 | public: | ||
726 | explicit LP2PSYS(Core::System& system_) : ServiceFramework{system_, "lp2p:sys"} { | ||
727 | // clang-format off | ||
728 | static const FunctionInfo functions[] = { | ||
729 | {0, &LP2PSYS::CreateMonitorService, "CreateNetworkService"}, | ||
730 | {8, &LP2PSYS::CreateMonitorService, "CreateNetworkServiceMonitor"}, | ||
731 | }; | ||
732 | // clang-format on | ||
733 | |||
734 | RegisterHandlers(functions); | ||
735 | } | ||
736 | |||
737 | void CreateNetworkervice(HLERequestContext& ctx) { | ||
738 | IPC::RequestParser rp{ctx}; | ||
739 | const u64 reserved_input = rp.Pop<u64>(); | ||
740 | const u32 input = rp.Pop<u32>(); | ||
741 | 94 | ||
95 | private: | ||
96 | Result CreateNetworkService(OutInterface<ISfService> out_interface, u32 input, | ||
97 | u64 reserved_input) { | ||
742 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, | 98 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, |
743 | input); | 99 | input); |
744 | 100 | ||
745 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 101 | *out_interface = std::make_shared<ISfService>(system); |
746 | rb.Push(ResultSuccess); | 102 | R_SUCCEED(); |
747 | rb.PushIpcInterface<INetworkService>(system); | ||
748 | } | 103 | } |
749 | 104 | ||
750 | void CreateMonitorService(HLERequestContext& ctx) { | 105 | Result CreateNetworkServiceMonitor(OutInterface<ISfServiceMonitor> out_interface, |
751 | IPC::RequestParser rp{ctx}; | 106 | u64 reserved_input) { |
752 | const u64 reserved_input = rp.Pop<u64>(); | ||
753 | |||
754 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); | 107 | LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); |
755 | 108 | ||
756 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 109 | *out_interface = std::make_shared<ISfServiceMonitor>(system); |
757 | rb.Push(ResultSuccess); | 110 | R_SUCCEED(); |
758 | rb.PushIpcInterface<INetworkServiceMonitor>(system); | ||
759 | } | 111 | } |
760 | }; | ||
761 | 112 | ||
762 | class ISfMonitorService final : public ServiceFramework<ISfMonitorService> { | 113 | bool is_system{}; |
763 | public: | ||
764 | explicit ISfMonitorService(Core::System& system_) | ||
765 | : ServiceFramework{system_, "ISfMonitorService"} { | ||
766 | // clang-format off | ||
767 | static const FunctionInfo functions[] = { | ||
768 | {0, &ISfMonitorService::Initialize, "Initialize"}, | ||
769 | {288, &ISfMonitorService::GetGroupInfo, "GetGroupInfo"}, | ||
770 | {320, nullptr, "GetLinkLevel"}, | ||
771 | }; | ||
772 | // clang-format on | ||
773 | |||
774 | RegisterHandlers(functions); | ||
775 | } | ||
776 | |||
777 | private: | ||
778 | void Initialize(HLERequestContext& ctx) { | ||
779 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
780 | |||
781 | IPC::ResponseBuilder rb{ctx, 3}; | ||
782 | rb.Push(ResultSuccess); | ||
783 | rb.Push(0); | ||
784 | } | ||
785 | |||
786 | void GetGroupInfo(HLERequestContext& ctx) { | ||
787 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
788 | |||
789 | struct GroupInfo { | ||
790 | std::array<u8, 0x200> info; | ||
791 | }; | ||
792 | |||
793 | GroupInfo group_info{}; | ||
794 | |||
795 | ctx.WriteBuffer(group_info); | ||
796 | IPC::ResponseBuilder rb{ctx, 2}; | ||
797 | rb.Push(ResultSuccess); | ||
798 | } | ||
799 | }; | 114 | }; |
800 | 115 | ||
801 | class LP2PM final : public ServiceFramework<LP2PM> { | 116 | class ISfMonitorServiceCreator final : public ServiceFramework<ISfMonitorServiceCreator> { |
802 | public: | 117 | public: |
803 | explicit LP2PM(Core::System& system_) : ServiceFramework{system_, "lp2p:m"} { | 118 | explicit ISfMonitorServiceCreator(Core::System& system_) : ServiceFramework{system_, "lp2p:m"} { |
804 | // clang-format off | 119 | // clang-format off |
805 | static const FunctionInfo functions[] = { | 120 | static const FunctionInfo functions[] = { |
806 | {0, &LP2PM::CreateMonitorService, "CreateMonitorService"}, | 121 | {0, C<&ISfMonitorServiceCreator::CreateMonitorService>, "CreateMonitorService"}, |
807 | }; | 122 | }; |
808 | // clang-format on | 123 | // clang-format on |
809 | 124 | ||
@@ -811,28 +126,27 @@ public: | |||
811 | } | 126 | } |
812 | 127 | ||
813 | private: | 128 | private: |
814 | void CreateMonitorService(HLERequestContext& ctx) { | 129 | Result CreateMonitorService(OutInterface<ISfMonitorService> out_interface, u64 reserved_input) { |
815 | IPC::RequestParser rp{ctx}; | ||
816 | const u64 reserved_input = rp.Pop<u64>(); | ||
817 | |||
818 | LOG_INFO(Service_LDN, "called, reserved_input={}", reserved_input); | 130 | LOG_INFO(Service_LDN, "called, reserved_input={}", reserved_input); |
819 | 131 | ||
820 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 132 | *out_interface = std::make_shared<ISfMonitorService>(system); |
821 | rb.Push(ResultSuccess); | 133 | R_SUCCEED(); |
822 | rb.PushIpcInterface<ISfMonitorService>(system); | ||
823 | } | 134 | } |
824 | }; | 135 | }; |
825 | 136 | ||
826 | void LoopProcess(Core::System& system) { | 137 | void LoopProcess(Core::System& system) { |
827 | auto server_manager = std::make_unique<ServerManager>(system); | 138 | auto server_manager = std::make_unique<ServerManager>(system); |
828 | 139 | ||
829 | server_manager->RegisterNamedService("ldn:m", std::make_shared<LDNM>(system)); | 140 | server_manager->RegisterNamedService("ldn:m", std::make_shared<IMonitorServiceCreator>(system)); |
830 | server_manager->RegisterNamedService("ldn:s", std::make_shared<LDNS>(system)); | 141 | server_manager->RegisterNamedService("ldn:s", std::make_shared<ISystemServiceCreator>(system)); |
831 | server_manager->RegisterNamedService("ldn:u", std::make_shared<LDNU>(system)); | 142 | server_manager->RegisterNamedService("ldn:u", std::make_shared<IUserServiceCreator>(system)); |
832 | 143 | ||
833 | server_manager->RegisterNamedService("lp2p:app", std::make_shared<LP2PAPP>(system)); | 144 | server_manager->RegisterNamedService( |
834 | server_manager->RegisterNamedService("lp2p:sys", std::make_shared<LP2PSYS>(system)); | 145 | "lp2p:app", std::make_shared<ISfServiceCreator>(system, false, "lp2p:app")); |
835 | server_manager->RegisterNamedService("lp2p:m", std::make_shared<LP2PM>(system)); | 146 | server_manager->RegisterNamedService( |
147 | "lp2p:sys", std::make_shared<ISfServiceCreator>(system, true, "lp2p:sys")); | ||
148 | server_manager->RegisterNamedService("lp2p:m", | ||
149 | std::make_shared<ISfMonitorServiceCreator>(system)); | ||
836 | 150 | ||
837 | ServerManager::RunServer(std::move(server_manager)); | 151 | ServerManager::RunServer(std::move(server_manager)); |
838 | } | 152 | } |
diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index 69439a91c..5303e1482 100755 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h | |||
@@ -3,12 +3,6 @@ | |||
3 | 3 | ||
4 | #pragma once | 4 | #pragma once |
5 | 5 | ||
6 | #include "core/hle/kernel/k_event.h" | ||
7 | #include "core/hle/result.h" | ||
8 | #include "core/hle/service/ipc_helpers.h" | ||
9 | #include "core/hle/service/kernel_helpers.h" | ||
10 | #include "core/hle/service/sm/sm.h" | ||
11 | |||
12 | namespace Core { | 6 | namespace Core { |
13 | class System; | 7 | class System; |
14 | } | 8 | } |
diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h index ddbd51989..047ee3570 100755 --- a/src/core/hle/service/ldn/ldn_types.h +++ b/src/core/hle/service/ldn/ldn_types.h | |||
@@ -123,6 +123,18 @@ enum class NodeStatus : u8 { | |||
123 | Connected, | 123 | Connected, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | enum class WirelessControllerRestriction : u32 { | ||
127 | None, | ||
128 | Default, | ||
129 | }; | ||
130 | |||
131 | struct ConnectOption { | ||
132 | union { | ||
133 | u32 raw; | ||
134 | }; | ||
135 | }; | ||
136 | static_assert(sizeof(ConnectOption) == 0x4, "ConnectOption is an invalid size"); | ||
137 | |||
126 | struct NodeLatestUpdate { | 138 | struct NodeLatestUpdate { |
127 | NodeStateChange state_change; | 139 | NodeStateChange state_change; |
128 | INSERT_PADDING_BYTES(0x7); // Unknown | 140 | INSERT_PADDING_BYTES(0x7); // Unknown |
@@ -139,9 +151,9 @@ static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size"); | |||
139 | 151 | ||
140 | struct IntentId { | 152 | struct IntentId { |
141 | u64 local_communication_id; | 153 | u64 local_communication_id; |
142 | INSERT_PADDING_BYTES(0x2); // Reserved | 154 | INSERT_PADDING_BYTES_NOINIT(0x2); // Reserved |
143 | u16 scene_id; | 155 | u16 scene_id; |
144 | INSERT_PADDING_BYTES(0x4); // Reserved | 156 | INSERT_PADDING_BYTES_NOINIT(0x4); // Reserved |
145 | }; | 157 | }; |
146 | static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); | 158 | static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); |
147 | 159 | ||
@@ -152,13 +164,14 @@ struct NetworkId { | |||
152 | static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); | 164 | static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); |
153 | 165 | ||
154 | struct Ssid { | 166 | struct Ssid { |
155 | u8 length{}; | 167 | u8 length; |
156 | std::array<char, SsidLengthMax + 1> raw{}; | 168 | std::array<char, SsidLengthMax + 1> raw; |
157 | 169 | ||
158 | Ssid() = default; | 170 | Ssid() = default; |
159 | 171 | ||
160 | constexpr explicit Ssid(std::string_view data) { | 172 | constexpr explicit Ssid(std::string_view data) { |
161 | length = static_cast<u8>(std::min(data.size(), SsidLengthMax)); | 173 | length = static_cast<u8>(std::min(data.size(), SsidLengthMax)); |
174 | raw = {}; | ||
162 | data.copy(raw.data(), length); | 175 | data.copy(raw.data(), length); |
163 | raw[length] = 0; | 176 | raw[length] = 0; |
164 | } | 177 | } |
@@ -181,7 +194,7 @@ using Ipv4Address = std::array<u8, 4>; | |||
181 | static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); | 194 | static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); |
182 | 195 | ||
183 | struct MacAddress { | 196 | struct MacAddress { |
184 | std::array<u8, 6> raw{}; | 197 | std::array<u8, 6> raw; |
185 | 198 | ||
186 | friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; | 199 | friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; |
187 | }; | 200 | }; |
@@ -211,7 +224,7 @@ struct CommonNetworkInfo { | |||
211 | WifiChannel channel; | 224 | WifiChannel channel; |
212 | LinkLevel link_level; | 225 | LinkLevel link_level; |
213 | PackedNetworkType network_type; | 226 | PackedNetworkType network_type; |
214 | INSERT_PADDING_BYTES(0x4); | 227 | INSERT_PADDING_BYTES_NOINIT(0x4); |
215 | }; | 228 | }; |
216 | static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); | 229 | static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); |
217 | 230 | ||
@@ -221,9 +234,9 @@ struct NodeInfo { | |||
221 | s8 node_id; | 234 | s8 node_id; |
222 | u8 is_connected; | 235 | u8 is_connected; |
223 | std::array<u8, UserNameBytesMax + 1> user_name; | 236 | std::array<u8, UserNameBytesMax + 1> user_name; |
224 | INSERT_PADDING_BYTES(0x1); // Reserved | 237 | INSERT_PADDING_BYTES_NOINIT(0x1); // Reserved |
225 | s16 local_communication_version; | 238 | s16 local_communication_version; |
226 | INSERT_PADDING_BYTES(0x10); // Reserved | 239 | INSERT_PADDING_BYTES_NOINIT(0x10); // Reserved |
227 | }; | 240 | }; |
228 | static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); | 241 | static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); |
229 | 242 | ||
@@ -232,14 +245,14 @@ struct LdnNetworkInfo { | |||
232 | SecurityMode security_mode; | 245 | SecurityMode security_mode; |
233 | AcceptPolicy station_accept_policy; | 246 | AcceptPolicy station_accept_policy; |
234 | u8 has_action_frame; | 247 | u8 has_action_frame; |
235 | INSERT_PADDING_BYTES(0x2); // Padding | 248 | INSERT_PADDING_BYTES_NOINIT(0x2); // Padding |
236 | u8 node_count_max; | 249 | u8 node_count_max; |
237 | u8 node_count; | 250 | u8 node_count; |
238 | std::array<NodeInfo, NodeCountMax> nodes; | 251 | std::array<NodeInfo, NodeCountMax> nodes; |
239 | INSERT_PADDING_BYTES(0x2); // Reserved | 252 | INSERT_PADDING_BYTES_NOINIT(0x2); // Reserved |
240 | u16 advertise_data_size; | 253 | u16 advertise_data_size; |
241 | std::array<u8, AdvertiseDataSizeMax> advertise_data; | 254 | std::array<u8, AdvertiseDataSizeMax> advertise_data; |
242 | INSERT_PADDING_BYTES(0x8C); // Reserved | 255 | INSERT_PADDING_BYTES_NOINIT(0x8C); // Reserved |
243 | u64 random_authentication_id; | 256 | u64 random_authentication_id; |
244 | }; | 257 | }; |
245 | static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); | 258 | static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); |
@@ -250,6 +263,7 @@ struct NetworkInfo { | |||
250 | LdnNetworkInfo ldn; | 263 | LdnNetworkInfo ldn; |
251 | }; | 264 | }; |
252 | static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); | 265 | static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); |
266 | static_assert(std::is_trivial_v<NetworkInfo>, "NetworkInfo type must be trivially copyable."); | ||
253 | 267 | ||
254 | struct SecurityConfig { | 268 | struct SecurityConfig { |
255 | SecurityMode security_mode; | 269 | SecurityMode security_mode; |
@@ -303,4 +317,36 @@ struct AddressList { | |||
303 | }; | 317 | }; |
304 | static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); | 318 | static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); |
305 | 319 | ||
320 | struct GroupInfo { | ||
321 | std::array<u8, 0x200> info; | ||
322 | }; | ||
323 | |||
324 | struct CreateNetworkConfig { | ||
325 | SecurityConfig security_config; | ||
326 | UserConfig user_config; | ||
327 | INSERT_PADDING_BYTES(0x4); | ||
328 | NetworkConfig network_config; | ||
329 | }; | ||
330 | static_assert(sizeof(CreateNetworkConfig) == 0x98, "CreateNetworkConfig is an invalid size"); | ||
331 | |||
332 | #pragma pack(push, 4) | ||
333 | struct CreateNetworkConfigPrivate { | ||
334 | SecurityConfig security_config; | ||
335 | SecurityParameter security_parameter; | ||
336 | UserConfig user_config; | ||
337 | INSERT_PADDING_BYTES(0x4); | ||
338 | NetworkConfig network_config; | ||
339 | }; | ||
340 | #pragma pack(pop) | ||
341 | static_assert(sizeof(CreateNetworkConfigPrivate) == 0xB8, | ||
342 | "CreateNetworkConfigPrivate is an invalid size"); | ||
343 | |||
344 | struct ConnectNetworkData { | ||
345 | SecurityConfig security_config; | ||
346 | UserConfig user_config; | ||
347 | s32 local_communication_version; | ||
348 | ConnectOption option; | ||
349 | }; | ||
350 | static_assert(sizeof(ConnectNetworkData) == 0x7c, "ConnectNetworkData is an invalid size"); | ||
351 | |||
306 | } // namespace Service::LDN | 352 | } // namespace Service::LDN |
diff --git a/src/core/hle/service/ldn/monitor_service.cpp b/src/core/hle/service/ldn/monitor_service.cpp new file mode 100755 index 000000000..3471f69da --- /dev/null +++ b/src/core/hle/service/ldn/monitor_service.cpp | |||
@@ -0,0 +1,43 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include "core/hle/service/cmif_serialization.h" | ||
5 | #include "core/hle/service/ldn/monitor_service.h" | ||
6 | |||
7 | namespace Service::LDN { | ||
8 | |||
9 | IMonitorService::IMonitorService(Core::System& system_) | ||
10 | : ServiceFramework{system_, "IMonitorService"} { | ||
11 | // clang-format off | ||
12 | static const FunctionInfo functions[] = { | ||
13 | {0, C<&IMonitorService::GetStateForMonitor>, "GetStateForMonitor"}, | ||
14 | {1, nullptr, "GetNetworkInfoForMonitor"}, | ||
15 | {2, nullptr, "GetIpv4AddressForMonitor"}, | ||
16 | {3, nullptr, "GetDisconnectReasonForMonitor"}, | ||
17 | {4, nullptr, "GetSecurityParameterForMonitor"}, | ||
18 | {5, nullptr, "GetNetworkConfigForMonitor"}, | ||
19 | {100, C<&IMonitorService::InitializeMonitor>, "InitializeMonitor"}, | ||
20 | {101, nullptr, "FinalizeMonitor"}, | ||
21 | }; | ||
22 | // clang-format on | ||
23 | |||
24 | RegisterHandlers(functions); | ||
25 | } | ||
26 | |||
27 | IMonitorService::~IMonitorService() = default; | ||
28 | |||
29 | Result IMonitorService::GetStateForMonitor(Out<State> out_state) { | ||
30 | LOG_INFO(Service_LDN, "called"); | ||
31 | |||
32 | *out_state = state; | ||
33 | R_SUCCEED(); | ||
34 | } | ||
35 | |||
36 | Result IMonitorService::InitializeMonitor() { | ||
37 | LOG_INFO(Service_LDN, "called"); | ||
38 | |||
39 | state = State::Initialized; | ||
40 | R_SUCCEED(); | ||
41 | } | ||
42 | |||
43 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/monitor_service.h b/src/core/hle/service/ldn/monitor_service.h new file mode 100755 index 000000000..61aacef30 --- /dev/null +++ b/src/core/hle/service/ldn/monitor_service.h | |||
@@ -0,0 +1,28 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/ldn/ldn_types.h" | ||
8 | #include "core/hle/service/service.h" | ||
9 | |||
10 | namespace Core { | ||
11 | class System; | ||
12 | } | ||
13 | |||
14 | namespace Service::LDN { | ||
15 | |||
16 | class IMonitorService final : public ServiceFramework<IMonitorService> { | ||
17 | public: | ||
18 | explicit IMonitorService(Core::System& system_); | ||
19 | ~IMonitorService() override; | ||
20 | |||
21 | private: | ||
22 | Result GetStateForMonitor(Out<State> out_state); | ||
23 | Result InitializeMonitor(); | ||
24 | |||
25 | State state{State::None}; | ||
26 | }; | ||
27 | |||
28 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_monitor_service.cpp b/src/core/hle/service/ldn/sf_monitor_service.cpp new file mode 100755 index 000000000..9e6736ff2 --- /dev/null +++ b/src/core/hle/service/ldn/sf_monitor_service.cpp | |||
@@ -0,0 +1,40 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include "core/hle/service/cmif_serialization.h" | ||
5 | #include "core/hle/service/ldn/ldn_types.h" | ||
6 | #include "core/hle/service/ldn/sf_monitor_service.h" | ||
7 | |||
8 | namespace Service::LDN { | ||
9 | |||
10 | ISfMonitorService::ISfMonitorService(Core::System& system_) | ||
11 | : ServiceFramework{system_, "ISfMonitorService"} { | ||
12 | // clang-format off | ||
13 | static const FunctionInfo functions[] = { | ||
14 | {0, C<&ISfMonitorService::Initialize>, "Initialize"}, | ||
15 | {288, C<&ISfMonitorService::GetGroupInfo>, "GetGroupInfo"}, | ||
16 | {320, nullptr, "GetLinkLevel"}, | ||
17 | }; | ||
18 | // clang-format on | ||
19 | |||
20 | RegisterHandlers(functions); | ||
21 | } | ||
22 | |||
23 | ISfMonitorService::~ISfMonitorService() = default; | ||
24 | |||
25 | Result ISfMonitorService::Initialize(Out<u32> out_value) { | ||
26 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
27 | |||
28 | *out_value = 0; | ||
29 | R_SUCCEED(); | ||
30 | } | ||
31 | |||
32 | Result ISfMonitorService::GetGroupInfo( | ||
33 | OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info) { | ||
34 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
35 | |||
36 | *out_group_info = GroupInfo{}; | ||
37 | R_SUCCEED(); | ||
38 | } | ||
39 | |||
40 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_monitor_service.h b/src/core/hle/service/ldn/sf_monitor_service.h new file mode 100755 index 000000000..d02115201 --- /dev/null +++ b/src/core/hle/service/ldn/sf_monitor_service.h | |||
@@ -0,0 +1,26 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::LDN { | ||
14 | struct GroupInfo; | ||
15 | |||
16 | class ISfMonitorService final : public ServiceFramework<ISfMonitorService> { | ||
17 | public: | ||
18 | explicit ISfMonitorService(Core::System& system_); | ||
19 | ~ISfMonitorService() override; | ||
20 | |||
21 | private: | ||
22 | Result Initialize(Out<u32> out_value); | ||
23 | Result GetGroupInfo(OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info); | ||
24 | }; | ||
25 | |||
26 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service.cpp b/src/core/hle/service/ldn/sf_service.cpp new file mode 100755 index 000000000..61cabe219 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service.cpp | |||
@@ -0,0 +1,37 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include "core/hle/service/ldn/sf_service.h" | ||
5 | |||
6 | namespace Service::LDN { | ||
7 | |||
8 | ISfService::ISfService(Core::System& system_) : ServiceFramework{system_, "ISfService"} { | ||
9 | // clang-format off | ||
10 | static const FunctionInfo functions[] = { | ||
11 | {0, nullptr, "Initialize"}, | ||
12 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
13 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
14 | {272, nullptr, "GetRole"}, | ||
15 | {280, nullptr, "GetAdvertiseData"}, | ||
16 | {288, nullptr, "GetGroupInfo"}, | ||
17 | {296, nullptr, "GetGroupInfo2"}, | ||
18 | {304, nullptr, "GetGroupOwner"}, | ||
19 | {312, nullptr, "GetIpConfig"}, | ||
20 | {320, nullptr, "GetLinkLevel"}, | ||
21 | {512, nullptr, "Scan"}, | ||
22 | {768, nullptr, "CreateGroup"}, | ||
23 | {776, nullptr, "DestroyGroup"}, | ||
24 | {784, nullptr, "SetAdvertiseData"}, | ||
25 | {1536, nullptr, "SendToOtherGroup"}, | ||
26 | {1544, nullptr, "RecvFromOtherGroup"}, | ||
27 | {1552, nullptr, "AddAcceptableGroupId"}, | ||
28 | {1560, nullptr, "ClearAcceptableGroupId"}, | ||
29 | }; | ||
30 | // clang-format on | ||
31 | |||
32 | RegisterHandlers(functions); | ||
33 | } | ||
34 | |||
35 | ISfService::~ISfService() = default; | ||
36 | |||
37 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service.h b/src/core/hle/service/ldn/sf_service.h new file mode 100755 index 000000000..05534b567 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service.h | |||
@@ -0,0 +1,21 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::LDN { | ||
14 | |||
15 | class ISfService final : public ServiceFramework<ISfService> { | ||
16 | public: | ||
17 | explicit ISfService(Core::System& system_); | ||
18 | ~ISfService() override; | ||
19 | }; | ||
20 | |||
21 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service_monitor.cpp b/src/core/hle/service/ldn/sf_service_monitor.cpp new file mode 100755 index 000000000..33e3c1d69 --- /dev/null +++ b/src/core/hle/service/ldn/sf_service_monitor.cpp | |||
@@ -0,0 +1,50 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include "core/hle/service/cmif_serialization.h" | ||
5 | #include "core/hle/service/ldn/ldn_types.h" | ||
6 | #include "core/hle/service/ldn/sf_service_monitor.h" | ||
7 | |||
8 | namespace Service::LDN { | ||
9 | |||
10 | ISfServiceMonitor::ISfServiceMonitor(Core::System& system_) | ||
11 | : ServiceFramework{system_, "ISfServiceMonitor"} { | ||
12 | // clang-format off | ||
13 | static const FunctionInfo functions[] = { | ||
14 | {0, C<&ISfServiceMonitor::Initialize>, "Initialize"}, | ||
15 | {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, | ||
16 | {264, nullptr, "GetNetworkInterfaceLastError"}, | ||
17 | {272, nullptr, "GetRole"}, | ||
18 | {280, nullptr, "GetAdvertiseData"}, | ||
19 | {281, nullptr, "GetAdvertiseData2"}, | ||
20 | {288, C<&ISfServiceMonitor::GetGroupInfo>, "GetGroupInfo"}, | ||
21 | {296, nullptr, "GetGroupInfo2"}, | ||
22 | {304, nullptr, "GetGroupOwner"}, | ||
23 | {312, nullptr, "GetIpConfig"}, | ||
24 | {320, nullptr, "GetLinkLevel"}, | ||
25 | {328, nullptr, "AttachJoinEvent"}, | ||
26 | {336, nullptr, "GetMembers"}, | ||
27 | }; | ||
28 | // clang-format on | ||
29 | |||
30 | RegisterHandlers(functions); | ||
31 | } | ||
32 | |||
33 | ISfServiceMonitor::~ISfServiceMonitor() = default; | ||
34 | |||
35 | Result ISfServiceMonitor::Initialize(Out<u32> out_value) { | ||
36 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
37 | |||
38 | *out_value = 0; | ||
39 | R_SUCCEED(); | ||
40 | } | ||
41 | |||
42 | Result ISfServiceMonitor::GetGroupInfo( | ||
43 | OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info) { | ||
44 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
45 | |||
46 | *out_group_info = GroupInfo{}; | ||
47 | R_SUCCEED(); | ||
48 | } | ||
49 | |||
50 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/sf_service_monitor.h b/src/core/hle/service/ldn/sf_service_monitor.h new file mode 100755 index 000000000..3cfc5005e --- /dev/null +++ b/src/core/hle/service/ldn/sf_service_monitor.h | |||
@@ -0,0 +1,26 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::LDN { | ||
14 | struct GroupInfo; | ||
15 | |||
16 | class ISfServiceMonitor final : public ServiceFramework<ISfServiceMonitor> { | ||
17 | public: | ||
18 | explicit ISfServiceMonitor(Core::System& system_); | ||
19 | ~ISfServiceMonitor() override; | ||
20 | |||
21 | private: | ||
22 | Result Initialize(Out<u32> out_value); | ||
23 | Result GetGroupInfo(OutLargeData<GroupInfo, BufferAttr_HipcAutoSelect> out_group_info); | ||
24 | }; | ||
25 | |||
26 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/system_local_communication_service.cpp b/src/core/hle/service/ldn/system_local_communication_service.cpp new file mode 100755 index 000000000..7b52223cd --- /dev/null +++ b/src/core/hle/service/ldn/system_local_communication_service.cpp | |||
@@ -0,0 +1,56 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include "core/hle/service/cmif_serialization.h" | ||
5 | #include "core/hle/service/ldn/system_local_communication_service.h" | ||
6 | |||
7 | namespace Service::LDN { | ||
8 | |||
9 | ISystemLocalCommunicationService::ISystemLocalCommunicationService(Core::System& system_) | ||
10 | : ServiceFramework{system_, "ISystemLocalCommunicationService"} { | ||
11 | // clang-format off | ||
12 | static const FunctionInfo functions[] = { | ||
13 | {0, nullptr, "GetState"}, | ||
14 | {1, nullptr, "GetNetworkInfo"}, | ||
15 | {2, nullptr, "GetIpv4Address"}, | ||
16 | {3, nullptr, "GetDisconnectReason"}, | ||
17 | {4, nullptr, "GetSecurityParameter"}, | ||
18 | {5, nullptr, "GetNetworkConfig"}, | ||
19 | {100, nullptr, "AttachStateChangeEvent"}, | ||
20 | {101, nullptr, "GetNetworkInfoLatestUpdate"}, | ||
21 | {102, nullptr, "Scan"}, | ||
22 | {103, nullptr, "ScanPrivate"}, | ||
23 | {104, nullptr, "SetWirelessControllerRestriction"}, | ||
24 | {200, nullptr, "OpenAccessPoint"}, | ||
25 | {201, nullptr, "CloseAccessPoint"}, | ||
26 | {202, nullptr, "CreateNetwork"}, | ||
27 | {203, nullptr, "CreateNetworkPrivate"}, | ||
28 | {204, nullptr, "DestroyNetwork"}, | ||
29 | {205, nullptr, "Reject"}, | ||
30 | {206, nullptr, "SetAdvertiseData"}, | ||
31 | {207, nullptr, "SetStationAcceptPolicy"}, | ||
32 | {208, nullptr, "AddAcceptFilterEntry"}, | ||
33 | {209, nullptr, "ClearAcceptFilter"}, | ||
34 | {300, nullptr, "OpenStation"}, | ||
35 | {301, nullptr, "CloseStation"}, | ||
36 | {302, nullptr, "Connect"}, | ||
37 | {303, nullptr, "ConnectPrivate"}, | ||
38 | {304, nullptr, "Disconnect"}, | ||
39 | {400, nullptr, "InitializeSystem"}, | ||
40 | {401, nullptr, "FinalizeSystem"}, | ||
41 | {402, nullptr, "SetOperationMode"}, | ||
42 | {403, C<&ISystemLocalCommunicationService::InitializeSystem2>, "InitializeSystem2"}, | ||
43 | }; | ||
44 | // clang-format on | ||
45 | |||
46 | RegisterHandlers(functions); | ||
47 | } | ||
48 | |||
49 | ISystemLocalCommunicationService::~ISystemLocalCommunicationService() = default; | ||
50 | |||
51 | Result ISystemLocalCommunicationService::InitializeSystem2() { | ||
52 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
53 | R_SUCCEED(); | ||
54 | } | ||
55 | |||
56 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/system_local_communication_service.h b/src/core/hle/service/ldn/system_local_communication_service.h new file mode 100755 index 000000000..a02b097ea --- /dev/null +++ b/src/core/hle/service/ldn/system_local_communication_service.h | |||
@@ -0,0 +1,25 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/service.h" | ||
8 | |||
9 | namespace Core { | ||
10 | class System; | ||
11 | } | ||
12 | |||
13 | namespace Service::LDN { | ||
14 | |||
15 | class ISystemLocalCommunicationService final | ||
16 | : public ServiceFramework<ISystemLocalCommunicationService> { | ||
17 | public: | ||
18 | explicit ISystemLocalCommunicationService(Core::System& system_); | ||
19 | ~ISystemLocalCommunicationService() override; | ||
20 | |||
21 | private: | ||
22 | Result InitializeSystem2(); | ||
23 | }; | ||
24 | |||
25 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp new file mode 100755 index 000000000..f28368962 --- /dev/null +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp | |||
@@ -0,0 +1,320 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #include <memory> | ||
5 | |||
6 | #include "core/core.h" | ||
7 | #include "core/hle/kernel/k_event.h" | ||
8 | #include "core/hle/service/cmif_serialization.h" | ||
9 | #include "core/hle/service/ldn/ldn_results.h" | ||
10 | #include "core/hle/service/ldn/ldn_types.h" | ||
11 | #include "core/hle/service/ldn/user_local_communication_service.h" | ||
12 | #include "core/hle/service/server_manager.h" | ||
13 | #include "core/internal_network/network.h" | ||
14 | #include "core/internal_network/network_interface.h" | ||
15 | #include "network/network.h" | ||
16 | |||
17 | // This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent | ||
18 | #undef CreateEvent | ||
19 | |||
20 | namespace Service::LDN { | ||
21 | |||
22 | IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_) | ||
23 | : ServiceFramework{system_, "IUserLocalCommunicationService"}, | ||
24 | service_context{system, "IUserLocalCommunicationService"}, | ||
25 | room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { | ||
26 | // clang-format off | ||
27 | static const FunctionInfo functions[] = { | ||
28 | {0, C<&IUserLocalCommunicationService::GetState>, "GetState"}, | ||
29 | {1, C<&IUserLocalCommunicationService::GetNetworkInfo>, "GetNetworkInfo"}, | ||
30 | {2, C<&IUserLocalCommunicationService::GetIpv4Address>, "GetIpv4Address"}, | ||
31 | {3, C<&IUserLocalCommunicationService::GetDisconnectReason>, "GetDisconnectReason"}, | ||
32 | {4, C<&IUserLocalCommunicationService::GetSecurityParameter>, "GetSecurityParameter"}, | ||
33 | {5, C<&IUserLocalCommunicationService::GetNetworkConfig>, "GetNetworkConfig"}, | ||
34 | {100, C<&IUserLocalCommunicationService::AttachStateChangeEvent>, "AttachStateChangeEvent"}, | ||
35 | {101, C<&IUserLocalCommunicationService::GetNetworkInfoLatestUpdate>, "GetNetworkInfoLatestUpdate"}, | ||
36 | {102, C<&IUserLocalCommunicationService::Scan>, "Scan"}, | ||
37 | {103, C<&IUserLocalCommunicationService::ScanPrivate>, "ScanPrivate"}, | ||
38 | {104, C<&IUserLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"}, | ||
39 | {200, C<&IUserLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"}, | ||
40 | {201, C<&IUserLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"}, | ||
41 | {202, C<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"}, | ||
42 | {203, C<&IUserLocalCommunicationService::CreateNetworkPrivate>, "CreateNetworkPrivate"}, | ||
43 | {204, C<&IUserLocalCommunicationService::DestroyNetwork>, "DestroyNetwork"}, | ||
44 | {205, nullptr, "Reject"}, | ||
45 | {206, C<&IUserLocalCommunicationService::SetAdvertiseData>, "SetAdvertiseData"}, | ||
46 | {207, C<&IUserLocalCommunicationService::SetStationAcceptPolicy>, "SetStationAcceptPolicy"}, | ||
47 | {208, C<&IUserLocalCommunicationService::AddAcceptFilterEntry>, "AddAcceptFilterEntry"}, | ||
48 | {209, nullptr, "ClearAcceptFilter"}, | ||
49 | {300, C<&IUserLocalCommunicationService::OpenStation>, "OpenStation"}, | ||
50 | {301, C<&IUserLocalCommunicationService::CloseStation>, "CloseStation"}, | ||
51 | {302, C<&IUserLocalCommunicationService::Connect>, "Connect"}, | ||
52 | {303, nullptr, "ConnectPrivate"}, | ||
53 | {304, C<&IUserLocalCommunicationService::Disconnect>, "Disconnect"}, | ||
54 | {400, C<&IUserLocalCommunicationService::Initialize>, "Initialize"}, | ||
55 | {401, C<&IUserLocalCommunicationService::Finalize>, "Finalize"}, | ||
56 | {402, C<&IUserLocalCommunicationService::Initialize2>, "Initialize2"}, | ||
57 | }; | ||
58 | // clang-format on | ||
59 | |||
60 | RegisterHandlers(functions); | ||
61 | |||
62 | state_change_event = | ||
63 | service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); | ||
64 | } | ||
65 | |||
66 | IUserLocalCommunicationService::~IUserLocalCommunicationService() { | ||
67 | if (is_initialized) { | ||
68 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
69 | room_member->Unbind(ldn_packet_received); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | service_context.CloseEvent(state_change_event); | ||
74 | } | ||
75 | |||
76 | Result IUserLocalCommunicationService::GetState(Out<State> out_state) { | ||
77 | *out_state = State::Error; | ||
78 | |||
79 | if (is_initialized) { | ||
80 | *out_state = lan_discovery.GetState(); | ||
81 | } | ||
82 | |||
83 | LOG_INFO(Service_LDN, "called, state={}", *out_state); | ||
84 | |||
85 | R_SUCCEED(); | ||
86 | } | ||
87 | |||
88 | Result IUserLocalCommunicationService::GetNetworkInfo( | ||
89 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info) { | ||
90 | LOG_INFO(Service_LDN, "called"); | ||
91 | |||
92 | R_RETURN(lan_discovery.GetNetworkInfo(*out_network_info)); | ||
93 | } | ||
94 | |||
95 | Result IUserLocalCommunicationService::GetIpv4Address(Out<Ipv4Address> out_current_address, | ||
96 | Out<Ipv4Address> out_subnet_mask) { | ||
97 | LOG_INFO(Service_LDN, "called"); | ||
98 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
99 | |||
100 | R_UNLESS(network_interface.has_value(), ResultNoIpAddress); | ||
101 | |||
102 | *out_current_address = {Network::TranslateIPv4(network_interface->ip_address)}; | ||
103 | *out_subnet_mask = {Network::TranslateIPv4(network_interface->subnet_mask)}; | ||
104 | |||
105 | // When we're connected to a room, spoof the hosts IP address | ||
106 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
107 | if (room_member->IsConnected()) { | ||
108 | *out_current_address = room_member->GetFakeIpAddress(); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | std::reverse(std::begin(*out_current_address), std::end(*out_current_address)); // ntohl | ||
113 | std::reverse(std::begin(*out_subnet_mask), std::end(*out_subnet_mask)); // ntohl | ||
114 | R_SUCCEED(); | ||
115 | } | ||
116 | |||
117 | Result IUserLocalCommunicationService::GetDisconnectReason( | ||
118 | Out<DisconnectReason> out_disconnect_reason) { | ||
119 | LOG_INFO(Service_LDN, "called"); | ||
120 | |||
121 | *out_disconnect_reason = lan_discovery.GetDisconnectReason(); | ||
122 | R_SUCCEED(); | ||
123 | } | ||
124 | |||
125 | Result IUserLocalCommunicationService::GetSecurityParameter( | ||
126 | Out<SecurityParameter> out_security_parameter) { | ||
127 | LOG_INFO(Service_LDN, "called"); | ||
128 | |||
129 | NetworkInfo info{}; | ||
130 | R_TRY(lan_discovery.GetNetworkInfo(info)); | ||
131 | |||
132 | out_security_parameter->session_id = info.network_id.session_id; | ||
133 | std::memcpy(out_security_parameter->data.data(), info.ldn.security_parameter.data(), | ||
134 | sizeof(SecurityParameter::data)); | ||
135 | R_SUCCEED(); | ||
136 | } | ||
137 | |||
138 | Result IUserLocalCommunicationService::GetNetworkConfig(Out<NetworkConfig> out_network_config) { | ||
139 | LOG_INFO(Service_LDN, "called"); | ||
140 | |||
141 | NetworkInfo info{}; | ||
142 | R_TRY(lan_discovery.GetNetworkInfo(info)); | ||
143 | |||
144 | out_network_config->intent_id = info.network_id.intent_id; | ||
145 | out_network_config->channel = info.common.channel; | ||
146 | out_network_config->node_count_max = info.ldn.node_count_max; | ||
147 | out_network_config->local_communication_version = info.ldn.nodes[0].local_communication_version; | ||
148 | R_SUCCEED(); | ||
149 | } | ||
150 | |||
151 | Result IUserLocalCommunicationService::AttachStateChangeEvent( | ||
152 | OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||
153 | LOG_INFO(Service_LDN, "called"); | ||
154 | |||
155 | *out_event = &state_change_event->GetReadableEvent(); | ||
156 | R_SUCCEED(); | ||
157 | } | ||
158 | |||
159 | Result IUserLocalCommunicationService::GetNetworkInfoLatestUpdate( | ||
160 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info, | ||
161 | OutArray<NodeLatestUpdate, BufferAttr_HipcPointer> out_node_latest_update) { | ||
162 | LOG_INFO(Service_LDN, "called"); | ||
163 | |||
164 | R_UNLESS(!out_node_latest_update.empty(), ResultBadInput); | ||
165 | |||
166 | R_RETURN(lan_discovery.GetNetworkInfo(*out_network_info, out_node_latest_update)); | ||
167 | } | ||
168 | |||
169 | Result IUserLocalCommunicationService::Scan( | ||
170 | Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
171 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info) { | ||
172 | LOG_INFO(Service_LDN, "called, channel={}, filter_scan_flag={}, filter_network_type={}", | ||
173 | channel, scan_filter.flag, scan_filter.network_type); | ||
174 | |||
175 | R_UNLESS(!out_network_info.empty(), ResultBadInput); | ||
176 | R_RETURN(lan_discovery.Scan(out_network_info, *network_count, scan_filter)); | ||
177 | } | ||
178 | |||
179 | Result IUserLocalCommunicationService::ScanPrivate( | ||
180 | Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
181 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info) { | ||
182 | LOG_INFO(Service_LDN, "called, channel={}, filter_scan_flag={}, filter_network_type={}", | ||
183 | channel, scan_filter.flag, scan_filter.network_type); | ||
184 | |||
185 | R_UNLESS(out_network_info.empty(), ResultBadInput); | ||
186 | R_RETURN(lan_discovery.Scan(out_network_info, *network_count, scan_filter)); | ||
187 | } | ||
188 | |||
189 | Result IUserLocalCommunicationService::SetWirelessControllerRestriction( | ||
190 | WirelessControllerRestriction wireless_restriction) { | ||
191 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
192 | R_SUCCEED(); | ||
193 | } | ||
194 | |||
195 | Result IUserLocalCommunicationService::OpenAccessPoint() { | ||
196 | LOG_INFO(Service_LDN, "called"); | ||
197 | |||
198 | R_RETURN(lan_discovery.OpenAccessPoint()); | ||
199 | } | ||
200 | |||
201 | Result IUserLocalCommunicationService::CloseAccessPoint() { | ||
202 | LOG_INFO(Service_LDN, "called"); | ||
203 | |||
204 | R_RETURN(lan_discovery.CloseAccessPoint()); | ||
205 | } | ||
206 | |||
207 | Result IUserLocalCommunicationService::CreateNetwork(const CreateNetworkConfig& create_config) { | ||
208 | LOG_INFO(Service_LDN, "called"); | ||
209 | |||
210 | R_RETURN(lan_discovery.CreateNetwork(create_config.security_config, create_config.user_config, | ||
211 | create_config.network_config)); | ||
212 | } | ||
213 | |||
214 | Result IUserLocalCommunicationService::CreateNetworkPrivate( | ||
215 | const CreateNetworkConfigPrivate& create_config, | ||
216 | InArray<AddressEntry, BufferAttr_HipcPointer> address_list) { | ||
217 | LOG_INFO(Service_LDN, "called"); | ||
218 | |||
219 | R_RETURN(lan_discovery.CreateNetwork(create_config.security_config, create_config.user_config, | ||
220 | create_config.network_config)); | ||
221 | } | ||
222 | |||
223 | Result IUserLocalCommunicationService::DestroyNetwork() { | ||
224 | LOG_INFO(Service_LDN, "called"); | ||
225 | |||
226 | R_RETURN(lan_discovery.DestroyNetwork()); | ||
227 | } | ||
228 | |||
229 | Result IUserLocalCommunicationService::SetAdvertiseData( | ||
230 | InBuffer<BufferAttr_HipcAutoSelect> buffer_data) { | ||
231 | LOG_INFO(Service_LDN, "called"); | ||
232 | |||
233 | R_RETURN(lan_discovery.SetAdvertiseData(buffer_data)); | ||
234 | } | ||
235 | |||
236 | Result IUserLocalCommunicationService::SetStationAcceptPolicy(AcceptPolicy accept_policy) { | ||
237 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
238 | R_SUCCEED(); | ||
239 | } | ||
240 | |||
241 | Result IUserLocalCommunicationService::AddAcceptFilterEntry(MacAddress mac_address) { | ||
242 | LOG_WARNING(Service_LDN, "(STUBBED) called"); | ||
243 | R_SUCCEED(); | ||
244 | } | ||
245 | |||
246 | Result IUserLocalCommunicationService::OpenStation() { | ||
247 | LOG_INFO(Service_LDN, "called"); | ||
248 | |||
249 | R_RETURN(lan_discovery.OpenStation()); | ||
250 | } | ||
251 | |||
252 | Result IUserLocalCommunicationService::CloseStation() { | ||
253 | LOG_INFO(Service_LDN, "called"); | ||
254 | |||
255 | R_RETURN(lan_discovery.CloseStation()); | ||
256 | } | ||
257 | |||
258 | Result IUserLocalCommunicationService::Connect( | ||
259 | const ConnectNetworkData& connect_data, | ||
260 | InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info) { | ||
261 | LOG_INFO(Service_LDN, | ||
262 | "called, passphrase_size={}, security_mode={}, " | ||
263 | "local_communication_version={}", | ||
264 | connect_data.security_config.passphrase_size, | ||
265 | connect_data.security_config.security_mode, connect_data.local_communication_version); | ||
266 | |||
267 | R_RETURN(lan_discovery.Connect(*network_info, connect_data.user_config, | ||
268 | static_cast<u16>(connect_data.local_communication_version))); | ||
269 | } | ||
270 | |||
271 | Result IUserLocalCommunicationService::Disconnect() { | ||
272 | LOG_INFO(Service_LDN, "called"); | ||
273 | |||
274 | R_RETURN(lan_discovery.Disconnect()); | ||
275 | } | ||
276 | |||
277 | Result IUserLocalCommunicationService::Initialize(ClientProcessId aruid) { | ||
278 | LOG_INFO(Service_LDN, "called, process_id={}", aruid.pid); | ||
279 | |||
280 | const auto network_interface = Network::GetSelectedNetworkInterface(); | ||
281 | R_UNLESS(network_interface, ResultAirplaneModeEnabled); | ||
282 | |||
283 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
284 | ldn_packet_received = room_member->BindOnLdnPacketReceived( | ||
285 | [this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); }); | ||
286 | } else { | ||
287 | LOG_ERROR(Service_LDN, "Couldn't bind callback!"); | ||
288 | R_RETURN(ResultAirplaneModeEnabled); | ||
289 | } | ||
290 | |||
291 | lan_discovery.Initialize([&]() { OnEventFired(); }); | ||
292 | is_initialized = true; | ||
293 | R_SUCCEED(); | ||
294 | } | ||
295 | |||
296 | Result IUserLocalCommunicationService::Finalize() { | ||
297 | LOG_INFO(Service_LDN, "called"); | ||
298 | if (auto room_member = room_network.GetRoomMember().lock()) { | ||
299 | room_member->Unbind(ldn_packet_received); | ||
300 | } | ||
301 | |||
302 | is_initialized = false; | ||
303 | |||
304 | R_RETURN(lan_discovery.Finalize()); | ||
305 | } | ||
306 | |||
307 | Result IUserLocalCommunicationService::Initialize2(u32 version, ClientProcessId process_id) { | ||
308 | LOG_INFO(Service_LDN, "called, version={}, process_id={}", version, process_id.pid); | ||
309 | R_RETURN(Initialize(process_id)); | ||
310 | } | ||
311 | |||
312 | void IUserLocalCommunicationService::OnLDNPacketReceived(const Network::LDNPacket& packet) { | ||
313 | lan_discovery.ReceivePacket(packet); | ||
314 | } | ||
315 | |||
316 | void IUserLocalCommunicationService::OnEventFired() { | ||
317 | state_change_event->Signal(); | ||
318 | } | ||
319 | |||
320 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/ldn/user_local_communication_service.h b/src/core/hle/service/ldn/user_local_communication_service.h new file mode 100755 index 000000000..6698d10d2 --- /dev/null +++ b/src/core/hle/service/ldn/user_local_communication_service.h | |||
@@ -0,0 +1,103 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/cmif_types.h" | ||
7 | #include "core/hle/service/kernel_helpers.h" | ||
8 | #include "core/hle/service/ldn/lan_discovery.h" | ||
9 | #include "core/hle/service/ldn/ldn_types.h" | ||
10 | #include "core/hle/service/service.h" | ||
11 | |||
12 | namespace Core { | ||
13 | class System; | ||
14 | } | ||
15 | |||
16 | namespace Network { | ||
17 | class RoomNetwork; | ||
18 | } | ||
19 | |||
20 | namespace Service::LDN { | ||
21 | |||
22 | class IUserLocalCommunicationService final | ||
23 | : public ServiceFramework<IUserLocalCommunicationService> { | ||
24 | public: | ||
25 | explicit IUserLocalCommunicationService(Core::System& system_); | ||
26 | ~IUserLocalCommunicationService() override; | ||
27 | |||
28 | private: | ||
29 | Result GetState(Out<State> out_state); | ||
30 | |||
31 | Result GetNetworkInfo(OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info); | ||
32 | |||
33 | Result GetIpv4Address(Out<Ipv4Address> out_current_address, Out<Ipv4Address> out_subnet_mask); | ||
34 | |||
35 | Result GetDisconnectReason(Out<DisconnectReason> out_disconnect_reason); | ||
36 | |||
37 | Result GetSecurityParameter(Out<SecurityParameter> out_security_parameter); | ||
38 | |||
39 | Result GetNetworkConfig(Out<NetworkConfig> out_network_config); | ||
40 | |||
41 | Result AttachStateChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); | ||
42 | |||
43 | Result GetNetworkInfoLatestUpdate( | ||
44 | OutLargeData<NetworkInfo, BufferAttr_HipcPointer> out_network_info, | ||
45 | OutArray<NodeLatestUpdate, BufferAttr_HipcPointer> out_node_latest_update); | ||
46 | |||
47 | Result Scan(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
48 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info); | ||
49 | |||
50 | Result ScanPrivate(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter, | ||
51 | OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info); | ||
52 | |||
53 | Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction); | ||
54 | |||
55 | Result OpenAccessPoint(); | ||
56 | |||
57 | Result CloseAccessPoint(); | ||
58 | |||
59 | Result CreateNetwork(const CreateNetworkConfig& create_network_Config); | ||
60 | |||
61 | Result CreateNetworkPrivate(const CreateNetworkConfigPrivate& create_network_Config, | ||
62 | InArray<AddressEntry, BufferAttr_HipcPointer> address_list); | ||
63 | |||
64 | Result DestroyNetwork(); | ||
65 | |||
66 | Result SetAdvertiseData(InBuffer<BufferAttr_HipcAutoSelect> buffer_data); | ||
67 | |||
68 | Result SetStationAcceptPolicy(AcceptPolicy accept_policy); | ||
69 | |||
70 | Result AddAcceptFilterEntry(MacAddress mac_address); | ||
71 | |||
72 | Result OpenStation(); | ||
73 | |||
74 | Result CloseStation(); | ||
75 | |||
76 | Result Connect(const ConnectNetworkData& connect_data, | ||
77 | InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info); | ||
78 | |||
79 | Result Disconnect(); | ||
80 | |||
81 | Result Initialize(ClientProcessId aruid); | ||
82 | |||
83 | Result Finalize(); | ||
84 | |||
85 | Result Initialize2(u32 version, ClientProcessId aruid); | ||
86 | |||
87 | private: | ||
88 | /// Callback to parse and handle a received LDN packet. | ||
89 | void OnLDNPacketReceived(const Network::LDNPacket& packet); | ||
90 | void OnEventFired(); | ||
91 | |||
92 | KernelHelpers::ServiceContext service_context; | ||
93 | Kernel::KEvent* state_change_event; | ||
94 | Network::RoomNetwork& room_network; | ||
95 | LANDiscovery lan_discovery; | ||
96 | |||
97 | // Callback identifier for the OnLDNPacketReceived event. | ||
98 | Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received; | ||
99 | |||
100 | bool is_initialized{}; | ||
101 | }; | ||
102 | |||
103 | } // namespace Service::LDN | ||
diff --git a/src/core/hle/service/omm/omm.cpp b/src/core/hle/service/omm/omm.cpp new file mode 100755 index 000000000..b95319e26 --- /dev/null +++ b/src/core/hle/service/omm/omm.cpp | |||
@@ -0,0 +1,22 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/omm/omm.h" | ||
5 | #include "core/hle/service/omm/operation_mode_manager.h" | ||
6 | #include "core/hle/service/omm/policy_manager_system.h" | ||
7 | #include "core/hle/service/omm/power_state_interface.h" | ||
8 | #include "core/hle/service/server_manager.h" | ||
9 | |||
10 | namespace Service::OMM { | ||
11 | |||
12 | void LoopProcess(Core::System& system) { | ||
13 | auto server_manager = std::make_unique<ServerManager>(system); | ||
14 | |||
15 | server_manager->RegisterNamedService("idle:sys", | ||
16 | std::make_shared<IPolicyManagerSystem>(system)); | ||
17 | server_manager->RegisterNamedService("omm", std::make_shared<IOperationModeManager>(system)); | ||
18 | server_manager->RegisterNamedService("spsm", std::make_shared<IPowerStateInterface>(system)); | ||
19 | ServerManager::RunServer(std::move(server_manager)); | ||
20 | } | ||
21 | |||
22 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/omm.h b/src/core/hle/service/omm/omm.h new file mode 100755 index 000000000..7bf04688a --- /dev/null +++ b/src/core/hle/service/omm/omm.h | |||
@@ -0,0 +1,14 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | namespace Core { | ||
7 | class System; | ||
8 | } | ||
9 | |||
10 | namespace Service::OMM { | ||
11 | |||
12 | void LoopProcess(Core::System& system); | ||
13 | |||
14 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/operation_mode_manager.cpp b/src/core/hle/service/omm/operation_mode_manager.cpp new file mode 100755 index 000000000..fe7ed84a7 --- /dev/null +++ b/src/core/hle/service/omm/operation_mode_manager.cpp | |||
@@ -0,0 +1,49 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/omm/operation_mode_manager.h" | ||
5 | |||
6 | namespace Service::OMM { | ||
7 | |||
8 | IOperationModeManager::IOperationModeManager(Core::System& system_) | ||
9 | : ServiceFramework{system_, "omm"} { | ||
10 | // clang-format off | ||
11 | static const FunctionInfo functions[] = { | ||
12 | {0, nullptr, "GetOperationMode"}, | ||
13 | {1, nullptr, "GetOperationModeChangeEvent"}, | ||
14 | {2, nullptr, "EnableAudioVisual"}, | ||
15 | {3, nullptr, "DisableAudioVisual"}, | ||
16 | {4, nullptr, "EnterSleepAndWait"}, | ||
17 | {5, nullptr, "GetCradleStatus"}, | ||
18 | {6, nullptr, "FadeInDisplay"}, | ||
19 | {7, nullptr, "FadeOutDisplay"}, | ||
20 | {8, nullptr, "GetCradleFwVersion"}, | ||
21 | {9, nullptr, "NotifyCecSettingsChanged"}, | ||
22 | {10, nullptr, "SetOperationModePolicy"}, | ||
23 | {11, nullptr, "GetDefaultDisplayResolution"}, | ||
24 | {12, nullptr, "GetDefaultDisplayResolutionChangeEvent"}, | ||
25 | {13, nullptr, "UpdateDefaultDisplayResolution"}, | ||
26 | {14, nullptr, "ShouldSleepOnBoot"}, | ||
27 | {15, nullptr, "NotifyHdcpApplicationExecutionStarted"}, | ||
28 | {16, nullptr, "NotifyHdcpApplicationExecutionFinished"}, | ||
29 | {17, nullptr, "NotifyHdcpApplicationDrawingStarted"}, | ||
30 | {18, nullptr, "NotifyHdcpApplicationDrawingFinished"}, | ||
31 | {19, nullptr, "GetHdcpAuthenticationFailedEvent"}, | ||
32 | {20, nullptr, "GetHdcpAuthenticationFailedEmulationEnabled"}, | ||
33 | {21, nullptr, "SetHdcpAuthenticationFailedEmulation"}, | ||
34 | {22, nullptr, "GetHdcpStateChangeEvent"}, | ||
35 | {23, nullptr, "GetHdcpState"}, | ||
36 | {24, nullptr, "ShowCardUpdateProcessing"}, | ||
37 | {25, nullptr, "SetApplicationCecSettingsAndNotifyChanged"}, | ||
38 | {26, nullptr, "GetOperationModeSystemInfo"}, | ||
39 | {27, nullptr, "GetAppletFullAwakingSystemEvent"}, | ||
40 | {28, nullptr, "CreateCradleFirmwareUpdater"}, | ||
41 | }; | ||
42 | // clang-format on | ||
43 | |||
44 | RegisterHandlers(functions); | ||
45 | } | ||
46 | |||
47 | IOperationModeManager::~IOperationModeManager() = default; | ||
48 | |||
49 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/operation_mode_manager.h b/src/core/hle/service/omm/operation_mode_manager.h new file mode 100755 index 000000000..32bc7b2f9 --- /dev/null +++ b/src/core/hle/service/omm/operation_mode_manager.h | |||
@@ -0,0 +1,20 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/service.h" | ||
7 | |||
8 | namespace Core { | ||
9 | class System; | ||
10 | } | ||
11 | |||
12 | namespace Service::OMM { | ||
13 | |||
14 | class IOperationModeManager final : public ServiceFramework<IOperationModeManager> { | ||
15 | public: | ||
16 | explicit IOperationModeManager(Core::System& system_); | ||
17 | ~IOperationModeManager() override; | ||
18 | }; | ||
19 | |||
20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/policy_manager_system.cpp b/src/core/hle/service/omm/policy_manager_system.cpp new file mode 100755 index 000000000..1cd6fd807 --- /dev/null +++ b/src/core/hle/service/omm/policy_manager_system.cpp | |||
@@ -0,0 +1,26 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/omm/policy_manager_system.h" | ||
5 | |||
6 | namespace Service::OMM { | ||
7 | |||
8 | IPolicyManagerSystem::IPolicyManagerSystem(Core::System& system_) | ||
9 | : ServiceFramework{system_, "idle:sys"} { | ||
10 | // clang-format off | ||
11 | static const FunctionInfo functions[] = { | ||
12 | {0, nullptr, "GetAutoPowerDownEvent"}, | ||
13 | {1, nullptr, "IsAutoPowerDownRequested"}, | ||
14 | {2, nullptr, "Unknown2"}, | ||
15 | {3, nullptr, "SetHandlingContext"}, | ||
16 | {4, nullptr, "LoadAndApplySettings"}, | ||
17 | {5, nullptr, "ReportUserIsActive"}, | ||
18 | }; | ||
19 | // clang-format on | ||
20 | |||
21 | RegisterHandlers(functions); | ||
22 | } | ||
23 | |||
24 | IPolicyManagerSystem::~IPolicyManagerSystem() = default; | ||
25 | |||
26 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/policy_manager_system.h b/src/core/hle/service/omm/policy_manager_system.h new file mode 100755 index 000000000..151ca0d2e --- /dev/null +++ b/src/core/hle/service/omm/policy_manager_system.h | |||
@@ -0,0 +1,20 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/service.h" | ||
7 | |||
8 | namespace Core { | ||
9 | class System; | ||
10 | } | ||
11 | |||
12 | namespace Service::OMM { | ||
13 | |||
14 | class IPolicyManagerSystem final : public ServiceFramework<IPolicyManagerSystem> { | ||
15 | public: | ||
16 | explicit IPolicyManagerSystem(Core::System& system_); | ||
17 | ~IPolicyManagerSystem() override; | ||
18 | }; | ||
19 | |||
20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/power_state_interface.cpp b/src/core/hle/service/omm/power_state_interface.cpp new file mode 100755 index 000000000..22cac8259 --- /dev/null +++ b/src/core/hle/service/omm/power_state_interface.cpp | |||
@@ -0,0 +1,32 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #include "core/hle/service/omm/power_state_interface.h" | ||
5 | |||
6 | namespace Service::OMM { | ||
7 | |||
8 | IPowerStateInterface::IPowerStateInterface(Core::System& system_) | ||
9 | : ServiceFramework{system_, "spsm"} { | ||
10 | // clang-format off | ||
11 | static const FunctionInfo functions[] = { | ||
12 | {0, nullptr, "GetState"}, | ||
13 | {1, nullptr, "EnterSleep"}, | ||
14 | {2, nullptr, "GetLastWakeReason"}, | ||
15 | {3, nullptr, "Shutdown"}, | ||
16 | {4, nullptr, "GetNotificationMessageEventHandle"}, | ||
17 | {5, nullptr, "ReceiveNotificationMessage"}, | ||
18 | {6, nullptr, "AnalyzeLogForLastSleepWakeSequence"}, | ||
19 | {7, nullptr, "ResetEventLog"}, | ||
20 | {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"}, | ||
21 | {9, nullptr, "ChangeHomeButtonLongPressingTime"}, | ||
22 | {10, nullptr, "PutErrorState"}, | ||
23 | {11, nullptr, "InvalidateCurrentHomeButtonPressing"}, | ||
24 | }; | ||
25 | // clang-format on | ||
26 | |||
27 | RegisterHandlers(functions); | ||
28 | } | ||
29 | |||
30 | IPowerStateInterface::~IPowerStateInterface() = default; | ||
31 | |||
32 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/omm/power_state_interface.h b/src/core/hle/service/omm/power_state_interface.h new file mode 100755 index 000000000..825a6512d --- /dev/null +++ b/src/core/hle/service/omm/power_state_interface.h | |||
@@ -0,0 +1,20 @@ | |||
1 | // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | ||
2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | #include "core/hle/service/service.h" | ||
7 | |||
8 | namespace Core { | ||
9 | class System; | ||
10 | } | ||
11 | |||
12 | namespace Service::OMM { | ||
13 | |||
14 | class IPowerStateInterface final : public ServiceFramework<IPowerStateInterface> { | ||
15 | public: | ||
16 | explicit IPowerStateInterface(Core::System& system_); | ||
17 | ~IPowerStateInterface() override; | ||
18 | }; | ||
19 | |||
20 | } // namespace Service::OMM | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 87e8eeed8..5a1a286f1 100755 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" | 52 | #include "core/hle/service/nvnflinger/hos_binder_driver_server.h" |
53 | #include "core/hle/service/nvnflinger/nvnflinger.h" | 53 | #include "core/hle/service/nvnflinger/nvnflinger.h" |
54 | #include "core/hle/service/olsc/olsc.h" | 54 | #include "core/hle/service/olsc/olsc.h" |
55 | #include "core/hle/service/omm/omm.h" | ||
55 | #include "core/hle/service/pcie/pcie.h" | 56 | #include "core/hle/service/pcie/pcie.h" |
56 | #include "core/hle/service/pctl/pctl_module.h" | 57 | #include "core/hle/service/pctl/pctl_module.h" |
57 | #include "core/hle/service/pcv/pcv.h" | 58 | #include "core/hle/service/pcv/pcv.h" |
@@ -266,6 +267,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system | |||
266 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); | 267 | kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); }); |
267 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); | 268 | kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); }); |
268 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); | 269 | kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); }); |
270 | kernel.RunOnGuestCoreProcess("omm", [&] { OMM::LoopProcess(system); }); | ||
269 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); | 271 | kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); }); |
270 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); | 272 | kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); }); |
271 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); | 273 | kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); }); |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 1f33301b7..1d6c117b1 100755 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
@@ -35,7 +35,7 @@ BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, R | |||
35 | const s64 min_spacing_critical = device_local_memory - 512_MiB; | 35 | const s64 min_spacing_critical = device_local_memory - 512_MiB; |
36 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); | 36 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); |
37 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; | 37 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; |
38 | const s64 min_vacancy_critical = (3 * mem_threshold) / 10; | 38 | const s64 min_vacancy_critical = (2 * mem_threshold) / 10; |
39 | minimum_memory = static_cast<u64>( | 39 | minimum_memory = static_cast<u64>( |
40 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), | 40 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), |
41 | DEFAULT_EXPECTED_MEMORY)); | 41 | DEFAULT_EXPECTED_MEMORY)); |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index c48e19ffa..a94d2371a 100755 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include "common/common_types.h" | 4 | #include "common/common_types.h" |
5 | #include "common/math_util.h" | 5 | #include "common/math_util.h" |
6 | #include "common/settings.h" | ||
6 | #include "video_core/surface.h" | 7 | #include "video_core/surface.h" |
7 | 8 | ||
8 | namespace VideoCore::Surface { | 9 | namespace VideoCore::Surface { |
@@ -400,11 +401,20 @@ std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | |||
400 | return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; | 401 | return {DefaultBlockWidth(format), DefaultBlockHeight(format)}; |
401 | } | 402 | } |
402 | 403 | ||
403 | u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format) { | 404 | u64 TranscodedAstcSize(u64 base_size, PixelFormat format) { |
404 | constexpr u64 RGBA8_PIXEL_SIZE = 4; | 405 | constexpr u64 RGBA8_PIXEL_SIZE = 4; |
405 | const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) * | 406 | const u64 base_block_size = static_cast<u64>(DefaultBlockWidth(format)) * |
406 | static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; | 407 | static_cast<u64>(DefaultBlockHeight(format)) * RGBA8_PIXEL_SIZE; |
407 | return (base_size * base_block_size) / BytesPerBlock(format); | 408 | const u64 uncompressed_size = (base_size * base_block_size) / BytesPerBlock(format); |
409 | |||
410 | switch (Settings::values.astc_recompression.GetValue()) { | ||
411 | case Settings::AstcRecompression::Bc1: | ||
412 | return uncompressed_size / 8; | ||
413 | case Settings::AstcRecompression::Bc3: | ||
414 | return uncompressed_size / 4; | ||
415 | default: | ||
416 | return uncompressed_size; | ||
417 | } | ||
408 | } | 418 | } |
409 | 419 | ||
410 | } // namespace VideoCore::Surface | 420 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 9ac9b6343..2c212a6b1 100755 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h | |||
@@ -517,6 +517,6 @@ size_t PixelComponentSizeBitsInteger(PixelFormat format); | |||
517 | 517 | ||
518 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); | 518 | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format); |
519 | 519 | ||
520 | u64 EstimatedDecompressedSize(u64 base_size, PixelFormat format); | 520 | u64 TranscodedAstcSize(u64 base_size, PixelFormat format); |
521 | 521 | ||
522 | } // namespace VideoCore::Surface | 522 | } // namespace VideoCore::Surface |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 47ea0bd96..f790897ef 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
@@ -55,7 +55,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag | |||
55 | const s64 min_spacing_critical = device_local_memory - 512_MiB; | 55 | const s64 min_spacing_critical = device_local_memory - 512_MiB; |
56 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); | 56 | const s64 mem_threshold = std::min(device_local_memory, TARGET_THRESHOLD); |
57 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; | 57 | const s64 min_vacancy_expected = (6 * mem_threshold) / 10; |
58 | const s64 min_vacancy_critical = (3 * mem_threshold) / 10; | 58 | const s64 min_vacancy_critical = (2 * mem_threshold) / 10; |
59 | expected_memory = static_cast<u64>( | 59 | expected_memory = static_cast<u64>( |
60 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), | 60 | std::max(std::min(device_local_memory - min_vacancy_expected, min_spacing_expected), |
61 | DEFAULT_EXPECTED_MEMORY)); | 61 | DEFAULT_EXPECTED_MEMORY)); |
@@ -1979,7 +1979,7 @@ void TextureCache<P>::RegisterImage(ImageId image_id) { | |||
1979 | if ((IsPixelFormatASTC(image.info.format) && | 1979 | if ((IsPixelFormatASTC(image.info.format) && |
1980 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | 1980 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || |
1981 | True(image.flags & ImageFlagBits::Converted)) { | 1981 | True(image.flags & ImageFlagBits::Converted)) { |
1982 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | 1982 | tentative_size = TranscodedAstcSize(tentative_size, image.info.format); |
1983 | } | 1983 | } |
1984 | total_used_memory += Common::AlignUp(tentative_size, 1024); | 1984 | total_used_memory += Common::AlignUp(tentative_size, 1024); |
1985 | image.lru_index = lru_cache.Insert(image_id, frame_tick); | 1985 | image.lru_index = lru_cache.Insert(image_id, frame_tick); |
@@ -2149,7 +2149,7 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { | |||
2149 | if ((IsPixelFormatASTC(image.info.format) && | 2149 | if ((IsPixelFormatASTC(image.info.format) && |
2150 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | 2150 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || |
2151 | True(image.flags & ImageFlagBits::Converted)) { | 2151 | True(image.flags & ImageFlagBits::Converted)) { |
2152 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | 2152 | tentative_size = TranscodedAstcSize(tentative_size, image.info.format); |
2153 | } | 2153 | } |
2154 | total_used_memory -= Common::AlignUp(tentative_size, 1024); | 2154 | total_used_memory -= Common::AlignUp(tentative_size, 1024); |
2155 | const GPUVAddr gpu_addr = image.gpu_addr; | 2155 | const GPUVAddr gpu_addr = image.gpu_addr; |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index bd77057b0..940cc0a54 100755 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
@@ -1290,10 +1290,6 @@ u64 Device::GetDeviceMemoryUsage() const { | |||
1290 | } | 1290 | } |
1291 | 1291 | ||
1292 | void Device::CollectPhysicalMemoryInfo() { | 1292 | void Device::CollectPhysicalMemoryInfo() { |
1293 | // Account for resolution scaling in memory limits | ||
1294 | const size_t normal_memory = 6_GiB; | ||
1295 | const size_t scaler_memory = 1_GiB * Settings::values.resolution_info.ScaleUp(1); | ||
1296 | |||
1297 | // Calculate limits using memory budget | 1293 | // Calculate limits using memory budget |
1298 | VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; | 1294 | VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; |
1299 | budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; | 1295 | budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; |
@@ -1324,7 +1320,6 @@ void Device::CollectPhysicalMemoryInfo() { | |||
1324 | if (!is_integrated) { | 1320 | if (!is_integrated) { |
1325 | const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); | 1321 | const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); |
1326 | device_access_memory -= reserve_memory; | 1322 | device_access_memory -= reserve_memory; |
1327 | device_access_memory = std::min<u64>(device_access_memory, normal_memory + scaler_memory); | ||
1328 | return; | 1323 | return; |
1329 | } | 1324 | } |
1330 | const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); | 1325 | const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); |
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 5ec8296a6..abbfdd7a6 100755 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
@@ -8,10 +8,7 @@ | |||
8 | #include "common/settings_enums.h" | 8 | #include "common/settings_enums.h" |
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" | ||
12 | #include "core/hle/service/am/applet_manager.h" | 11 | #include "core/hle/service/am/applet_manager.h" |
13 | #include "core/hle/service/am/applet_message_queue.h" | ||
14 | #include "core/hle/service/am/applet_oe.h" | ||
15 | #include "core/hle/service/sm/sm.h" | 12 | #include "core/hle/service/sm/sm.h" |
16 | #include "hid_core/frontend/emulated_controller.h" | 13 | #include "hid_core/frontend/emulated_controller.h" |
17 | #include "hid_core/hid_core.h" | 14 | #include "hid_core/hid_core.h" |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 010dd82a8..97814836f 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
@@ -44,9 +44,6 @@ | |||
44 | #include "core/frontend/applets/mii_edit.h" | 44 | #include "core/frontend/applets/mii_edit.h" |
45 | #include "core/frontend/applets/software_keyboard.h" | 45 | #include "core/frontend/applets/software_keyboard.h" |
46 | #include "core/hle/service/acc/profile_manager.h" | 46 | #include "core/hle/service/acc/profile_manager.h" |
47 | #include "core/hle/service/am/applet_ae.h" | ||
48 | #include "core/hle/service/am/applet_message_queue.h" | ||
49 | #include "core/hle/service/am/applet_oe.h" | ||
50 | #include "core/hle/service/am/frontend/applets.h" | 47 | #include "core/hle/service/am/frontend/applets.h" |
51 | #include "core/hle/service/set/system_settings_server.h" | 48 | #include "core/hle/service/set/system_settings_server.h" |
52 | #include "frontend_common/content_manager.h" | 49 | #include "frontend_common/content_manager.h" |