diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt index 22976900f2..9c39f7b166 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt @@ -133,6 +133,11 @@ class InstallableFragment : Fragment() { R.string.install_firmware_description, install = { mainActivity.getFirmware.launch(arrayOf("application/zip")) } ), + Installable( + R.string.uninstall_firmware, + R.string.uninstall_firmware_description, + install = { mainActivity.uninstallFirmware() } + ), Installable( R.string.install_prod_keys, R.string.install_prod_keys_description, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index f1f05e6b20..74cf958f34 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -367,7 +367,31 @@ class MainActivity : AppCompatActivity(), ThemeProvider { messageToShow }.show(supportFragmentManager, ProgressDialogFragment.TAG) } - + fun uninstallFirmware() { + val firmwarePath = File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/") + ProgressDialogFragment.newInstance( + this, + R.string.firmware_uninstalling + ) { progressCallback, _ -> + var messageToShow: Any + try { + // Ensure the firmware directory exists before attempting to delete + if (firmwarePath.exists()) { + firmwarePath.deleteRecursively() + // Optionally reinitialize the system or perform other necessary steps + NativeLibrary.initializeSystem(true) + homeViewModel.setCheckKeys(true) + messageToShow = getString(R.string.firmware_uninstalled_success) + } else { + messageToShow = getString(R.string.firmware_uninstalled_failure) + } + } catch (e: Exception) { + Log.error("[MainActivity] Firmware uninstall failed - ${e.message}") + messageToShow = getString(R.string.fatal_error) + } + messageToShow + }.show(supportFragmentManager, ProgressDialogFragment.TAG) + } val getAmiiboKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> if (result == null) { diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 2987ea91fc..febe174c2b 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -143,6 +143,11 @@ Firmware installed successfully Firmware installation failed Make sure the firmware nca files are at the root of the zip and try again. + Uninstall firmware + Uninstalling the firmware will remove it from the device and may affect game compatibility. + Uninstalling firmware + Firmware uninstalled successfully + Firmware uninstallation failed Share debug logs Share eden\'s log file to debug issues No log file found diff --git a/src/core/hle/service/am/process_creation.cpp b/src/core/hle/service/am/process_creation.cpp index aaa03c4c39..81a8fb0b44 100644 --- a/src/core/hle/service/am/process_creation.cpp +++ b/src/core/hle/service/am/process_creation.cpp @@ -60,24 +60,29 @@ std::unique_ptr CreateProcessImpl(std::unique_ptr& o } // Anonymous namespace std::unique_ptr CreateProcess(Core::System& system, u64 program_id, - u8 minimum_key_generation, u8 maximum_key_generation) { - FileSys::VirtualFile nca_raw = system.GetContentProviderUnion() - .GetEntryRaw(program_id, FileSys::ContentRecordType::Program); + u8 minimum_key_generation, u8 maximum_key_generation) { + // Attempt to load program NCA. + FileSys::VirtualFile nca_raw{}; + // Get the program NCA from storage. + auto& storage = system.GetContentProviderUnion(); + nca_raw = storage.GetEntryRaw(program_id, FileSys::ContentRecordType::Program); + + // Ensure we retrieved a program NCA. if (!nca_raw) { return nullptr; } - FileSys::NCA nca(nca_raw); - if (nca.GetStatus() != Loader::ResultStatus::Success) { - return nullptr; - } - - u8 current_gen = nca.GetKeyGeneration(); - if (minimum_key_generation > 0 && (current_gen < minimum_key_generation || - current_gen > maximum_key_generation)) { - LOG_WARNING(Service_LDR, "Program {:016X} has unsupported generation {}. " - "Attempting to load anyway...", program_id, current_gen); + // Ensure we have a suitable version. + if (minimum_key_generation > 0) { + FileSys::NCA nca(nca_raw); + if (nca.GetStatus() == Loader::ResultStatus::Success && + (nca.GetKeyGeneration() < minimum_key_generation || + nca.GetKeyGeneration() > maximum_key_generation)) { + LOG_WARNING(Service_LDR, "Skipping program {:016X} with generation {}", program_id, + nca.GetKeyGeneration()); + return nullptr; + } } std::unique_ptr loader; @@ -101,7 +106,7 @@ std::unique_ptr CreateApplicationProcess(std::vector& out_control, out_control = nacp.GetRawBytes(); } else { out_control.resize(sizeof(FileSys::RawNACP)); - std::fill(out_control.begin(), out_control.end(), (u8) 0); + std::fill(out_control.begin(), out_control.end(), 0); } auto& storage = system.GetContentProviderUnion(); diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp index 5a787494a8..fc9c77fc36 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp @@ -18,6 +18,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys // clang-format off static const FunctionInfo functions[] = { {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, + {110, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxyForDebug>, "OpenSystemAppletProxyForDebug"}, {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"}, {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"}, {300, nullptr, "OpenOverlayAppletProxy"}, @@ -25,6 +26,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, {410, nullptr, "GetSystemAppletControllerForDebug"}, {450, D<&IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions>, "GetSystemProcessCommonFunctions"}, // 19.0.0+ + {460, nullptr, "Unknown460"}, {1000, nullptr, "GetDebugFunctions"}, }; // clang-format on @@ -49,6 +51,26 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( } } +Result IAllSystemAppletProxiesService::OpenSystemAppletProxyForDebug( + Out> out_proxy, ClientProcessId pid) { + LOG_DEBUG(Service_AM, "OpenSystemAppletProxyForDebug called"); + + auto process = system.ApplicationProcess(); + if (!process) { + LOG_ERROR(Service_AM, "No application process available"); + R_THROW(ResultUnknown); + } + + if (const auto applet = GetAppletFromProcessId(pid)) { + *out_proxy = std::make_shared( + system, applet, process, m_window_system); + R_SUCCEED(); + } + + LOG_ERROR(Service_AM, "Applet not found for pid={}", pid.pid); + R_THROW(ResultUnknown); +} + Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( Out> out_library_applet_proxy, ClientProcessId pid, InCopyHandle process_handle, diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h index a3111c4c9b..72730ea55a 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h @@ -27,6 +27,7 @@ private: Result OpenSystemAppletProxy(Out> out_system_applet_proxy, ClientProcessId pid, InCopyHandle process_handle); + Result OpenSystemAppletProxyForDebug(Out> out_proxy, ClientProcessId pid); Result OpenLibraryAppletProxy(Out> out_library_applet_proxy, ClientProcessId pid, InCopyHandle process_handle, diff --git a/src/core/hle/service/am/service/applet_common_functions.cpp b/src/core/hle/service/am/service/applet_common_functions.cpp index a051000af4..ed203e979a 100644 --- a/src/core/hle/service/am/service/applet_common_functions.cpp +++ b/src/core/hle/service/am/service/applet_common_functions.cpp @@ -32,6 +32,11 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_, {91, nullptr, "OpenNamedChannelAsChild"}, {100, nullptr, "SetApplicationCoreUsageMode"}, {300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"}, + {310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+ + {311, nullptr, "Unknown311"}, + {320, nullptr, "SetGpuTimeSliceBoost"}, //19.0.0+ + {321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+ + {350, nullptr, "Unknown350"}, }; // clang-format on diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 3ffb03bc97..413388d40a 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -111,9 +111,11 @@ std::shared_ptr CreateGuestApplet(Core::System& system, Firmware1500 = 15, Firmware1600 = 16, Firmware1700 = 17, + Firmware1800 = 18, + Firmware1900 = 19, }; - auto process = CreateProcess(system, program_id, Firmware1400, Firmware1700); + auto process = CreateProcess(system, program_id, Firmware1400, Firmware1900); if (!process) { // Couldn't initialize the guest process return {}; diff --git a/src/core/hle/service/am/service/process_winding_controller.cpp b/src/core/hle/service/am/service/process_winding_controller.cpp index 10df830d70..a150248e71 100644 --- a/src/core/hle/service/am/service/process_winding_controller.cpp +++ b/src/core/hle/service/am/service/process_winding_controller.cpp @@ -15,7 +15,7 @@ IProcessWindingController::IProcessWindingController(Core::System& system_, static const FunctionInfo functions[] = { {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"}, {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"}, - {21, nullptr, "PushContext"}, + {21, D<&IProcessWindingController::PushContext>, "PushContext"}, {22, nullptr, "PopContext"}, {23, nullptr, "CancelWindingReservation"}, {30, nullptr, "WindAndDoReserved"}, @@ -51,4 +51,9 @@ Result IProcessWindingController::OpenCallingLibraryApplet( R_SUCCEED(); } +Result IProcessWindingController::PushContext() { + LOG_WARNING(Service_AM, "(STUBBED) called"); + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/process_winding_controller.h b/src/core/hle/service/am/service/process_winding_controller.h index 4408af1f1d..bcf341d94c 100644 --- a/src/core/hle/service/am/service/process_winding_controller.h +++ b/src/core/hle/service/am/service/process_winding_controller.h @@ -21,7 +21,7 @@ private: Result GetLaunchReason(Out out_launch_reason); Result OpenCallingLibraryApplet( Out> out_calling_library_applet); - + Result PushContext(); const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 1db02b88fd..fa36c93060 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp @@ -67,6 +67,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr {110, nullptr, "SetApplicationAlbumUserData"}, {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"}, {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"}, + {230, D<&ISelfController::Unknown230>, "Unknown230"}, {1000, nullptr, "GetDebugStorageChannel"}, }; // clang-format on @@ -394,6 +395,10 @@ Result ISelfController::SaveCurrentScreenshot(Capture::AlbumReportOption album_r R_SUCCEED(); } +Result ISelfController::Unknown230() { + LOG_WARNING(Service_AM, "(STUBBED) called - function 230 (0xE6)"); + R_SUCCEED(); +} Result ISelfController::SetRecordVolumeMuted(bool muted) { LOG_WARNING(Service_AM, "(STUBBED) called. muted={}", muted); diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h index eca083cfe5..a384846231 100644 --- a/src/core/hle/service/am/service/self_controller.h +++ b/src/core/hle/service/am/service/self_controller.h @@ -62,6 +62,7 @@ private: Result GetAccumulatedSuspendedTickChangedEvent(OutCopyHandle out_event); Result SetAlbumImageTakenNotificationEnabled(bool enabled); Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); + Result Unknown230(); Result SetRecordVolumeMuted(bool muted); Kernel::KProcess* const m_process; diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp index 52228b830a..588cf2f09b 100644 --- a/src/core/hle/service/caps/caps_a.cpp +++ b/src/core/hle/service/caps/caps_a.cpp @@ -53,6 +53,8 @@ IAlbumAccessorService::IAlbumAccessorService(Core::System& system_, {8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"}, {10011, nullptr, "SetInternalErrorConversionEnabled"}, {50000, nullptr, "LoadMakerNoteInfoForDebug"}, + {50011, C<&IAlbumAccessorService::GetAlbumAccessResultForDebug>, "GetAlbumAccessResultForDebug"}, + {50012, C<&IAlbumAccessorService::SetAlbumAccessResultForDebug>, "SetAlbumAccessResultForDebug"}, {60002, nullptr, "OpenAccessorSession"}, }; // clang-format on @@ -137,6 +139,15 @@ Result IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1( R_RETURN(TranslateResult(result)); } +Result IAlbumAccessorService::GetAlbumAccessResultForDebug() { + LOG_DEBUG(Service_Capture, "(STUBBED) called."); + R_SUCCEED(); +} + +Result IAlbumAccessorService::SetAlbumAccessResultForDebug() { + LOG_DEBUG(Service_Capture, "(STUBBED) called."); + R_SUCCEED(); +} Result IAlbumAccessorService::TranslateResult(Result in_result) { if (in_result.IsSuccess()) { return in_result; diff --git a/src/core/hle/service/caps/caps_a.h b/src/core/hle/service/caps/caps_a.h index c7a5208e32..9590e71e70 100644 --- a/src/core/hle/service/caps/caps_a.h +++ b/src/core/hle/service/caps/caps_a.h @@ -50,6 +50,10 @@ private: OutArray out_image, OutArray out_buffer); + Result GetAlbumAccessResultForDebug(); + + Result SetAlbumAccessResultForDebug(); + Result TranslateResult(Result in_result); std::shared_ptr manager = nullptr; diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp index 7a91727f97..814e0b6e62 100644 --- a/src/core/hle/service/ns/application_manager_interface.cpp +++ b/src/core/hle/service/ns/application_manager_interface.cpp @@ -303,6 +303,9 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ {3013, nullptr, "IsGameCardEnabled"}, {3014, nullptr, "IsLocalContentShareEnabled"}, {3050, nullptr, "ListAssignELicenseTaskResult"}, + {4022, D<&IApplicationManagerInterface::Unknown4022>, "Unknown4022"}, + {4023, D<&IApplicationManagerInterface::Unknown4023>, "Unknown4023"}, + {4088, D<&IApplicationManagerInterface::Unknown4088>, "Unknown4088"}, {9999, nullptr, "GetApplicationCertificate"}, }; // clang-format on @@ -509,6 +512,23 @@ Result IApplicationManagerInterface::CheckApplicationLaunchVersion(u64 applicati R_SUCCEED(); } +Result IApplicationManagerInterface::Unknown4022(Out out_unknown) { + LOG_WARNING(Service_NS, "(STUBBED) Unknown4022 called"); + *out_unknown = 0; + R_SUCCEED(); +} + +Result IApplicationManagerInterface::Unknown4023(Out out_unknown) { + LOG_WARNING(Service_NS, "(STUBBED) Unknown4022 called"); + + *out_unknown = 0; + R_SUCCEED(); +} +Result IApplicationManagerInterface::Unknown4088() { + LOG_WARNING(Service_NS, "(STUBBED) Unknown4088 called"); + R_SUCCEED(); +} + Result IApplicationManagerInterface::GetApplicationTerminateResult(Out out_result, u64 application_id) { LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id); diff --git a/src/core/hle/service/ns/application_manager_interface.h b/src/core/hle/service/ns/application_manager_interface.h index f33d269b35..e96e50c8e1 100644 --- a/src/core/hle/service/ns/application_manager_interface.h +++ b/src/core/hle/service/ns/application_manager_interface.h @@ -48,6 +48,9 @@ public: Result IsApplicationUpdateRequested(Out out_update_required, Out out_update_version, u64 application_id); Result CheckApplicationLaunchVersion(u64 application_id); + Result Unknown4022(Out out_unknown); + Result Unknown4023(Out out_unknown); + Result Unknown4088(); Result GetApplicationTerminateResult(Out out_result, u64 application_id); private: diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp index ad14c7740b..a65088de9c 100644 --- a/src/core/hle/service/pctl/parental_control_service.cpp +++ b/src/core/hle/service/pctl/parental_control_service.cpp @@ -81,12 +81,12 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili {1451, D<&IParentalControlService::StartPlayTimer>, "StartPlayTimer"}, {1452, D<&IParentalControlService::StopPlayTimer>, "StopPlayTimer"}, {1453, D<&IParentalControlService::IsPlayTimerEnabled>, "IsPlayTimerEnabled"}, - {1454, nullptr, "GetPlayTimerRemainingTime"}, + {1454, D<&IParentalControlService::GetPlayTimerRemainingTime>, "GetPlayTimerRemainingTime"}, {1455, D<&IParentalControlService::IsRestrictedByPlayTimer>, "IsRestrictedByPlayTimer"}, {1456, D<&IParentalControlService::GetPlayTimerSettingsOld>, "GetPlayTimerSettingsOld"}, {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"}, {1458, D<&IParentalControlService::IsPlayTimerAlarmDisabled>, "IsPlayTimerAlarmDisabled"}, - {1459, nullptr, "GetPlayTimerRemainingTimeDisplayInfo"}, // 20.0.0+ + {1459, D<&IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo>, "GetPlayTimerRemainingTimeDisplayInfo"}, // 20.0.0+ {1471, nullptr, "NotifyWrongPinCodeInputManyTimes"}, {1472, nullptr, "CancelNetworkRequest"}, {1473, D<&IParentalControlService::GetUnlinkedEvent>, "GetUnlinkedEvent"}, @@ -388,6 +388,12 @@ Result IParentalControlService::IsPlayTimerEnabled(Out out_is_play_timer_e R_SUCCEED(); } +Result IParentalControlService::GetPlayTimerRemainingTime(Out out_remaining_minutes) { + *out_remaining_minutes = 0; + LOG_WARNING(Service_PCTL, "(STUBBED) called, remaining_minutes={}", *out_remaining_minutes); + R_SUCCEED(); +} + Result IParentalControlService::IsRestrictedByPlayTimer(Out out_is_restricted_by_play_timer) { *out_is_restricted_by_play_timer = false; LOG_WARNING(Service_PCTL, "(STUBBED) called, restricted={}", *out_is_restricted_by_play_timer); @@ -422,6 +428,15 @@ Result IParentalControlService::IsPlayTimerAlarmDisabled(Out out_play_time R_SUCCEED(); } +Result IParentalControlService::GetPlayTimerRemainingTimeDisplayInfo( + Out out_remaining_minutes, Out out_unknown) { + *out_remaining_minutes = 0; + *out_unknown = 0; + LOG_WARNING(Service_PCTL, "(STUBBED) called, remaining_minutes={}, unknown={}", + *out_remaining_minutes, *out_unknown); + R_SUCCEED(); +} + Result IParentalControlService::GetUnlinkedEvent(OutCopyHandle out_event) { LOG_INFO(Service_PCTL, "called"); *out_event = unlinked_event.GetHandle(); diff --git a/src/core/hle/service/pctl/parental_control_service.h b/src/core/hle/service/pctl/parental_control_service.h index d58c75f380..5b72ed1f03 100644 --- a/src/core/hle/service/pctl/parental_control_service.h +++ b/src/core/hle/service/pctl/parental_control_service.h @@ -45,10 +45,12 @@ private: Result StartPlayTimer(); Result StopPlayTimer(); Result IsPlayTimerEnabled(Out out_is_play_timer_enabled); + Result GetPlayTimerRemainingTime(Out out_remaining_minutes); Result IsRestrictedByPlayTimer(Out out_is_restricted_by_play_timer); Result GetPlayTimerSettingsOld(Out out_play_timer_settings); Result GetPlayTimerEventToRequestSuspension(OutCopyHandle out_event); Result IsPlayTimerAlarmDisabled(Out out_play_timer_alarm_disabled); + Result GetPlayTimerRemainingTimeDisplayInfo(Out out_remaining_minutes, Out out_unknown); Result GetUnlinkedEvent(OutCopyHandle out_event); Result GetStereoVisionRestriction(Out out_stereo_vision_restriction); Result SetStereoVisionRestriction(bool stereo_vision_restriction);