summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar mailwl2018-02-03 00:03:40 +0300
committerGravatar bunnei2018-02-02 13:03:40 -0800
commit1a8f5bfb8e5caf5db56be40c25b33e5781e6f1cd (patch)
treee6d412d9d701125c4c76ab7f8e7d23b44ccf98b8 /src/core
parentMerge pull request #154 from mailwl/vi_create_stray_array (diff)
downloadyuzu-1a8f5bfb8e5caf5db56be40c25b33e5781e6f1cd.tar.gz
yuzu-1a8f5bfb8e5caf5db56be40c25b33e5781e6f1cd.tar.xz
yuzu-1a8f5bfb8e5caf5db56be40c25b33e5781e6f1cd.zip
Service/am: Add AppletAE service (#153)
* Add AppletAE, step 1: move common interfaces to am.h * Add AppletAE, step 2
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/am/am.cpp333
-rw-r--r--src/core/hle/service/am/am.h93
-rw-r--r--src/core/hle/service/am/applet_ae.cpp112
-rw-r--r--src/core/hle/service/am/applet_ae.h30
-rw-r--r--src/core/hle/service/am/applet_oe.cpp374
-rw-r--r--src/core/hle/service/am/applet_oe.h6
7 files changed, 571 insertions, 379 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2e32ff35b..848b17b18 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -84,6 +84,8 @@ add_library(core STATIC
84 hle/service/acc/acc_u0.h 84 hle/service/acc/acc_u0.h
85 hle/service/am/am.cpp 85 hle/service/am/am.cpp
86 hle/service/am/am.h 86 hle/service/am/am.h
87 hle/service/am/applet_ae.cpp
88 hle/service/am/applet_ae.h
87 hle/service/am/applet_oe.cpp 89 hle/service/am/applet_oe.cpp
88 hle/service/am/applet_oe.h 90 hle/service/am/applet_oe.h
89 hle/service/aoc/aoc_u.cpp 91 hle/service/aoc/aoc_u.cpp
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index b6896852e..2825abd1a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -2,14 +2,347 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/event.h"
5#include "core/hle/service/am/am.h" 7#include "core/hle/service/am/am.h"
8#include "core/hle/service/am/applet_ae.h"
6#include "core/hle/service/am/applet_oe.h" 9#include "core/hle/service/am/applet_oe.h"
10#include "core/hle/service/apm/apm.h"
11#include "core/hle/service/nvflinger/nvflinger.h"
7 12
8namespace Service { 13namespace Service {
9namespace AM { 14namespace AM {
10 15
16IWindowController::IWindowController() : ServiceFramework("IWindowController") {
17 static const FunctionInfo functions[] = {
18 {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
19 {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
20 };
21 RegisterHandlers(functions);
22}
23
24void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
25 LOG_WARNING(Service, "(STUBBED) called");
26 IPC::ResponseBuilder rb{ctx, 4};
27 rb.Push(RESULT_SUCCESS);
28 rb.Push<u64>(0);
29}
30
31void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
32 LOG_WARNING(Service, "(STUBBED) called");
33 IPC::ResponseBuilder rb{ctx, 2};
34 rb.Push(RESULT_SUCCESS);
35}
36
37IAudioController::IAudioController() : ServiceFramework("IAudioController") {}
38
39IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {}
40
41IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
42
43ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
44 : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
45 static const FunctionInfo functions[] = {
46 {1, &ISelfController::LockExit, "LockExit"},
47 {2, &ISelfController::UnlockExit, "UnlockExit"},
48 {11, &ISelfController::SetOperationModeChangedNotification,
49 "SetOperationModeChangedNotification"},
50 {12, &ISelfController::SetPerformanceModeChangedNotification,
51 "SetPerformanceModeChangedNotification"},
52 {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
53 {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
54 {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
55 {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
56 };
57 RegisterHandlers(functions);
58}
59
60void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
61 // Takes 3 input u8s with each field located immediately after the previous u8, these are
62 // bool flags. No output.
63
64 IPC::RequestParser rp{ctx};
65
66 struct FocusHandlingModeParams {
67 u8 unknown0;
68 u8 unknown1;
69 u8 unknown2;
70 };
71 auto flags = rp.PopRaw<FocusHandlingModeParams>();
72
73 IPC::ResponseBuilder rb{ctx, 2};
74 rb.Push(RESULT_SUCCESS);
75
76 LOG_WARNING(Service, "(STUBBED) called");
77}
78
79void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
80 IPC::ResponseBuilder rb{ctx, 2};
81 rb.Push(RESULT_SUCCESS);
82
83 LOG_WARNING(Service, "(STUBBED) called");
84}
85
86void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
87 IPC::RequestParser rp{ctx};
88
89 bool flag = rp.Pop<bool>();
90
91 IPC::ResponseBuilder rb{ctx, 2};
92 rb.Push(RESULT_SUCCESS);
93
94 LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
95}
96
97void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
98 IPC::RequestParser rp{ctx};
99
100 bool flag = rp.Pop<bool>();
101
102 IPC::ResponseBuilder rb{ctx, 2};
103 rb.Push(RESULT_SUCCESS);
104
105 LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
106}
107
108void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
109 // Takes 3 input u8s with each field located immediately after the previous u8, these are
110 // bool flags. No output.
111 IPC::RequestParser rp{ctx};
112
113 bool enabled = rp.Pop<bool>();
114
115 IPC::ResponseBuilder rb{ctx, 2};
116 rb.Push(RESULT_SUCCESS);
117
118 LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
119}
120
121void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
122 IPC::ResponseBuilder rb{ctx, 2};
123 rb.Push(RESULT_SUCCESS);
124
125 LOG_WARNING(Service, "(STUBBED) called");
126}
127
128void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
129 IPC::ResponseBuilder rb{ctx, 2};
130 rb.Push(RESULT_SUCCESS);
131
132 LOG_WARNING(Service, "(STUBBED) called");
133}
134
135void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
136 // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
137 // in the Default display.
138 u64 display_id = nvflinger->OpenDisplay("Default");
139 u64 layer_id = nvflinger->CreateLayer(display_id);
140
141 IPC::ResponseBuilder rb{ctx, 4};
142 rb.Push(RESULT_SUCCESS);
143 rb.Push(layer_id);
144
145 LOG_WARNING(Service, "(STUBBED) called");
146}
147
148ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
149 static const FunctionInfo functions[] = {
150 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
151 {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
152 {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
153 {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
154 {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
155 };
156 RegisterHandlers(functions);
157
158 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
159}
160
161void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
162 event->Signal();
163
164 IPC::ResponseBuilder rb{ctx, 2, 1};
165 rb.Push(RESULT_SUCCESS);
166 rb.PushCopyObjects(event);
167
168 LOG_WARNING(Service, "(STUBBED) called");
169}
170
171void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
172 IPC::ResponseBuilder rb{ctx, 3};
173 rb.Push(RESULT_SUCCESS);
174 rb.Push<u32>(15);
175
176 LOG_WARNING(Service, "(STUBBED) called");
177}
178
179void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
180 IPC::ResponseBuilder rb{ctx, 3};
181 rb.Push(RESULT_SUCCESS);
182 rb.Push(static_cast<u8>(FocusState::InFocus));
183
184 LOG_WARNING(Service, "(STUBBED) called");
185}
186
187void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
188 IPC::ResponseBuilder rb{ctx, 3};
189 rb.Push(RESULT_SUCCESS);
190 rb.Push(static_cast<u8>(OperationMode::Handheld));
191
192 LOG_WARNING(Service, "(STUBBED) called");
193}
194
195void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
196 IPC::ResponseBuilder rb{ctx, 3};
197 rb.Push(RESULT_SUCCESS);
198 rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
199
200 LOG_WARNING(Service, "(STUBBED) called");
201}
202
203ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
204
205class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
206public:
207 explicit IStorageAccessor(std::vector<u8> buffer)
208 : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
209 static const FunctionInfo functions[] = {
210 {0, &IStorageAccessor::GetSize, "GetSize"},
211 {11, &IStorageAccessor::Read, "Read"},
212 };
213 RegisterHandlers(functions);
214 }
215
216private:
217 std::vector<u8> buffer;
218
219 void GetSize(Kernel::HLERequestContext& ctx) {
220 IPC::ResponseBuilder rb{ctx, 4};
221
222 rb.Push(RESULT_SUCCESS);
223 rb.Push(static_cast<u64>(buffer.size()));
224
225 LOG_DEBUG(Service, "called");
226 }
227
228 void Read(Kernel::HLERequestContext& ctx) {
229 IPC::RequestParser rp{ctx};
230
231 u64 offset = rp.Pop<u64>();
232
233 const auto& output_buffer = ctx.BufferDescriptorC()[0];
234
235 ASSERT(offset + output_buffer.Size() <= buffer.size());
236
237 Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
238
239 IPC::ResponseBuilder rb{ctx, 2};
240
241 rb.Push(RESULT_SUCCESS);
242
243 LOG_DEBUG(Service, "called");
244 }
245};
246
247class IStorage final : public ServiceFramework<IStorage> {
248public:
249 explicit IStorage(std::vector<u8> buffer)
250 : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
251 static const FunctionInfo functions[] = {
252 {0, &IStorage::Open, "Open"},
253 };
254 RegisterHandlers(functions);
255 }
256
257private:
258 std::vector<u8> buffer;
259
260 void Open(Kernel::HLERequestContext& ctx) {
261 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
262
263 rb.Push(RESULT_SUCCESS);
264 rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
265
266 LOG_DEBUG(Service, "called");
267 }
268};
269
270IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
271 static const FunctionInfo functions[] = {
272 {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
273 {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
274 {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
275 {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
276 {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
277 {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
278 };
279 RegisterHandlers(functions);
280}
281
282void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
283 constexpr u8 data[0x88] = {
284 0xca, 0x97, 0x94, 0xc7, // Magic
285 1, 0, 0, 0, // IsAccountSelected (bool)
286 1, 0, 0, 0, // User Id (word 0)
287 0, 0, 0, 0, // User Id (word 1)
288 0, 0, 0, 0, // User Id (word 2)
289 0, 0, 0, 0 // User Id (word 3)
290 };
291
292 std::vector<u8> buffer(data, data + sizeof(data));
293
294 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
295
296 rb.Push(RESULT_SUCCESS);
297 rb.PushIpcInterface<AM::IStorage>(buffer);
298
299 LOG_DEBUG(Service, "called");
300}
301
302void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
303 // Takes an input u32 Result, no output.
304 // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
305
306 IPC::RequestParser rp{ctx};
307 u32 result = rp.Pop<u32>();
308
309 IPC::ResponseBuilder rb{ctx, 2};
310 rb.Push(RESULT_SUCCESS);
311
312 LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
313}
314
315void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
316 IPC::ResponseBuilder rb{ctx, 4};
317 rb.Push(RESULT_SUCCESS);
318 rb.Push<u64>(SystemLanguage::English);
319 LOG_WARNING(Service, "(STUBBED) called");
320}
321
322void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
323 IPC::ResponseBuilder rb{ctx, 2};
324 rb.Push(RESULT_SUCCESS);
325 LOG_WARNING(Service, "(STUBBED) called");
326}
327
328void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
329 IPC::ResponseBuilder rb{ctx, 2};
330 rb.Push(RESULT_SUCCESS);
331
332 LOG_WARNING(Service, "(STUBBED) called");
333}
334
335void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
336 IPC::ResponseBuilder rb{ctx, 3};
337 rb.Push(RESULT_SUCCESS);
338 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
339
340 LOG_WARNING(Service, "(STUBBED) called");
341}
342
11void InstallInterfaces(SM::ServiceManager& service_manager, 343void InstallInterfaces(SM::ServiceManager& service_manager,
12 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { 344 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
345 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
13 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); 346 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
14} 347}
15 348
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 3b8a06c1d..b603c17dd 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -7,6 +7,10 @@
7#include <memory> 7#include <memory>
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Kernel {
11class Event;
12}
13
10namespace Service { 14namespace Service {
11namespace NVFlinger { 15namespace NVFlinger {
12class NVFlinger; 16class NVFlinger;
@@ -14,6 +18,95 @@ class NVFlinger;
14 18
15namespace AM { 19namespace AM {
16 20
21// TODO: Add more languages
22enum SystemLanguage {
23 Japanese = 0,
24 English = 1,
25};
26
27class IWindowController final : public ServiceFramework<IWindowController> {
28public:
29 IWindowController();
30
31private:
32 void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
33 void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
34};
35
36class IAudioController final : public ServiceFramework<IAudioController> {
37public:
38 IAudioController();
39};
40
41class IDisplayController final : public ServiceFramework<IDisplayController> {
42public:
43 IDisplayController();
44};
45
46class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
47public:
48 IDebugFunctions();
49};
50
51class ISelfController final : public ServiceFramework<ISelfController> {
52public:
53 ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
54
55private:
56 void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);
57 void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx);
58 void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx);
59 void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx);
60 void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
61 void LockExit(Kernel::HLERequestContext& ctx);
62 void UnlockExit(Kernel::HLERequestContext& ctx);
63 void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx);
64
65 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
66};
67
68class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
69public:
70 ICommonStateGetter();
71
72private:
73 enum class FocusState : u8 {
74 InFocus = 1,
75 NotInFocus = 2,
76 };
77
78 enum class OperationMode : u8 {
79 Handheld = 0,
80 Docked = 1,
81 };
82
83 void GetEventHandle(Kernel::HLERequestContext& ctx);
84 void ReceiveMessage(Kernel::HLERequestContext& ctx);
85 void GetCurrentFocusState(Kernel::HLERequestContext& ctx);
86 void GetOperationMode(Kernel::HLERequestContext& ctx);
87 void GetPerformanceMode(Kernel::HLERequestContext& ctx);
88
89 Kernel::SharedPtr<Kernel::Event> event;
90};
91
92class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
93public:
94 ILibraryAppletCreator();
95};
96
97class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
98public:
99 IApplicationFunctions();
100
101private:
102 void PopLaunchParameter(Kernel::HLERequestContext& ctx);
103 void SetTerminateResult(Kernel::HLERequestContext& ctx);
104 void GetDesiredLanguage(Kernel::HLERequestContext& ctx);
105 void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx);
106 void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
107 void NotifyRunning(Kernel::HLERequestContext& ctx);
108};
109
17/// Registers all AM services with the specified service manager. 110/// Registers all AM services with the specified service manager.
18void InstallInterfaces(SM::ServiceManager& service_manager, 111void InstallInterfaces(SM::ServiceManager& service_manager,
19 std::shared_ptr<NVFlinger::NVFlinger> nvflinger); 112 std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
new file mode 100644
index 000000000..a63fb6210
--- /dev/null
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -0,0 +1,112 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/am/am.h"
8#include "core/hle/service/am/applet_ae.h"
9#include "core/hle/service/nvflinger/nvflinger.h"
10
11namespace Service {
12namespace AM {
13
14class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
15public:
16 ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
17 : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) {
18 static const FunctionInfo functions[] = {
19 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
20 {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
21 {2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"},
22 {3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"},
23 {4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
24 {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
25 {20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"},
26 {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
27 };
28 RegisterHandlers(functions);
29 }
30
31private:
32 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
33 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
34 rb.Push(RESULT_SUCCESS);
35 rb.PushIpcInterface<ICommonStateGetter>();
36 LOG_DEBUG(Service, "called");
37 }
38
39 void GetSelfController(Kernel::HLERequestContext& ctx) {
40 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
41 rb.Push(RESULT_SUCCESS);
42 rb.PushIpcInterface<ISelfController>(nvflinger);
43 LOG_DEBUG(Service, "called");
44 }
45
46 void GetWindowController(Kernel::HLERequestContext& ctx) {
47 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
48 rb.Push(RESULT_SUCCESS);
49 rb.PushIpcInterface<IWindowController>();
50 LOG_DEBUG(Service, "called");
51 }
52
53 void GetAudioController(Kernel::HLERequestContext& ctx) {
54 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
55 rb.Push(RESULT_SUCCESS);
56 rb.PushIpcInterface<IAudioController>();
57 LOG_DEBUG(Service, "called");
58 }
59
60 void GetDisplayController(Kernel::HLERequestContext& ctx) {
61 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
62 rb.Push(RESULT_SUCCESS);
63 rb.PushIpcInterface<IDisplayController>();
64 LOG_DEBUG(Service, "called");
65 }
66
67 void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
68 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
69 rb.Push(RESULT_SUCCESS);
70 rb.PushIpcInterface<IDebugFunctions>();
71 LOG_DEBUG(Service, "called");
72 }
73
74 void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
75 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
76 rb.Push(RESULT_SUCCESS);
77 rb.PushIpcInterface<ILibraryAppletCreator>();
78 LOG_DEBUG(Service, "called");
79 }
80
81 void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
82 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
83 rb.Push(RESULT_SUCCESS);
84 rb.PushIpcInterface<IApplicationFunctions>();
85 LOG_DEBUG(Service, "called");
86 }
87
88 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
89};
90
91void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
92 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
93 rb.Push(RESULT_SUCCESS);
94 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
95 LOG_DEBUG(Service, "called");
96}
97
98AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
99 : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) {
100 static const FunctionInfo functions[] = {
101 {100, nullptr, "OpenSystemAppletProxy"},
102 {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"},
103 {201, nullptr, "OpenLibraryAppletProxy"},
104 {300, nullptr, "OpenOverlayAppletProxy"},
105 {350, nullptr, "OpenSystemApplicationProxy"},
106 {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
107 };
108 RegisterHandlers(functions);
109}
110
111} // namespace AM
112} // namespace Service
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
new file mode 100644
index 000000000..38fc428fb
--- /dev/null
+++ b/src/core/hle/service/am/applet_ae.h
@@ -0,0 +1,30 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "core/hle/kernel/hle_ipc.h"
9#include "core/hle/service/service.h"
10
11namespace Service {
12namespace NVFlinger {
13class NVFlinger;
14}
15
16namespace AM {
17
18class AppletAE final : public ServiceFramework<AppletAE> {
19public:
20 AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
21 ~AppletAE() = default;
22
23private:
24 void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
25
26 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
27};
28
29} // namespace AM
30} // namespace Service
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 15b7701e0..5aa765770 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -4,385 +4,13 @@
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/kernel/event.h" 7#include "core/hle/service/am/am.h"
8#include "core/hle/service/am/applet_oe.h" 8#include "core/hle/service/am/applet_oe.h"
9#include "core/hle/service/apm/apm.h"
10#include "core/hle/service/nvflinger/nvflinger.h" 9#include "core/hle/service/nvflinger/nvflinger.h"
11 10
12namespace Service { 11namespace Service {
13namespace AM { 12namespace AM {
14 13
15class IWindowController final : public ServiceFramework<IWindowController> {
16public:
17 IWindowController() : ServiceFramework("IWindowController") {
18 static const FunctionInfo functions[] = {
19 {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
20 {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
21 };
22 RegisterHandlers(functions);
23 }
24
25private:
26 void GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
27 LOG_WARNING(Service, "(STUBBED) called");
28 IPC::ResponseBuilder rb{ctx, 4};
29 rb.Push(RESULT_SUCCESS);
30 rb.Push<u64>(0);
31 }
32
33 void AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
34 LOG_WARNING(Service, "(STUBBED) called");
35 IPC::ResponseBuilder rb{ctx, 2};
36 rb.Push(RESULT_SUCCESS);
37 }
38};
39
40class IAudioController final : public ServiceFramework<IAudioController> {
41public:
42 IAudioController() : ServiceFramework("IAudioController") {}
43};
44
45class IDisplayController final : public ServiceFramework<IDisplayController> {
46public:
47 IDisplayController() : ServiceFramework("IDisplayController") {}
48};
49
50class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
51public:
52 IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
53};
54
55class ISelfController final : public ServiceFramework<ISelfController> {
56public:
57 ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
58 : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
59 static const FunctionInfo functions[] = {
60 {1, &ISelfController::LockExit, "LockExit"},
61 {2, &ISelfController::UnlockExit, "UnlockExit"},
62 {11, &ISelfController::SetOperationModeChangedNotification,
63 "SetOperationModeChangedNotification"},
64 {12, &ISelfController::SetPerformanceModeChangedNotification,
65 "SetPerformanceModeChangedNotification"},
66 {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
67 {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
68 {16, &ISelfController::SetOutOfFocusSuspendingEnabled,
69 "SetOutOfFocusSuspendingEnabled"},
70 {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
71 };
72 RegisterHandlers(functions);
73 }
74
75private:
76 void SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
77 // Takes 3 input u8s with each field located immediately after the previous u8, these are
78 // bool flags. No output.
79
80 IPC::RequestParser rp{ctx};
81
82 struct FocusHandlingModeParams {
83 u8 unknown0;
84 u8 unknown1;
85 u8 unknown2;
86 };
87 auto flags = rp.PopRaw<FocusHandlingModeParams>();
88
89 IPC::ResponseBuilder rb{ctx, 2};
90 rb.Push(RESULT_SUCCESS);
91
92 LOG_WARNING(Service, "(STUBBED) called");
93 }
94
95 void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
96 IPC::ResponseBuilder rb{ctx, 2};
97 rb.Push(RESULT_SUCCESS);
98
99 LOG_WARNING(Service, "(STUBBED) called");
100 }
101
102 void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
103 IPC::RequestParser rp{ctx};
104
105 bool flag = rp.Pop<bool>();
106
107 IPC::ResponseBuilder rb{ctx, 2};
108 rb.Push(RESULT_SUCCESS);
109
110 LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
111 }
112
113 void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
114 IPC::RequestParser rp{ctx};
115
116 bool flag = rp.Pop<bool>();
117
118 IPC::ResponseBuilder rb{ctx, 2};
119 rb.Push(RESULT_SUCCESS);
120
121 LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
122 }
123
124 void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
125 // Takes 3 input u8s with each field located immediately after the previous u8, these are
126 // bool flags. No output.
127 IPC::RequestParser rp{ctx};
128
129 bool enabled = rp.Pop<bool>();
130
131 IPC::ResponseBuilder rb{ctx, 2};
132 rb.Push(RESULT_SUCCESS);
133
134 LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
135 }
136
137 void LockExit(Kernel::HLERequestContext& ctx) {
138 IPC::ResponseBuilder rb{ctx, 2};
139 rb.Push(RESULT_SUCCESS);
140
141 LOG_WARNING(Service, "(STUBBED) called");
142 }
143
144 void UnlockExit(Kernel::HLERequestContext& ctx) {
145 IPC::ResponseBuilder rb{ctx, 2};
146 rb.Push(RESULT_SUCCESS);
147
148 LOG_WARNING(Service, "(STUBBED) called");
149 }
150
151 void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
152 // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
153 // in the Default display.
154 u64 display_id = nvflinger->OpenDisplay("Default");
155 u64 layer_id = nvflinger->CreateLayer(display_id);
156
157 IPC::ResponseBuilder rb{ctx, 4};
158 rb.Push(RESULT_SUCCESS);
159 rb.Push(layer_id);
160
161 LOG_WARNING(Service, "(STUBBED) called");
162 }
163
164 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
165};
166
167class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
168public:
169 ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
170 static const FunctionInfo functions[] = {
171 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
172 {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
173 {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
174 {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
175 {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
176 };
177 RegisterHandlers(functions);
178
179 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
180 }
181
182private:
183 enum class FocusState : u8 {
184 InFocus = 1,
185 NotInFocus = 2,
186 };
187
188 enum class OperationMode : u8 {
189 Handheld = 0,
190 Docked = 1,
191 };
192
193 void GetEventHandle(Kernel::HLERequestContext& ctx) {
194 event->Signal();
195
196 IPC::ResponseBuilder rb{ctx, 2, 1};
197 rb.Push(RESULT_SUCCESS);
198 rb.PushCopyObjects(event);
199
200 LOG_WARNING(Service, "(STUBBED) called");
201 }
202
203 void ReceiveMessage(Kernel::HLERequestContext& ctx) {
204 IPC::ResponseBuilder rb{ctx, 3};
205 rb.Push(RESULT_SUCCESS);
206 rb.Push<u32>(15);
207
208 LOG_WARNING(Service, "(STUBBED) called");
209 }
210
211 void GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
212 IPC::ResponseBuilder rb{ctx, 3};
213 rb.Push(RESULT_SUCCESS);
214 rb.Push(static_cast<u8>(FocusState::InFocus));
215
216 LOG_WARNING(Service, "(STUBBED) called");
217 }
218
219 void GetOperationMode(Kernel::HLERequestContext& ctx) {
220 IPC::ResponseBuilder rb{ctx, 3};
221 rb.Push(RESULT_SUCCESS);
222 rb.Push(static_cast<u8>(OperationMode::Handheld));
223
224 LOG_WARNING(Service, "(STUBBED) called");
225 }
226
227 void GetPerformanceMode(Kernel::HLERequestContext& ctx) {
228 IPC::ResponseBuilder rb{ctx, 3};
229 rb.Push(RESULT_SUCCESS);
230 rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
231
232 LOG_WARNING(Service, "(STUBBED) called");
233 }
234
235 Kernel::SharedPtr<Kernel::Event> event;
236};
237
238class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
239public:
240 explicit IStorageAccessor(std::vector<u8> buffer)
241 : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
242 static const FunctionInfo functions[] = {
243 {0, &IStorageAccessor::GetSize, "GetSize"},
244 {11, &IStorageAccessor::Read, "Read"},
245 };
246 RegisterHandlers(functions);
247 }
248
249private:
250 std::vector<u8> buffer;
251
252 void GetSize(Kernel::HLERequestContext& ctx) {
253 IPC::ResponseBuilder rb{ctx, 4};
254
255 rb.Push(RESULT_SUCCESS);
256 rb.Push(static_cast<u64>(buffer.size()));
257
258 LOG_DEBUG(Service, "called");
259 }
260
261 void Read(Kernel::HLERequestContext& ctx) {
262 IPC::RequestParser rp{ctx};
263
264 u64 offset = rp.Pop<u64>();
265
266 const auto& output_buffer = ctx.BufferDescriptorC()[0];
267
268 ASSERT(offset + output_buffer.Size() <= buffer.size());
269
270 Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
271
272 IPC::ResponseBuilder rb{ctx, 2};
273
274 rb.Push(RESULT_SUCCESS);
275
276 LOG_DEBUG(Service, "called");
277 }
278};
279
280class IStorage final : public ServiceFramework<IStorage> {
281public:
282 explicit IStorage(std::vector<u8> buffer)
283 : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
284 static const FunctionInfo functions[] = {
285 {0, &IStorage::Open, "Open"},
286 };
287 RegisterHandlers(functions);
288 }
289
290private:
291 std::vector<u8> buffer;
292
293 void Open(Kernel::HLERequestContext& ctx) {
294 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
295
296 rb.Push(RESULT_SUCCESS);
297 rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
298
299 LOG_DEBUG(Service, "called");
300 }
301};
302
303class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
304public:
305 IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
306 static const FunctionInfo functions[] = {
307 {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
308 {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
309 {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
310 {66, &IApplicationFunctions::InitializeGamePlayRecording,
311 "InitializeGamePlayRecording"},
312 {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
313 {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
314 };
315 RegisterHandlers(functions);
316 }
317
318private:
319 void PopLaunchParameter(Kernel::HLERequestContext& ctx) {
320 constexpr u8 data[0x88] = {
321 0xca, 0x97, 0x94, 0xc7, // Magic
322 1, 0, 0, 0, // IsAccountSelected (bool)
323 1, 0, 0, 0, // User Id (word 0)
324 0, 0, 0, 0, // User Id (word 1)
325 0, 0, 0, 0, // User Id (word 2)
326 0, 0, 0, 0 // User Id (word 3)
327 };
328
329 std::vector<u8> buffer(data, data + sizeof(data));
330
331 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
332
333 rb.Push(RESULT_SUCCESS);
334 rb.PushIpcInterface<AM::IStorage>(buffer);
335
336 LOG_DEBUG(Service, "called");
337 }
338
339 void SetTerminateResult(Kernel::HLERequestContext& ctx) {
340 // Takes an input u32 Result, no output.
341 // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
342
343 IPC::RequestParser rp{ctx};
344 u32 result = rp.Pop<u32>();
345
346 IPC::ResponseBuilder rb{ctx, 2};
347 rb.Push(RESULT_SUCCESS);
348
349 LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
350 }
351
352 void GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
353 IPC::ResponseBuilder rb{ctx, 4};
354 rb.Push(RESULT_SUCCESS);
355 rb.Push<u64>(SystemLanguage::English);
356 LOG_WARNING(Service, "(STUBBED) called");
357 }
358
359 void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
360 IPC::ResponseBuilder rb{ctx, 2};
361 rb.Push(RESULT_SUCCESS);
362 LOG_WARNING(Service, "(STUBBED) called");
363 }
364
365 void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
366 IPC::ResponseBuilder rb{ctx, 2};
367 rb.Push(RESULT_SUCCESS);
368
369 LOG_WARNING(Service, "(STUBBED) called");
370 }
371
372 void NotifyRunning(Kernel::HLERequestContext& ctx) {
373 IPC::ResponseBuilder rb{ctx, 3};
374 rb.Push(RESULT_SUCCESS);
375 rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
376
377 LOG_WARNING(Service, "(STUBBED) called");
378 }
379};
380
381class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
382public:
383 ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {}
384};
385
386class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { 14class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
387public: 15public:
388 IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 16 IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 8083135c3..d2ab44c67 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -15,12 +15,6 @@ class NVFlinger;
15 15
16namespace AM { 16namespace AM {
17 17
18// TODO: Add more languages
19enum SystemLanguage {
20 Japanese = 0,
21 English = 1,
22};
23
24class AppletOE final : public ServiceFramework<AppletOE> { 18class AppletOE final : public ServiceFramework<AppletOE> {
25public: 19public:
26 AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); 20 AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);