diff options
| author | Levi <L3ehunin@gmail.com> | 2021-01-10 22:09:56 -0700 |
|---|---|---|
| committer | Levi <L3ehunin@gmail.com> | 2021-01-10 22:09:56 -0700 |
| commit | 7a3c884e39fccfbb498b855080bffabc9ce2e7f1 (patch) | |
| tree | 5056f9406dec188439cb0deb87603498243a9412 /src/core/hle/service/time | |
| parent | bc69cc151192326f9b8e18bbda831f1589ba27e0 (diff) | |
| parent | 46cd71d1c773c29cce8b48e7e2b478bdf6d77085 (diff) | |
Merge remote-tracking branch 'upstream/master' into int-flags
Diffstat (limited to 'src/core/hle/service/time')
| -rw-r--r-- | src/core/hle/service/time/interface.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.cpp | 46 | ||||
| -rw-r--r-- | src/core/hle/service/time/time.h | 13 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_manager.cpp | 359 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_manager.h | 85 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_content_manager.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_content_manager.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_manager.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_service.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/time/time_zone_service.h | 7 |
10 files changed, 336 insertions, 211 deletions
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index ba8fd6152..a01d9e0ff 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp @@ -7,7 +7,7 @@ namespace Service::Time { Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* name) - : Module::Interface(std::move(module), system, name) { + : Interface(std::move(module), system, name) { // clang-format off static const FunctionInfo functions[] = { {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ee4fa4b48..abc753d5d 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -10,7 +10,8 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/scheduler.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/service/time/interface.h" #include "core/hle/service/time/time.h" #include "core/hle/service/time/time_sharedmemory.h" @@ -20,8 +21,8 @@ namespace Service::Time { class ISystemClock final : public ServiceFramework<ISystemClock> { public: - explicit ISystemClock(Clock::SystemClockCore& clock_core, Core::System& system) - : ServiceFramework("ISystemClock"), clock_core{clock_core}, system{system} { + explicit ISystemClock(Clock::SystemClockCore& clock_core_, Core::System& system_) + : ServiceFramework{system_, "ISystemClock"}, clock_core{clock_core_} { // clang-format off static const FunctionInfo functions[] = { {0, &ISystemClock::GetCurrentTime, "GetCurrentTime"}, @@ -81,13 +82,12 @@ private: } Clock::SystemClockCore& clock_core; - Core::System& system; }; class ISteadyClock final : public ServiceFramework<ISteadyClock> { public: - explicit ISteadyClock(Clock::SteadyClockCore& clock_core, Core::System& system) - : ServiceFramework("ISteadyClock"), clock_core{clock_core}, system{system} { + explicit ISteadyClock(Clock::SteadyClockCore& clock_core_, Core::System& system_) + : ServiceFramework{system_, "ISteadyClock"}, clock_core{clock_core_} { static const FunctionInfo functions[] = { {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, {2, nullptr, "GetTestOffset"}, @@ -118,14 +118,13 @@ private: } Clock::SteadyClockCore& clock_core; - Core::System& system; }; ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal( Kernel::Thread* thread, Clock::SystemClockContext user_context, Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) { - auto& time_manager{module->GetTimeManager()}; + auto& time_manager{system.GetTimeManager()}; clock_snapshot.is_automatic_correction_enabled = time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); @@ -182,7 +181,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardUserSystemClockCore(), + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardUserSystemClockCore(), system); } @@ -190,7 +189,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardNetworkSystemClockCore(), + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardNetworkSystemClockCore(), system); } @@ -198,29 +197,29 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISteadyClock>(module->GetTimeManager().GetStandardSteadyClockCore(), - system); + rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system); } void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager()); + rb.PushIpcInterface<ITimeZoneService>(system, + system.GetTimeManager().GetTimeZoneContentManager()); } void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardLocalSystemClockCore(), + rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardLocalSystemClockCore(), system); } void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()}; + auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()}; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); @@ -229,7 +228,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called"); - auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()}; + auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()}; if (!steady_clock_core.IsInitialized()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERROR_UNINITIALIZED_CLOCK); @@ -262,8 +261,8 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { Clock::SystemClockContext user_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext( - system, user_context)}; + system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system, + user_context)}; result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -271,7 +270,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) { } Clock::SystemClockContext network_context{}; if (const ResultCode result{ - module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( + system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( system, network_context)}; result.IsError()) { IPC::ResponseBuilder rb{ctx, 2}; @@ -372,16 +371,17 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder()); + rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem())); } -Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) - : ServiceFramework(name), module{std::move(module)}, system{system} {} +Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_, + const char* name) + : ServiceFramework{system_, name}, module{std::move(module_)} {} Module::Interface::~Interface() = default; void InstallInterfaces(Core::System& system) { - auto module{std::make_shared<Module>(system)}; + auto module{std::make_shared<Module>()}; std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 41f3002e9..975a8ae5b 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -16,11 +16,12 @@ namespace Service::Time { class Module final { public: - Module(Core::System& system) : time_manager{system} {} + Module() = default; class Interface : public ServiceFramework<Interface> { public: - explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name); + explicit Interface(std::shared_ptr<Module> module_, Core::System& system_, + const char* name); ~Interface() override; void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx); @@ -44,15 +45,7 @@ public: protected: std::shared_ptr<Module> module; - Core::System& system; }; - - TimeManager& GetTimeManager() { - return time_manager; - } - -private: - TimeManager time_manager; }; /// Registers all Time services with the specified service manager. diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index b4dfe45e5..858623e2b 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp @@ -22,125 +22,282 @@ static std::chrono::seconds GetSecondsSinceEpoch() { Settings::values.custom_rtc_differential; } -static s64 GetExternalTimeZoneOffset() { - // With "auto" timezone setting, we use the external system's timezone offset - if (Settings::GetTimeZoneString() == "auto") { - return Common::TimeZone::GetCurrentOffsetSeconds().count(); - } - return 0; -} - static s64 GetExternalRtcValue() { - return GetSecondsSinceEpoch().count() + GetExternalTimeZoneOffset(); -} - -TimeManager::TimeManager(Core::System& system) - : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core}, - standard_network_system_clock_core{standard_steady_clock_core}, - standard_user_system_clock_core{standard_local_system_clock_core, - standard_network_system_clock_core, system}, - ephemeral_network_system_clock_core{tick_based_steady_clock_core}, - local_system_clock_context_writer{ - std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)}, - network_system_clock_context_writer{ - std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)}, - ephemeral_network_system_clock_context_writer{ - std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()}, - time_zone_content_manager{*this, system} { - - const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())}; - SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {}); - SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds()); - SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy); - SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom()); - SetupEphemeralNetworkSystemClock(); + return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset(); } -TimeManager::~TimeManager() = default; +struct TimeManager::Impl final { + explicit Impl(Core::System& system) + : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core}, + standard_network_system_clock_core{standard_steady_clock_core}, + standard_user_system_clock_core{standard_local_system_clock_core, + standard_network_system_clock_core, system}, + ephemeral_network_system_clock_core{tick_based_steady_clock_core}, + local_system_clock_context_writer{ + std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)}, + network_system_clock_context_writer{ + std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)}, + ephemeral_network_system_clock_context_writer{ + std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()}, + time_zone_content_manager{system} { -void TimeManager::SetupTimeZoneManager(std::string location_name, - Clock::SteadyClockTimePoint time_zone_updated_time_point, - std::size_t total_location_name_count, - u128 time_zone_rule_version, - FileSys::VirtualFile& vfs_file) { - if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( - location_name, vfs_file) != RESULT_SUCCESS) { - UNREACHABLE(); - return; - } - - time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point); - time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount( - total_location_name_count); - time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(time_zone_rule_version); - time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized(); -} - -void TimeManager::SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, - Clock::TimeSpanType setup_value, - Clock::TimeSpanType internal_offset, - bool is_rtc_reset_detected) { - standard_steady_clock_core.SetClockSourceId(clock_source_id); - standard_steady_clock_core.SetSetupValue(setup_value); - standard_steady_clock_core.SetInternalOffset(internal_offset); - standard_steady_clock_core.MarkAsInitialized(); - - const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)}; - shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point); -} - -void TimeManager::SetupStandardLocalSystemClock(Core::System& system, - Clock::SystemClockContext clock_context, - s64 posix_time) { - standard_local_system_clock_core.SetUpdateCallbackInstance(local_system_clock_context_writer); - - const auto current_time_point{ - standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)}; - if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) { - standard_local_system_clock_core.SetSystemClockContext(clock_context); - } else { - if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != RESULT_SUCCESS) { + const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())}; + SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {}); + SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds()); + SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy); + SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom()); + SetupEphemeralNetworkSystemClock(); + } + + ~Impl() = default; + + Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() { + return standard_steady_clock_core; + } + + const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const { + return standard_steady_clock_core; + } + + Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() { + return standard_local_system_clock_core; + } + + const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const { + return standard_local_system_clock_core; + } + + Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() { + return standard_network_system_clock_core; + } + + const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const { + return standard_network_system_clock_core; + } + + Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() { + return standard_user_system_clock_core; + } + + const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const { + return standard_user_system_clock_core; + } + + TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() { + return time_zone_content_manager; + } + + const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const { + return time_zone_content_manager; + } + + SharedMemory& GetSharedMemory() { + return shared_memory; + } + + const SharedMemory& GetSharedMemory() const { + return shared_memory; + } + + void SetupTimeZoneManager(std::string location_name, + Clock::SteadyClockTimePoint time_zone_updated_time_point, + std::size_t total_location_name_count, u128 time_zone_rule_version, + FileSys::VirtualFile& vfs_file) { + if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( + location_name, vfs_file) != RESULT_SUCCESS) { UNREACHABLE(); return; } + + time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point); + time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount( + total_location_name_count); + time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion( + time_zone_rule_version); + time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized(); } - standard_local_system_clock_core.MarkAsInitialized(); -} + static s64 GetExternalTimeZoneOffset() { + // With "auto" timezone setting, we use the external system's timezone offset + if (Settings::GetTimeZoneString() == "auto") { + return Common::TimeZone::GetCurrentOffsetSeconds().count(); + } + return 0; + } -void TimeManager::SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context, - Clock::TimeSpanType sufficient_accuracy) { - standard_network_system_clock_core.SetUpdateCallbackInstance( - network_system_clock_context_writer); + void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, + Clock::TimeSpanType setup_value, + Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected) { + standard_steady_clock_core.SetClockSourceId(clock_source_id); + standard_steady_clock_core.SetSetupValue(setup_value); + standard_steady_clock_core.SetInternalOffset(internal_offset); + standard_steady_clock_core.MarkAsInitialized(); - if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != RESULT_SUCCESS) { - UNREACHABLE(); - return; + const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)}; + shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point); } - standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy( - sufficient_accuracy); - standard_network_system_clock_core.MarkAsInitialized(); -} + void SetupStandardLocalSystemClock(Core::System& system, + Clock::SystemClockContext clock_context, s64 posix_time) { + standard_local_system_clock_core.SetUpdateCallbackInstance( + local_system_clock_context_writer); + + const auto current_time_point{ + standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)}; + if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) { + standard_local_system_clock_core.SetSystemClockContext(clock_context); + } else { + if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != + RESULT_SUCCESS) { + UNREACHABLE(); + return; + } + } + + standard_local_system_clock_core.MarkAsInitialized(); + } + + void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context, + Clock::TimeSpanType sufficient_accuracy) { + standard_network_system_clock_core.SetUpdateCallbackInstance( + network_system_clock_context_writer); -void TimeManager::SetupStandardUserSystemClock( - Core::System& system, bool is_automatic_correction_enabled, - Clock::SteadyClockTimePoint steady_clock_time_point) { - if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( - system, is_automatic_correction_enabled) != RESULT_SUCCESS) { - UNREACHABLE(); - return; + if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != + RESULT_SUCCESS) { + UNREACHABLE(); + return; + } + + standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy( + sufficient_accuracy); + standard_network_system_clock_core.MarkAsInitialized(); } - standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point); - standard_user_system_clock_core.MarkAsInitialized(); - shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled); + void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled, + Clock::SteadyClockTimePoint steady_clock_time_point) { + if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( + system, is_automatic_correction_enabled) != RESULT_SUCCESS) { + UNREACHABLE(); + return; + } + + standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point); + standard_user_system_clock_core.MarkAsInitialized(); + shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled); + } + + void SetupEphemeralNetworkSystemClock() { + ephemeral_network_system_clock_core.SetUpdateCallbackInstance( + ephemeral_network_system_clock_context_writer); + ephemeral_network_system_clock_core.MarkAsInitialized(); + } + + void UpdateLocalSystemClockTime(Core::System& system, s64 posix_time) { + const auto timespan{Service::Time::Clock::TimeSpanType::FromSeconds(posix_time)}; + if (GetStandardLocalSystemClockCore() + .SetCurrentTime(system, timespan.ToSeconds()) + .IsError()) { + UNREACHABLE(); + return; + } + } + + SharedMemory shared_memory; + + Clock::StandardSteadyClockCore standard_steady_clock_core; + Clock::TickBasedSteadyClockCore tick_based_steady_clock_core; + Clock::StandardLocalSystemClockCore standard_local_system_clock_core; + Clock::StandardNetworkSystemClockCore standard_network_system_clock_core; + Clock::StandardUserSystemClockCore standard_user_system_clock_core; + Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core; + + std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer; + std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer; + std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter> + ephemeral_network_system_clock_context_writer; + + TimeZone::TimeZoneContentManager time_zone_content_manager; +}; + +TimeManager::TimeManager(Core::System& system) : system{system} {} + +TimeManager::~TimeManager() = default; + +void TimeManager::Initialize() { + impl = std::make_unique<Impl>(system); + + // Time zones can only be initialized after impl is valid + impl->time_zone_content_manager.Initialize(*this); +} + +Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() { + return impl->standard_steady_clock_core; +} + +const Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() const { + return impl->standard_steady_clock_core; +} + +Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() { + return impl->standard_local_system_clock_core; +} + +const Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() const { + return impl->standard_local_system_clock_core; +} + +Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore() { + return impl->standard_network_system_clock_core; } -void TimeManager::SetupEphemeralNetworkSystemClock() { - ephemeral_network_system_clock_core.SetUpdateCallbackInstance( - ephemeral_network_system_clock_context_writer); - ephemeral_network_system_clock_core.MarkAsInitialized(); +const Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore() + const { + return impl->standard_network_system_clock_core; +} + +Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() { + return impl->standard_user_system_clock_core; +} + +const Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() const { + return impl->standard_user_system_clock_core; +} + +TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() { + return impl->time_zone_content_manager; +} + +const TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() const { + return impl->time_zone_content_manager; +} + +SharedMemory& TimeManager::GetSharedMemory() { + return impl->shared_memory; +} + +const SharedMemory& TimeManager::GetSharedMemory() const { + return impl->shared_memory; +} + +void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) { + impl->UpdateLocalSystemClockTime(system, posix_time); +} + +void TimeManager::SetupTimeZoneManager(std::string location_name, + Clock::SteadyClockTimePoint time_zone_updated_time_point, + std::size_t total_location_name_count, + u128 time_zone_rule_version, + FileSys::VirtualFile& vfs_file) { + impl->SetupTimeZoneManager(location_name, time_zone_updated_time_point, + total_location_name_count, time_zone_rule_version, vfs_file); +} + +/*static*/ s64 TimeManager::GetExternalTimeZoneOffset() { + // With "auto" timezone setting, we use the external system's timezone offset + if (Settings::GetTimeZoneString() == "auto") { + return Common::TimeZone::GetCurrentOffsetSeconds().count(); + } + return 0; } } // namespace Service::Time diff --git a/src/core/hle/service/time/time_manager.h b/src/core/hle/service/time/time_manager.h index 8e65f0d22..993c7c288 100644 --- a/src/core/hle/service/time/time_manager.h +++ b/src/core/hle/service/time/time_manager.h @@ -5,6 +5,7 @@ #pragma once #include "common/common_types.h" +#include "common/time_zone.h" #include "core/file_sys/vfs_types.h" #include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/ephemeral_network_system_clock_core.h" @@ -32,86 +33,46 @@ public: explicit TimeManager(Core::System& system); ~TimeManager(); - Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() { - return standard_steady_clock_core; - } + void Initialize(); - const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const { - return standard_steady_clock_core; - } + Clock::StandardSteadyClockCore& GetStandardSteadyClockCore(); - Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() { - return standard_local_system_clock_core; - } + const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const; - const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const { - return standard_local_system_clock_core; - } + Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore(); - Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() { - return standard_network_system_clock_core; - } + const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const; - const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const { - return standard_network_system_clock_core; - } + Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore(); - Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() { - return standard_user_system_clock_core; - } + const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const; - const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const { - return standard_user_system_clock_core; - } + Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore(); - TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() { - return time_zone_content_manager; - } + const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const; - const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const { - return time_zone_content_manager; - } + TimeZone::TimeZoneContentManager& GetTimeZoneContentManager(); - SharedMemory& GetSharedMemory() { - return shared_memory; - } + const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const; - const SharedMemory& GetSharedMemory() const { - return shared_memory; - } + void UpdateLocalSystemClockTime(s64 posix_time); + + SharedMemory& GetSharedMemory(); + + const SharedMemory& GetSharedMemory() const; void SetupTimeZoneManager(std::string location_name, Clock::SteadyClockTimePoint time_zone_updated_time_point, std::size_t total_location_name_count, u128 time_zone_rule_version, FileSys::VirtualFile& vfs_file); + static s64 GetExternalTimeZoneOffset(); + private: - void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, - Clock::TimeSpanType setup_value, - Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected); - void SetupStandardLocalSystemClock(Core::System& system, - Clock::SystemClockContext clock_context, s64 posix_time); - void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context, - Clock::TimeSpanType sufficient_accuracy); - void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled, - Clock::SteadyClockTimePoint steady_clock_time_point); - void SetupEphemeralNetworkSystemClock(); - - SharedMemory shared_memory; - - Clock::StandardSteadyClockCore standard_steady_clock_core; - Clock::TickBasedSteadyClockCore tick_based_steady_clock_core; - Clock::StandardLocalSystemClockCore standard_local_system_clock_core; - Clock::StandardNetworkSystemClockCore standard_network_system_clock_core; - Clock::StandardUserSystemClockCore standard_user_system_clock_core; - Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core; - - std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer; - std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer; - std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter> - ephemeral_network_system_clock_context_writer; - - TimeZone::TimeZoneContentManager time_zone_content_manager; + Core::System& system; + + struct Impl; + std::unique_ptr<Impl> impl; }; } // namespace Service::Time diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp index 320672add..4177d0a41 100644 --- a/src/core/hle/service/time/time_zone_content_manager.cpp +++ b/src/core/hle/service/time/time_zone_content_manager.cpp @@ -68,9 +68,10 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) { return location_name_cache; } -TimeZoneContentManager::TimeZoneContentManager(TimeManager& time_manager, Core::System& system) - : system{system}, location_name_cache{BuildLocationNameCache(system)} { +TimeZoneContentManager::TimeZoneContentManager(Core::System& system) + : system{system}, location_name_cache{BuildLocationNameCache(system)} {} +void TimeZoneContentManager::Initialize(TimeManager& time_manager) { std::string location_name; const auto timezone_setting = Settings::GetTimeZoneString(); if (timezone_setting == "auto" || timezone_setting == "default") { diff --git a/src/core/hle/service/time/time_zone_content_manager.h b/src/core/hle/service/time/time_zone_content_manager.h index 4f302c3b9..52dd1a020 100644 --- a/src/core/hle/service/time/time_zone_content_manager.h +++ b/src/core/hle/service/time/time_zone_content_manager.h @@ -21,7 +21,9 @@ namespace Service::Time::TimeZone { class TimeZoneContentManager final { public: - TimeZoneContentManager(TimeManager& time_manager, Core::System& system); + explicit TimeZoneContentManager(Core::System& system); + + void Initialize(TimeManager& time_manager); TimeZoneManager& GetTimeZoneManager() { return time_zone_manager; diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 69152d0ac..bdf0439f2 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp @@ -820,7 +820,10 @@ static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, Calend const ResultCode result{ ToCalendarTimeInternal(rules, time, calendar_time, calendar.additiona_info)}; calendar.time.year = static_cast<s16>(calendar_time.year); - calendar.time.month = calendar_time.month + 1; // Internal impl. uses 0-indexed month + + // Internal impl. uses 0-indexed month + calendar.time.month = static_cast<s8>(calendar_time.month + 1); + calendar.time.day = calendar_time.day; calendar.time.hour = calendar_time.hour; calendar.time.minute = calendar_time.minute; @@ -872,13 +875,15 @@ ResultCode TimeZoneManager::ToPosixTime(const TimeZoneRule& rules, const CalendarTime& calendar_time, s64& posix_time) const { posix_time = 0; - CalendarTimeInternal internal_time{}; - internal_time.year = calendar_time.year; - internal_time.month = calendar_time.month - 1; // Internal impl. uses 0-indexed month - internal_time.day = calendar_time.day; - internal_time.hour = calendar_time.hour; - internal_time.minute = calendar_time.minute; - internal_time.second = calendar_time.second; + CalendarTimeInternal internal_time{ + .year = calendar_time.year, + // Internal impl. uses 0-indexed month + .month = static_cast<s8>(calendar_time.month - 1), + .day = calendar_time.day, + .hour = calendar_time.hour, + .minute = calendar_time.minute, + .second = calendar_time.second, + }; s32 hour{internal_time.hour}; s32 minute{internal_time.minute}; diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp index ff3a10b3e..25cecbc83 100644 --- a/src/core/hle/service/time/time_zone_service.cpp +++ b/src/core/hle/service/time/time_zone_service.cpp @@ -10,8 +10,9 @@ namespace Service::Time { -ITimeZoneService ::ITimeZoneService(TimeZone::TimeZoneContentManager& time_zone_content_manager) - : ServiceFramework("ITimeZoneService"), time_zone_content_manager{time_zone_content_manager} { +ITimeZoneService ::ITimeZoneService(Core::System& system_, + TimeZone::TimeZoneContentManager& time_zone_manager_) + : ServiceFramework{system_, "ITimeZoneService"}, time_zone_content_manager{time_zone_manager_} { static const FunctionInfo functions[] = { {0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"}, {1, nullptr, "SetDeviceLocationName"}, diff --git a/src/core/hle/service/time/time_zone_service.h b/src/core/hle/service/time/time_zone_service.h index cb495748b..2c9b97603 100644 --- a/src/core/hle/service/time/time_zone_service.h +++ b/src/core/hle/service/time/time_zone_service.h @@ -6,6 +6,10 @@ #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Service::Time { namespace TimeZone { @@ -14,7 +18,8 @@ class TimeZoneContentManager; class ITimeZoneService final : public ServiceFramework<ITimeZoneService> { public: - explicit ITimeZoneService(TimeZone::TimeZoneContentManager& time_zone_manager); + explicit ITimeZoneService(Core::System& system_, + TimeZone::TimeZoneContentManager& time_zone_manager_); private: void GetDeviceLocationName(Kernel::HLERequestContext& ctx); |
