am.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cinttypes>
  5. #include <stack>
  6. #include "core/core.h"
  7. #include "core/hle/ipc_helpers.h"
  8. #include "core/hle/kernel/event.h"
  9. #include "core/hle/kernel/process.h"
  10. #include "core/hle/service/am/am.h"
  11. #include "core/hle/service/am/applet_ae.h"
  12. #include "core/hle/service/am/applet_oe.h"
  13. #include "core/hle/service/am/idle.h"
  14. #include "core/hle/service/am/omm.h"
  15. #include "core/hle/service/am/spsm.h"
  16. #include "core/hle/service/apm/apm.h"
  17. #include "core/hle/service/filesystem/filesystem.h"
  18. #include "core/hle/service/nvflinger/nvflinger.h"
  19. #include "core/hle/service/set/set.h"
  20. #include "core/settings.h"
  21. namespace Service::AM {
  22. IWindowController::IWindowController() : ServiceFramework("IWindowController") {
  23. static const FunctionInfo functions[] = {
  24. {0, nullptr, "CreateWindow"},
  25. {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
  26. {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
  27. {11, nullptr, "ReleaseForegroundRights"},
  28. {12, nullptr, "RejectToChangeIntoBackground"},
  29. };
  30. RegisterHandlers(functions);
  31. }
  32. void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
  33. LOG_WARNING(Service_AM, "(STUBBED) called");
  34. IPC::ResponseBuilder rb{ctx, 4};
  35. rb.Push(RESULT_SUCCESS);
  36. rb.Push<u64>(0);
  37. }
  38. void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
  39. LOG_WARNING(Service_AM, "(STUBBED) called");
  40. IPC::ResponseBuilder rb{ctx, 2};
  41. rb.Push(RESULT_SUCCESS);
  42. }
  43. IAudioController::IAudioController() : ServiceFramework("IAudioController") {
  44. static const FunctionInfo functions[] = {
  45. {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
  46. {1, &IAudioController::GetMainAppletExpectedMasterVolume,
  47. "GetMainAppletExpectedMasterVolume"},
  48. {2, &IAudioController::GetLibraryAppletExpectedMasterVolume,
  49. "GetLibraryAppletExpectedMasterVolume"},
  50. {3, nullptr, "ChangeMainAppletMasterVolume"},
  51. {4, nullptr, "SetTransparentVolumeRate"},
  52. };
  53. RegisterHandlers(functions);
  54. }
  55. void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  56. LOG_WARNING(Service_AM, "(STUBBED) called");
  57. IPC::ResponseBuilder rb{ctx, 2};
  58. rb.Push(RESULT_SUCCESS);
  59. }
  60. void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  61. LOG_WARNING(Service_AM, "(STUBBED) called");
  62. IPC::ResponseBuilder rb{ctx, 3};
  63. rb.Push(RESULT_SUCCESS);
  64. rb.Push(volume);
  65. }
  66. void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
  67. LOG_WARNING(Service_AM, "(STUBBED) called");
  68. IPC::ResponseBuilder rb{ctx, 3};
  69. rb.Push(RESULT_SUCCESS);
  70. rb.Push(volume);
  71. }
  72. IDisplayController::IDisplayController() : ServiceFramework("IDisplayController") {
  73. static const FunctionInfo functions[] = {
  74. {0, nullptr, "GetLastForegroundCaptureImage"},
  75. {1, nullptr, "UpdateLastForegroundCaptureImage"},
  76. {2, nullptr, "GetLastApplicationCaptureImage"},
  77. {3, nullptr, "GetCallerAppletCaptureImage"},
  78. {4, nullptr, "UpdateCallerAppletCaptureImage"},
  79. {5, nullptr, "GetLastForegroundCaptureImageEx"},
  80. {6, nullptr, "GetLastApplicationCaptureImageEx"},
  81. {7, nullptr, "GetCallerAppletCaptureImageEx"},
  82. {8, nullptr, "TakeScreenShotOfOwnLayer"}, // 2.0.0+
  83. {9, nullptr, "CopyBetweenCaptureBuffers"}, // 5.0.0+
  84. {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
  85. {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
  86. {12, nullptr, "AcquireLastForegroundCaptureBuffer"},
  87. {13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
  88. {14, nullptr, "AcquireCallerAppletCaptureBuffer"},
  89. {15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
  90. {16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
  91. {17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
  92. {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
  93. // 2.0.0+
  94. {20, nullptr, "ClearCaptureBuffer"},
  95. {21, nullptr, "ClearAppletTransitionBuffer"},
  96. // 4.0.0+
  97. {22, nullptr, "AcquireLastApplicationCaptureSharedBuffer"},
  98. {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
  99. {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"},
  100. {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"},
  101. {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"},
  102. {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"},
  103. };
  104. RegisterHandlers(functions);
  105. }
  106. IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
  107. ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
  108. : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
  109. static const FunctionInfo functions[] = {
  110. {0, nullptr, "Exit"},
  111. {1, &ISelfController::LockExit, "LockExit"},
  112. {2, &ISelfController::UnlockExit, "UnlockExit"},
  113. {3, nullptr, "EnterFatalSection"},
  114. {4, nullptr, "LeaveFatalSection"},
  115. {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
  116. {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
  117. {11, &ISelfController::SetOperationModeChangedNotification,
  118. "SetOperationModeChangedNotification"},
  119. {12, &ISelfController::SetPerformanceModeChangedNotification,
  120. "SetPerformanceModeChangedNotification"},
  121. {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
  122. {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
  123. {15, nullptr, "SetScreenShotAppletIdentityInfo"},
  124. {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
  125. {17, nullptr, "SetControllerFirmwareUpdateSection"},
  126. {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
  127. {19, nullptr, "SetScreenShotImageOrientation"},
  128. {20, nullptr, "SetDesirableKeyboardLayout"},
  129. {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
  130. {41, nullptr, "IsSystemBufferSharingEnabled"},
  131. {42, nullptr, "GetSystemSharedLayerHandle"},
  132. {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
  133. {51, nullptr, "ApproveToDisplay"},
  134. {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
  135. {61, nullptr, "SetMediaPlaybackState"},
  136. {62, nullptr, "SetIdleTimeDetectionExtension"},
  137. {63, nullptr, "GetIdleTimeDetectionExtension"},
  138. {64, nullptr, "SetInputDetectionSourceSet"},
  139. {65, nullptr, "ReportUserIsActive"},
  140. {66, nullptr, "GetCurrentIlluminance"},
  141. {67, nullptr, "IsIlluminanceAvailable"},
  142. {68, nullptr, "SetAutoSleepDisabled"},
  143. {69, nullptr, "IsAutoSleepDisabled"},
  144. {70, nullptr, "ReportMultimediaError"},
  145. {80, nullptr, "SetWirelessPriorityMode"},
  146. };
  147. RegisterHandlers(functions);
  148. launchable_event =
  149. Kernel::Event::Create(Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent");
  150. }
  151. void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
  152. // Takes 3 input u8s with each field located immediately after the previous u8, these are
  153. // bool flags. No output.
  154. IPC::RequestParser rp{ctx};
  155. struct FocusHandlingModeParams {
  156. u8 unknown0;
  157. u8 unknown1;
  158. u8 unknown2;
  159. };
  160. auto flags = rp.PopRaw<FocusHandlingModeParams>();
  161. IPC::ResponseBuilder rb{ctx, 2};
  162. rb.Push(RESULT_SUCCESS);
  163. LOG_WARNING(Service_AM, "(STUBBED) called");
  164. }
  165. void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
  166. IPC::ResponseBuilder rb{ctx, 2};
  167. rb.Push(RESULT_SUCCESS);
  168. LOG_WARNING(Service_AM, "(STUBBED) called");
  169. }
  170. void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
  171. IPC::RequestParser rp{ctx};
  172. bool flag = rp.Pop<bool>();
  173. IPC::ResponseBuilder rb{ctx, 2};
  174. rb.Push(RESULT_SUCCESS);
  175. LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
  176. }
  177. void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
  178. IPC::ResponseBuilder rb{ctx, 2};
  179. rb.Push(RESULT_SUCCESS);
  180. LOG_WARNING(Service_AM, "(STUBBED) called");
  181. }
  182. void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
  183. IPC::RequestParser rp{ctx};
  184. bool flag = rp.Pop<bool>();
  185. IPC::ResponseBuilder rb{ctx, 2};
  186. rb.Push(RESULT_SUCCESS);
  187. LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
  188. }
  189. void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
  190. // Takes 3 input u8s with each field located immediately after the previous u8, these are
  191. // bool flags. No output.
  192. IPC::RequestParser rp{ctx};
  193. bool enabled = rp.Pop<bool>();
  194. IPC::ResponseBuilder rb{ctx, 2};
  195. rb.Push(RESULT_SUCCESS);
  196. LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
  197. }
  198. void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
  199. IPC::ResponseBuilder rb{ctx, 2};
  200. rb.Push(RESULT_SUCCESS);
  201. LOG_WARNING(Service_AM, "(STUBBED) called");
  202. }
  203. void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
  204. IPC::ResponseBuilder rb{ctx, 2};
  205. rb.Push(RESULT_SUCCESS);
  206. LOG_WARNING(Service_AM, "(STUBBED) called");
  207. }
  208. void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
  209. launchable_event->Signal();
  210. IPC::ResponseBuilder rb{ctx, 2, 1};
  211. rb.Push(RESULT_SUCCESS);
  212. rb.PushCopyObjects(launchable_event);
  213. LOG_WARNING(Service_AM, "(STUBBED) called");
  214. }
  215. void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
  216. // TODO(Subv): Find out how AM determines the display to use, for now just create the layer
  217. // in the Default display.
  218. u64 display_id = nvflinger->OpenDisplay("Default");
  219. u64 layer_id = nvflinger->CreateLayer(display_id);
  220. IPC::ResponseBuilder rb{ctx, 4};
  221. rb.Push(RESULT_SUCCESS);
  222. rb.Push(layer_id);
  223. LOG_WARNING(Service_AM, "(STUBBED) called");
  224. }
  225. void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
  226. IPC::ResponseBuilder rb{ctx, 2};
  227. rb.Push(RESULT_SUCCESS);
  228. LOG_WARNING(Service_AM, "(STUBBED) called");
  229. }
  230. ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
  231. static const FunctionInfo functions[] = {
  232. {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
  233. {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
  234. {2, nullptr, "GetThisAppletKind"},
  235. {3, nullptr, "AllowToEnterSleep"},
  236. {4, nullptr, "DisallowToEnterSleep"},
  237. {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
  238. {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
  239. {7, nullptr, "GetCradleStatus"},
  240. {8, nullptr, "GetBootMode"},
  241. {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
  242. {10, nullptr, "RequestToAcquireSleepLock"},
  243. {11, nullptr, "ReleaseSleepLock"},
  244. {12, nullptr, "ReleaseSleepLockTransiently"},
  245. {13, nullptr, "GetAcquiredSleepLockEvent"},
  246. {20, nullptr, "PushToGeneralChannel"},
  247. {30, nullptr, "GetHomeButtonReaderLockAccessor"},
  248. {31, nullptr, "GetReaderLockAccessorEx"},
  249. {40, nullptr, "GetCradleFwVersion"},
  250. {50, nullptr, "IsVrModeEnabled"},
  251. {51, nullptr, "SetVrModeEnabled"},
  252. {52, nullptr, "SwitchLcdBacklight"},
  253. {55, nullptr, "IsInControllerFirmwareUpdateSection"},
  254. {60, nullptr, "GetDefaultDisplayResolution"},
  255. {61, nullptr, "GetDefaultDisplayResolutionChangeEvent"},
  256. {62, nullptr, "GetHdcpAuthenticationState"},
  257. {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
  258. };
  259. RegisterHandlers(functions);
  260. event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
  261. }
  262. void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
  263. event->Signal();
  264. IPC::ResponseBuilder rb{ctx, 2, 1};
  265. rb.Push(RESULT_SUCCESS);
  266. rb.PushCopyObjects(event);
  267. LOG_WARNING(Service_AM, "(STUBBED) called");
  268. }
  269. void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
  270. IPC::ResponseBuilder rb{ctx, 3};
  271. rb.Push(RESULT_SUCCESS);
  272. rb.Push<u32>(15);
  273. LOG_WARNING(Service_AM, "(STUBBED) called");
  274. }
  275. void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
  276. IPC::ResponseBuilder rb{ctx, 3};
  277. rb.Push(RESULT_SUCCESS);
  278. rb.Push(static_cast<u8>(FocusState::InFocus));
  279. LOG_WARNING(Service_AM, "(STUBBED) called");
  280. }
  281. void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
  282. const bool use_docked_mode{Settings::values.use_docked_mode};
  283. IPC::ResponseBuilder rb{ctx, 3};
  284. rb.Push(RESULT_SUCCESS);
  285. rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
  286. LOG_WARNING(Service_AM, "(STUBBED) called");
  287. }
  288. void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
  289. const bool use_docked_mode{Settings::values.use_docked_mode};
  290. IPC::ResponseBuilder rb{ctx, 3};
  291. rb.Push(RESULT_SUCCESS);
  292. rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
  293. : APM::PerformanceMode::Handheld));
  294. LOG_WARNING(Service_AM, "(STUBBED) called");
  295. }
  296. class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
  297. public:
  298. explicit IStorageAccessor(std::vector<u8> buffer)
  299. : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
  300. static const FunctionInfo functions[] = {
  301. {0, &IStorageAccessor::GetSize, "GetSize"},
  302. {10, &IStorageAccessor::Write, "Write"},
  303. {11, &IStorageAccessor::Read, "Read"},
  304. };
  305. RegisterHandlers(functions);
  306. }
  307. private:
  308. std::vector<u8> buffer;
  309. void GetSize(Kernel::HLERequestContext& ctx) {
  310. IPC::ResponseBuilder rb{ctx, 4};
  311. rb.Push(RESULT_SUCCESS);
  312. rb.Push(static_cast<u64>(buffer.size()));
  313. LOG_DEBUG(Service_AM, "called");
  314. }
  315. void Write(Kernel::HLERequestContext& ctx) {
  316. IPC::RequestParser rp{ctx};
  317. const u64 offset{rp.Pop<u64>()};
  318. const std::vector<u8> data{ctx.ReadBuffer()};
  319. ASSERT(offset + data.size() <= buffer.size());
  320. std::memcpy(&buffer[offset], data.data(), data.size());
  321. IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
  322. rb.Push(RESULT_SUCCESS);
  323. LOG_DEBUG(Service_AM, "called, offset={}", offset);
  324. }
  325. void Read(Kernel::HLERequestContext& ctx) {
  326. IPC::RequestParser rp{ctx};
  327. const u64 offset{rp.Pop<u64>()};
  328. const size_t size{ctx.GetWriteBufferSize()};
  329. ASSERT(offset + size <= buffer.size());
  330. ctx.WriteBuffer(buffer.data() + offset, size);
  331. IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
  332. rb.Push(RESULT_SUCCESS);
  333. LOG_DEBUG(Service_AM, "called, offset={}", offset);
  334. }
  335. };
  336. class IStorage final : public ServiceFramework<IStorage> {
  337. public:
  338. explicit IStorage(std::vector<u8> buffer)
  339. : ServiceFramework("IStorage"), buffer(std::move(buffer)) {
  340. static const FunctionInfo functions[] = {
  341. {0, &IStorage::Open, "Open"},
  342. {1, nullptr, "OpenTransferStorage"},
  343. };
  344. RegisterHandlers(functions);
  345. }
  346. private:
  347. std::vector<u8> buffer;
  348. void Open(Kernel::HLERequestContext& ctx) {
  349. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  350. rb.Push(RESULT_SUCCESS);
  351. rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
  352. LOG_DEBUG(Service_AM, "called");
  353. }
  354. };
  355. class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
  356. public:
  357. explicit ILibraryAppletAccessor() : ServiceFramework("ILibraryAppletAccessor") {
  358. static const FunctionInfo functions[] = {
  359. {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
  360. {1, nullptr, "IsCompleted"},
  361. {10, &ILibraryAppletAccessor::Start, "Start"},
  362. {20, nullptr, "RequestExit"},
  363. {25, nullptr, "Terminate"},
  364. {30, &ILibraryAppletAccessor::GetResult, "GetResult"},
  365. {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
  366. {100, &ILibraryAppletAccessor::PushInData, "PushInData"},
  367. {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"},
  368. {102, nullptr, "PushExtraStorage"},
  369. {103, nullptr, "PushInteractiveInData"},
  370. {104, nullptr, "PopInteractiveOutData"},
  371. {105, nullptr, "GetPopOutDataEvent"},
  372. {106, nullptr, "GetPopInteractiveOutDataEvent"},
  373. {110, nullptr, "NeedsToExitProcess"},
  374. {120, nullptr, "GetLibraryAppletInfo"},
  375. {150, nullptr, "RequestForAppletToGetForeground"},
  376. {160, nullptr, "GetIndirectLayerConsumerHandle"},
  377. };
  378. RegisterHandlers(functions);
  379. state_changed_event = Kernel::Event::Create(Kernel::ResetType::OneShot,
  380. "ILibraryAppletAccessor:StateChangedEvent");
  381. }
  382. private:
  383. void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
  384. state_changed_event->Signal();
  385. IPC::ResponseBuilder rb{ctx, 2, 1};
  386. rb.Push(RESULT_SUCCESS);
  387. rb.PushCopyObjects(state_changed_event);
  388. LOG_WARNING(Service_AM, "(STUBBED) called");
  389. }
  390. void GetResult(Kernel::HLERequestContext& ctx) {
  391. IPC::ResponseBuilder rb{ctx, 2};
  392. rb.Push(RESULT_SUCCESS);
  393. LOG_WARNING(Service_AM, "(STUBBED) called");
  394. }
  395. void Start(Kernel::HLERequestContext& ctx) {
  396. IPC::ResponseBuilder rb{ctx, 2};
  397. rb.Push(RESULT_SUCCESS);
  398. LOG_WARNING(Service_AM, "(STUBBED) called");
  399. }
  400. void PushInData(Kernel::HLERequestContext& ctx) {
  401. IPC::RequestParser rp{ctx};
  402. storage_stack.push(rp.PopIpcInterface<AM::IStorage>());
  403. IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
  404. rb.Push(RESULT_SUCCESS);
  405. LOG_DEBUG(Service_AM, "called");
  406. }
  407. void PopOutData(Kernel::HLERequestContext& ctx) {
  408. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  409. rb.Push(RESULT_SUCCESS);
  410. rb.PushIpcInterface<AM::IStorage>(std::move(storage_stack.top()));
  411. storage_stack.pop();
  412. LOG_DEBUG(Service_AM, "called");
  413. }
  414. std::stack<std::shared_ptr<AM::IStorage>> storage_stack;
  415. Kernel::SharedPtr<Kernel::Event> state_changed_event;
  416. };
  417. ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryAppletCreator") {
  418. static const FunctionInfo functions[] = {
  419. {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
  420. {1, nullptr, "TerminateAllLibraryApplets"},
  421. {2, nullptr, "AreAnyLibraryAppletsLeft"},
  422. {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
  423. {11, nullptr, "CreateTransferMemoryStorage"},
  424. {12, nullptr, "CreateHandleStorage"},
  425. };
  426. RegisterHandlers(functions);
  427. }
  428. void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
  429. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  430. rb.Push(RESULT_SUCCESS);
  431. rb.PushIpcInterface<AM::ILibraryAppletAccessor>();
  432. LOG_DEBUG(Service_AM, "called");
  433. }
  434. void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
  435. IPC::RequestParser rp{ctx};
  436. const u64 size{rp.Pop<u64>()};
  437. std::vector<u8> buffer(size);
  438. IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 1)};
  439. rb.Push(RESULT_SUCCESS);
  440. rb.PushIpcInterface<AM::IStorage>(std::move(buffer));
  441. LOG_DEBUG(Service_AM, "called, size={}", size);
  442. }
  443. IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
  444. static const FunctionInfo functions[] = {
  445. {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
  446. {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
  447. {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
  448. {12, nullptr, "CreateApplicationAndRequestToStart"},
  449. {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest,
  450. "CreateApplicationAndRequestToStartForQuest"},
  451. {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
  452. {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
  453. {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
  454. {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
  455. {24, nullptr, "GetLaunchStorageInfoForDebug"},
  456. {25, nullptr, "ExtendSaveData"},
  457. {26, nullptr, "GetSaveDataSize"},
  458. {30, nullptr, "BeginBlockingHomeButtonShortAndLongPressed"},
  459. {31, nullptr, "EndBlockingHomeButtonShortAndLongPressed"},
  460. {32, nullptr, "BeginBlockingHomeButton"},
  461. {33, nullptr, "EndBlockingHomeButton"},
  462. {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
  463. {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
  464. {60, nullptr, "SetMediaPlaybackStateForApplication"},
  465. {65, nullptr, "IsGamePlayRecordingSupported"},
  466. {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
  467. {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
  468. {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
  469. {70, nullptr, "RequestToShutdown"},
  470. {71, nullptr, "RequestToReboot"},
  471. {80, nullptr, "ExitAndRequestToShowThanksMessage"},
  472. {90, nullptr, "EnableApplicationCrashReport"},
  473. {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"},
  474. {101, nullptr, "SetApplicationCopyrightImage"},
  475. {102, nullptr, "SetApplicationCopyrightVisibility"},
  476. {110, nullptr, "QueryApplicationPlayStatistics"},
  477. {120, nullptr, "ExecuteProgram"},
  478. {121, nullptr, "ClearUserChannel"},
  479. {122, nullptr, "UnpopToUserChannel"},
  480. {500, nullptr, "StartContinuousRecordingFlushForDebug"},
  481. {1000, nullptr, "CreateMovieMaker"},
  482. {1001, nullptr, "PrepareForJit"},
  483. };
  484. RegisterHandlers(functions);
  485. }
  486. void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
  487. constexpr u8 data[0x88] = {
  488. 0xca, 0x97, 0x94, 0xc7, // Magic
  489. 1, 0, 0, 0, // IsAccountSelected (bool)
  490. 1, 0, 0, 0, // User Id (word 0)
  491. 0, 0, 0, 0, // User Id (word 1)
  492. 0, 0, 0, 0, // User Id (word 2)
  493. 0, 0, 0, 0 // User Id (word 3)
  494. };
  495. std::vector<u8> buffer(data, data + sizeof(data));
  496. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  497. rb.Push(RESULT_SUCCESS);
  498. rb.PushIpcInterface<AM::IStorage>(buffer);
  499. LOG_DEBUG(Service_AM, "called");
  500. }
  501. void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
  502. Kernel::HLERequestContext& ctx) {
  503. IPC::ResponseBuilder rb{ctx, 2};
  504. rb.Push(RESULT_SUCCESS);
  505. LOG_WARNING(Service_AM, "(STUBBED) called");
  506. }
  507. void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
  508. IPC::RequestParser rp{ctx};
  509. u128 uid = rp.PopRaw<u128>(); // What does this do?
  510. LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
  511. IPC::ResponseBuilder rb{ctx, 4};
  512. rb.Push(RESULT_SUCCESS);
  513. rb.Push<u64>(0);
  514. } // namespace Service::AM
  515. void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
  516. // Takes an input u32 Result, no output.
  517. // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
  518. IPC::RequestParser rp{ctx};
  519. u32 result = rp.Pop<u32>();
  520. IPC::ResponseBuilder rb{ctx, 2};
  521. rb.Push(RESULT_SUCCESS);
  522. LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
  523. }
  524. void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
  525. IPC::ResponseBuilder rb{ctx, 6};
  526. rb.Push(RESULT_SUCCESS);
  527. rb.Push<u64>(1);
  528. rb.Push<u64>(0);
  529. LOG_WARNING(Service_AM, "(STUBBED) called");
  530. }
  531. void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
  532. // TODO(bunnei): This should be configurable
  533. IPC::ResponseBuilder rb{ctx, 4};
  534. rb.Push(RESULT_SUCCESS);
  535. rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US));
  536. LOG_DEBUG(Service_AM, "called");
  537. }
  538. void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
  539. IPC::ResponseBuilder rb{ctx, 2};
  540. rb.Push(RESULT_SUCCESS);
  541. LOG_WARNING(Service_AM, "(STUBBED) called");
  542. }
  543. void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
  544. IPC::ResponseBuilder rb{ctx, 2};
  545. rb.Push(RESULT_SUCCESS);
  546. LOG_WARNING(Service_AM, "(STUBBED) called");
  547. }
  548. void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
  549. IPC::ResponseBuilder rb{ctx, 3};
  550. rb.Push(RESULT_SUCCESS);
  551. rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
  552. LOG_WARNING(Service_AM, "(STUBBED) called");
  553. }
  554. void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
  555. IPC::ResponseBuilder rb{ctx, 6};
  556. rb.Push(RESULT_SUCCESS);
  557. // Returns a 128-bit UUID
  558. rb.Push<u64>(0);
  559. rb.Push<u64>(0);
  560. LOG_WARNING(Service_AM, "(STUBBED) called");
  561. }
  562. void InstallInterfaces(SM::ServiceManager& service_manager,
  563. std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
  564. std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
  565. std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
  566. std::make_shared<IdleSys>()->InstallAsService(service_manager);
  567. std::make_shared<OMM>()->InstallAsService(service_manager);
  568. std::make_shared<SPSM>()->InstallAsService(service_manager);
  569. }
  570. IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") {
  571. static const FunctionInfo functions[] = {
  572. {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
  573. {11, nullptr, "LockForeground"},
  574. {12, nullptr, "UnlockForeground"},
  575. {20, nullptr, "PopFromGeneralChannel"},
  576. {21, nullptr, "GetPopFromGeneralChannelEvent"},
  577. {30, nullptr, "GetHomeButtonWriterLockAccessor"},
  578. {31, nullptr, "GetWriterLockAccessorEx"},
  579. };
  580. RegisterHandlers(functions);
  581. }
  582. void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
  583. IPC::ResponseBuilder rb{ctx, 2};
  584. rb.Push(RESULT_SUCCESS);
  585. LOG_WARNING(Service_AM, "(STUBBED) called");
  586. }
  587. IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
  588. static const FunctionInfo functions[] = {
  589. {0, nullptr, "RequestToEnterSleep"},
  590. {1, nullptr, "EnterSleep"},
  591. {2, nullptr, "StartSleepSequence"},
  592. {3, nullptr, "StartShutdownSequence"},
  593. {4, nullptr, "StartRebootSequence"},
  594. {10, nullptr, "LoadAndApplyIdlePolicySettings"},
  595. {11, nullptr, "NotifyCecSettingsChanged"},
  596. {12, nullptr, "SetDefaultHomeButtonLongPressTime"},
  597. {13, nullptr, "UpdateDefaultDisplayResolution"},
  598. {14, nullptr, "ShouldSleepOnBoot"},
  599. {15, nullptr, "GetHdcpAuthenticationFailedEvent"},
  600. };
  601. RegisterHandlers(functions);
  602. }
  603. IApplicationCreator::IApplicationCreator() : ServiceFramework("IApplicationCreator") {
  604. static const FunctionInfo functions[] = {
  605. {0, nullptr, "CreateApplication"},
  606. {1, nullptr, "PopLaunchRequestedApplication"},
  607. {10, nullptr, "CreateSystemApplication"},
  608. {100, nullptr, "PopFloatingApplicationForDevelopment"},
  609. };
  610. RegisterHandlers(functions);
  611. }
  612. IProcessWindingController::IProcessWindingController()
  613. : ServiceFramework("IProcessWindingController") {
  614. static const FunctionInfo functions[] = {
  615. {0, nullptr, "GetLaunchReason"},
  616. {11, nullptr, "OpenCallingLibraryApplet"},
  617. {21, nullptr, "PushContext"},
  618. {22, nullptr, "PopContext"},
  619. {23, nullptr, "CancelWindingReservation"},
  620. {30, nullptr, "WindAndDoReserved"},
  621. {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"},
  622. {41, nullptr, "ReserveToStartAndWait"},
  623. };
  624. RegisterHandlers(functions);
  625. }
  626. } // namespace Service::AM