service: time: Update current time with changes to RTC setting.
- This can be used to advance time, e.g. for Pokemon Sword/Shield pokejobs.
This commit is contained in:
		@@ -40,6 +40,7 @@
 | 
			
		||||
#include "core/hle/service/lm/manager.h"
 | 
			
		||||
#include "core/hle/service/service.h"
 | 
			
		||||
#include "core/hle/service/sm/sm.h"
 | 
			
		||||
#include "core/hle/service/time/time_manager.h"
 | 
			
		||||
#include "core/loader/loader.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
#include "core/memory/cheat_engine.h"
 | 
			
		||||
@@ -121,7 +122,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
 | 
			
		||||
struct System::Impl {
 | 
			
		||||
    explicit Impl(System& system)
 | 
			
		||||
        : kernel{system}, fs_controller{system}, memory{system},
 | 
			
		||||
          cpu_manager{system}, reporter{system}, applet_manager{system} {}
 | 
			
		||||
          cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
 | 
			
		||||
 | 
			
		||||
    ResultStatus Run() {
 | 
			
		||||
        status = ResultStatus::Success;
 | 
			
		||||
@@ -189,6 +190,9 @@ struct System::Impl {
 | 
			
		||||
            return ResultStatus::ErrorVideoCore;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Initialize time manager, which must happen after kernel is created
 | 
			
		||||
        time_manager.Initialize();
 | 
			
		||||
 | 
			
		||||
        is_powered_on = true;
 | 
			
		||||
        exit_lock = false;
 | 
			
		||||
 | 
			
		||||
@@ -387,6 +391,7 @@ struct System::Impl {
 | 
			
		||||
    /// Service State
 | 
			
		||||
    Service::Glue::ARPManager arp_manager;
 | 
			
		||||
    Service::LM::Manager lm_manager{reporter};
 | 
			
		||||
    Service::Time::TimeManager time_manager;
 | 
			
		||||
 | 
			
		||||
    /// Service manager
 | 
			
		||||
    std::shared_ptr<Service::SM::ServiceManager> service_manager;
 | 
			
		||||
@@ -717,6 +722,14 @@ const Service::LM::Manager& System::GetLogManager() const {
 | 
			
		||||
    return impl->lm_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Service::Time::TimeManager& System::GetTimeManager() {
 | 
			
		||||
    return impl->time_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Service::Time::TimeManager& System::GetTimeManager() const {
 | 
			
		||||
    return impl->time_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void System::SetExitLock(bool locked) {
 | 
			
		||||
    impl->exit_lock = locked;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,10 @@ namespace SM {
 | 
			
		||||
class ServiceManager;
 | 
			
		||||
} // namespace SM
 | 
			
		||||
 | 
			
		||||
namespace Time {
 | 
			
		||||
class TimeManager;
 | 
			
		||||
} // namespace Time
 | 
			
		||||
 | 
			
		||||
} // namespace Service
 | 
			
		||||
 | 
			
		||||
namespace Tegra {
 | 
			
		||||
@@ -361,6 +365,10 @@ public:
 | 
			
		||||
 | 
			
		||||
    const Service::LM::Manager& GetLogManager() const;
 | 
			
		||||
 | 
			
		||||
    Service::Time::TimeManager& GetTimeManager();
 | 
			
		||||
 | 
			
		||||
    const Service::Time::TimeManager& GetTimeManager() const;
 | 
			
		||||
 | 
			
		||||
    void SetExitLock(bool locked);
 | 
			
		||||
 | 
			
		||||
    bool GetExitLock() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
#include "core/hle/ipc_helpers.h"
 | 
			
		||||
#include "core/hle/kernel/client_port.h"
 | 
			
		||||
#include "core/hle/kernel/client_session.h"
 | 
			
		||||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/scheduler.h"
 | 
			
		||||
#include "core/hle/service/time/interface.h"
 | 
			
		||||
#include "core/hle/service/time/time.h"
 | 
			
		||||
@@ -125,7 +126,7 @@ 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 +183,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 +191,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 +199,28 @@ 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.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 +229,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 +262,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 +271,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,7 +372,7 @@ 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)
 | 
			
		||||
@@ -381,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& syste
 | 
			
		||||
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());
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace Service::Time {
 | 
			
		||||
 | 
			
		||||
class Module final {
 | 
			
		||||
public:
 | 
			
		||||
    Module(Core::System& system) : time_manager{system} {}
 | 
			
		||||
    Module() = default;
 | 
			
		||||
 | 
			
		||||
    class Interface : public ServiceFramework<Interface> {
 | 
			
		||||
    public:
 | 
			
		||||
@@ -46,13 +46,6 @@ public:
 | 
			
		||||
        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.
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,277 @@ static std::chrono::seconds GetSecondsSinceEpoch() {
 | 
			
		||||
           Settings::values.custom_rtc_differential;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static s64 GetExternalTimeZoneOffset() {
 | 
			
		||||
static s64 GetExternalRtcValue() {
 | 
			
		||||
    return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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} {
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 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 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);
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
@@ -30,117 +300,4 @@ static s64 GetExternalTimeZoneOffset() {
 | 
			
		||||
    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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TimeManager::~TimeManager() = default;
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    standard_local_system_clock_core.MarkAsInitialized();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TimeManager::SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
 | 
			
		||||
                                                  Clock::TimeSpanType sufficient_accuracy) {
 | 
			
		||||
    standard_network_system_clock_core.SetUpdateCallbackInstance(
 | 
			
		||||
        network_system_clock_context_writer);
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
 | 
			
		||||
    standard_user_system_clock_core.MarkAsInitialized();
 | 
			
		||||
    shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TimeManager::SetupEphemeralNetworkSystemClock() {
 | 
			
		||||
    ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
 | 
			
		||||
        ephemeral_network_system_clock_context_writer);
 | 
			
		||||
    ephemeral_network_system_clock_core.MarkAsInitialized();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Time
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    struct Impl;
 | 
			
		||||
    std::unique_ptr<Impl> impl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Service::Time
 | 
			
		||||
 
 | 
			
		||||
@@ -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") {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,9 @@ namespace Service::Time::TimeZone {
 | 
			
		||||
 | 
			
		||||
class TimeZoneContentManager final {
 | 
			
		||||
public:
 | 
			
		||||
    TimeZoneContentManager(TimeManager& time_manager, Core::System& system);
 | 
			
		||||
    TimeZoneContentManager(Core::System& system);
 | 
			
		||||
 | 
			
		||||
    void Initialize(TimeManager& time_manager);
 | 
			
		||||
 | 
			
		||||
    TimeZoneManager& GetTimeZoneManager() {
 | 
			
		||||
        return time_zone_manager;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/file_util.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/hle/service/time/time.h"
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "ui_configure_system.h"
 | 
			
		||||
#include "yuzu/configuration/configuration_shared.h"
 | 
			
		||||
@@ -104,6 +105,22 @@ void ConfigureSystem::SetConfiguration() {
 | 
			
		||||
void ConfigureSystem::ReadSystemSettings() {}
 | 
			
		||||
 | 
			
		||||
void ConfigureSystem::ApplyConfiguration() {
 | 
			
		||||
    // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast
 | 
			
		||||
    // forwared
 | 
			
		||||
    if (Settings::values.custom_rtc.UsingGlobal()) {
 | 
			
		||||
        if (ui->custom_rtc_checkbox->isChecked()) {
 | 
			
		||||
            Settings::values.custom_rtc.SetValue(
 | 
			
		||||
                std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
 | 
			
		||||
            if (Core::System::GetInstance().IsPoweredOn()) {
 | 
			
		||||
                const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
 | 
			
		||||
                                     Service::Time::TimeManager::GetExternalTimeZoneOffset()};
 | 
			
		||||
                Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Settings::values.custom_rtc.SetValue(std::nullopt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!enabled) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@@ -131,15 +148,6 @@ void ConfigureSystem::ApplyConfiguration() {
 | 
			
		||||
                Settings::values.rng_seed.SetValue(std::nullopt);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Settings::values.custom_rtc.UsingGlobal()) {
 | 
			
		||||
            if (ui->custom_rtc_checkbox->isChecked()) {
 | 
			
		||||
                Settings::values.custom_rtc.SetValue(
 | 
			
		||||
                    std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
 | 
			
		||||
            } else {
 | 
			
		||||
                Settings::values.custom_rtc.SetValue(std::nullopt);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
 | 
			
		||||
                                                 ui->combo_language);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user