am.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <array>
  5. #include <cinttypes>
  6. #include <cstring>
  7. #include <stack>
  8. #include "applets/applets.h"
  9. #include "applets/software_keyboard.h"
  10. #include "audio_core/audio_renderer.h"
  11. #include "core/core.h"
  12. #include "core/hle/ipc_helpers.h"
  13. #include "core/hle/kernel/event.h"
  14. #include "core/hle/kernel/process.h"
  15. #include "core/hle/kernel/shared_memory.h"
  16. #include "core/hle/service/acc/profile_manager.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_oe.h"
  20. #include "core/hle/service/am/idle.h"
  21. #include "core/hle/service/am/omm.h"
  22. #include "core/hle/service/am/spsm.h"
  23. #include "core/hle/service/am/tcap.h"
  24. #include "core/hle/service/apm/apm.h"
  25. #include "core/hle/service/filesystem/filesystem.h"
  26. #include "core/hle/service/nvflinger/nvflinger.h"
  27. #include "core/hle/service/pm/pm.h"
  28. #include "core/hle/service/set/set.h"
  29. #include "core/hle/service/vi/vi.h"
  30. #include "core/settings.h"
  31. namespace Service::AM {
  32. enum class AppletId : u32 {
  33. SoftwareKeyboard = 0x11,
  34. };
  35. constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA;
  36. struct LaunchParameters {
  37. u32_le magic;
  38. u32_le is_account_selected;
  39. u128 current_user;
  40. INSERT_PADDING_BYTES(0x70);
  41. };
  42. static_assert(sizeof(LaunchParameters) == 0x88);
  43. IWindowController::IWindowController() : ServiceFramework("IWindowController") {
  44. // clang-format off
  45. static const FunctionInfo functions[] = {
  46. {0, nullptr, "CreateWindow"},
  47. {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
  48. {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
  49. {11, nullptr, "ReleaseForegroundRights"},
  50. {12, nullptr, "RejectToChangeIntoBackground"},
  51. {20, nullptr, "SetAppletWindowVisibility"},
  52. {21, nullptr, "SetAppletGpuTimeSlice"},
  53. };
  54. // clang-format on
  55. RegisterHandlers(functions);
  56. }
  57. IWindowController::~IWindowController() = default;
  58. void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
  59. LOG_WARNING(Service_AM, "(STUBBED) called");
  60. IPC::ResponseBuilder rb{ctx, 4};
  61. rb.Push(RESULT_SUCCESS);
  62. rb.Push<u64>(0);
  63. }
  64. void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
  65. LOG_WARNING(Service_AM, "(STUBBED) called");
  66. IPC::ResponseBuilder rb{ctx, 2};
  67. rb.Push(RESULT_SUCCESS);
  68. }
  69. IAudioController::IAudioController() : ServiceFramework("IAudioController") {
  70. static const FunctionInfo functions[] = {
  71. {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
  72. {1, &IAudioController::GetMainAppletExpectedMasterVolume,
  73. "GetMainAppletExpectedMasterVolume"},
  74. {2, &IAudioController::GetLibraryAppletExpectedMasterVolume,
  75. "GetLibraryAppletExpectedMasterVolume"},
  76. {3, nullptr, "ChangeMainAppletMasterVolume"},
  77. {4, nullptr, "SetTransparentVolumeRate"},
  78. };
  79. RegisterHandlers(functions);
  80. }
  81. IAudioController::~IAudioController() = default;
  82. void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  83. LOG_WARNING(Service_AM, "(STUBBED) called");
  84. IPC::ResponseBuilder rb{ctx, 2};
  85. rb.Push(RESULT_SUCCESS);
  86. }
  87. void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  88. LOG_WARNING(Service_AM, "(STUBBED) called");
  89. IPC::ResponseBuilder rb{ctx, 3};
  90. rb.Push(RESULT_SUCCESS);
  91. rb.Push(volume);
  92. }
  93. void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  94. LOG_WARNING(Service_AM, "(STUBBED) called");
  95. IPC::ResponseBuilder rb{ctx, 3};
  96. rb.Push(RESULT_SUCCESS);
  97. rb.Push(volume);
  98. }
  99. IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {
  100. // clang-format off
  101. static const FunctionInfo functions[] = {
  102. {0, nullptr, "GetLastForegroundCaptureImage"},
  103. {1, nullptr, "UpdateLastForegroundCaptureImage"},
  104. {2, nullptr, "GetLastApplicationCaptureImage"},
  105. {3, nullptr, "GetCallerAppletCaptureImage"},
  106. {4, nullptr, "UpdateCallerAppletCaptureImage"},
  107. {5, nullptr, "GetLastForegroundCaptureImageEx"},
  108. {6, nullptr, "GetLastApplicationCaptureImageEx"},
  109. {7, nullptr, "GetCallerAppletCaptureImageEx"},
  110. {8, nullptr, "TakeScreenShotOfOwnLayer"}, // 2.0.0+
  111. {9, nullptr, "CopyBetweenCaptureBuffers"}, // 5.0.0+
  112. {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
  113. {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
  114. {12, nullptr, "AcquireLastForegroundCaptureBuffer"},
  115. {13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
  116. {14, nullptr, "AcquireCallerAppletCaptureBuffer"},
  117. {15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
  118. {16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
  119. {17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
  120. {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
  121. // 2.0.0+
  122. {20, nullptr, "ClearCaptureBuffer"},
  123. {21, nullptr, "ClearAppletTransitionBuffer"},
  124. // 4.0.0+
  125. {22, nullptr, "AcquireLastApplicationCaptureSharedBuffer"},
  126. {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
  127. {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
  128. {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
  129. {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"},
  130. {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"},
  131. // 6.0.0+
  132. {28, nullptr, "TakeScreenShotOfOwnLayerEx"},
  133. };
  134. // clang-format on
  135. RegisterHandlers(functions);
  136. }
  137. IDisplayController::~IDisplayController() = default;
  138. IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
  139. IDebugFunctions::~IDebugFunctions() = default;
  140. ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
  141. : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
  142. // clang-format off
  143. static const FunctionInfo functions[] = {
  144. {0, nullptr, "Exit"},
  145. {1, &ISelfController::LockExit, "LockExit"},
  146. {2, &ISelfController::UnlockExit, "UnlockExit"},
  147. {3, nullptr, "EnterFatalSection"},
  148. {4, nullptr, "LeaveFatalSection"},
  149. {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
  150. {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
  151. {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"},
  152. {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"},
  153. {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
  154. {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
  155. {15, nullptr, "SetScreenShotAppletIdentityInfo"},
  156. {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
  157. {17, nullptr, "SetControllerFirmwareUpdateSection"},
  158. {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
  159. {19, &ISelfController::SetScreenShotImageOrientation, "SetScreenShotImageOrientation"},
  160. {20, nullptr, "SetDesirableKeyboardLayout"},
  161. {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
  162. {41, nullptr, "IsSystemBufferSharingEnabled"},
  163. {42, nullptr, "GetSystemSharedLayerHandle"},
  164. {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
  165. {51, nullptr, "ApproveToDisplay"},
  166. {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
  167. {61, nullptr, "SetMediaPlaybackState"},
  168. {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
  169. {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"},
  170. {64, nullptr, "SetInputDetectionSourceSet"},
  171. {65, nullptr, "ReportUserIsActive"},
  172. {66, nullptr, "GetCurrentIlluminance"},
  173. {67, nullptr, "IsIlluminanceAvailable"},
  174. {68, nullptr, "SetAutoSleepDisabled"},
  175. {69, nullptr, "IsAutoSleepDisabled"},
  176. {70, nullptr, "ReportMultimediaError"},
  177. {80, nullptr, "SetWirelessPriorityMode"},
  178. {90, nullptr, "GetAccumulatedSuspendedTickValue"},
  179. {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"},
  180. {1000, nullptr, "GetDebugStorageChannel"},
  181. };
  182. // clang-format on
  183. RegisterHandlers(functions);
  184. auto& kernel = Core::System::GetInstance().Kernel();
  185. launchable_event =
  186. Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent");
  187. }
  188. ISelfController::~ISelfController() = default;
  189. void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
  190. // Takes 3 input u8s with each field located immediately after the previous
  191. // u8, these are bool flags. No output.
  192. IPC::RequestParser rp{ctx};
  193. struct FocusHandlingModeParams {
  194. u8 unknown0;
  195. u8 unknown1;
  196. u8 unknown2;
  197. };
  198. auto flags = rp.PopRaw<FocusHandlingModeParams>();
  199. IPC::ResponseBuilder rb{ctx, 2};
  200. rb.Push(RESULT_SUCCESS);
  201. LOG_WARNING(Service_AM, "(STUBBED) called");
  202. }
  203. void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
  204. IPC::ResponseBuilder rb{ctx, 2};
  205. rb.Push(RESULT_SUCCESS);
  206. LOG_WARNING(Service_AM, "(STUBBED) called");
  207. }
  208. void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
  209. IPC::RequestParser rp{ctx};
  210. bool flag = rp.Pop<bool>();
  211. IPC::ResponseBuilder rb{ctx, 2};
  212. rb.Push(RESULT_SUCCESS);
  213. LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
  214. }
  215. void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
  216. IPC::ResponseBuilder rb{ctx, 2};
  217. rb.Push(RESULT_SUCCESS);
  218. LOG_WARNING(Service_AM, "(STUBBED) called");
  219. }
  220. void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
  221. IPC::RequestParser rp{ctx};
  222. bool flag = rp.Pop<bool>();
  223. IPC::ResponseBuilder rb{ctx, 2};
  224. rb.Push(RESULT_SUCCESS);
  225. LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
  226. }
  227. void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
  228. // Takes 3 input u8s with each field located immediately after the previous
  229. // u8, these are bool flags. No output.
  230. IPC::RequestParser rp{ctx};
  231. bool enabled = rp.Pop<bool>();
  232. IPC::ResponseBuilder rb{ctx, 2};
  233. rb.Push(RESULT_SUCCESS);
  234. LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
  235. }
  236. void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
  237. IPC::ResponseBuilder rb{ctx, 2};
  238. rb.Push(RESULT_SUCCESS);
  239. LOG_WARNING(Service_AM, "(STUBBED) called");
  240. }
  241. void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
  242. IPC::ResponseBuilder rb{ctx, 2};
  243. rb.Push(RESULT_SUCCESS);
  244. LOG_WARNING(Service_AM, "(STUBBED) called");
  245. }
  246. void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
  247. launchable_event->Signal();
  248. IPC::ResponseBuilder rb{ctx, 2, 1};
  249. rb.Push(RESULT_SUCCESS);
  250. rb.PushCopyObjects(launchable_event);
  251. LOG_WARNING(Service_AM, "(STUBBED) called");
  252. }
  253. void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) {
  254. IPC::ResponseBuilder rb{ctx, 2};
  255. rb.Push(RESULT_SUCCESS);
  256. LOG_WARNING(Service_AM, "(STUBBED) called");
  257. }
  258. void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
  259. // TODO(Subv): Find out how AM determines the display to use, for now just
  260. // create the layer in the Default display.
  261. u64 display_id = nvflinger->OpenDisplay("Default");
  262. u64 layer_id = nvflinger->CreateLayer(display_id);
  263. IPC::ResponseBuilder rb{ctx, 4};
  264. rb.Push(RESULT_SUCCESS);
  265. rb.Push(layer_id);
  266. LOG_WARNING(Service_AM, "(STUBBED) called");
  267. }
  268. void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
  269. IPC::ResponseBuilder rb{ctx, 2};
  270. rb.Push(RESULT_SUCCESS);
  271. LOG_WARNING(Service_AM, "(STUBBED) called");
  272. }
  273. void ISelfController::SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx) {
  274. IPC::RequestParser rp{ctx};
  275. idle_time_detection_extension = rp.Pop<u32>();
  276. IPC::ResponseBuilder rb{ctx, 2};
  277. rb.Push(RESULT_SUCCESS);
  278. LOG_WARNING(Service_AM, "(STUBBED) called");
  279. }
  280. void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx) {
  281. IPC::ResponseBuilder rb{ctx, 3};
  282. rb.Push(RESULT_SUCCESS);
  283. rb.Push<u32>(idle_time_detection_extension);
  284. LOG_WARNING(Service_AM, "(STUBBED) called");
  285. }
  286. AppletMessageQueue::AppletMessageQueue() {
  287. auto& kernel = Core::System::GetInstance().Kernel();
  288. on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
  289. "AMMessageQueue:OnMessageRecieved");
  290. on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
  291. "AMMessageQueue:OperationModeChanged");
  292. }
  293. AppletMessageQueue::~AppletMessageQueue() = default;
  294. const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const {
  295. return on_new_message;
  296. }
  297. const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const {
  298. return on_operation_mode_changed;
  299. }
  300. void AppletMessageQueue::PushMessage(AppletMessage msg) {
  301. messages.push(msg);
  302. on_new_message->Signal();
  303. }
  304. AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
  305. if (messages.empty()) {
  306. on_new_message->Clear();
  307. return AppletMessage::NoMessage;
  308. }
  309. auto msg = messages.front();
  310. messages.pop();
  311. if (messages.empty()) {
  312. on_new_message->Clear();
  313. }
  314. return msg;
  315. }
  316. std::size_t AppletMessageQueue::GetMessageCount() const {
  317. return messages.size();
  318. }
  319. void AppletMessageQueue::OperationModeChanged() {
  320. PushMessage(AppletMessage::OperationModeChanged);
  321. PushMessage(AppletMessage::PerformanceModeChanged);
  322. on_operation_mode_changed->Signal();
  323. }
  324. ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
  325. : ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
  326. // clang-format off
  327. static const FunctionInfo functions[] = {
  328. {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
  329. {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
  330. {2, nullptr, "GetThisAppletKind"},
  331. {3, nullptr, "AllowToEnterSleep"},
  332. {4, nullptr, "DisallowToEnterSleep"},
  333. {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
  334. {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
  335. {7, nullptr, "GetCradleStatus"},
  336. {8, &ICommonStateGetter::GetBootMode, "GetBootMode"},
  337. {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
  338. {10, nullptr, "RequestToAcquireSleepLock"},
  339. {11, nullptr, "ReleaseSleepLock"},
  340. {12, nullptr, "ReleaseSleepLockTransiently"},
  341. {13, nullptr, "GetAcquiredSleepLockEvent"},
  342. {20, nullptr, "PushToGeneralChannel"},
  343. {30, nullptr, "GetHomeButtonReaderLockAccessor"},
  344. {31, nullptr, "GetReaderLockAccessorEx"},
  345. {40, nullptr, "GetCradleFwVersion"},
  346. {50, nullptr, "IsVrModeEnabled"},
  347. {51, nullptr, "SetVrModeEnabled"},
  348. {52, nullptr, "SwitchLcdBacklight"},
  349. {55, nullptr, "IsInControllerFirmwareUpdateSection"},
  350. {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"},
  351. {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"},
  352. {62, nullptr, "GetHdcpAuthenticationState"},
  353. {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
  354. };
  355. // clang-format on
  356. RegisterHandlers(functions);
  357. auto& kernel = Core::System::GetInstance().Kernel();
  358. event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
  359. }
  360. ICommonStateGetter::~ICommonStateGetter() = default;
  361. void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
  362. IPC::ResponseBuilder rb{ctx, 3};
  363. rb.Push(RESULT_SUCCESS);
  364. rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode
  365. LOG_DEBUG(Service_AM, "called");
  366. }
  367. void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
  368. IPC::ResponseBuilder rb{ctx, 2, 1};
  369. rb.Push(RESULT_SUCCESS);
  370. rb.PushCopyObjects(msg_queue->GetMesssageRecieveEvent());
  371. LOG_DEBUG(Service_AM, "called");
  372. }
  373. void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
  374. IPC::ResponseBuilder rb{ctx, 3};
  375. rb.Push(RESULT_SUCCESS);
  376. rb.PushEnum<AppletMessageQueue::AppletMessage>(msg_queue->PopMessage());
  377. LOG_DEBUG(Service_AM, "called");
  378. }
  379. void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
  380. IPC::ResponseBuilder rb{ctx, 3};
  381. rb.Push(RESULT_SUCCESS);
  382. rb.Push(static_cast<u8>(FocusState::InFocus));
  383. LOG_WARNING(Service_AM, "(STUBBED) called");
  384. }
  385. void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
  386. IPC::ResponseBuilder rb{ctx, 2, 1};
  387. rb.Push(RESULT_SUCCESS);
  388. rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent());
  389. LOG_DEBUG(Service_AM, "called");
  390. }
  391. void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) {
  392. IPC::ResponseBuilder rb{ctx, 4};
  393. rb.Push(RESULT_SUCCESS);
  394. if (Settings::values.use_docked_mode) {
  395. rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
  396. rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
  397. } else {
  398. rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth));
  399. rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight));
  400. }
  401. LOG_DEBUG(Service_AM, "called");
  402. }
  403. IStorage::IStorage(std::vector<u8> buffer)
  404. : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
  405. // clang-format off
  406. static const FunctionInfo functions[] = {
  407. {0, &IStorage::Open, "Open"},
  408. {1, nullptr, "OpenTransferStorage"},
  409. };
  410. // clang-format on
  411. RegisterHandlers(functions);
  412. }
  413. IStorage::~IStorage() = default;
  414. const std::vector<u8>& IStorage::GetData() const {
  415. return buffer;
  416. }
  417. void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
  418. const bool use_docked_mode{Settings::values.use_docked_mode};
  419. IPC::ResponseBuilder rb{ctx, 3};
  420. rb.Push(RESULT_SUCCESS);
  421. rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
  422. LOG_DEBUG(Service_AM, "called");
  423. }
  424. void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
  425. const bool use_docked_mode{Settings::values.use_docked_mode};
  426. IPC::ResponseBuilder rb{ctx, 3};
  427. rb.Push(RESULT_SUCCESS);
  428. rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
  429. : APM::PerformanceMode::Handheld));
  430. LOG_DEBUG(Service_AM, "called");
  431. }
  432. class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
  433. public:
  434. explicit ILibraryAppletAccessor(std::shared_ptr<Applets::Applet> applet)
  435. : ServiceFramework("ILibraryAppletAccessor"), applet(std::move(applet)) {
  436. // clang-format off
  437. static const FunctionInfo functions[] = {
  438. {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
  439. {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"},
  440. {10, &ILibraryAppletAccessor::Start, "Start"},
  441. {20, nullptr, "RequestExit"},
  442. {25, nullptr, "Terminate"},
  443. {30, &ILibraryAppletAccessor::GetResult, "GetResult"},
  444. {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
  445. {100, &ILibraryAppletAccessor::PushInData, "PushInData"},
  446. {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"},
  447. {102, nullptr, "PushExtraStorage"},
  448. {103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"},
  449. {104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"},
  450. {105, &ILibraryAppletAccessor::GetPopOutDataEvent, "GetPopOutDataEvent"},
  451. {106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"},
  452. {110, nullptr, "NeedsToExitProcess"},
  453. {120, nullptr, "GetLibraryAppletInfo"},
  454. {150, nullptr, "RequestForAppletToGetForeground"},
  455. {160, nullptr, "GetIndirectLayerConsumerHandle"},
  456. };
  457. // clang-format on
  458. RegisterHandlers(functions);
  459. auto& kernel = Core::System::GetInstance().Kernel();
  460. state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
  461. "ILibraryAppletAccessor:StateChangedEvent");
  462. pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
  463. "ILibraryAppletAccessor:PopDataOutEvent");
  464. pop_interactive_out_data_event =
  465. Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
  466. "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
  467. }
  468. private:
  469. void AppletStorageProxyOutData(IStorage storage) {
  470. storage_stack.push_back(std::make_shared<IStorage>(storage));
  471. pop_out_data_event->Signal();
  472. }
  473. void AppletStorageProxyOutInteractiveData(IStorage storage) {
  474. interactive_storage_stack.push_back(std::make_shared<IStorage>(storage));
  475. pop_interactive_out_data_event->Signal();
  476. }
  477. void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
  478. state_changed_event->Signal();
  479. IPC::ResponseBuilder rb{ctx, 2, 1};
  480. rb.Push(RESULT_SUCCESS);
  481. rb.PushCopyObjects(state_changed_event);
  482. LOG_WARNING(Service_AM, "(STUBBED) called");
  483. }
  484. void IsCompleted(Kernel::HLERequestContext& ctx) {
  485. IPC::ResponseBuilder rb{ctx, 3};
  486. rb.Push(RESULT_SUCCESS);
  487. rb.Push<u32>(applet->TransactionComplete());
  488. }
  489. void GetResult(Kernel::HLERequestContext& ctx) {
  490. IPC::ResponseBuilder rb{ctx, 2};
  491. rb.Push(applet->GetStatus());
  492. }
  493. void Start(Kernel::HLERequestContext& ctx) {
  494. ASSERT(applet != nullptr);
  495. applet->Initialize(storage_stack);
  496. applet->Execute(
  497. [this](IStorage storage) { AppletStorageProxyOutData(storage); },
  498. [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); });
  499. state_changed_event->Signal();
  500. IPC::ResponseBuilder rb{ctx, 2};
  501. rb.Push(RESULT_SUCCESS);
  502. }
  503. void PushInData(Kernel::HLERequestContext& ctx) {
  504. IPC::RequestParser rp{ctx};
  505. storage_stack.push_back(rp.PopIpcInterface<IStorage>());
  506. IPC::ResponseBuilder rb{ctx, 2};
  507. rb.Push(RESULT_SUCCESS);
  508. LOG_DEBUG(Service_AM, "called");
  509. }
  510. void PopOutData(Kernel::HLERequestContext& ctx) {
  511. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  512. rb.Push(RESULT_SUCCESS);
  513. rb.PushIpcInterface<IStorage>(std::move(storage_stack.back()));
  514. storage_stack.pop_back();
  515. LOG_DEBUG(Service_AM, "called");
  516. }
  517. void PushInteractiveInData(Kernel::HLERequestContext& ctx) {
  518. IPC::RequestParser rp{ctx};
  519. interactive_storage_stack.push_back(rp.PopIpcInterface<IStorage>());
  520. ASSERT(applet->IsInitialized());
  521. applet->ReceiveInteractiveData(interactive_storage_stack.back());
  522. applet->Execute(
  523. [this](IStorage storage) { AppletStorageProxyOutData(storage); },
  524. [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); });
  525. state_changed_event->Signal();
  526. IPC::ResponseBuilder rb{ctx, 2};
  527. rb.Push(RESULT_SUCCESS);
  528. LOG_DEBUG(Service_AM, "called");
  529. }
  530. void PopInteractiveOutData(Kernel::HLERequestContext& ctx) {
  531. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  532. rb.Push(RESULT_SUCCESS);
  533. rb.PushIpcInterface<IStorage>(std::move(interactive_storage_stack.back()));
  534. interactive_storage_stack.pop_back();
  535. LOG_DEBUG(Service_AM, "called");
  536. }
  537. void GetPopOutDataEvent(Kernel::HLERequestContext& ctx) {
  538. IPC::ResponseBuilder rb{ctx, 2, 1};
  539. rb.Push(RESULT_SUCCESS);
  540. rb.PushCopyObjects(pop_out_data_event);
  541. }
  542. void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) {
  543. IPC::ResponseBuilder rb{ctx, 2, 1};
  544. rb.Push(RESULT_SUCCESS);
  545. rb.PushCopyObjects(pop_interactive_out_data_event);
  546. LOG_WARNING(Service_AM, "(STUBBED) called");
  547. }
  548. std::shared_ptr<Applets::Applet> applet;
  549. std::vector<std::shared_ptr<IStorage>> storage_stack;
  550. std::vector<std::shared_ptr<IStorage>> interactive_storage_stack;
  551. Kernel::SharedPtr<Kernel::Event> state_changed_event;
  552. Kernel::SharedPtr<Kernel::Event> pop_out_data_event;
  553. Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event;
  554. };
  555. void IStorage::Open(Kernel::HLERequestContext& ctx) {
  556. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  557. rb.Push(RESULT_SUCCESS);
  558. rb.PushIpcInterface<IStorageAccessor>(*this);
  559. LOG_DEBUG(Service_AM, "called");
  560. }
  561. IStorageAccessor::IStorageAccessor(IStorage& storage)
  562. : ServiceFramework("IStorageAccessor"), backing(storage) {
  563. // clang-format off
  564. static const FunctionInfo functions[] = {
  565. {0, &IStorageAccessor::GetSize, "GetSize"},
  566. {10, &IStorageAccessor::Write, "Write"},
  567. {11, &IStorageAccessor::Read, "Read"},
  568. };
  569. // clang-format on
  570. RegisterHandlers(functions);
  571. }
  572. IStorageAccessor::~IStorageAccessor() = default;
  573. void IStorageAccessor::GetSize(Kernel::HLERequestContext& ctx) {
  574. IPC::ResponseBuilder rb{ctx, 4};
  575. rb.Push(RESULT_SUCCESS);
  576. rb.Push(static_cast<u64>(backing.buffer.size()));
  577. LOG_DEBUG(Service_AM, "called");
  578. }
  579. void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
  580. IPC::RequestParser rp{ctx};
  581. const u64 offset{rp.Pop<u64>()};
  582. const std::vector<u8> data{ctx.ReadBuffer()};
  583. const auto size = std::min<std::size_t>(data.size(), backing.buffer.size() - offset);
  584. std::memcpy(&backing.buffer[offset], data.data(), size);
  585. IPC::ResponseBuilder rb{ctx, 2};
  586. rb.Push(RESULT_SUCCESS);
  587. LOG_DEBUG(Service_AM, "called, offset={}", offset);
  588. }
  589. void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
  590. IPC::RequestParser rp{ctx};
  591. const u64 offset{rp.Pop<u64>()};
  592. std::size_t size{ctx.GetWriteBufferSize()};
  593. size = std::min(size, backing.buffer.size() - offset);
  594. ctx.WriteBuffer(backing.buffer.data() + offset, size);
  595. IPC::ResponseBuilder rb{ctx, 2};
  596. rb.Push(RESULT_SUCCESS);
  597. LOG_DEBUG(Service_AM, "called, offset={}", offset);
  598. }
  599. ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {
  600. static const FunctionInfo functions[] = {
  601. {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
  602. {1, nullptr, "TerminateAllLibraryApplets"},
  603. {2, nullptr, "AreAnyLibraryAppletsLeft"},
  604. {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
  605. {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
  606. {12, nullptr, "CreateHandleStorage"},
  607. };
  608. RegisterHandlers(functions);
  609. }
  610. ILibraryAppletCreator::~ILibraryAppletCreator() = default;
  611. static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) {
  612. switch (id) {
  613. case AppletId::SoftwareKeyboard:
  614. return std::make_shared<Applets::SoftwareKeyboard>();
  615. default:
  616. UNREACHABLE_MSG("Unimplemented AppletId [{:08X}]!", static_cast<u32>(id));
  617. return nullptr;
  618. }
  619. }
  620. void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
  621. IPC::RequestParser rp{ctx};
  622. const auto applet_id = rp.PopRaw<AppletId>();
  623. const auto applet_mode = rp.PopRaw<u32>();
  624. LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}",
  625. static_cast<u32>(applet_id), applet_mode);
  626. const auto applet = GetAppletFromId(applet_id);
  627. if (applet == nullptr) {
  628. IPC::ResponseBuilder rb{ctx, 2};
  629. rb.Push(ResultCode(-1));
  630. return;
  631. }
  632. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  633. rb.Push(RESULT_SUCCESS);
  634. rb.PushIpcInterface<AM::ILibraryAppletAccessor>(applet);
  635. LOG_DEBUG(Service_AM, "called");
  636. }
  637. void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
  638. IPC::RequestParser rp{ctx};
  639. const u64 size{rp.Pop<u64>()};
  640. std::vector<u8> buffer(size);
  641. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  642. rb.Push(RESULT_SUCCESS);
  643. rb.PushIpcInterface<AM::IStorage>(std::move(buffer));
  644. LOG_DEBUG(Service_AM, "called, size={}", size);
  645. }
  646. void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
  647. IPC::RequestParser rp{ctx};
  648. rp.SetCurrentOffset(3);
  649. const auto handle{rp.Pop<Kernel::Handle>()};
  650. const auto shared_mem =
  651. Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::SharedMemory>(
  652. handle);
  653. if (shared_mem == nullptr) {
  654. IPC::ResponseBuilder rb{ctx, 2};
  655. rb.Push(ResultCode(-1));
  656. return;
  657. }
  658. const auto mem_begin = shared_mem->backing_block->begin() + shared_mem->backing_block_offset;
  659. const auto mem_end = mem_begin + shared_mem->size;
  660. std::vector<u8> memory{mem_begin, mem_end};
  661. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  662. rb.Push(RESULT_SUCCESS);
  663. rb.PushIpcInterface(std::make_shared<IStorage>(std::move(memory)));
  664. }
  665. IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
  666. // clang-format off
  667. static const FunctionInfo functions[] = {
  668. {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
  669. {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
  670. {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
  671. {12, nullptr, "CreateApplicationAndRequestToStart"},
  672. {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"},
  673. {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
  674. {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
  675. {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
  676. {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
  677. {24, nullptr, "GetLaunchStorageInfoForDebug"},
  678. {25, nullptr, "ExtendSaveData"},
  679. {26, nullptr, "GetSaveDataSize"},
  680. {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
  681. {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
  682. {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
  683. {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
  684. {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
  685. {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
  686. {60, nullptr, "SetMediaPlaybackStateForApplication"},
  687. {65, nullptr, "IsGamePlayRecordingSupported"},
  688. {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
  689. {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
  690. {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
  691. {70, nullptr, "RequestToShutdown"},
  692. {71, nullptr, "RequestToReboot"},
  693. {80, nullptr, "ExitAndRequestToShowThanksMessage"},
  694. {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"},
  695. {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"},
  696. {101, nullptr, "SetApplicationCopyrightImage"},
  697. {102, nullptr, "SetApplicationCopyrightVisibility"},
  698. {110, nullptr, "QueryApplicationPlayStatistics"},
  699. {120, nullptr, "ExecuteProgram"},
  700. {121, nullptr, "ClearUserChannel"},
  701. {122, nullptr, "UnpopToUserChannel"},
  702. {500, nullptr, "StartContinuousRecordingFlushForDebug"},
  703. {1000, nullptr, "CreateMovieMaker"},
  704. {1001, nullptr, "PrepareForJit"},
  705. };
  706. // clang-format on
  707. RegisterHandlers(functions);
  708. }
  709. IApplicationFunctions::~IApplicationFunctions() = default;
  710. void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestContext& ctx) {
  711. IPC::ResponseBuilder rb{ctx, 2};
  712. rb.Push(RESULT_SUCCESS);
  713. LOG_WARNING(Service_AM, "(STUBBED) called");
  714. }
  715. void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(
  716. Kernel::HLERequestContext& ctx) {
  717. IPC::ResponseBuilder rb{ctx, 2};
  718. rb.Push(RESULT_SUCCESS);
  719. LOG_WARNING(Service_AM, "(STUBBED) called");
  720. }
  721. void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(
  722. Kernel::HLERequestContext& ctx) {
  723. IPC::ResponseBuilder rb{ctx, 2};
  724. rb.Push(RESULT_SUCCESS);
  725. LOG_WARNING(Service_AM, "(STUBBED) called");
  726. }
  727. void IApplicationFunctions::BeginBlockingHomeButton(Kernel::HLERequestContext& ctx) {
  728. IPC::ResponseBuilder rb{ctx, 2};
  729. rb.Push(RESULT_SUCCESS);
  730. LOG_WARNING(Service_AM, "(STUBBED) called");
  731. }
  732. void IApplicationFunctions::EndBlockingHomeButton(Kernel::HLERequestContext& ctx) {
  733. IPC::ResponseBuilder rb{ctx, 2};
  734. rb.Push(RESULT_SUCCESS);
  735. LOG_WARNING(Service_AM, "(STUBBED) called");
  736. }
  737. void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
  738. LaunchParameters params{};
  739. params.magic = POP_LAUNCH_PARAMETER_MAGIC;
  740. params.is_account_selected = 1;
  741. Account::ProfileManager profile_manager{};
  742. const auto uuid = profile_manager.GetUser(Settings::values.current_user);
  743. ASSERT(uuid);
  744. params.current_user = uuid->uuid;
  745. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  746. rb.Push(RESULT_SUCCESS);
  747. std::vector<u8> buffer(sizeof(LaunchParameters));
  748. std::memcpy(buffer.data(), &params, buffer.size());
  749. rb.PushIpcInterface<AM::IStorage>(buffer);
  750. LOG_DEBUG(Service_AM, "called");
  751. }
  752. void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
  753. Kernel::HLERequestContext& ctx) {
  754. IPC::ResponseBuilder rb{ctx, 2};
  755. rb.Push(RESULT_SUCCESS);
  756. LOG_WARNING(Service_AM, "(STUBBED) called");
  757. }
  758. void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
  759. IPC::RequestParser rp{ctx};
  760. u128 uid = rp.PopRaw<u128>(); // What does this do?
  761. LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
  762. IPC::ResponseBuilder rb{ctx, 4};
  763. rb.Push(RESULT_SUCCESS);
  764. rb.Push<u64>(0);
  765. } // namespace Service::AM
  766. void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
  767. // Takes an input u32 Result, no output.
  768. // For example, in some cases official apps use this with error 0x2A2 then
  769. // uses svcBreak.
  770. IPC::RequestParser rp{ctx};
  771. u32 result = rp.Pop<u32>();
  772. IPC::ResponseBuilder rb{ctx, 2};
  773. rb.Push(RESULT_SUCCESS);
  774. LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
  775. }
  776. void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
  777. IPC::ResponseBuilder rb{ctx, 6};
  778. rb.Push(RESULT_SUCCESS);
  779. rb.Push<u64>(1);
  780. rb.Push<u64>(0);
  781. LOG_WARNING(Service_AM, "(STUBBED) called");
  782. }
  783. void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
  784. // TODO(bunnei): This should be configurable
  785. IPC::ResponseBuilder rb{ctx, 4};
  786. rb.Push(RESULT_SUCCESS);
  787. rb.Push(
  788. static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index)));
  789. LOG_DEBUG(Service_AM, "called");
  790. }
  791. void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
  792. IPC::ResponseBuilder rb{ctx, 2};
  793. rb.Push(RESULT_SUCCESS);
  794. LOG_WARNING(Service_AM, "(STUBBED) called");
  795. }
  796. void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
  797. IPC::ResponseBuilder rb{ctx, 2};
  798. rb.Push(RESULT_SUCCESS);
  799. LOG_WARNING(Service_AM, "(STUBBED) called");
  800. }
  801. void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
  802. IPC::ResponseBuilder rb{ctx, 3};
  803. rb.Push(RESULT_SUCCESS);
  804. rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
  805. LOG_WARNING(Service_AM, "(STUBBED) called");
  806. }
  807. void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
  808. IPC::ResponseBuilder rb{ctx, 6};
  809. rb.Push(RESULT_SUCCESS);
  810. // Returns a 128-bit UUID
  811. rb.Push<u64>(0);
  812. rb.Push<u64>(0);
  813. LOG_WARNING(Service_AM, "(STUBBED) called");
  814. }
  815. void InstallInterfaces(SM::ServiceManager& service_manager,
  816. std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
  817. auto message_queue = std::make_shared<AppletMessageQueue>();
  818. message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); // Needed on
  819. // game boot
  820. std::make_shared<AppletAE>(nvflinger, message_queue)->InstallAsService(service_manager);
  821. std::make_shared<AppletOE>(nvflinger, message_queue)->InstallAsService(service_manager);
  822. std::make_shared<IdleSys>()->InstallAsService(service_manager);
  823. std::make_shared<OMM>()->InstallAsService(service_manager);
  824. std::make_shared<SPSM>()->InstallAsService(service_manager);
  825. std::make_shared<TCAP>()->InstallAsService(service_manager);
  826. }
  827. IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
  828. // clang-format off
  829. static const FunctionInfo functions[] = {
  830. {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
  831. {11, nullptr, "LockForeground"},
  832. {12, nullptr, "UnlockForeground"},
  833. {20, nullptr, "PopFromGeneralChannel"},
  834. {21, nullptr, "GetPopFromGeneralChannelEvent"},
  835. {30, nullptr, "GetHomeButtonWriterLockAccessor"},
  836. {31, nullptr, "GetWriterLockAccessorEx"},
  837. {100, nullptr, "PopRequestLaunchApplicationForDebug"},
  838. };
  839. // clang-format on
  840. RegisterHandlers(functions);
  841. }
  842. IHomeMenuFunctions::~IHomeMenuFunctions() = default;
  843. void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
  844. IPC::ResponseBuilder rb{ctx, 2};
  845. rb.Push(RESULT_SUCCESS);
  846. LOG_WARNING(Service_AM, "(STUBBED) called");
  847. }
  848. IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
  849. // clang-format off
  850. static const FunctionInfo functions[] = {
  851. {0, nullptr, "RequestToEnterSleep"},
  852. {1, nullptr, "EnterSleep"},
  853. {2, nullptr, "StartSleepSequence"},
  854. {3, nullptr, "StartShutdownSequence"},
  855. {4, nullptr, "StartRebootSequence"},
  856. {10, nullptr, "LoadAndApplyIdlePolicySettings"},
  857. {11, nullptr, "NotifyCecSettingsChanged"},
  858. {12, nullptr, "SetDefaultHomeButtonLongPressTime"},
  859. {13, nullptr, "UpdateDefaultDisplayResolution"},
  860. {14, nullptr, "ShouldSleepOnBoot"},
  861. {15, nullptr, "GetHdcpAuthenticationFailedEvent"},
  862. };
  863. // clang-format on
  864. RegisterHandlers(functions);
  865. }
  866. IGlobalStateController::~IGlobalStateController() = default;
  867. IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") {
  868. // clang-format off
  869. static const FunctionInfo functions[] = {
  870. {0, nullptr, "CreateApplication"},
  871. {1, nullptr, "PopLaunchRequestedApplication"},
  872. {10, nullptr, "CreateSystemApplication"},
  873. {100, nullptr, "PopFloatingApplicationForDevelopment"},
  874. };
  875. // clang-format on
  876. RegisterHandlers(functions);
  877. }
  878. IApplicationCreator::~IApplicationCreator() = default;
  879. IProcessWindingController::IProcessWindingController()
  880. : ServiceFramework("IProcessWindingController") {
  881. // clang-format off
  882. static const FunctionInfo functions[] = {
  883. {0, nullptr, "GetLaunchReason"},
  884. {11, nullptr, "OpenCallingLibraryApplet"},
  885. {21, nullptr, "PushContext"},
  886. {22, nullptr, "PopContext"},
  887. {23, nullptr, "CancelWindingReservation"},
  888. {30, nullptr, "WindAndDoReserved"},
  889. {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"},
  890. {41, nullptr, "ReserveToStartAndWait"},
  891. };
  892. // clang-format on
  893. RegisterHandlers(functions);
  894. }
  895. IProcessWindingController::~IProcessWindingController() = default;
  896. } // namespace Service::AM