summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/hle/service/am/am_types.h7
-rw-r--r--src/core/hle/service/am/self_controller.cpp470
-rw-r--r--src/core/hle/service/am/self_controller.h60
-rw-r--r--src/core/hle/service/am/service/application_proxy.cpp5
-rw-r--r--src/core/hle/service/am/service/library_applet_proxy.cpp5
-rw-r--r--src/core/hle/service/am/service/self_controller.cpp393
-rw-r--r--src/core/hle/service/am/service/self_controller.h72
-rw-r--r--src/core/hle/service/am/service/system_applet_proxy.cpp5
9 files changed, 479 insertions, 542 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 935e3c57c..956207fcf 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -439,8 +439,6 @@ add_library(core STATIC
439 hle/service/am/omm.h 439 hle/service/am/omm.h
440 hle/service/am/process.cpp 440 hle/service/am/process.cpp
441 hle/service/am/process.h 441 hle/service/am/process.h
442 hle/service/am/self_controller.cpp
443 hle/service/am/self_controller.h
444 hle/service/am/service/all_system_applet_proxies_service.cpp 442 hle/service/am/service/all_system_applet_proxies_service.cpp
445 hle/service/am/service/all_system_applet_proxies_service.h 443 hle/service/am/service/all_system_applet_proxies_service.h
446 hle/service/am/service/applet_common_functions.cpp 444 hle/service/am/service/applet_common_functions.cpp
@@ -475,6 +473,8 @@ add_library(core STATIC
475 hle/service/am/service/library_applet_self_accessor.h 473 hle/service/am/service/library_applet_self_accessor.h
476 hle/service/am/service/process_winding_controller.cpp 474 hle/service/am/service/process_winding_controller.cpp
477 hle/service/am/service/process_winding_controller.h 475 hle/service/am/service/process_winding_controller.h
476 hle/service/am/service/self_controller.cpp
477 hle/service/am/service/self_controller.h
478 hle/service/am/service/system_applet_proxy.cpp 478 hle/service/am/service/system_applet_proxy.cpp
479 hle/service/am/service/system_applet_proxy.h 479 hle/service/am/service/system_applet_proxy.h
480 hle/service/am/system_buffer_manager.cpp 480 hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index 093adcdea..46afb3996 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 {
67}; 67};
68 68
69struct FocusHandlingMode { 69struct 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
76enum class IdleTimeDetectionExtension : u32 { 75enum class IdleTimeDetectionExtension : u32 {
diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp
deleted file mode 100644
index 65e249c0c..000000000
--- a/src/core/hle/service/am/self_controller.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
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/self_controller.h"
9#include "core/hle/service/caps/caps_su.h"
10#include "core/hle/service/hle_ipc.h"
11#include "core/hle/service/ipc_helpers.h"
12#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
13#include "core/hle/service/nvnflinger/nvnflinger.h"
14#include "core/hle/service/sm/sm.h"
15#include "core/hle/service/vi/vi_results.h"
16
17namespace Service::AM {
18
19ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
20 Nvnflinger::Nvnflinger& nvnflinger_)
21 : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, applet{std::move(
22 applet_)} {
23 // clang-format off
24 static const FunctionInfo functions[] = {
25 {0, &ISelfController::Exit, "Exit"},
26 {1, &ISelfController::LockExit, "LockExit"},
27 {2, &ISelfController::UnlockExit, "UnlockExit"},
28 {3, &ISelfController::EnterFatalSection, "EnterFatalSection"},
29 {4, &ISelfController::LeaveFatalSection, "LeaveFatalSection"},
30 {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
31 {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
32 {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"},
33 {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"},
34 {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
35 {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
36 {15, &ISelfController::SetScreenShotAppletIdentityInfo, "SetScreenShotAppletIdentityInfo"},
37 {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
38 {17, nullptr, "SetControllerFirmwareUpdateSection"},
39 {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
40 {19, &ISelfController::SetAlbumImageOrientation, "SetAlbumImageOrientation"},
41 {20, nullptr, "SetDesirableKeyboardLayout"},
42 {21, nullptr, "GetScreenShotProgramId"},
43 {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
44 {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"},
45 {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"},
46 {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"},
47 {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
48 {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
49 {46, nullptr, "SetRecordingLayerCompositionEnabled"},
50 {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
51 {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"},
52 {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
53 {61, &ISelfController::SetMediaPlaybackState, "SetMediaPlaybackState"},
54 {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
55 {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"},
56 {64, nullptr, "SetInputDetectionSourceSet"},
57 {65, &ISelfController::ReportUserIsActive, "ReportUserIsActive"},
58 {66, nullptr, "GetCurrentIlluminance"},
59 {67, nullptr, "IsIlluminanceAvailable"},
60 {68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"},
61 {69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
62 {70, nullptr, "ReportMultimediaError"},
63 {71, nullptr, "GetCurrentIlluminanceEx"},
64 {72, nullptr, "SetInputDetectionPolicy"},
65 {80, nullptr, "SetWirelessPriorityMode"},
66 {90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
67 {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
68 {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
69 {110, nullptr, "SetApplicationAlbumUserData"},
70 {120, &ISelfController::SaveCurrentScreenshot, "SaveCurrentScreenshot"},
71 {130, &ISelfController::SetRecordVolumeMuted, "SetRecordVolumeMuted"},
72 {1000, nullptr, "GetDebugStorageChannel"},
73 };
74 // clang-format on
75
76 RegisterHandlers(functions);
77}
78
79ISelfController::~ISelfController() = default;
80
81void ISelfController::Exit(HLERequestContext& ctx) {
82 LOG_DEBUG(Service_AM, "called");
83
84 IPC::ResponseBuilder rb{ctx, 2};
85 rb.Push(ResultSuccess);
86
87 // TODO
88 system.Exit();
89}
90
91void ISelfController::LockExit(HLERequestContext& ctx) {
92 LOG_DEBUG(Service_AM, "called");
93
94 system.SetExitLocked(true);
95
96 IPC::ResponseBuilder rb{ctx, 2};
97 rb.Push(ResultSuccess);
98}
99
100void ISelfController::UnlockExit(HLERequestContext& ctx) {
101 LOG_DEBUG(Service_AM, "called");
102
103 system.SetExitLocked(false);
104
105 IPC::ResponseBuilder rb{ctx, 2};
106 rb.Push(ResultSuccess);
107
108 if (system.GetExitRequested()) {
109 system.Exit();
110 }
111}
112
113void ISelfController::EnterFatalSection(HLERequestContext& ctx) {
114
115 std::scoped_lock lk{applet->lock};
116 applet->fatal_section_count++;
117 LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", applet->fatal_section_count);
118
119 IPC::ResponseBuilder rb{ctx, 2};
120 rb.Push(ResultSuccess);
121}
122
123void ISelfController::LeaveFatalSection(HLERequestContext& ctx) {
124 LOG_DEBUG(Service_AM, "called.");
125
126 // Entry and exit of fatal sections must be balanced.
127 std::scoped_lock lk{applet->lock};
128 if (applet->fatal_section_count == 0) {
129 IPC::ResponseBuilder rb{ctx, 2};
130 rb.Push(AM::ResultFatalSectionCountImbalance);
131 return;
132 }
133
134 applet->fatal_section_count--;
135
136 IPC::ResponseBuilder rb{ctx, 2};
137 rb.Push(ResultSuccess);
138}
139
140void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) {
141 LOG_WARNING(Service_AM, "(STUBBED) called");
142
143 applet->library_applet_launchable_event.Signal();
144
145 IPC::ResponseBuilder rb{ctx, 2, 1};
146 rb.Push(ResultSuccess);
147 rb.PushCopyObjects(applet->library_applet_launchable_event.GetHandle());
148}
149
150void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) {
151 IPC::RequestParser rp{ctx};
152 const auto permission = rp.PopEnum<ScreenshotPermission>();
153 LOG_DEBUG(Service_AM, "called, permission={}", permission);
154
155 std::scoped_lock lk{applet->lock};
156 applet->screenshot_permission = permission;
157
158 IPC::ResponseBuilder rb{ctx, 2};
159 rb.Push(ResultSuccess);
160}
161
162void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) {
163 IPC::RequestParser rp{ctx};
164
165 const bool notification_enabled = rp.Pop<bool>();
166 LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
167
168 std::scoped_lock lk{applet->lock};
169 applet->operation_mode_changed_notification_enabled = notification_enabled;
170
171 IPC::ResponseBuilder rb{ctx, 2};
172 rb.Push(ResultSuccess);
173}
174
175void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) {
176 IPC::RequestParser rp{ctx};
177
178 const bool notification_enabled = rp.Pop<bool>();
179 LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
180
181 std::scoped_lock lk{applet->lock};
182 applet->performance_mode_changed_notification_enabled = notification_enabled;
183
184 IPC::ResponseBuilder rb{ctx, 2};
185 rb.Push(ResultSuccess);
186}
187
188void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) {
189 IPC::RequestParser rp{ctx};
190
191 const auto flags = rp.PopRaw<FocusHandlingMode>();
192
193 LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}",
194 flags.unknown0, flags.unknown1, flags.unknown2);
195
196 std::scoped_lock lk{applet->lock};
197 applet->focus_handling_mode = flags;
198
199 IPC::ResponseBuilder rb{ctx, 2};
200 rb.Push(ResultSuccess);
201}
202
203void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) {
204 LOG_WARNING(Service_AM, "(STUBBED) called");
205
206 std::scoped_lock lk{applet->lock};
207 applet->restart_message_enabled = true;
208
209 IPC::ResponseBuilder rb{ctx, 2};
210 rb.Push(ResultSuccess);
211}
212
213void ISelfController::SetScreenShotAppletIdentityInfo(HLERequestContext& ctx) {
214 LOG_WARNING(Service_AM, "(STUBBED) called");
215
216 IPC::RequestParser rp{ctx};
217 std::scoped_lock lk{applet->lock};
218 applet->screen_shot_identity = rp.PopRaw<AppletIdentityInfo>();
219
220 IPC::ResponseBuilder rb{ctx, 2};
221 rb.Push(ResultSuccess);
222}
223
224void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) {
225 IPC::RequestParser rp{ctx};
226
227 const bool enabled = rp.Pop<bool>();
228 LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
229
230 std::scoped_lock lk{applet->lock};
231 ASSERT(applet->type == AppletType::Application);
232 applet->out_of_focus_suspension_enabled = enabled;
233
234 IPC::ResponseBuilder rb{ctx, 2};
235 rb.Push(ResultSuccess);
236}
237
238void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) {
239 IPC::RequestParser rp{ctx};
240
241 const auto orientation = rp.PopRaw<Capture::AlbumImageOrientation>();
242 LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", static_cast<s32>(orientation));
243
244 std::scoped_lock lk{applet->lock};
245 applet->album_image_orientation = orientation;
246
247 IPC::ResponseBuilder rb{ctx, 2};
248 rb.Push(ResultSuccess);
249}
250
251void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
252 LOG_WARNING(Service_AM, "(STUBBED) called");
253
254 u64 layer_id{};
255 applet->managed_layer_holder.Initialize(&nvnflinger);
256 applet->managed_layer_holder.CreateManagedDisplayLayer(&layer_id);
257
258 IPC::ResponseBuilder rb{ctx, 4};
259 rb.Push(ResultSuccess);
260 rb.Push(layer_id);
261}
262
263void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) {
264 LOG_WARNING(Service_AM, "(STUBBED) called");
265
266 IPC::ResponseBuilder rb{ctx, 2};
267 rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
268}
269
270void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) {
271 LOG_WARNING(Service_AM, "(STUBBED) called");
272
273 u64 buffer_id, layer_id;
274 applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
275
276 IPC::ResponseBuilder rb{ctx, 6};
277 rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
278 rb.Push<s64>(buffer_id);
279 rb.Push<s64>(layer_id);
280}
281
282void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) {
283 LOG_WARNING(Service_AM, "(STUBBED) called");
284
285 u64 buffer_id, layer_id;
286 applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
287
288 IPC::ResponseBuilder rb{ctx, 4};
289 rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
290 rb.Push<s64>(buffer_id);
291}
292
293Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) {
294 if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id,
295 applet->library_applet_mode)) {
296 return ResultSuccess;
297 }
298
299 return VI::ResultOperationFailed;
300}
301
302void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) {
303 LOG_WARNING(Service_AM, "(STUBBED) called");
304
305 u64 layer_id{};
306 u64 recording_layer_id{};
307 applet->managed_layer_holder.Initialize(&nvnflinger);
308 applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(&layer_id, &recording_layer_id);
309
310 IPC::ResponseBuilder rb{ctx, 6};
311 rb.Push(ResultSuccess);
312 rb.Push(layer_id);
313 rb.Push(recording_layer_id);
314}
315
316void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
317 LOG_WARNING(Service_AM, "(STUBBED) called");
318
319 IPC::ResponseBuilder rb{ctx, 2};
320 rb.Push(ResultSuccess);
321}
322
323void ISelfController::ApproveToDisplay(HLERequestContext& ctx) {
324 LOG_WARNING(Service_AM, "(STUBBED) called");
325
326 IPC::ResponseBuilder rb{ctx, 2};
327 rb.Push(ResultSuccess);
328}
329
330void ISelfController::SetMediaPlaybackState(HLERequestContext& ctx) {
331 IPC::RequestParser rp{ctx};
332 const u8 state = rp.Pop<u8>();
333
334 LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
335
336 IPC::ResponseBuilder rb{ctx, 2};
337 rb.Push(ResultSuccess);
338}
339
340void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
341 IPC::RequestParser rp{ctx};
342
343 const auto extension = rp.PopRaw<IdleTimeDetectionExtension>();
344 LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", extension);
345
346 std::scoped_lock lk{applet->lock};
347 applet->idle_time_detection_extension = extension;
348
349 IPC::ResponseBuilder rb{ctx, 2};
350 rb.Push(ResultSuccess);
351}
352
353void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) {
354 LOG_WARNING(Service_AM, "(STUBBED) called");
355
356 std::scoped_lock lk{applet->lock};
357
358 IPC::ResponseBuilder rb{ctx, 3};
359 rb.Push(ResultSuccess);
360 rb.PushRaw<IdleTimeDetectionExtension>(applet->idle_time_detection_extension);
361}
362
363void ISelfController::ReportUserIsActive(HLERequestContext& ctx) {
364 LOG_WARNING(Service_AM, "(STUBBED) called");
365
366 IPC::ResponseBuilder rb{ctx, 2};
367 rb.Push(ResultSuccess);
368}
369
370void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) {
371 IPC::RequestParser rp{ctx};
372
373 std::scoped_lock lk{applet->lock};
374 applet->auto_sleep_disabled = rp.Pop<bool>();
375
376 // On the system itself, if the previous state of is_auto_sleep_disabled
377 // differed from the current value passed in, it'd signify the internal
378 // window manager to update (and also increment some statistics like update counts)
379 //
380 // It'd also indicate this change to an idle handling context.
381 //
382 // However, given we're emulating this behavior, most of this can be ignored
383 // and it's sufficient to simply set the member variable for querying via
384 // IsAutoSleepDisabled().
385
386 LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", applet->auto_sleep_disabled);
387
388 IPC::ResponseBuilder rb{ctx, 2};
389 rb.Push(ResultSuccess);
390}
391
392void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) {
393 LOG_DEBUG(Service_AM, "called.");
394
395 std::scoped_lock lk{applet->lock};
396
397 IPC::ResponseBuilder rb{ctx, 3};
398 rb.Push(ResultSuccess);
399 rb.Push(applet->auto_sleep_disabled);
400}
401
402void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) {
403 LOG_DEBUG(Service_AM, "called.");
404
405 std::scoped_lock lk{applet->lock};
406 // This command returns the total number of system ticks since ISelfController creation
407 // where the game was suspended. Since Yuzu doesn't implement game suspension, this command
408 // can just always return 0 ticks.
409 IPC::ResponseBuilder rb{ctx, 4};
410 rb.Push(ResultSuccess);
411 rb.Push<u64>(applet->suspended_ticks);
412}
413
414void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) {
415 LOG_DEBUG(Service_AM, "called.");
416
417 IPC::ResponseBuilder rb{ctx, 2, 1};
418 rb.Push(ResultSuccess);
419 rb.PushCopyObjects(applet->accumulated_suspended_tick_changed_event.GetHandle());
420}
421
422void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) {
423 IPC::RequestParser rp{ctx};
424
425 // This service call sets an internal flag whether a notification is shown when an image is
426 // captured. Currently we do not support capturing images via the capture button, so this can be
427 // stubbed for now.
428 const bool enabled = rp.Pop<bool>();
429 LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
430
431 std::scoped_lock lk{applet->lock};
432 applet->album_image_taken_notification_enabled = enabled;
433
434 IPC::ResponseBuilder rb{ctx, 2};
435 rb.Push(ResultSuccess);
436}
437
438void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
439 IPC::RequestParser rp{ctx};
440
441 const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
442
443 LOG_INFO(Service_AM, "called, report_option={}", report_option);
444
445 const auto screenshot_service =
446 system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
447 "caps:su");
448
449 if (screenshot_service) {
450 screenshot_service->CaptureAndSaveScreenshot(report_option);
451 }
452
453 IPC::ResponseBuilder rb{ctx, 2};
454 rb.Push(ResultSuccess);
455}
456
457void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) {
458 IPC::RequestParser rp{ctx};
459
460 const auto enabled = rp.Pop<bool>();
461 LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
462
463 std::scoped_lock lk{applet->lock};
464 applet->record_volume_muted = enabled;
465
466 IPC::ResponseBuilder rb{ctx, 2};
467 rb.Push(ResultSuccess);
468}
469
470} // namespace Service::AM
diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h
deleted file mode 100644
index ab21a1881..000000000
--- a/src/core/hle/service/am/self_controller.h
+++ /dev/null
@@ -1,60 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/service/hle_ipc.h"
7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/service.h"
9
10namespace Service::AM {
11
12struct Applet;
13
14class ISelfController final : public ServiceFramework<ISelfController> {
15public:
16 explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
17 Nvnflinger::Nvnflinger& nvnflinger_);
18 ~ISelfController() override;
19
20private:
21 void Exit(HLERequestContext& ctx);
22 void LockExit(HLERequestContext& ctx);
23 void UnlockExit(HLERequestContext& ctx);
24 void EnterFatalSection(HLERequestContext& ctx);
25 void LeaveFatalSection(HLERequestContext& ctx);
26 void GetLibraryAppletLaunchableEvent(HLERequestContext& ctx);
27 void SetScreenShotPermission(HLERequestContext& ctx);
28 void SetOperationModeChangedNotification(HLERequestContext& ctx);
29 void SetPerformanceModeChangedNotification(HLERequestContext& ctx);
30 void SetFocusHandlingMode(HLERequestContext& ctx);
31 void SetRestartMessageEnabled(HLERequestContext& ctx);
32 void SetScreenShotAppletIdentityInfo(HLERequestContext& ctx);
33 void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx);
34 void SetAlbumImageOrientation(HLERequestContext& ctx);
35 void IsSystemBufferSharingEnabled(HLERequestContext& ctx);
36 void GetSystemSharedBufferHandle(HLERequestContext& ctx);
37 void GetSystemSharedLayerHandle(HLERequestContext& ctx);
38 void CreateManagedDisplayLayer(HLERequestContext& ctx);
39 void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx);
40 void SetHandlesRequestToDisplay(HLERequestContext& ctx);
41 void ApproveToDisplay(HLERequestContext& ctx);
42 void SetMediaPlaybackState(HLERequestContext& ctx);
43 void SetIdleTimeDetectionExtension(HLERequestContext& ctx);
44 void GetIdleTimeDetectionExtension(HLERequestContext& ctx);
45 void ReportUserIsActive(HLERequestContext& ctx);
46 void SetAutoSleepDisabled(HLERequestContext& ctx);
47 void IsAutoSleepDisabled(HLERequestContext& ctx);
48 void GetAccumulatedSuspendedTickValue(HLERequestContext& ctx);
49 void GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx);
50 void SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx);
51 void SaveCurrentScreenshot(HLERequestContext& ctx);
52 void SetRecordVolumeMuted(HLERequestContext& ctx);
53
54 Result EnsureBufferSharingEnabled(Kernel::KProcess* process);
55
56 Nvnflinger::Nvnflinger& nvnflinger;
57 const std::shared_ptr<Applet> applet;
58};
59
60} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 5f5a8f06c..9bba985be 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/am/self_controller.h"
5#include "core/hle/service/am/service/applet_common_functions.h" 4#include "core/hle/service/am/service/applet_common_functions.h"
6#include "core/hle/service/am/service/application_functions.h" 5#include "core/hle/service/am/service/application_functions.h"
7#include "core/hle/service/am/service/application_proxy.h" 6#include "core/hle/service/am/service/application_proxy.h"
@@ -11,6 +10,7 @@
11#include "core/hle/service/am/service/display_controller.h" 10#include "core/hle/service/am/service/display_controller.h"
12#include "core/hle/service/am/service/library_applet_creator.h" 11#include "core/hle/service/am/service/library_applet_creator.h"
13#include "core/hle/service/am/service/process_winding_controller.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/window_controller.h" 14#include "core/hle/service/am/window_controller.h"
15#include "core/hle/service/cmif_serialization.h" 15#include "core/hle/service/cmif_serialization.h"
16 16
@@ -77,7 +77,8 @@ Result IApplicationProxy::GetWindowController(
77Result IApplicationProxy::GetSelfController( 77Result IApplicationProxy::GetSelfController(
78 Out<SharedPointer<ISelfController>> out_self_controller) { 78 Out<SharedPointer<ISelfController>> out_self_controller) {
79 LOG_DEBUG(Service_AM, "called"); 79 LOG_DEBUG(Service_AM, "called");
80 *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger); 80 *out_self_controller =
81 std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
81 R_SUCCEED(); 82 R_SUCCEED();
82} 83}
83 84
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 91aa9f4db..bac3e0168 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/am/self_controller.h"
5#include "core/hle/service/am/service/applet_common_functions.h" 4#include "core/hle/service/am/service/applet_common_functions.h"
6#include "core/hle/service/am/service/audio_controller.h" 5#include "core/hle/service/am/service/audio_controller.h"
7#include "core/hle/service/am/service/common_state_getter.h" 6#include "core/hle/service/am/service/common_state_getter.h"
@@ -13,6 +12,7 @@
13#include "core/hle/service/am/service/library_applet_proxy.h" 12#include "core/hle/service/am/service/library_applet_proxy.h"
14#include "core/hle/service/am/service/library_applet_self_accessor.h" 13#include "core/hle/service/am/service/library_applet_self_accessor.h"
15#include "core/hle/service/am/service/process_winding_controller.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/window_controller.h" 16#include "core/hle/service/am/window_controller.h"
17#include "core/hle/service/cmif_serialization.h" 17#include "core/hle/service/cmif_serialization.h"
18 18
@@ -83,7 +83,8 @@ Result ILibraryAppletProxy::GetWindowController(
83Result ILibraryAppletProxy::GetSelfController( 83Result ILibraryAppletProxy::GetSelfController(
84 Out<SharedPointer<ISelfController>> out_self_controller) { 84 Out<SharedPointer<ISelfController>> out_self_controller) {
85 LOG_DEBUG(Service_AM, "called"); 85 LOG_DEBUG(Service_AM, "called");
86 *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger); 86 *out_self_controller =
87 std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
87 R_SUCCEED(); 88 R_SUCCEED();
88} 89}
89 90
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 100644
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
15namespace Service::AM {
16
17ISelfController::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
77ISelfController::~ISelfController() = default;
78
79Result ISelfController::Exit() {
80 LOG_DEBUG(Service_AM, "called");
81
82 // TODO
83 system.Exit();
84
85 R_SUCCEED();
86}
87
88Result ISelfController::LockExit() {
89 LOG_DEBUG(Service_AM, "called");
90
91 system.SetExitLocked(true);
92
93 R_SUCCEED();
94}
95
96Result 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
108Result 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
117Result 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
128Result 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
138Result 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
147Result 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
156Result 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
165Result 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
175Result 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
184Result 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
194Result 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
203Result 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
213Result 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
220Result 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
230Result 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
239Result 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
248Result 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
259Result ISelfController::SetHandlesRequestToDisplay(bool enable) {
260 LOG_WARNING(Service_AM, "(STUBBED) called, enable={}", enable);
261 R_SUCCEED();
262}
263
264Result ISelfController::ApproveToDisplay() {
265 LOG_WARNING(Service_AM, "(STUBBED) called");
266 R_SUCCEED();
267}
268
269Result ISelfController::SetMediaPlaybackState(bool state) {
270 LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
271 R_SUCCEED();
272}
273
274Result 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
279Result 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
289Result 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
299Result ISelfController::ReportUserIsActive() {
300 LOG_WARNING(Service_AM, "(STUBBED) called");
301 R_SUCCEED();
302}
303
304Result 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
323Result 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
332Result ISelfController::SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy) {
333 LOG_WARNING(Service_AM, "(STUBBED) called");
334 R_SUCCEED();
335}
336
337Result 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
350Result 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
358Result 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
370Result 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
384Result 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 100644
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
10namespace Kernel {
11class KReadableEvent;
12}
13
14namespace Service::Capture {
15enum class AlbumImageOrientation;
16enum class AlbumReportOption;
17} // namespace Service::Capture
18
19namespace Service::AM {
20
21struct Applet;
22
23class ISelfController final : public ServiceFramework<ISelfController> {
24public:
25 explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
26 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
27 ~ISelfController() override;
28
29private:
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/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 0f6175d32..da6e8dadd 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/am/application_creator.h" 4#include "core/hle/service/am/application_creator.h"
5#include "core/hle/service/am/self_controller.h"
6#include "core/hle/service/am/service/applet_common_functions.h" 5#include "core/hle/service/am/service/applet_common_functions.h"
7#include "core/hle/service/am/service/audio_controller.h" 6#include "core/hle/service/am/service/audio_controller.h"
8#include "core/hle/service/am/service/common_state_getter.h" 7#include "core/hle/service/am/service/common_state_getter.h"
@@ -12,6 +11,7 @@
12#include "core/hle/service/am/service/home_menu_functions.h" 11#include "core/hle/service/am/service/home_menu_functions.h"
13#include "core/hle/service/am/service/library_applet_creator.h" 12#include "core/hle/service/am/service/library_applet_creator.h"
14#include "core/hle/service/am/service/process_winding_controller.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" 15#include "core/hle/service/am/service/system_applet_proxy.h"
16#include "core/hle/service/am/window_controller.h" 16#include "core/hle/service/am/window_controller.h"
17#include "core/hle/service/cmif_serialization.h" 17#include "core/hle/service/cmif_serialization.h"
@@ -83,7 +83,8 @@ Result ISystemAppletProxy::GetWindowController(
83Result ISystemAppletProxy::GetSelfController( 83Result ISystemAppletProxy::GetSelfController(
84 Out<SharedPointer<ISelfController>> out_self_controller) { 84 Out<SharedPointer<ISelfController>> out_self_controller) {
85 LOG_DEBUG(Service_AM, "called"); 85 LOG_DEBUG(Service_AM, "called");
86 *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger); 86 *out_self_controller =
87 std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
87 R_SUCCEED(); 88 R_SUCCEED();
88} 89}
89 90