am.cpp 46 KB

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