am.cpp 47 KB

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