mirror of
https://github.com/ong19th/Citron.git
synced 2025-12-12 19:37:06 +00:00
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.
This commit is contained in:
parent
1c9e17496b
commit
c5e480e55d
16 changed files with 206 additions and 115 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -472,6 +472,10 @@ public:
|
|||
const KPageTable& GetBasePageTable() const {
|
||||
return m_page_table;
|
||||
}
|
||||
|
||||
size_t GetReservedRegionExtraSize() const {
|
||||
return m_page_table.GetReservedRegionExtraSize();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue