am.cpp 31 KB

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