application_functions.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/settings.h"
  4. #include "common/uuid.h"
  5. #include "core/file_sys/control_metadata.h"
  6. #include "core/file_sys/patch_manager.h"
  7. #include "core/file_sys/registered_cache.h"
  8. #include "core/file_sys/savedata_factory.h"
  9. #include "core/hle/service/acc/profile_manager.h"
  10. #include "core/hle/service/am/am_results.h"
  11. #include "core/hle/service/am/applet.h"
  12. #include "core/hle/service/am/application_functions.h"
  13. #include "core/hle/service/am/storage.h"
  14. #include "core/hle/service/filesystem/filesystem.h"
  15. #include "core/hle/service/filesystem/save_data_controller.h"
  16. #include "core/hle/service/ipc_helpers.h"
  17. #include "core/hle/service/ns/ns.h"
  18. #include "core/hle/service/sm/sm.h"
  19. namespace Service::AM {
  20. enum class LaunchParameterKind : u32 {
  21. UserChannel = 1,
  22. AccountPreselectedUser = 2,
  23. };
  24. IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_)
  25. : ServiceFramework{system_, "IApplicationFunctions"}, applet{std::move(applet_)} {
  26. // clang-format off
  27. static const FunctionInfo functions[] = {
  28. {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
  29. {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
  30. {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
  31. {12, nullptr, "CreateApplicationAndRequestToStart"},
  32. {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"},
  33. {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"},
  34. {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"},
  35. {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
  36. {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
  37. {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
  38. {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
  39. {24, nullptr, "GetLaunchStorageInfoForDebug"},
  40. {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
  41. {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
  42. {27, &IApplicationFunctions::CreateCacheStorage, "CreateCacheStorage"},
  43. {28, &IApplicationFunctions::GetSaveDataSizeMax, "GetSaveDataSizeMax"},
  44. {29, nullptr, "GetCacheStorageMax"},
  45. {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
  46. {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
  47. {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
  48. {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
  49. {34, nullptr, "SelectApplicationLicense"},
  50. {35, nullptr, "GetDeviceSaveDataSizeMax"},
  51. {36, nullptr, "GetLimitedApplicationLicense"},
  52. {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
  53. {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
  54. {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
  55. {60, nullptr, "SetMediaPlaybackStateForApplication"},
  56. {65, &IApplicationFunctions::IsGamePlayRecordingSupported, "IsGamePlayRecordingSupported"},
  57. {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
  58. {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
  59. {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
  60. {70, nullptr, "RequestToShutdown"},
  61. {71, nullptr, "RequestToReboot"},
  62. {72, nullptr, "RequestToSleep"},
  63. {80, nullptr, "ExitAndRequestToShowThanksMessage"},
  64. {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"},
  65. {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"},
  66. {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"},
  67. {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
  68. {110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"},
  69. {111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"},
  70. {120, &IApplicationFunctions::ExecuteProgram, "ExecuteProgram"},
  71. {121, &IApplicationFunctions::ClearUserChannel, "ClearUserChannel"},
  72. {122, &IApplicationFunctions::UnpopToUserChannel, "UnpopToUserChannel"},
  73. {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
  74. {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
  75. {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
  76. {131, nullptr, "SetDelayTimeToAbortOnGpuError"},
  77. {140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
  78. {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
  79. {150, &IApplicationFunctions::GetNotificationStorageChannelEvent, "GetNotificationStorageChannelEvent"},
  80. {151, nullptr, "TryPopFromNotificationStorageChannel"},
  81. {160, &IApplicationFunctions::GetHealthWarningDisappearedSystemEvent, "GetHealthWarningDisappearedSystemEvent"},
  82. {170, nullptr, "SetHdcpAuthenticationActivated"},
  83. {180, nullptr, "GetLaunchRequiredVersion"},
  84. {181, nullptr, "UpgradeLaunchRequiredVersion"},
  85. {190, nullptr, "SendServerMaintenanceOverlayNotification"},
  86. {200, nullptr, "GetLastApplicationExitReason"},
  87. {500, nullptr, "StartContinuousRecordingFlushForDebug"},
  88. {1000, nullptr, "CreateMovieMaker"},
  89. {1001, &IApplicationFunctions::PrepareForJit, "PrepareForJit"},
  90. };
  91. // clang-format on
  92. RegisterHandlers(functions);
  93. }
  94. IApplicationFunctions::~IApplicationFunctions() = default;
  95. void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) {
  96. LOG_WARNING(Service_AM, "(STUBBED) called");
  97. std::scoped_lock lk{applet->lock};
  98. applet->application_crash_report_enabled = true;
  99. IPC::ResponseBuilder rb{ctx, 2};
  100. rb.Push(ResultSuccess);
  101. }
  102. void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx) {
  103. LOG_WARNING(Service_AM, "(STUBBED) called");
  104. IPC::ResponseBuilder rb{ctx, 2};
  105. rb.Push(ResultSuccess);
  106. }
  107. void IApplicationFunctions::SetApplicationCopyrightImage(HLERequestContext& ctx) {
  108. LOG_WARNING(Service_AM, "(STUBBED) called");
  109. IPC::ResponseBuilder rb{ctx, 2};
  110. rb.Push(ResultSuccess);
  111. }
  112. void IApplicationFunctions::SetApplicationCopyrightVisibility(HLERequestContext& ctx) {
  113. IPC::RequestParser rp{ctx};
  114. const auto is_visible = rp.Pop<bool>();
  115. LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible);
  116. IPC::ResponseBuilder rb{ctx, 2};
  117. rb.Push(ResultSuccess);
  118. }
  119. void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
  120. LOG_WARNING(Service_AM, "(STUBBED) called");
  121. std::scoped_lock lk{applet->lock};
  122. applet->home_button_long_pressed_blocked = true;
  123. applet->home_button_short_pressed_blocked = true;
  124. IPC::ResponseBuilder rb{ctx, 2};
  125. rb.Push(ResultSuccess);
  126. }
  127. void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
  128. LOG_WARNING(Service_AM, "(STUBBED) called");
  129. std::scoped_lock lk{applet->lock};
  130. applet->home_button_long_pressed_blocked = false;
  131. applet->home_button_short_pressed_blocked = false;
  132. IPC::ResponseBuilder rb{ctx, 2};
  133. rb.Push(ResultSuccess);
  134. }
  135. void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) {
  136. LOG_WARNING(Service_AM, "(STUBBED) called");
  137. std::scoped_lock lk{applet->lock};
  138. applet->home_button_long_pressed_blocked = true;
  139. applet->home_button_short_pressed_blocked = true;
  140. applet->home_button_double_click_enabled = true;
  141. IPC::ResponseBuilder rb{ctx, 2};
  142. rb.Push(ResultSuccess);
  143. }
  144. void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) {
  145. LOG_WARNING(Service_AM, "(STUBBED) called");
  146. std::scoped_lock lk{applet->lock};
  147. applet->home_button_long_pressed_blocked = false;
  148. applet->home_button_short_pressed_blocked = false;
  149. applet->home_button_double_click_enabled = false;
  150. IPC::ResponseBuilder rb{ctx, 2};
  151. rb.Push(ResultSuccess);
  152. }
  153. void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) {
  154. IPC::RequestParser rp{ctx};
  155. const auto kind = rp.PopEnum<LaunchParameterKind>();
  156. LOG_INFO(Service_AM, "called, kind={:08X}", kind);
  157. std::scoped_lock lk{applet->lock};
  158. auto& channel = kind == LaunchParameterKind::UserChannel
  159. ? applet->user_channel_launch_parameter
  160. : applet->preselected_user_launch_parameter;
  161. if (channel.empty()) {
  162. LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", kind);
  163. IPC::ResponseBuilder rb{ctx, 2};
  164. rb.Push(AM::ResultNoDataInChannel);
  165. return;
  166. }
  167. auto data = channel.back();
  168. channel.pop_back();
  169. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  170. rb.Push(ResultSuccess);
  171. rb.PushIpcInterface<IStorage>(system, std::move(data));
  172. }
  173. void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) {
  174. LOG_WARNING(Service_AM, "(STUBBED) called");
  175. IPC::ResponseBuilder rb{ctx, 2};
  176. rb.Push(ResultSuccess);
  177. }
  178. void IApplicationFunctions::EnsureSaveData(HLERequestContext& ctx) {
  179. IPC::RequestParser rp{ctx};
  180. u128 user_id = rp.PopRaw<u128>();
  181. LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]);
  182. FileSys::SaveDataAttribute attribute{};
  183. attribute.title_id = applet->program_id;
  184. attribute.user_id = user_id;
  185. attribute.type = FileSys::SaveDataType::SaveData;
  186. FileSys::VirtualDir save_data{};
  187. const auto res = system.GetFileSystemController().OpenSaveDataController()->CreateSaveData(
  188. &save_data, FileSys::SaveDataSpaceId::NandUser, attribute);
  189. IPC::ResponseBuilder rb{ctx, 4};
  190. rb.Push(res);
  191. rb.Push<u64>(0);
  192. }
  193. void IApplicationFunctions::SetTerminateResult(HLERequestContext& ctx) {
  194. // Takes an input u32 Result, no output.
  195. // For example, in some cases official apps use this with error 0x2A2 then
  196. // uses svcBreak.
  197. IPC::RequestParser rp{ctx};
  198. u32 result = rp.Pop<u32>();
  199. LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
  200. std::scoped_lock lk{applet->lock};
  201. applet->terminate_result = Result(result);
  202. IPC::ResponseBuilder rb{ctx, 2};
  203. rb.Push(ResultSuccess);
  204. }
  205. void IApplicationFunctions::GetDisplayVersion(HLERequestContext& ctx) {
  206. LOG_DEBUG(Service_AM, "called");
  207. std::array<u8, 0x10> version_string{};
  208. const auto res = [this] {
  209. const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(),
  210. system.GetContentProvider()};
  211. auto metadata = pm.GetControlMetadata();
  212. if (metadata.first != nullptr) {
  213. return metadata;
  214. }
  215. const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id),
  216. system.GetFileSystemController(),
  217. system.GetContentProvider()};
  218. return pm_update.GetControlMetadata();
  219. }();
  220. if (res.first != nullptr) {
  221. const auto& version = res.first->GetVersionString();
  222. std::copy(version.begin(), version.end(), version_string.begin());
  223. } else {
  224. static constexpr char default_version[]{"1.0.0"};
  225. std::memcpy(version_string.data(), default_version, sizeof(default_version));
  226. }
  227. IPC::ResponseBuilder rb{ctx, 6};
  228. rb.Push(ResultSuccess);
  229. rb.PushRaw(version_string);
  230. }
  231. void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) {
  232. // TODO(bunnei): This should be configurable
  233. LOG_DEBUG(Service_AM, "called");
  234. // Get supported languages from NACP, if possible
  235. // Default to 0 (all languages supported)
  236. u32 supported_languages = 0;
  237. const auto res = [this] {
  238. const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(),
  239. system.GetContentProvider()};
  240. auto metadata = pm.GetControlMetadata();
  241. if (metadata.first != nullptr) {
  242. return metadata;
  243. }
  244. const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id),
  245. system.GetFileSystemController(),
  246. system.GetContentProvider()};
  247. return pm_update.GetControlMetadata();
  248. }();
  249. if (res.first != nullptr) {
  250. supported_languages = res.first->GetSupportedLanguages();
  251. }
  252. // Call IApplicationManagerInterface implementation.
  253. auto& service_manager = system.ServiceManager();
  254. auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
  255. auto app_man = ns_am2->GetApplicationManagerInterface();
  256. // Get desired application language
  257. u8 desired_language{};
  258. const auto res_lang =
  259. app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages);
  260. if (res_lang != ResultSuccess) {
  261. IPC::ResponseBuilder rb{ctx, 2};
  262. rb.Push(res_lang);
  263. return;
  264. }
  265. // Convert to settings language code.
  266. u64 language_code{};
  267. const auto res_code =
  268. app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language);
  269. if (res_code != ResultSuccess) {
  270. IPC::ResponseBuilder rb{ctx, 2};
  271. rb.Push(res_code);
  272. return;
  273. }
  274. LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
  275. IPC::ResponseBuilder rb{ctx, 4};
  276. rb.Push(ResultSuccess);
  277. rb.Push(language_code);
  278. }
  279. void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) {
  280. LOG_WARNING(Service_AM, "(STUBBED) called");
  281. IPC::ResponseBuilder rb{ctx, 3};
  282. rb.Push(ResultSuccess);
  283. rb.Push(applet->gameplay_recording_supported);
  284. }
  285. void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) {
  286. LOG_WARNING(Service_AM, "(STUBBED) called");
  287. IPC::ResponseBuilder rb{ctx, 2};
  288. rb.Push(ResultSuccess);
  289. }
  290. void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) {
  291. LOG_WARNING(Service_AM, "(STUBBED) called");
  292. IPC::RequestParser rp{ctx};
  293. std::scoped_lock lk{applet->lock};
  294. applet->gameplay_recording_state = rp.PopRaw<GameplayRecordingState>();
  295. IPC::ResponseBuilder rb{ctx, 2};
  296. rb.Push(ResultSuccess);
  297. }
  298. void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) {
  299. LOG_WARNING(Service_AM, "(STUBBED) called");
  300. std::scoped_lock lk{applet->lock};
  301. applet->is_running = true;
  302. IPC::ResponseBuilder rb{ctx, 3};
  303. rb.Push(ResultSuccess);
  304. rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
  305. }
  306. void IApplicationFunctions::GetPseudoDeviceId(HLERequestContext& ctx) {
  307. LOG_WARNING(Service_AM, "(STUBBED) called");
  308. IPC::ResponseBuilder rb{ctx, 6};
  309. rb.Push(ResultSuccess);
  310. // Returns a 128-bit UUID
  311. rb.Push<u64>(0);
  312. rb.Push<u64>(0);
  313. }
  314. void IApplicationFunctions::ExtendSaveData(HLERequestContext& ctx) {
  315. struct Parameters {
  316. FileSys::SaveDataType type;
  317. u128 user_id;
  318. u64 new_normal_size;
  319. u64 new_journal_size;
  320. };
  321. static_assert(sizeof(Parameters) == 40);
  322. IPC::RequestParser rp{ctx};
  323. const auto [type, user_id, new_normal_size, new_journal_size] = rp.PopRaw<Parameters>();
  324. LOG_DEBUG(Service_AM,
  325. "called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, "
  326. "new_journal={:016X}",
  327. static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
  328. system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize(
  329. type, applet->program_id, user_id, {new_normal_size, new_journal_size});
  330. IPC::ResponseBuilder rb{ctx, 4};
  331. rb.Push(ResultSuccess);
  332. // The following value is used upon failure to help the system recover.
  333. // Since we always succeed, this should be 0.
  334. rb.Push<u64>(0);
  335. }
  336. void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) {
  337. struct Parameters {
  338. FileSys::SaveDataType type;
  339. u128 user_id;
  340. };
  341. static_assert(sizeof(Parameters) == 24);
  342. IPC::RequestParser rp{ctx};
  343. const auto [type, user_id] = rp.PopRaw<Parameters>();
  344. LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", type, user_id[1],
  345. user_id[0]);
  346. const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize(
  347. type, applet->program_id, user_id);
  348. IPC::ResponseBuilder rb{ctx, 6};
  349. rb.Push(ResultSuccess);
  350. rb.Push(size.normal);
  351. rb.Push(size.journal);
  352. }
  353. void IApplicationFunctions::CreateCacheStorage(HLERequestContext& ctx) {
  354. struct InputParameters {
  355. u16 index;
  356. s64 size;
  357. s64 journal_size;
  358. };
  359. static_assert(sizeof(InputParameters) == 24);
  360. struct OutputParameters {
  361. u32 storage_target;
  362. u64 required_size;
  363. };
  364. static_assert(sizeof(OutputParameters) == 16);
  365. IPC::RequestParser rp{ctx};
  366. const auto params = rp.PopRaw<InputParameters>();
  367. LOG_WARNING(Service_AM, "(STUBBED) called with index={}, size={:#x}, journal_size={:#x}",
  368. params.index, params.size, params.journal_size);
  369. const OutputParameters resp{
  370. .storage_target = 1,
  371. .required_size = 0,
  372. };
  373. IPC::ResponseBuilder rb{ctx, 6};
  374. rb.Push(ResultSuccess);
  375. rb.PushRaw(resp);
  376. }
  377. void IApplicationFunctions::GetSaveDataSizeMax(HLERequestContext& ctx) {
  378. LOG_WARNING(Service_AM, "(STUBBED) called");
  379. constexpr u64 size_max_normal = 0xFFFFFFF;
  380. constexpr u64 size_max_journal = 0xFFFFFFF;
  381. IPC::ResponseBuilder rb{ctx, 6};
  382. rb.Push(ResultSuccess);
  383. rb.Push(size_max_normal);
  384. rb.Push(size_max_journal);
  385. }
  386. void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) {
  387. LOG_WARNING(Service_AM, "(STUBBED) called");
  388. IPC::ResponseBuilder rb{ctx, 3};
  389. rb.Push(ResultSuccess);
  390. rb.Push<u32>(0);
  391. }
  392. void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx) {
  393. LOG_WARNING(Service_AM, "(STUBBED) called");
  394. IPC::ResponseBuilder rb{ctx, 3};
  395. rb.Push(ResultSuccess);
  396. rb.Push<u32>(0);
  397. }
  398. void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) {
  399. LOG_WARNING(Service_AM, "(STUBBED) called");
  400. IPC::RequestParser rp{ctx};
  401. [[maybe_unused]] const auto unk_1 = rp.Pop<u32>();
  402. [[maybe_unused]] const auto unk_2 = rp.Pop<u32>();
  403. const auto program_index = rp.Pop<u64>();
  404. IPC::ResponseBuilder rb{ctx, 2};
  405. rb.Push(ResultSuccess);
  406. // Swap user channel ownership into the system so that it will be preserved
  407. system.GetUserChannel().swap(applet->user_channel_launch_parameter);
  408. system.ExecuteProgram(program_index);
  409. }
  410. void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) {
  411. LOG_DEBUG(Service_AM, "called");
  412. applet->user_channel_launch_parameter.clear();
  413. IPC::ResponseBuilder rb{ctx, 2};
  414. rb.Push(ResultSuccess);
  415. }
  416. void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) {
  417. LOG_DEBUG(Service_AM, "called");
  418. IPC::RequestParser rp{ctx};
  419. const auto storage = rp.PopIpcInterface<IStorage>().lock();
  420. if (storage) {
  421. applet->user_channel_launch_parameter.push_back(storage->GetData());
  422. }
  423. IPC::ResponseBuilder rb{ctx, 2};
  424. rb.Push(ResultSuccess);
  425. }
  426. void IApplicationFunctions::GetPreviousProgramIndex(HLERequestContext& ctx) {
  427. LOG_WARNING(Service_AM, "(STUBBED) called");
  428. IPC::ResponseBuilder rb{ctx, 3};
  429. rb.Push(ResultSuccess);
  430. rb.Push<s32>(applet->previous_program_index);
  431. }
  432. void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) {
  433. LOG_WARNING(Service_AM, "(STUBBED) called");
  434. IPC::ResponseBuilder rb{ctx, 2, 1};
  435. rb.Push(ResultSuccess);
  436. rb.PushCopyObjects(applet->gpu_error_detected_event.GetHandle());
  437. }
  438. void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) {
  439. LOG_DEBUG(Service_AM, "called");
  440. IPC::ResponseBuilder rb{ctx, 2, 1};
  441. rb.Push(ResultSuccess);
  442. rb.PushCopyObjects(applet->friend_invitation_storage_channel_event.GetHandle());
  443. }
  444. void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) {
  445. LOG_DEBUG(Service_AM, "(STUBBED) called");
  446. IPC::ResponseBuilder rb{ctx, 2};
  447. rb.Push(AM::ResultNoDataInChannel);
  448. }
  449. void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) {
  450. LOG_DEBUG(Service_AM, "called");
  451. IPC::ResponseBuilder rb{ctx, 2, 1};
  452. rb.Push(ResultSuccess);
  453. rb.PushCopyObjects(applet->notification_storage_channel_event.GetHandle());
  454. }
  455. void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) {
  456. LOG_DEBUG(Service_AM, "called");
  457. IPC::ResponseBuilder rb{ctx, 2, 1};
  458. rb.Push(ResultSuccess);
  459. rb.PushCopyObjects(applet->health_warning_disappeared_system_event.GetHandle());
  460. }
  461. void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) {
  462. LOG_WARNING(Service_AM, "(STUBBED) called");
  463. std::scoped_lock lk{applet->lock};
  464. applet->jit_service_launched = true;
  465. IPC::ResponseBuilder rb{ctx, 2};
  466. rb.Push(ResultSuccess);
  467. }
  468. } // namespace Service::AM