diff options
author | Zephyron <zephyron@citron-emu.orgq> | 2025-02-17 17:33:10 +1000 |
---|---|---|
committer | Zephyron <zephyron@citron-emu.orgq> | 2025-02-17 17:33:10 +1000 |
commit | c5e480e55ddc3183c48148daaa14c00ada855fee (patch) | |
tree | 36613554e13c7526fc106b59b80c49bb1c893392 /src/core/hle | |
parent | 1c9e17496b6f9f4b083c62aa25548617dd179a8b (diff) |
feat: Add Home Menu launch support and system improvements
This commit adds support for launching the system Home Menu and implements
several system-level improvements:
- Add Home Menu launch functionality through new UI action
- Implement shutdown/reboot sequence handlers in GlobalStateController
- Add support for reserved region extra size in page tables
- Enhance audio controller with output management
- Expand parental control service capabilities
- Add profile service improvements for user management
Technical changes:
- Add OnHomeMenu() handler to launch QLaunch system applet
- Implement m_alias_region_extra_size tracking in page tables
- Add new CreateProcessFlag for reserved region extra size
- Expand audio controller interface with output management
- Add self-controller methods to various services
- Implement play timer and profile service improvements
The changes primarily focus on system menu integration and core service
improvements to better support system functionality.
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/kernel/k_page_table_base.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/kernel/k_page_table_base.h | 5 | ||||
-rw-r--r-- | src/core/hle/kernel/k_process_page_table.h | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/svc_types.h | 7 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc.cpp | 27 | ||||
-rw-r--r-- | src/core/hle/service/am/service/all_system_applet_proxies_service.cpp | 9 | ||||
-rw-r--r-- | src/core/hle/service/am/service/all_system_applet_proxies_service.h | 5 | ||||
-rw-r--r-- | src/core/hle/service/am/service/global_state_controller.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/am/service/global_state_controller.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio_controller.cpp | 57 | ||||
-rw-r--r-- | src/core/hle/service/audio/audio_controller.h | 12 | ||||
-rw-r--r-- | src/core/hle/service/pctl/parental_control_service.cpp | 21 | ||||
-rw-r--r-- | src/core/hle/service/pctl/parental_control_service.h | 2 |
13 files changed, 153 insertions, 15 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 5e00f0c81..5d5e3d002 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -172,6 +172,7 @@ Result KPageTableBase::InitializeForKernel(bool is_64_bit, KVirtualAddress start m_mapped_unsafe_physical_memory = 0; m_mapped_insecure_memory = 0; m_mapped_ipc_server_memory = 0; + m_alias_region_extra_size = 0; m_memory_block_slab_manager = m_kernel.GetSystemSystemResource().GetMemoryBlockSlabManagerPointer(); diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h index 939b8a7ae..1a6f90ec2 100644 --- a/src/core/hle/kernel/k_page_table_base.h +++ b/src/core/hle/kernel/k_page_table_base.h @@ -208,6 +208,7 @@ private: size_t m_mapped_unsafe_physical_memory{}; size_t m_mapped_insecure_memory{}; size_t m_mapped_ipc_server_memory{}; + size_t m_alias_region_extra_size{}; mutable KLightLock m_general_lock; mutable KLightLock m_map_physical_memory_lock; KLightLock m_device_map_lock; @@ -715,6 +716,10 @@ public: return m_address_space_width; } + size_t GetReservedRegionExtraSize() const { + return m_alias_region_extra_size; + } + public: // Linear mapped static u8* GetLinearMappedVirtualPointer(KernelCore& kernel, KPhysicalAddress addr) { diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h index 346d7ca08..4b9942d50 100644 --- a/src/core/hle/kernel/k_process_page_table.h +++ b/src/core/hle/kernel/k_process_page_table.h @@ -472,6 +472,10 @@ public: const KPageTable& GetBasePageTable() const { return m_page_table; } + + size_t GetReservedRegionExtraSize() const { + return m_page_table.GetReservedRegionExtraSize(); + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h index e301f67c5..e4f60d953 100644 --- a/src/core/hle/kernel/svc_types.h +++ b/src/core/hle/kernel/svc_types.h @@ -153,6 +153,7 @@ enum class InfoType : u32 { ThreadTickCount = 25, IsSvcPermitted = 26, IoRegionHint = 27, + ReservedRegionExtraSize = 28, MesosphereMeta = 65000, MesosphereCurrentProcess = 65001, @@ -643,9 +644,13 @@ enum class CreateProcessFlag : u32 { // 11.x+ DisableDeviceAddressSpaceMerge. DisableDeviceAddressSpaceMerge = (1 << 12), + // 13.x+ EnableReservedRegionExtraSize. + EnableReservedRegionExtraSize = (1 << 13), + // Mask of all flags. All = Is64Bit | AddressSpaceMask | EnableDebug | EnableAslr | IsApplication | - PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge, + PoolPartitionMask | OptimizeMemoryAllocation | DisableDeviceAddressSpaceMerge | + EnableReservedRegionExtraSize, }; DECLARE_ENUM_FLAG_OPERATORS(CreateProcessFlag); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9f40c5425..e628c025c 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -317,6 +317,10 @@ public: {1, &IProfileCommon::GetBase, "GetBase"}, {10, &IProfileCommon::GetImageSize, "GetImageSize"}, {11, &IProfileCommon::LoadImage, "LoadImage"}, + {20, &IProfileCommon::GetImageSize, "GetLargeImageSize"}, + {21, &IProfileCommon::LoadImage, "LoadLargeImage"}, + {30, &IProfileCommon::Unknown, "GetImageId"}, + {40, &IProfileCommon::GetStableUserId, "GetStableUserId"}, }; RegisterHandlers(functions); @@ -486,6 +490,20 @@ protected: rb.Push(ResultSuccess); } + void Unknown(HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } + + void GetStableUserId(HLERequestContext& ctx) { + LOG_DEBUG(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(user_id.Hash()); + } + ProfileManager& profile_manager; Common::UUID user_id{}; ///< The user id this profile refers to. }; @@ -500,8 +518,13 @@ public: class IProfileEditor final : public IProfileCommon { public: explicit IProfileEditor(Core::System& system_, Common::UUID user_id_, - ProfileManager& profile_manager_) - : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} {} + ProfileManager& profile_manager_) + : IProfileCommon{system_, "IProfileEditor", true, user_id_, profile_manager_} { + static const FunctionInfo functions[] = { + {30, &IProfileEditor::Unknown, "Unknown"}, + }; + RegisterHandlers(functions); + } }; class ISessionObject final : public ServiceFramework<ISessionObject> { 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 bc9c86c55..e44037d30 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 @@ -4,6 +4,7 @@ #include "core/core.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/service/all_system_applet_proxies_service.h" +#include "core/hle/service/am/service/global_state_controller.h" #include "core/hle/service/am/service/library_applet_proxy.h" #include "core/hle/service/am/service/system_applet_proxy.h" #include "core/hle/service/am/window_system.h" @@ -23,6 +24,7 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys {350, nullptr, "OpenSystemApplicationProxy"}, {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"}, {410, nullptr, "GetSystemAppletControllerForDebug"}, + {450, D<&IAllSystemAppletProxiesService::GetGlobalStateController>, "GetGlobalStateController"}, {1000, nullptr, "GetDebugFunctions"}, }; // clang-format on @@ -73,6 +75,13 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute)); } +Result IAllSystemAppletProxiesService::GetGlobalStateController( + Out<SharedPointer<IGlobalStateController>> out_controller) { + LOG_DEBUG(Service_AM, "called"); + *out_controller = std::make_shared<IGlobalStateController>(this->system); + R_SUCCEED(); +} + std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( ProcessId process_id) { return m_window_system.GetByAppletResourceUserId(process_id.pid); 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 e3e79dc4f..344d93b13 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 @@ -5,6 +5,7 @@ #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" +#include "core/hle/service/am/service/global_state_controller.h" namespace Service { @@ -14,6 +15,7 @@ struct Applet; struct AppletAttribute; class ILibraryAppletProxy; class ISystemAppletProxy; +class IGlobalStateController; class WindowSystem; class IAllSystemAppletProxiesService final @@ -34,7 +36,8 @@ private: Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle); -private: + Result GetGlobalStateController(Out<SharedPointer<IGlobalStateController>> out_controller); + std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); WindowSystem& m_window_system; diff --git a/src/core/hle/service/am/service/global_state_controller.cpp b/src/core/hle/service/am/service/global_state_controller.cpp index dba5d3613..e1ffff919 100644 --- a/src/core/hle/service/am/service/global_state_controller.cpp +++ b/src/core/hle/service/am/service/global_state_controller.cpp @@ -15,8 +15,8 @@ IGlobalStateController::IGlobalStateController(Core::System& system_) {0, nullptr, "RequestToEnterSleep"}, {1, nullptr, "EnterSleep"}, {2, nullptr, "StartSleepSequence"}, - {3, nullptr, "StartShutdownSequence"}, - {4, nullptr, "StartRebootSequence"}, + {3, D<&IGlobalStateController::StartShutdownSequence>, "StartShutdownSequence"}, + {4, D<&IGlobalStateController::StartRebootSequence>, "StartRebootSequence"}, {9, nullptr, "IsAutoPowerDownRequested"}, {10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"}, {11, nullptr, "NotifyCecSettingsChanged"}, @@ -58,4 +58,16 @@ Result IGlobalStateController::OpenCradleFirmwareUpdater( R_SUCCEED(); } +Result IGlobalStateController::StartShutdownSequence() { + LOG_INFO(Service_AM, "called"); + system.Exit(); + R_SUCCEED(); +} + +Result IGlobalStateController::StartRebootSequence() { + LOG_INFO(Service_AM, "called"); + system.Exit(); + R_SUCCEED(); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/service/global_state_controller.h b/src/core/hle/service/am/service/global_state_controller.h index 67c753513..83efb57df 100644 --- a/src/core/hle/service/am/service/global_state_controller.h +++ b/src/core/hle/service/am/service/global_state_controller.h @@ -18,6 +18,8 @@ public: ~IGlobalStateController() override; private: + Result StartShutdownSequence(); + Result StartRebootSequence(); Result LoadAndApplyIdlePolicySettings(); Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot); Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index 300764ad6..c725e05fc 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -11,8 +11,19 @@ namespace Service::Audio { IAudioController::IAudioController(Core::System& system_) - : ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} { - // clang-format off + : ServiceFramework{system_, "audctl"} + , service_context{system, "audctl"} + , m_current_output_target{1} // Initialize with default values + , m_current_parameter{0x1388} + , m_current_volume{100} { + + // Create notification event first + notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); + + // Get system settings service + m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); + + // Register handlers static const FunctionInfo functions[] = { {0, nullptr, "GetTargetVolume"}, {1, nullptr, "SetTargetVolume"}, @@ -67,15 +78,15 @@ IAudioController::IAudioController(Core::System& system_) {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"}, {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"}, - {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"}, + {5000, D<&IAudioController::GetSelfController>, "GetSelfController"}, + {50001, D<&IAudioController::SetAudioControllerOutput>, "SetAudioControllerOutput"}, }; - // clang-format on - RegisterHandlers(functions); - m_set_sys = - system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); - notification_event = service_context.CreateEvent("IAudioController:NotificationEvent"); + // Signal initial state + if (notification_event) { + notification_event->Signal(); + } } IAudioController::~IAudioController() { @@ -176,4 +187,34 @@ Result IAudioController::AcquireTargetNotification( R_SUCCEED(); } +Result IAudioController::SetAudioControllerOutput(u32 output_target, u32 parameter, u32 volume) { + LOG_DEBUG(Audio, "called. output_target={}, parameter={}, volume={}", output_target, parameter, volume); + + if (!notification_event) { + LOG_ERROR(Audio, "Notification event not initialized"); + R_THROW(ResultCode::ResultInvalidState); + } + + m_current_output_target = output_target; + m_current_parameter = parameter; + m_current_volume = volume; + + notification_event->Signal(); + R_SUCCEED(); +} + +Result IAudioController::GetSelfController(Out<SharedPointer<IAudioController>> out_controller) { + LOG_DEBUG(Audio, "called"); + + // Use ServiceFramework's built-in method to get a shared pointer + *out_controller = SharedPointer<IAudioController>(this); + + // Signal notification event since we're returning a new interface + if (notification_event) { + notification_event->Signal(); + } + + R_SUCCEED(); +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_controller.h b/src/core/hle/service/audio/audio_controller.h index d37c4843e..98d7ecf89 100644 --- a/src/core/hle/service/audio/audio_controller.h +++ b/src/core/hle/service/audio/audio_controller.h @@ -6,6 +6,7 @@ #include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings_types.h" +#include "core/hle/result.h" namespace Core { class System; @@ -17,6 +18,10 @@ class ISystemSettingsServer; namespace Service::Audio { +namespace ResultCode { + constexpr Result ResultInvalidState{ErrorModule::Audio, 1}; +} // namespace ResultCode + class IAudioController final : public ServiceFramework<IAudioController> { public: explicit IAudioController(Core::System& system_); @@ -49,11 +54,18 @@ private: Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled); Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled); Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event); + Result SetAudioControllerOutput(u32 output_target, u32 parameter, u32 volume); + Result GetSelfController(Out<SharedPointer<IAudioController>> out_controller); KernelHelpers::ServiceContext service_context; Kernel::KEvent* notification_event; std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; + + // Add state tracking + u32 m_current_output_target{0}; + u32 m_current_parameter{0}; + u32 m_current_volume{0}; }; } // namespace Service::Audio diff --git a/src/core/hle/service/pctl/parental_control_service.cpp b/src/core/hle/service/pctl/parental_control_service.cpp index f57f2f157..3d156e87a 100644 --- a/src/core/hle/service/pctl/parental_control_service.cpp +++ b/src/core/hle/service/pctl/parental_control_service.cpp @@ -77,7 +77,7 @@ 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::GetPlayTimerSettings>, "GetPlayTimerSettings"}, {1457, D<&IParentalControlService::GetPlayTimerEventToRequestSuspension>, "GetPlayTimerEventToRequestSuspension"}, @@ -117,6 +117,7 @@ IParentalControlService::IParentalControlService(Core::System& system_, Capabili {2014, nullptr, "FinishSynchronizeParentalControlSettings"}, {2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"}, {2016, nullptr, "RequestUpdateExemptionListAsync"}, + {145601, D<&IParentalControlService::GetSelfController>, "GetSelfController"}, }; // clang-format on RegisterHandlers(functions); @@ -431,4 +432,22 @@ Result IParentalControlService::ResetConfirmedStereoVisionPermission() { R_SUCCEED(); } +Result IParentalControlService::GetSelfController(Out<SharedPointer<IParentalControlService>> out_controller) { + LOG_DEBUG(Service_PCTL, "called"); + + // Return a shared pointer to this service instance + *out_controller = SharedPointer<IParentalControlService>(this); + + R_SUCCEED(); +} + +Result IParentalControlService::GetPlayTimerRemainingTime(Out<s32> out_remaining_time) { + LOG_DEBUG(Service_PCTL, "called"); + + // For now, return maximum time remaining since play timer is stubbed + *out_remaining_time = std::numeric_limits<s32>::max(); + + R_SUCCEED(); +} + } // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/parental_control_service.h b/src/core/hle/service/pctl/parental_control_service.h index 03dbaa2e5..121e67664 100644 --- a/src/core/hle/service/pctl/parental_control_service.h +++ b/src/core/hle/service/pctl/parental_control_service.h @@ -53,6 +53,8 @@ private: Result GetStereoVisionRestriction(Out<bool> out_stereo_vision_restriction); Result SetStereoVisionRestriction(bool stereo_vision_restriction); Result ResetConfirmedStereoVisionPermission(); + Result GetSelfController(Out<SharedPointer<IParentalControlService>> out_controller); + Result GetPlayTimerRemainingTime(Out<s32> out_remaining_time); struct States { u64 current_tid{}; |