From 239e2d0f9e89c529b267f2369d74daf5909d213e Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 28 Jan 2024 20:16:36 +0100 Subject: [PATCH] early-access version 4095 --- README.md | 2 +- externals/tz/tz/tz.cpp | 4 +- externals/tz/tz/tz.h | 4 +- .../yuzu/yuzu_emu/model/DriverViewModel.kt | 5 +- .../yuzu/yuzu_emu/utils/GpuDriverHelper.kt | 7 + src/android/app/src/main/jni/CMakeLists.txt | 2 +- src/android/app/src/main/jni/native.cpp | 34 ++ src/audio_core/CMakeLists.txt | 4 +- src/common/CMakeLists.txt | 4 +- src/core/CMakeLists.txt | 4 +- src/core/core.cpp | 14 +- src/core/hle/kernel/k_thread.cpp | 3 +- src/core/hle/service/audio/audctl.cpp | 84 ++- src/core/hle/service/audio/audctl.h | 20 +- src/core/hle/service/caps/caps_manager.cpp | 12 +- src/core/hle/service/cmif_serialization.h | 123 ++++- src/core/hle/service/cmif_types.h | 213 ++++---- .../hle/service/glue/time/alarm_worker.cpp | 3 +- src/core/hle/service/glue/time/alarm_worker.h | 4 +- .../glue/time/file_timestamp_worker.cpp | 4 +- src/core/hle/service/glue/time/manager.cpp | 40 +- src/core/hle/service/glue/time/static.cpp | 400 ++++---------- src/core/hle/service/glue/time/static.h | 76 +-- src/core/hle/service/glue/time/time_zone.cpp | 347 ++++-------- src/core/hle/service/glue/time/time_zone.h | 67 ++- .../service/glue/time/time_zone_binary.cpp | 11 +- .../hle/service/glue/time/time_zone_binary.h | 2 +- src/core/hle/service/glue/time/worker.cpp | 42 +- src/core/hle/service/glue/time/worker.h | 8 +- src/core/hle/service/nfc/common/device.cpp | 8 +- .../hle/service/nfc/common/device_manager.cpp | 8 +- src/core/hle/service/psc/time/common.h | 135 ++++- .../service/psc/time/power_state_service.cpp | 28 +- .../service/psc/time/power_state_service.h | 7 +- .../hle/service/psc/time/service_manager.cpp | 444 +++++---------- .../hle/service/psc/time/service_manager.h | 60 +-- src/core/hle/service/psc/time/static.cpp | 507 ++++++------------ src/core/hle/service/psc/time/static.h | 65 +-- .../hle/service/psc/time/steady_clock.cpp | 133 ++--- src/core/hle/service/psc/time/steady_clock.h | 21 +- .../hle/service/psc/time/system_clock.cpp | 92 +--- src/core/hle/service/psc/time/system_clock.h | 13 +- src/core/hle/service/psc/time/time_zone.cpp | 18 +- src/core/hle/service/psc/time/time_zone.h | 15 +- .../service/psc/time/time_zone_service.cpp | 334 ++++-------- .../hle/service/psc/time/time_zone_service.h | 57 +- .../set/setting_formats/system_settings.cpp | 12 + .../set/setting_formats/system_settings.h | 12 +- src/core/hle/service/set/settings_types.h | 15 + .../service/set/system_settings_server.cpp | 246 +++++++-- .../hle/service/set/system_settings_server.h | 20 +- src/dedicated_room/CMakeLists.txt | 4 +- src/hid_core/resource_manager.cpp | 2 +- .../resources/hid_firmware_settings.cpp | 3 +- src/video_core/CMakeLists.txt | 4 +- src/yuzu/CMakeLists.txt | 4 +- src/yuzu_cmd/CMakeLists.txt | 4 +- 57 files changed, 1658 insertions(+), 2156 deletions(-) diff --git a/README.md b/README.md index 16e676b17..77958f08a 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4094. +This is the source code for early-access 4095. ## Legal Notice diff --git a/externals/tz/tz/tz.cpp b/externals/tz/tz/tz.cpp index 0c8b68217..04fa6cc8a 100755 --- a/externals/tz/tz/tz.cpp +++ b/externals/tz/tz/tz.cpp @@ -1625,11 +1625,11 @@ s32 ParseTimeZoneBinary(Rule& out_rule, std::span binary) { return 0; } -bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep) { +bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep) { return localsub(sp, timep, 0, tmp) == nullptr; } -u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp) { +u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp) { return time1(out_time, tmp, localsub, sp, 0); } diff --git a/externals/tz/tz/tz.h b/externals/tz/tz/tz.h index 38605cfb1..dae4459bc 100755 --- a/externals/tz/tz/tz.h +++ b/externals/tz/tz/tz.h @@ -75,7 +75,7 @@ static_assert(sizeof(CalendarTimeInternal) == 0x3C, "CalendarTimeInternal has th s32 ParseTimeZoneBinary(Rule& out_rule, std::span binary); -bool localtime_rz(CalendarTimeInternal* tmp, Rule* sp, time_t* timep); -u32 mktime_tzname(time_t* out_time, Rule* sp, CalendarTimeInternal* tmp); +bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep); +u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp); } // namespace Tz diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt index 5ed754c96..a49c887a1 100755 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/DriverViewModel.kt @@ -66,10 +66,13 @@ class DriverViewModel : ViewModel() { fun updateDriverList() { val selectedDriver = GpuDriverHelper.customDriverSettingData + val systemDriverData = GpuDriverHelper.getSystemDriverInfo() val newDriverList = mutableListOf( Driver( selectedDriver == GpuDriverMetadata(), - YuzuApplication.appContext.getString(R.string.system_gpu_driver) + YuzuApplication.appContext.getString(R.string.system_gpu_driver), + systemDriverData?.get(0) ?: "", + systemDriverData?.get(1) ?: "" ) ) driverData.forEach { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt index 81212cbee..a72dea8f1 100755 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.kt @@ -3,8 +3,10 @@ package org.yuzu.yuzu_emu.utils +import android.graphics.SurfaceTexture import android.net.Uri import android.os.Build +import android.view.Surface import java.io.File import java.io.IOException import org.yuzu.yuzu_emu.NativeLibrary @@ -195,6 +197,11 @@ object GpuDriverHelper { external fun supportsCustomDriverLoading(): Boolean + external fun getSystemDriverInfo( + surface: Surface = Surface(SurfaceTexture(true)), + hookLibPath: String = GpuDriverHelper.hookLibPath!! + ): Array? + // Parse the custom driver metadata to retrieve the name. val installedCustomDriverData: GpuDriverMetadata get() = GpuDriverMetadata(File(driverInstallationPath + META_JSON_FILENAME)) diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index 2acc93da8..abc6055ab 100755 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -22,7 +22,7 @@ add_library(yuzu-android SHARED set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) -target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common) +target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common Vulkan::Headers) target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log) if (ARCHITECTURE_arm64) target_link_libraries(yuzu-android PRIVATE adrenotools) diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 36d83c1a8..4b433b67b 100755 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -61,6 +61,9 @@ #include "jni/id_cache.h" #include "jni/native.h" #include "video_core/renderer_base.h" +#include "video_core/renderer_vulkan/renderer_vulkan.h" +#include "video_core/vulkan_common/vulkan_instance.h" +#include "video_core/vulkan_common/vulkan_surface.h" #define jconst [[maybe_unused]] const auto #define jauto [[maybe_unused]] auto @@ -554,6 +557,37 @@ jboolean JNICALL Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_supportsCustomDri #endif } +jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo( + JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) { + const char* file_redirect_dir_{}; + int featureFlags{}; + std::string hook_lib_dir = GetJString(env, j_hook_lib_dir); + auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(), + nullptr, nullptr, file_redirect_dir_, nullptr); + auto driver_library = std::make_shared(handle); + InputCommon::InputSubsystem input_subsystem; + auto m_window = std::make_unique( + &input_subsystem, ANativeWindow_fromSurface(env, j_surf), driver_library); + + Vulkan::vk::InstanceDispatch dld; + Vulkan::vk::Instance vk_instance = Vulkan::CreateInstance( + *driver_library, dld, VK_API_VERSION_1_1, Core::Frontend::WindowSystemType::Android); + + auto surface = Vulkan::CreateSurface(vk_instance, m_window->GetWindowInfo()); + + auto device = Vulkan::CreateDevice(vk_instance, dld, *surface); + + auto driver_version = device.GetDriverVersion(); + auto version_string = + fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version), + VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version)); + + jobjectArray j_driver_info = + env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string)); + env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName())); + return j_driver_info; +} + jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadKeys(JNIEnv* env, jclass clazz) { Core::Crypto::KeyManager::Instance().ReloadKeys(); return static_cast(Core::Crypto::KeyManager::Instance().AreKeysLoaded()); diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 437a0f47a..ed51d6e30 100755 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -210,8 +210,6 @@ add_library(audio_core STATIC sink/sink_stream.h ) -create_target_directory_groups(audio_core) - if (MSVC) target_compile_options(audio_core PRIVATE /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data @@ -267,3 +265,5 @@ endif() if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(audio_core PRIVATE precompiled_headers.h) endif() + +create_target_directory_groups(audio_core) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index b008fbe6b..29789d499 100755 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -245,8 +245,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") ) endif() -create_target_directory_groups(common) - target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile stb::headers Threads::Threads) target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle) @@ -258,3 +256,5 @@ endif() if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(common PRIVATE precompiled_headers.h) endif() + +create_target_directory_groups(common) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 50fed69c0..b12851dcf 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -979,8 +979,6 @@ else() ) endif() -create_target_directory_groups(core) - target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb tz) target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API) if (MINGW) @@ -1058,3 +1056,5 @@ endif() if (YUZU_ENABLE_LTO) set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) endif() + +create_target_directory_groups(core) diff --git a/src/core/core.cpp b/src/core/core.cpp index f56d10e60..104c004ef 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -201,22 +201,22 @@ struct System::Impl { system.ServiceManager().GetService("time:s", true); std::shared_ptr user_clock; - static_service_a->GetStandardUserSystemClock(user_clock); + static_service_a->GetStandardUserSystemClock(&user_clock); std::shared_ptr local_clock; - static_service_a->GetStandardLocalSystemClock(local_clock); + static_service_a->GetStandardLocalSystemClock(&local_clock); std::shared_ptr network_clock; - static_service_s->GetStandardNetworkSystemClock(network_clock); + static_service_s->GetStandardNetworkSystemClock(&network_clock); std::shared_ptr timezone_service; - static_service_a->GetTimeZoneService(timezone_service); + static_service_a->GetTimeZoneService(&timezone_service); Service::PSC::Time::LocationName name{}; auto new_name = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); - std::memcpy(name.name.data(), new_name.data(), std::min(name.name.size(), new_name.size())); + std::memcpy(name.data(), new_name.data(), std::min(name.size(), new_name.size())); - timezone_service->SetDeviceLocation(name); + timezone_service->SetDeviceLocationName(name); u64 time_offset = 0; if (Settings::values.custom_rtc_enabled) { @@ -234,7 +234,7 @@ struct System::Impl { local_clock->SetCurrentTime(new_time); - network_clock->GetSystemClockContext(context); + network_clock->GetSystemClockContext(&context); settings_service->SetNetworkSystemClockContext(context); network_clock->SetCurrentTime(new_time); } diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index c1baed917..e650a8157 100755 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -543,7 +543,8 @@ void KThread::Unpin() { ASSERT(m_parent != nullptr); // Resume any threads that began waiting on us while we were pinned. - for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); ++it) { + for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); + it = m_pinned_waiter_list.erase(it)) { it->EndWait(ResultSuccess); } } diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp index 1770fc840..ea8e6ca63 100755 --- a/src/core/hle/service/audio/audctl.cpp +++ b/src/core/hle/service/audio/audctl.cpp @@ -4,6 +4,8 @@ #include "common/logging/log.h" #include "core/hle/service/audio/audctl.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/set/system_settings_server.h" +#include "core/hle/service/sm/sm.h" namespace Service::Audio { @@ -19,15 +21,15 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { {6, nullptr, "IsTargetConnected"}, {7, nullptr, "SetDefaultTarget"}, {8, nullptr, "GetDefaultTarget"}, - {9, nullptr, "GetAudioOutputMode"}, - {10, nullptr, "SetAudioOutputMode"}, + {9, &AudCtl::GetAudioOutputMode, "GetAudioOutputMode"}, + {10, &AudCtl::SetAudioOutputMode, "SetAudioOutputMode"}, {11, nullptr, "SetForceMutePolicy"}, {12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"}, {13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"}, - {14, nullptr, "SetOutputModeSetting"}, + {14, &AudCtl::SetOutputModeSetting, "SetOutputModeSetting"}, {15, nullptr, "SetOutputTarget"}, {16, nullptr, "SetInputTargetForceEnabled"}, - {17, nullptr, "SetHeadphoneOutputLevelMode"}, + {17, &AudCtl::SetHeadphoneOutputLevelMode, "SetHeadphoneOutputLevelMode"}, {18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"}, {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, @@ -40,7 +42,7 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { {27, nullptr, "SetVolumeMappingTableForDev"}, {28, nullptr, "GetAudioOutputChannelCountForPlayReport"}, {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"}, - {30, nullptr, "SetSpeakerAutoMuteEnabled"}, + {30, &AudCtl::SetSpeakerAutoMuteEnabled, "SetSpeakerAutoMuteEnabled"}, {31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"}, {32, nullptr, "GetActiveOutputTarget"}, {33, nullptr, "GetTargetDeviceInfo"}, @@ -68,6 +70,9 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} { // clang-format on RegisterHandlers(functions); + + m_set_sys = + system.ServiceManager().GetService("set:sys", true); } AudCtl::~AudCtl() = default; @@ -96,6 +101,33 @@ void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) { rb.Push(target_max_volume); } +void AudCtl::GetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum()}; + + Set::AudioOutputMode output_mode{}; + const auto result = m_set_sys->GetAudioOutputMode(output_mode, target); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.PushEnum(output_mode); +} + +void AudCtl::SetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum()}; + const auto output_mode{rp.PopEnum()}; + + const auto result = m_set_sys->SetAudioOutputMode(target, output_mode); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { LOG_WARNING(Audio, "(STUBBED) called"); @@ -106,13 +138,31 @@ void AudCtl::GetForceMutePolicy(HLERequestContext& ctx) { void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto value = rp.Pop(); + const auto target{rp.PopEnum()}; - LOG_WARNING(Audio, "(STUBBED) called, value={}", value); + LOG_WARNING(Audio, "(STUBBED) called, target={}", target); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.PushEnum(AudioOutputMode::PcmAuto); + rb.PushEnum(Set::AudioOutputMode::ch_7_1); +} + +void AudCtl::SetOutputModeSetting(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum()}; + const auto output_mode{rp.PopEnum()}; + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void AudCtl::SetHeadphoneOutputLevelMode(HLERequestContext& ctx) { + LOG_WARNING(Audio, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); } void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { @@ -123,14 +173,28 @@ void AudCtl::GetHeadphoneOutputLevelMode(HLERequestContext& ctx) { rb.PushEnum(HeadphoneOutputLevelMode::Normal); } +void AudCtl::SetSpeakerAutoMuteEnabled(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto is_speaker_auto_mute_enabled{rp.Pop()}; + + LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", + is_speaker_auto_mute_enabled); + + const auto result = m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void AudCtl::IsSpeakerAutoMuteEnabled(HLERequestContext& ctx) { - const bool is_speaker_auto_mute_enabled = false; + bool is_speaker_auto_mute_enabled{}; + const auto result = m_set_sys->GetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled); LOG_WARNING(Audio, "(STUBBED) called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled); IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); + rb.Push(result); rb.Push(is_speaker_auto_mute_enabled); } diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h index e3cc91f55..681b58f81 100755 --- a/src/core/hle/service/audio/audctl.h +++ b/src/core/hle/service/audio/audctl.h @@ -9,6 +9,10 @@ namespace Core { class System; } +namespace Service::Set { +class ISystemSettingsServer; +} + namespace Service::Audio { class AudCtl final : public ServiceFramework { @@ -17,14 +21,6 @@ public: ~AudCtl() override; private: - enum class AudioOutputMode { - Invalid, - Pcm1ch, - Pcm2ch, - Pcm6ch, - PcmAuto, - }; - enum class ForceMutePolicy { Disable, SpeakerMuteOnHeadphoneUnplugged, @@ -37,10 +33,18 @@ private: void GetTargetVolumeMin(HLERequestContext& ctx); void GetTargetVolumeMax(HLERequestContext& ctx); + void GetAudioOutputMode(HLERequestContext& ctx); + void SetAudioOutputMode(HLERequestContext& ctx); void GetForceMutePolicy(HLERequestContext& ctx); void GetOutputModeSetting(HLERequestContext& ctx); + void SetOutputModeSetting(HLERequestContext& ctx); + void SetHeadphoneOutputLevelMode(HLERequestContext& ctx); void GetHeadphoneOutputLevelMode(HLERequestContext& ctx); + void SetSpeakerAutoMuteEnabled(HLERequestContext& ctx); void IsSpeakerAutoMuteEnabled(HLERequestContext& ctx); + void AcquireTargetNotification(HLERequestContext& ctx); + + std::shared_ptr m_set_sys; }; } // namespace Service::Audio diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp index e3b8ecf3e..3a22b135f 100755 --- a/src/core/hle/service/caps/caps_manager.cpp +++ b/src/core/hle/service/caps/caps_manager.cpp @@ -246,10 +246,10 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, system.ServiceManager().GetService("time:u", true); std::shared_ptr user_clock{}; - static_service->GetStandardUserSystemClock(user_clock); + static_service->GetStandardUserSystemClock(&user_clock); s64 posix_time{}; - auto result = user_clock->GetCurrentTime(posix_time); + auto result = user_clock->GetCurrentTime(&posix_time); if (result.IsError()) { return result; @@ -268,10 +268,10 @@ Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, system.ServiceManager().GetService("time:u", true); std::shared_ptr user_clock{}; - static_service->GetStandardUserSystemClock(user_clock); + static_service->GetStandardUserSystemClock(&user_clock); s64 posix_time{}; - auto result = user_clock->GetCurrentTime(posix_time); + auto result = user_clock->GetCurrentTime(&posix_time); if (result.IsError()) { return result; @@ -470,11 +470,11 @@ AlbumFileDateTime AlbumManager::ConvertToAlbumDateTime(u64 posix_time) const { system.ServiceManager().GetService("time:u", true); std::shared_ptr timezone_service{}; - static_service->GetTimeZoneService(timezone_service); + static_service->GetTimeZoneService(&timezone_service); Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time); + timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time); return { .year = calendar_time.year, diff --git a/src/core/hle/service/cmif_serialization.h b/src/core/hle/service/cmif_serialization.h index 9eb10e816..9ee26400d 100755 --- a/src/core/hle/service/cmif_serialization.h +++ b/src/core/hle/service/cmif_serialization.h @@ -12,6 +12,109 @@ namespace Service { // clang-format off +template +struct UnwrapArg { + using Type = std::remove_cvref_t; +}; + +template +struct UnwrapArg> { + using Type = std::remove_cv_t::Type>; +}; + +template +struct UnwrapArg> { + using Type = AutoOut::Type>; +}; + +template +struct UnwrapArg> { + using Type = AutoOut::Type>; +}; + +template +struct UnwrapArg> { + using Type = AutoOut::Type>; +}; + +template +struct UnwrapArg> { + using Type = AutoOut::Type>; +}; + +enum class ArgumentType { + InProcessId, + InData, + InInterface, + InCopyHandle, + OutData, + OutInterface, + OutCopyHandle, + OutMoveHandle, + InBuffer, + InLargeData, + OutBuffer, + OutLargeData, +}; + +template +struct ArgumentTraits; + +template <> +struct ArgumentTraits { + static constexpr ArgumentType Type = ArgumentType::InProcessId; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::InInterface; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::InCopyHandle; +}; + +template +struct ArgumentTraits>> { + static constexpr ArgumentType Type = ArgumentType::OutInterface; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::OutData; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::OutCopyHandle; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::OutMoveHandle; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::InLargeData; +}; + +template +struct ArgumentTraits> { + static constexpr ArgumentType Type = ArgumentType::OutLargeData; +}; + +template +struct ArgumentTraits { + static constexpr ArgumentType Type = ArgumentType::InData; +}; + struct RequestLayout { u32 copy_handle_count; u32 move_handle_count; @@ -122,6 +225,8 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE static_assert(PrevAlign <= ArgAlign, "Input argument is not ordered by alignment"); static_assert(!RawDataFinished, "All input interface arguments must appear after raw data"); + static_assert(!std::is_pointer_v, "Input raw data must not be a pointer"); + static_assert(std::is_trivially_copyable_v, "Input raw data must be trivially copyable"); constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); constexpr size_t ArgEnd = ArgOffset + ArgSize; @@ -198,7 +303,7 @@ void ReadInArgument(bool is_domain, CallArguments& args, const u8* raw_data, HLE constexpr size_t BufferSize = sizeof(ArgType); // Clear the existing data. - std::memset(&std::get(args), 0, BufferSize); + std::memset(&std::get(args).raw, 0, BufferSize); return ReadInArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutBuffer) { @@ -237,27 +342,29 @@ void WriteOutArgument(bool is_domain, CallArguments& args, u8* raw_data, HLERequ static_assert(PrevAlign <= ArgAlign, "Output argument is not ordered by alignment"); static_assert(!RawDataFinished, "All output interface arguments must appear after raw data"); + static_assert(!std::is_pointer_v, "Output raw data must not be a pointer"); + static_assert(std::is_trivially_copyable_v(args).raw)>, "Output raw data must be trivially copyable"); constexpr size_t ArgOffset = Common::AlignUp(DataOffset, ArgAlign); constexpr size_t ArgEnd = ArgOffset + ArgSize; - std::memcpy(raw_data + ArgOffset, &std::get(args), ArgSize); + std::memcpy(raw_data + ArgOffset, &std::get(args).raw, ArgSize); return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutInterface) { if (is_domain) { - ctx.AddDomainObject(std::get(args)); + ctx.AddDomainObject(std::get(args).raw); } else { - ctx.AddMoveInterface(std::get(args)); + ctx.AddMoveInterface(std::get(args).raw); } return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutCopyHandle) { - ctx.AddCopyObject(std::get(args)); + ctx.AddCopyObject(std::get(args).raw); return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutMoveHandle) { - ctx.AddMoveObject(std::get(args)); + ctx.AddMoveObject(std::get(args).raw); return WriteOutArgument(is_domain, args, raw_data, ctx, temp); } else if constexpr (ArgumentTraits::Type == ArgumentType::OutLargeData) { @@ -302,10 +409,10 @@ void CmifReplyWrapImpl(HLERequestContext& ctx, T& t, Result (T::*f)(A...)) { } const bool is_domain = Domain ? ctx.GetManager()->IsDomain() : false; - using MethodArguments = std::tuple...>; + using MethodArguments = std::tuple...>; OutTemporaryBuffers buffers{}; - auto call_arguments = std::tuple::Type...>(); + auto call_arguments = std::tuple::Type...>(); // Read inputs. const size_t offset_plus_command_id = ctx.GetDataPayloadOffset() + 2; diff --git a/src/core/hle/service/cmif_types.h b/src/core/hle/service/cmif_types.h index 2610c49f3..dc06169f4 100755 --- a/src/core/hle/service/cmif_types.h +++ b/src/core/hle/service/cmif_types.h @@ -12,22 +12,31 @@ namespace Service { // clang-format off +template +struct AutoOut { + T raw; +}; + template class Out { public: using Type = T; - /* implicit */ Out(Type& t) : raw(&t) {} - ~Out() = default; + /* implicit */ Out(AutoOut& t) : raw(&t.raw) {} + /* implicit */ Out(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; @@ -35,6 +44,9 @@ private: template using SharedPointer = std::shared_ptr; +template +using OutInterface = Out>; + struct ClientProcessId { explicit operator bool() const { return pid != 0; @@ -101,17 +113,21 @@ class OutCopyHandle { public: using Type = T*; - /* implicit */ OutCopyHandle(Type& t) : raw(&t) {} - ~OutCopyHandle() = default; + /* implicit */ OutCopyHandle(AutoOut& t) : raw(&t.raw) {} + /* implicit */ OutCopyHandle(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; @@ -121,30 +137,34 @@ class OutMoveHandle { public: using Type = T*; - /* implicit */ OutMoveHandle(Type& t) : raw(&t) {} - ~OutMoveHandle() = default; + /* implicit */ OutMoveHandle(AutoOut& t) : raw(&t.raw) {} + /* implicit */ OutMoveHandle(Type* t) : raw(t) {} Type* Get() const { return raw; } - Type& operator*() { + Type& operator*() const { return *raw; } + Type* operator->() const { + return raw; + } + private: Type* raw; }; enum BufferAttr : int { - BufferAttr_In = (1U << 0), - BufferAttr_Out = (1U << 1), - BufferAttr_HipcMapAlias = (1U << 2), - BufferAttr_HipcPointer = (1U << 3), - BufferAttr_FixedSize = (1U << 4), - BufferAttr_HipcAutoSelect = (1U << 5), - BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), - BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7), + /* 0x01 */ BufferAttr_In = (1U << 0), + /* 0x02 */ BufferAttr_Out = (1U << 1), + /* 0x04 */ BufferAttr_HipcMapAlias = (1U << 2), + /* 0x08 */ BufferAttr_HipcPointer = (1U << 3), + /* 0x10 */ BufferAttr_FixedSize = (1U << 4), + /* 0x20 */ BufferAttr_HipcAutoSelect = (1U << 5), + /* 0x40 */ BufferAttr_HipcMapTransferAllowsNonSecure = (1U << 6), + /* 0x80 */ BufferAttr_HipcMapTransferAllowsNonDevice = (1U << 7), }; template @@ -172,123 +192,80 @@ struct Buffer : public std::span { } }; -template +template using InBuffer = Buffer; -template +template using InArray = Buffer; -template +template using OutBuffer = Buffer; -template +template using OutArray = Buffer; template -struct LargeData : public T { +class InLargeData { +public: static_assert(std::is_trivially_copyable_v, "LargeData type must be trivially copyable"); - static_assert((A & BufferAttr_FixedSize) != 0, "LargeData attr must contain FixedSize"); - static_assert(((A & BufferAttr_In) == 0) ^ ((A & BufferAttr_Out) == 0), "LargeData attr must be In or Out"); - static constexpr BufferAttr Attr = static_cast(A); + static_assert((A & BufferAttr_Out) == 0, "InLargeData attr must not be Out"); + static constexpr BufferAttr Attr = static_cast(A | BufferAttr_In | BufferAttr_FixedSize); + using Type = const T; + + /* implicit */ InLargeData(Type& t) : raw(&t) {} + ~InLargeData() = default; + + InLargeData& operator=(Type* rhs) { + raw = rhs; + return *this; + } + + Type* Get() const { + return raw; + } + + Type& operator*() const { + return *raw; + } + + Type* operator->() const { + return raw; + } + + explicit operator bool() const { + return raw != nullptr; + } + +private: + Type* raw; +}; + +template +class OutLargeData { +public: + static_assert(std::is_trivially_copyable_v, "LargeData type must be trivially copyable"); + static_assert((A & BufferAttr_In) == 0, "OutLargeData attr must not be In"); + static constexpr BufferAttr Attr = static_cast(A | BufferAttr_In | BufferAttr_FixedSize); using Type = T; - /* implicit */ LargeData(const T& rhs) : T(rhs) {} - /* implicit */ LargeData() = default; -}; + /* implicit */ OutLargeData(Type* t) : raw(t) {} + /* implicit */ OutLargeData(AutoOut& t) : raw(&t.raw) {} -template -using InLargeData = LargeData; + Type* Get() const { + return raw; + } -template -using OutLargeData = LargeData; + Type& operator*() const { + return *raw; + } -template -struct RemoveOut { - using Type = std::remove_reference_t; -}; + Type* operator->() const { + return raw; + } -template -struct RemoveOut> { - using Type = typename Out::Type; -}; - -template -struct RemoveOut> { - using Type = typename OutCopyHandle::Type; -}; - -template -struct RemoveOut> { - using Type = typename OutMoveHandle::Type; -}; - -enum class ArgumentType { - InProcessId, - InData, - InInterface, - InCopyHandle, - OutData, - OutInterface, - OutCopyHandle, - OutMoveHandle, - InBuffer, - InLargeData, - OutBuffer, - OutLargeData, -}; - -template -struct ArgumentTraits; - -template <> -struct ArgumentTraits { - static constexpr ArgumentType Type = ArgumentType::InProcessId; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = ArgumentType::InInterface; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = ArgumentType::InCopyHandle; -}; - -template -struct ArgumentTraits>> { - static constexpr ArgumentType Type = ArgumentType::OutInterface; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = ArgumentType::OutData; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = ArgumentType::OutCopyHandle; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = ArgumentType::OutMoveHandle; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutBuffer : ArgumentType::InBuffer; -}; - -template -struct ArgumentTraits> { - static constexpr ArgumentType Type = (A & BufferAttr_In) == 0 ? ArgumentType::OutLargeData : ArgumentType::InLargeData; -}; - -template -struct ArgumentTraits { - static constexpr ArgumentType Type = ArgumentType::InData; +private: + Type* raw; }; // clang-format on -} // namespace Service +} // namespace Service \ No newline at end of file diff --git a/src/core/hle/service/glue/time/alarm_worker.cpp b/src/core/hle/service/glue/time/alarm_worker.cpp index f549ed00a..3ff071f4a 100755 --- a/src/core/hle/service/glue/time/alarm_worker.cpp +++ b/src/core/hle/service/glue/time/alarm_worker.cpp @@ -41,7 +41,7 @@ bool AlarmWorker::GetClosestAlarmInfo(Service::PSC::Time::AlarmInfo& out_alarm_i Service::PSC::Time::AlarmInfo alarm_info{}; s64 closest_time{}; - auto res = m_time_m->GetClosestAlarmInfo(is_valid, alarm_info, closest_time); + auto res = m_time_m->GetClosestAlarmInfo(&is_valid, &alarm_info, &closest_time); ASSERT(res == ResultSuccess); if (is_valid) { @@ -76,6 +76,7 @@ void AlarmWorker::OnPowerStateChanged() { Result AlarmWorker::AttachToClosestAlarmEvent() { m_time_m->GetClosestAlarmUpdatedEvent(&m_event); + R_SUCCEED(); } diff --git a/src/core/hle/service/glue/time/alarm_worker.h b/src/core/hle/service/glue/time/alarm_worker.h index f269cffdb..131d012a6 100755 --- a/src/core/hle/service/glue/time/alarm_worker.h +++ b/src/core/hle/service/glue/time/alarm_worker.h @@ -26,7 +26,7 @@ public: void Initialize(std::shared_ptr time_m); - Kernel::KEvent& GetEvent() { + Kernel::KReadableEvent& GetEvent() { return *m_event; } @@ -44,7 +44,7 @@ private: KernelHelpers::ServiceContext m_ctx; std::shared_ptr m_time_m; - Kernel::KEvent* m_event{}; + Kernel::KReadableEvent* m_event{}; Kernel::KEvent* m_timer_event{}; std::shared_ptr m_timer_timing_event; StandardSteadyClockResource& m_steady_clock_resource; diff --git a/src/core/hle/service/glue/time/file_timestamp_worker.cpp b/src/core/hle/service/glue/time/file_timestamp_worker.cpp index 5a6309549..048ff174c 100755 --- a/src/core/hle/service/glue/time/file_timestamp_worker.cpp +++ b/src/core/hle/service/glue/time/file_timestamp_worker.cpp @@ -13,8 +13,8 @@ void FileTimestampWorker::SetFilesystemPosixTime() { Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - if (m_initialized && m_system_clock->GetCurrentTime(time) == ResultSuccess && - m_time_zone->ToCalendarTimeWithMyRule(calendar_time, additional_info, time) == + if (m_initialized && m_system_clock->GetCurrentTime(&time) == ResultSuccess && + m_time_zone->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, time) == ResultSuccess) { // TODO IFileSystemProxy::SetCurrentPosixTime } diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index b56762941..0c27e8029 100755 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -79,18 +79,18 @@ Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationN auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue()); Service::PSC::Time::LocationName configured_name{}; - std::memcpy(configured_name.name.data(), configured_zone.data(), - std::min(configured_name.name.size(), configured_zone.size())); + std::memcpy(configured_name.data(), configured_zone.data(), + std::min(configured_name.size(), configured_zone.size())); if (!IsTimeZoneBinaryValid(configured_name)) { configured_zone = Common::TimeZone::FindSystemTimeZone(); configured_name = {}; - std::memcpy(configured_name.name.data(), configured_zone.data(), - std::min(configured_name.name.size(), configured_zone.size())); + std::memcpy(configured_name.data(), configured_zone.data(), + std::min(configured_name.size(), configured_zone.size())); } ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!", - configured_name.name.data()); + configured_name.data()); return configured_name; } @@ -103,7 +103,7 @@ TimeManager::TimeManager(Core::System& system) m_time_m = system.ServiceManager().GetService("time:m", true); - auto res = m_time_m->GetStaticServiceAsServiceManager(m_time_sm); + auto res = m_time_m->GetStaticServiceAsServiceManager(&m_time_sm); ASSERT(res == ResultSuccess); m_set_sys = @@ -114,10 +114,10 @@ TimeManager::TimeManager(Core::System& system) m_worker.Initialize(m_time_sm, m_set_sys); - res = m_time_sm->GetStandardUserSystemClock(m_file_timestamp_worker.m_system_clock); + res = m_time_sm->GetStandardUserSystemClock(&m_file_timestamp_worker.m_system_clock); ASSERT(res == ResultSuccess); - res = m_time_sm->GetTimeZoneService(m_file_timestamp_worker.m_time_zone); + res = m_time_sm->GetTimeZoneService(&m_file_timestamp_worker.m_time_zone); ASSERT(res == ResultSuccess); res = SetupStandardSteadyClockCore(); @@ -161,8 +161,8 @@ TimeManager::TimeManager(Core::System& system) automatic_correction_time_point); ASSERT(res == ResultSuccess); - res = m_time_m->SetupStandardUserSystemClockCore(automatic_correction_time_point, - is_automatic_correction_enabled); + res = m_time_m->SetupStandardUserSystemClockCore(is_automatic_correction_enabled, + automatic_correction_time_point); ASSERT(res == ResultSuccess); res = m_time_m->SetupEphemeralNetworkSystemClockCore(); @@ -184,12 +184,12 @@ TimeManager::TimeManager(Core::System& system) m_file_timestamp_worker.m_initialized = true; s64 system_clock_time{}; - if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(system_clock_time) == + if (m_file_timestamp_worker.m_system_clock->GetCurrentTime(&system_clock_time) == ResultSuccess) { Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo calendar_additional{}; if (m_file_timestamp_worker.m_time_zone->ToCalendarTimeWithMyRule( - calendar_time, calendar_additional, system_clock_time) == ResultSuccess) { + &calendar_time, &calendar_additional, system_clock_time) == ResultSuccess) { // TODO IFileSystemProxy::SetCurrentPosixTime(system_clock_time, // calendar_additional.ut_offset) } @@ -228,10 +228,9 @@ Result TimeManager::SetupStandardSteadyClockCore() { m_set_sys->SetExternalSteadyClockSourceId(clock_source_id); } - res = m_time_m->SetupStandardSteadyClockCore(clock_source_id, m_steady_clock_resource.GetTime(), - external_steady_clock_internal_offset_ns, - standard_steady_clock_test_offset_ns, - reset_detected); + res = m_time_m->SetupStandardSteadyClockCore( + reset_detected, clock_source_id, m_steady_clock_resource.GetTime(), + external_steady_clock_internal_offset_ns, standard_steady_clock_test_offset_ns); ASSERT(res == ResultSuccess); R_SUCCEED(); } @@ -243,14 +242,15 @@ Result TimeManager::SetupTimeZoneServiceCore() { auto configured_zone = GetTimeZoneString(name); - if (configured_zone.name != name.name) { + if (configured_zone != name) { m_set_sys->SetDeviceTimeZoneLocationName(configured_zone); name = configured_zone; std::shared_ptr local_clock; - m_time_sm->GetStandardLocalSystemClock(local_clock); + m_time_sm->GetStandardLocalSystemClock(&local_clock); + Service::PSC::Time::SystemClockContext context{}; - local_clock->GetSystemClockContext(context); + local_clock->GetSystemClockContext(&context); m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(context.steady_time_point); } @@ -267,7 +267,7 @@ Result TimeManager::SetupTimeZoneServiceCore() { res = GetTimeZoneRule(rule_buffer, rule_size, name); ASSERT(res == ResultSuccess); - res = m_time_m->SetupTimeZoneServiceCore(name, time_point, rule_version, location_count, + res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point, rule_buffer); ASSERT(res == ResultSuccess); diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp index 63b7d91da..f56db76e1 100755 --- a/src/core/hle/service/glue/time/static.cpp +++ b/src/core/hle/service/glue/time/static.cpp @@ -3,9 +3,11 @@ #include +#include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/svc.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/glue/time/file_timestamp_worker.h" #include "core/hle/service/glue/time/static.h" #include "core/hle/service/psc/time/errors.h" @@ -41,25 +43,25 @@ StaticService::StaticService(Core::System& system_, time->m_steady_clock_resource} { // clang-format off static const FunctionInfo functions[] = { - {0, &StaticService::Handle_GetStandardUserSystemClock, "GetStandardUserSystemClock"}, - {1, &StaticService::Handle_GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, - {2, &StaticService::Handle_GetStandardSteadyClock, "GetStandardSteadyClock"}, - {3, &StaticService::Handle_GetTimeZoneService, "GetTimeZoneService"}, - {4, &StaticService::Handle_GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, - {5, &StaticService::Handle_GetEphemeralNetworkSystemClock, "GetEphemeralNetworkSystemClock"}, - {20, &StaticService::Handle_GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, - {50, &StaticService::Handle_SetStandardSteadyClockInternalOffset, "SetStandardSteadyClockInternalOffset"}, - {51, &StaticService::Handle_GetStandardSteadyClockRtcValue, "GetStandardSteadyClockRtcValue"}, - {100, &StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, - {101, &StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, - {102, &StaticService::Handle_GetStandardUserSystemClockInitialYear, "GetStandardUserSystemClockInitialYear"}, - {200, &StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"}, - {201, &StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, - {300, &StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, - {400, &StaticService::Handle_GetClockSnapshot, "GetClockSnapshot"}, - {401, &StaticService::Handle_GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, - {500, &StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, - {501, &StaticService::Handle_CalculateSpanBetween, "CalculateSpanBetween"}, + {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"}, + {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"}, + {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"}, + {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"}, + {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"}, + {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"}, + {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"}, + {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"}, + {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"}, + {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, + {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, + {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"}, + {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"}, + {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, + {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"}, + {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"}, + {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"}, + {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"}, + {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"}, }; // clang-format on @@ -71,314 +73,80 @@ StaticService::StaticService(Core::System& system_, if (m_setup_info.can_write_local_clock && m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && m_setup_info.can_write_timezone_device_location && !m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsAdmin(m_wrapped_service); + m_time_m->GetStaticServiceAsAdmin(&m_wrapped_service); } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && !m_setup_info.can_write_timezone_device_location && !m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsUser(m_wrapped_service); + m_time_m->GetStaticServiceAsUser(&m_wrapped_service); } else if (!m_setup_info.can_write_local_clock && !m_setup_info.can_write_user_clock && !m_setup_info.can_write_network_clock && !m_setup_info.can_write_timezone_device_location && m_setup_info.can_write_steady_clock && !m_setup_info.can_write_uninitialized_clock) { - m_time_m->GetStaticServiceAsRepair(m_wrapped_service); + m_time_m->GetStaticServiceAsRepair(&m_wrapped_service); } else { UNREACHABLE(); } - auto res = m_wrapped_service->GetTimeZoneService(m_time_zone); + auto res = m_wrapped_service->GetTimeZoneService(&m_time_zone); ASSERT(res == ResultSuccess); } -void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardUserSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardSteadyClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetTimeZoneService(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetTimeZoneService(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardLocalSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardLocalSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetEphemeralNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KSharedMemory* shared_memory{}; - auto res = GetSharedMemoryNativeHandle(&shared_memory); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(shared_memory); -} - -void StaticService::Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto offset_ns{rp.Pop()}; - - auto res = SetStandardSteadyClockInternalOffset(offset_ns); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 rtc_value{}; - auto res = GetStandardSteadyClockRtcValue(rtc_value); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(rtc_value); -} - -void StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_enabled{}; - auto res = IsStandardUserSystemClockAutomaticCorrectionEnabled(is_enabled); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(is_enabled); -} - -void StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto automatic_correction{rp.Pop()}; - - auto res = SetStandardUserSystemClockAutomaticCorrectionEnabled(automatic_correction); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s32 initial_year{}; - auto res = GetStandardUserSystemClockInitialYear(initial_year); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(initial_year); -} - -void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_sufficient{}; - auto res = IsStandardNetworkSystemClockAccuracySufficient(is_sufficient); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(is_sufficient); -} - -void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::SteadyClockTimePoint time_point{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); - - IPC::ResponseBuilder rb{ctx, - 2 + sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(time_point); -} - -void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw()}; - - s64 time{}; - auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto type{rp.PopEnum()}; - - Service::PSC::Time::ClockSnapshot snapshot{}; - auto res = GetClockSnapshot(snapshot, type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto clock_type{rp.PopEnum()}; - [[maybe_unused]] auto alignment{rp.Pop()}; - auto user_context{rp.PopRaw()}; - auto network_context{rp.PopRaw()}; - - Service::PSC::Time::ClockSnapshot snapshot{}; - auto res = - GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::ClockSnapshot a{}; - Service::PSC::Time::ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - - s64 difference{}; - auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(difference); -} - -void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::ClockSnapshot a{}; - Service::PSC::Time::ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(Service::PSC::Time::ClockSnapshot)); - - s64 time{}; - auto res = CalculateSpanBetween(time, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -// =============================== Implementations =========================== - Result StaticService::GetStandardUserSystemClock( - std::shared_ptr& out_service) { + OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetStandardUserSystemClock(out_service)); } Result StaticService::GetStandardNetworkSystemClock( - std::shared_ptr& out_service) { + OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetStandardNetworkSystemClock(out_service)); } Result StaticService::GetStandardSteadyClock( - std::shared_ptr& out_service) { + OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetStandardSteadyClock(out_service)); } -Result StaticService::GetTimeZoneService(std::shared_ptr& out_service) { - out_service = std::make_shared(m_system, m_file_timestamp_worker, - m_setup_info.can_write_timezone_device_location, - m_time_zone); +Result StaticService::GetTimeZoneService(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + + *out_service = std::make_shared( + m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location, + m_time_zone); R_SUCCEED(); } Result StaticService::GetStandardLocalSystemClock( - std::shared_ptr& out_service) { + OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetStandardLocalSystemClock(out_service)); } Result StaticService::GetEphemeralNetworkSystemClock( - std::shared_ptr& out_service) { + OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetEphemeralNetworkSystemClock(out_service)); } -Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) { +Result StaticService::GetSharedMemoryNativeHandle( + OutCopyHandle out_shared_memory) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(m_wrapped_service->GetSharedMemoryNativeHandle(out_shared_memory)); } Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { + LOG_DEBUG(Service_Time, "called. offset_ns={}", offset_ns); + R_UNLESS(m_setup_info.can_write_steady_clock, Service::PSC::Time::ResultPermissionDenied); R_RETURN(m_set_sys->SetExternalSteadyClockInternalOffset( @@ -386,62 +154,92 @@ Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { std::chrono::duration_cast(std::chrono::seconds(1)).count())); } -Result StaticService::GetStandardSteadyClockRtcValue(s64& out_rtc_value) { - R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(out_rtc_value)); +Result StaticService::GetStandardSteadyClockRtcValue(Out out_rtc_value) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); + + R_RETURN(m_standard_steady_clock_resource.GetRtcTimeInSeconds(*out_rtc_value)); } Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( - bool& out_automatic_correction) { + Out out_automatic_correction) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. out_automatic_correction={}", *out_automatic_correction); + }); + R_RETURN(m_wrapped_service->IsStandardUserSystemClockAutomaticCorrectionEnabled( out_automatic_correction)); } Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( bool automatic_correction) { + LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction); + R_RETURN(m_wrapped_service->SetStandardUserSystemClockAutomaticCorrectionEnabled( automatic_correction)); } -Result StaticService::GetStandardUserSystemClockInitialYear(s32& out_year) { - out_year = GetSettingsItemValue(m_set_sys, "time", "standard_user_clock_initial_year"); +Result StaticService::GetStandardUserSystemClockInitialYear(Out out_year) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_year={}", *out_year); }); + + *out_year = GetSettingsItemValue(m_set_sys, "time", "standard_user_clock_initial_year"); R_SUCCEED(); } -Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) { +Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out out_is_sufficient) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); + R_RETURN(m_wrapped_service->IsStandardNetworkSystemClockAccuracySufficient(out_is_sufficient)); } Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point) { + Out out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); + R_RETURN(m_wrapped_service->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( out_time_point)); } Result StaticService::CalculateMonotonicSystemClockBaseTimePoint( - s64& out_time, Service::PSC::Time::SystemClockContext& context) { + Out out_time, Service::PSC::Time::SystemClockContext& context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); + R_RETURN(m_wrapped_service->CalculateMonotonicSystemClockBaseTimePoint(out_time, context)); } -Result StaticService::GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot, +Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, Service::PSC::Time::TimeType type) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); + R_RETURN(m_wrapped_service->GetClockSnapshot(out_snapshot, type)); } Result StaticService::GetClockSnapshotFromSystemClockContext( - Service::PSC::Time::ClockSnapshot& out_snapshot, + Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type) { - R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext(out_snapshot, user_context, - network_context, type)); + Service::PSC::Time::SystemClockContext& network_context) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. type={} out_snapshot={} user_context={} network_context={}", type, + *out_snapshot, user_context, network_context); + }); + + R_RETURN(m_wrapped_service->GetClockSnapshotFromSystemClockContext( + type, out_snapshot, user_context, network_context)); } -Result StaticService::CalculateStandardUserSystemClockDifferenceByUser( - s64& out_time, Service::PSC::Time::ClockSnapshot& a, Service::PSC::Time::ClockSnapshot& b) { +Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out out_time, + InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); + R_RETURN(m_wrapped_service->CalculateStandardUserSystemClockDifferenceByUser(out_time, a, b)); } -Result StaticService::CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::ClockSnapshot& b) { +Result StaticService::CalculateSpanBetween(Out out_time, InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); + R_RETURN(m_wrapped_service->CalculateSpanBetween(out_time, a, b)); } diff --git a/src/core/hle/service/glue/time/static.h b/src/core/hle/service/glue/time/static.h index 75fe4e2cd..d3cc0fdd6 100755 --- a/src/core/hle/service/glue/time/static.h +++ b/src/core/hle/service/glue/time/static.h @@ -4,6 +4,7 @@ #pragma once #include "common/common_types.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/glue/time/manager.h" #include "core/hle/service/glue/time/time_zone.h" #include "core/hle/service/psc/time/common.h" @@ -29,6 +30,10 @@ class FileTimestampWorker; class StandardSteadyClockResource; class StaticService final : public ServiceFramework { + using InClockSnapshot = InLargeData; + using OutClockSnapshot = + OutLargeData; + public: explicit StaticService(Core::System& system, Service::PSC::Time::StaticServiceSetupInfo setup_info, @@ -36,65 +41,34 @@ public: ~StaticService() override = default; - Result GetStandardUserSystemClock( - std::shared_ptr& out_service); - Result GetStandardNetworkSystemClock( - std::shared_ptr& out_service); - Result GetStandardSteadyClock(std::shared_ptr& out_service); - Result GetTimeZoneService(std::shared_ptr& out_service); - Result GetStandardLocalSystemClock( - std::shared_ptr& out_service); + Result GetStandardUserSystemClock(OutInterface out_service); + Result GetStandardNetworkSystemClock(OutInterface out_service); + Result GetStandardSteadyClock(OutInterface out_service); + Result GetTimeZoneService(OutInterface out_service); + Result GetStandardLocalSystemClock(OutInterface out_service); Result GetEphemeralNetworkSystemClock( - std::shared_ptr& out_service); - Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory); - Result SetStandardSteadyClockInternalOffset(s64 offset); - Result GetStandardSteadyClockRtcValue(s64& out_rtc_value); - Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_automatic_correction); + OutInterface out_service); + Result GetSharedMemoryNativeHandle(OutCopyHandle out_shared_memory); + Result SetStandardSteadyClockInternalOffset(s64 offset_ns); + Result GetStandardSteadyClockRtcValue(Out out_rtc_value); + Result IsStandardUserSystemClockAutomaticCorrectionEnabled(Out out_is_enabled); Result SetStandardUserSystemClockAutomaticCorrectionEnabled(bool automatic_correction); - Result GetStandardUserSystemClockInitialYear(s32& out_year); - Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient); + Result GetStandardUserSystemClockInitialYear(Out out_year); + Result IsStandardNetworkSystemClockAccuracySufficient(Out out_is_sufficient); Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point); + Out out_time_point); Result CalculateMonotonicSystemClockBaseTimePoint( - s64& out_time, Service::PSC::Time::SystemClockContext& context); - Result GetClockSnapshot(Service::PSC::Time::ClockSnapshot& out_snapshot, - Service::PSC::Time::TimeType type); + Out out_time, Service::PSC::Time::SystemClockContext& context); + Result GetClockSnapshot(OutClockSnapshot out_snapshot, Service::PSC::Time::TimeType type); Result GetClockSnapshotFromSystemClockContext( - Service::PSC::Time::ClockSnapshot& out_snapshot, + Service::PSC::Time::TimeType type, OutClockSnapshot out_snapshot, Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, Service::PSC::Time::TimeType type); - Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, - Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::ClockSnapshot& b); - Result CalculateSpanBetween(s64& out_time, Service::PSC::Time::ClockSnapshot& a, - Service::PSC::Time::ClockSnapshot& b); + Service::PSC::Time::SystemClockContext& network_context); + Result CalculateStandardUserSystemClockDifferenceByUser(Out out_difference, + InClockSnapshot a, InClockSnapshot b); + Result CalculateSpanBetween(Out out_time, InClockSnapshot a, InClockSnapshot b); private: - Result GetClockSnapshotImpl(Service::PSC::Time::ClockSnapshot& out_snapshot, - Service::PSC::Time::SystemClockContext& user_context, - Service::PSC::Time::SystemClockContext& network_context, - Service::PSC::Time::TimeType type); - - void Handle_GetStandardUserSystemClock(HLERequestContext& ctx); - void Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetStandardSteadyClock(HLERequestContext& ctx); - void Handle_GetTimeZoneService(HLERequestContext& ctx); - void Handle_GetStandardLocalSystemClock(HLERequestContext& ctx); - void Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx); - void Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx); - void Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx); - void Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx); - void Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); - void Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx); - void Handle_GetClockSnapshot(HLERequestContext& ctx); - void Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx); - void Handle_CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx); - void Handle_CalculateSpanBetween(HLERequestContext& ctx); - Core::System& m_system; std::shared_ptr m_set_sys; diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp index 503c327dd..5dc1187cb 100755 --- a/src/core/hle/service/glue/time/time_zone.cpp +++ b/src/core/hle/service/glue/time/time_zone.cpp @@ -3,8 +3,10 @@ #include +#include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/svc.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/glue/time/file_timestamp_worker.h" #include "core/hle/service/glue/time/time_zone.h" #include "core/hle/service/glue/time/time_zone_binary.h" @@ -28,20 +30,20 @@ TimeZoneService::TimeZoneService( m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} { // clang-format off static const FunctionInfo functions[] = { - {0, &TimeZoneService::Handle_GetDeviceLocationName, "GetDeviceLocationName"}, - {1, &TimeZoneService::Handle_SetDeviceLocationName, "SetDeviceLocationName"}, - {2, &TimeZoneService::Handle_GetTotalLocationNameCount, "GetTotalLocationNameCount"}, - {3, &TimeZoneService::Handle_LoadLocationNameList, "LoadLocationNameList"}, - {4, &TimeZoneService::Handle_LoadTimeZoneRule, "LoadTimeZoneRule"}, - {5, &TimeZoneService::Handle_GetTimeZoneRuleVersion, "GetTimeZoneRuleVersion"}, - {6, &TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime, "GetDeviceLocationNameAndUpdatedTime"}, - {7, &TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule, "SetDeviceLocationNameWithTimeZoneRule"}, - {8, &TimeZoneService::Handle_ParseTimeZoneBinary, "ParseTimeZoneBinary"}, - {20, &TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle, "GetDeviceLocationNameOperationEventReadableHandle"}, - {100, &TimeZoneService::Handle_ToCalendarTime, "ToCalendarTime"}, - {101, &TimeZoneService::Handle_ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, - {201, &TimeZoneService::Handle_ToPosixTime, "ToPosixTime"}, - {202, &TimeZoneService::Handle_ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"}, + {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, + {1, D<&TimeZoneService::SetDeviceLocationName>, "SetDeviceLocationName"}, + {2, D<&TimeZoneService::GetTotalLocationNameCount>, "GetTotalLocationNameCount"}, + {3, D<&TimeZoneService::LoadLocationNameList>, "LoadLocationNameList"}, + {4, D<&TimeZoneService::LoadTimeZoneRule>, "LoadTimeZoneRule"}, + {5, D<&TimeZoneService::GetTimeZoneRuleVersion>, "GetTimeZoneRuleVersion"}, + {6, D<&TimeZoneService::GetDeviceLocationNameAndUpdatedTime>, "GetDeviceLocationNameAndUpdatedTime"}, + {7, D<&TimeZoneService::SetDeviceLocationNameWithTimeZoneRule>, "SetDeviceLocationNameWithTimeZoneRule"}, + {8, D<&TimeZoneService::ParseTimeZoneBinary>, "ParseTimeZoneBinary"}, + {20, D<&TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle>, "GetDeviceLocationNameOperationEventReadableHandle"}, + {100, D<&TimeZoneService::ToCalendarTime>, "ToCalendarTime"}, + {101, D<&TimeZoneService::ToCalendarTimeWithMyRule>, "ToCalendarTimeWithMyRule"}, + {201, D<&TimeZoneService::ToPosixTime>, "ToPosixTime"}, + {202, D<&TimeZoneService::ToPosixTimeWithMyRule>, "ToPosixTimeWithMyRule"}, }; // clang-format on RegisterHandlers(functions); @@ -53,220 +55,16 @@ TimeZoneService::TimeZoneService( TimeZoneService::~TimeZoneService() = default; -void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetDeviceLocationName( + Out out_location_name) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); - Service::PSC::Time::LocationName name{}; - auto res = GetDeviceLocationName(name); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(name); -} - -void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw()}; - - auto res = SetDeviceLocation(name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - u32 count{}; - auto res = GetTotalLocationNameCount(count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto index{rp.Pop()}; - - auto max_names{ctx.GetWriteBufferSize() / sizeof(Service::PSC::Time::LocationName)}; - - std::vector names{}; - u32 count{}; - auto res = LoadLocationNameList(count, names, max_names, index); - - ctx.WriteBuffer(names); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw()}; - - Tz::Rule rule{}; - auto res = LoadTimeZoneRule(rule, name); - - ctx.WriteBuffer(rule); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::RuleVersion rule_version{}; - auto res = GetTimeZoneRuleVersion(rule_version); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::RuleVersion) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(rule_version); -} - -void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Service::PSC::Time::LocationName name{}; - Service::PSC::Time::SteadyClockTimePoint time_point{}; - auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::LocationName) / sizeof(u32)) + - (sizeof(Service::PSC::Time::SteadyClockTimePoint) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(name); - rb.PushRaw(time_point); -} - -void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto res = SetDeviceLocationNameWithTimeZoneRule(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Service::PSC::Time::ResultNotImplemented); -} - -void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetDeviceLocationNameOperationEventReadableHandle(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop()}; - - auto rule_buffer{ctx.ReadBuffer()}; - Tz::Rule rule{}; - std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule)); - - Service::PSC::Time::CalendarTime calendar_time{}; - Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTime(calendar_time, additional_info, time, rule); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) + - (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(calendar_time); - rb.PushRaw(additional_info); -} - -void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto time{rp.Pop()}; - - LOG_DEBUG(Service_Time, "called. time={}", time); - - Service::PSC::Time::CalendarTime calendar_time{}; - Service::PSC::Time::CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time); - - IPC::ResponseBuilder rb{ctx, - 2 + (sizeof(Service::PSC::Time::CalendarTime) / sizeof(u32)) + - (sizeof(Service::PSC::Time::CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(calendar_time); - rb.PushRaw(additional_info); -} - -void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw()}; - - LOG_DEBUG(Service_Time, "called. calendar year {} month {} day {} hour {} minute {} second {}", - calendar.year, calendar.month, calendar.day, calendar.hour, calendar.minute, - calendar.second); - - auto binary{ctx.ReadBuffer()}; - - Tz::Rule rule{}; - std::memcpy(&rule, binary.data(), sizeof(Tz::Rule)); - - u32 count{}; - std::array times{}; - u32 times_count{static_cast(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTime(count, times, times_count, calendar, rule); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw()}; - - u32 count{}; - std::array times{}; - u32 times_count{static_cast(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTimeWithMyRule(count, times, times_count, calendar); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -// =============================== Implementations =========================== - -Result TimeZoneService::GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name) { R_RETURN(m_wrapped_service->GetDeviceLocationName(out_location_name)); } -Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& location_name) { +Result TimeZoneService::SetDeviceLocationName(Service::PSC::Time::LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); + R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied); R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound); @@ -282,7 +80,7 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca Service::PSC::Time::SteadyClockTimePoint time_point{}; Service::PSC::Time::LocationName name{}; - R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(time_point, name)); + R_TRY(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(&name, &time_point)); m_set_sys->SetDeviceTimeZoneLocationName(name); m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point); @@ -294,19 +92,27 @@ Result TimeZoneService::SetDeviceLocation(Service::PSC::Time::LocationName& loca R_SUCCEED(); } -Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) { +Result TimeZoneService::GetTotalLocationNameCount(Out out_count) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); + R_RETURN(m_wrapped_service->GetTotalLocationNameCount(out_count)); } Result TimeZoneService::LoadLocationNameList( - u32& out_count, std::vector& out_names, size_t max_names, - u32 index) { + Out out_count, + OutArray out_names, u32 index) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. index={} out_count={} out_names[0]={} out_names[1]={}", + index, *out_count, out_names[0], out_names[1]); + }); + std::scoped_lock l{m_mutex}; - R_RETURN(GetTimeZoneLocationList(out_count, out_names, max_names, index)); + R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index)); } -Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule, - Service::PSC::Time::LocationName& name) { +Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& name) { + LOG_DEBUG(Service_Time, "called. name={}", name); + std::scoped_lock l{m_mutex}; std::span binary{}; size_t binary_size{}; @@ -314,23 +120,43 @@ Result TimeZoneService::LoadTimeZoneRule(Tz::Rule& out_rule, R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary)); } -Result TimeZoneService::GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version) { +Result TimeZoneService::GetTimeZoneRuleVersion( + Out out_rule_version) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); + R_RETURN(m_wrapped_service->GetTimeZoneRuleVersion(out_rule_version)); } Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point, - Service::PSC::Time::LocationName& location_name) { - R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(out_time_point, location_name)); + Out location_name, + Out out_time_point) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. location_name={} out_time_point={}", *location_name, + *out_time_point); + }); + + R_RETURN(m_wrapped_service->GetDeviceLocationNameAndUpdatedTime(location_name, out_time_point)); } -Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule() { +Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule( + Service::PSC::Time::LocationName& location_name, InBuffer binary) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); + R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied); R_RETURN(Service::PSC::Time::ResultNotImplemented); } +Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule, + InBuffer binary) { + LOG_DEBUG(Service_Time, "called."); + + R_RETURN(Service::PSC::Time::ResultNotImplemented); +} + Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( - Kernel::KEvent** out_event) { + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + if (!operation_event_initialized) { operation_event_initialized = false; @@ -342,34 +168,59 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( g_list_nodes.push_back(m_operation_event); } - *out_event = m_operation_event.m_event; + *out_event = &m_operation_event.m_event->GetReadableEvent(); R_SUCCEED(); } Result TimeZoneService::ToCalendarTime( - Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule) { + Out out_calendar_time, + Out out_additional_info, s64 time, InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); + R_RETURN(m_wrapped_service->ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); } Result TimeZoneService::ToCalendarTimeWithMyRule( - Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time) { + Out out_calendar_time, + Out out_additional_info, s64 time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); + R_RETURN( m_wrapped_service->ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); } -Result TimeZoneService::ToPosixTime(u32& out_count, std::span out_times, - u32 out_times_count, - Service::PSC::Time::CalendarTime& calendar_time, - Tz::Rule& rule) { +Result TimeZoneService::ToPosixTime(Out out_count, + OutArray out_times, + Out out_times_count, + Service::PSC::Time::CalendarTime& calendar_time, InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); + R_RETURN( m_wrapped_service->ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule)); } -Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span out_times, - u32 out_times_count, +Result TimeZoneService::ToPosixTimeWithMyRule(Out out_count, + OutArray out_times, + Out out_times_count, Service::PSC::Time::CalendarTime& calendar_time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); + R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, out_times_count, calendar_time)); } diff --git a/src/core/hle/service/glue/time/time_zone.h b/src/core/hle/service/glue/time/time_zone.h index 3c8ae4bf8..bf12adbdc 100755 --- a/src/core/hle/service/glue/time/time_zone.h +++ b/src/core/hle/service/glue/time/time_zone.h @@ -8,6 +8,7 @@ #include #include +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/server_manager.h" @@ -33,6 +34,9 @@ namespace Service::Glue::Time { class FileTimestampWorker; class TimeZoneService final : public ServiceFramework { + using InRule = InLargeData; + using OutRule = OutLargeData; + public: explicit TimeZoneService( Core::System& system, FileTimestampWorker& file_timestamp_worker, @@ -41,46 +45,37 @@ public: ~TimeZoneService() override; - Result GetDeviceLocationName(Service::PSC::Time::LocationName& out_location_name); - Result SetDeviceLocation(Service::PSC::Time::LocationName& location_name); - Result GetTotalLocationNameCount(u32& out_count); - Result LoadLocationNameList(u32& out_count, - std::vector& out_names, - size_t max_names, u32 index); - Result LoadTimeZoneRule(Tz::Rule& out_rule, Service::PSC::Time::LocationName& name); - Result GetTimeZoneRuleVersion(Service::PSC::Time::RuleVersion& out_rule_version); + Result GetDeviceLocationName(Out out_location_name); + Result SetDeviceLocationName(Service::PSC::Time::LocationName& location_name); + Result GetTotalLocationNameCount(Out out_count); + Result LoadLocationNameList( + Out out_count, + OutArray out_names, u32 index); + Result LoadTimeZoneRule(OutRule out_rule, Service::PSC::Time::LocationName& location_name); + Result GetTimeZoneRuleVersion(Out out_rule_version); Result GetDeviceLocationNameAndUpdatedTime( - Service::PSC::Time::SteadyClockTimePoint& out_time_point, - Service::PSC::Time::LocationName& location_name); - Result SetDeviceLocationNameWithTimeZoneRule(); - Result GetDeviceLocationNameOperationEventReadableHandle(Kernel::KEvent** out_event); - Result ToCalendarTime(Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule); - Result ToCalendarTimeWithMyRule(Service::PSC::Time::CalendarTime& out_calendar_time, - Service::PSC::Time::CalendarAdditionalInfo& out_additional_info, - s64 time); - Result ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, - Service::PSC::Time::CalendarTime& calendar_time, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span out_times, u32 out_times_count, + Out location_name, + Out out_time_point); + Result SetDeviceLocationNameWithTimeZoneRule(Service::PSC::Time::LocationName& location_name, + InBuffer binary); + Result ParseTimeZoneBinary(OutRule out_rule, InBuffer binary); + Result GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle out_event); + Result ToCalendarTime(Out out_calendar_time, + Out out_additional_info, + s64 time, InRule rule); + Result ToCalendarTimeWithMyRule( + Out out_calendar_time, + Out out_additional_info, s64 time); + Result ToPosixTime(Out out_count, OutArray out_times, + Out out_times_count, Service::PSC::Time::CalendarTime& calendar_time, + InRule rule); + Result ToPosixTimeWithMyRule(Out out_count, + OutArray out_times, + Out out_times_count, Service::PSC::Time::CalendarTime& calendar_time); private: - void Handle_GetDeviceLocationName(HLERequestContext& ctx); - void Handle_SetDeviceLocationName(HLERequestContext& ctx); - void Handle_GetTotalLocationNameCount(HLERequestContext& ctx); - void Handle_LoadLocationNameList(HLERequestContext& ctx); - void Handle_LoadTimeZoneRule(HLERequestContext& ctx); - void Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx); - void Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx); - void Handle_ParseTimeZoneBinary(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameOperationEventReadableHandle(HLERequestContext& ctx); - void Handle_ToCalendarTime(HLERequestContext& ctx); - void Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx); - void Handle_ToPosixTime(HLERequestContext& ctx); - void Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx); - Core::System& m_system; std::shared_ptr m_set_sys; diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp index d33f784c0..cc50b6b7b 100755 --- a/src/core/hle/service/glue/time/time_zone_binary.cpp +++ b/src/core/hle/service/glue/time/time_zone_binary.cpp @@ -103,7 +103,7 @@ void GetTimeZoneZonePath(std::string& out_path, Service::PSC::Time::LocationName return; } // out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name); - out_path = fmt::format("/zoneinfo/{}", name.name.data()); + out_path = fmt::format("/zoneinfo/{}", name.data()); } bool IsTimeZoneBinaryValid(Service::PSC::Time::LocationName& name) { @@ -169,7 +169,7 @@ Result GetTimeZoneRule(std::span& out_rule, size_t& out_rule_size, } Result GetTimeZoneLocationList(u32& out_count, - std::vector& out_names, + std::span out_names, size_t max_names, u32 index) { std::string path{}; GetTimeZoneBinaryListPath(path); @@ -193,7 +193,7 @@ Result GetTimeZoneLocationList(u32& out_count, if (chr == '\n') { if (name_count >= index) { - out_names.push_back(current_name); + out_names[out_count] = current_name; out_count++; if (out_count >= max_names) { break; @@ -209,10 +209,9 @@ Result GetTimeZoneLocationList(u32& out_count, break; } - R_UNLESS(current_name_len <= current_name.name.size() - 2, - Service::PSC::Time::ResultFailed); + R_UNLESS(current_name_len <= current_name.size() - 2, Service::PSC::Time::ResultFailed); - current_name.name[current_name_len++] = chr; + current_name[current_name_len++] = chr; } R_SUCCEED(); diff --git a/src/core/hle/service/glue/time/time_zone_binary.h b/src/core/hle/service/glue/time/time_zone_binary.h index 2cad6b458..461f4577e 100755 --- a/src/core/hle/service/glue/time/time_zone_binary.h +++ b/src/core/hle/service/glue/time/time_zone_binary.h @@ -26,7 +26,7 @@ Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version); Result GetTimeZoneRule(std::span& out_rule, size_t& out_rule_size, Service::PSC::Time::LocationName& name); Result GetTimeZoneLocationList(u32& out_count, - std::vector& out_names, + std::span out_names, size_t max_names, u32 index); } // namespace Service::Glue::Time diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index ea0e49b90..f44f3077e 100755 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp @@ -38,11 +38,12 @@ T GetSettingsItemValue(std::shared_ptr& set TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource, FileTimestampWorker& file_timestamp_worker) - : m_system{system}, m_ctx{m_system, "Glue:58"}, m_event{m_ctx.CreateEvent("Glue:58:Event")}, + : m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, m_event{m_ctx.CreateEvent( + "Glue:TimeWorker:Event")}, m_steady_clock_resource{steady_clock_resource}, m_file_timestamp_worker{file_timestamp_worker}, m_timer_steady_clock{m_ctx.CreateEvent( - "Glue:58:SteadyClockTimerEvent")}, - m_timer_file_system{m_ctx.CreateEvent("Glue:58:FileTimeTimerEvent")}, + "Glue:TimeWorker:SteadyClockTimerEvent")}, + m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")}, m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} { g_ig_report_network_clock_context_set = false; g_report_network_clock_context = {}; @@ -113,17 +114,17 @@ void TimeWorker::Initialize(std::shared_ptr t std::chrono::nanoseconds(fs_notify_time_ns), m_timer_file_system_timing_event); - auto res = m_time_sm->GetStandardLocalSystemClock(m_local_clock); + auto res = m_time_sm->GetStandardLocalSystemClock(&m_local_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetStandardLocalClockOperationEvent(&m_local_clock_event); ASSERT(res == ResultSuccess); - res = m_time_sm->GetStandardNetworkSystemClock(m_network_clock); + res = m_time_sm->GetStandardNetworkSystemClock(&m_network_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetStandardNetworkClockOperationEventForServiceManager(&m_network_clock_event); ASSERT(res == ResultSuccess); - res = m_time_sm->GetEphemeralNetworkSystemClock(m_ephemeral_clock); + res = m_time_sm->GetEphemeralNetworkSystemClock(&m_ephemeral_clock); ASSERT(res == ResultSuccess); res = m_time_m->GetEphemeralNetworkClockOperationEventForServiceManager(&m_ephemeral_clock_event); @@ -183,22 +184,19 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { AddWaiter(&m_event->GetReadableEvent(), EventType::Exit); // TODO // AddWaiter(gIPmModuleService::GetEvent(), 1); - AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange); + AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange); } else { AddWaiter(&m_event->GetReadableEvent(), EventType::Exit); // TODO // AddWaiter(gIPmModuleService::GetEvent(), 1); - AddWaiter(&m_alarm_worker.GetEvent().GetReadableEvent(), EventType::PowerStateChange); + AddWaiter(&m_alarm_worker.GetEvent(), EventType::PowerStateChange); AddWaiter(&m_alarm_worker.GetTimerEvent().GetReadableEvent(), EventType::SignalAlarms); - AddWaiter(&m_local_clock_event->GetReadableEvent(), EventType::UpdateLocalSystemClock); - AddWaiter(&m_network_clock_event->GetReadableEvent(), - EventType::UpdateNetworkSystemClock); - AddWaiter(&m_ephemeral_clock_event->GetReadableEvent(), - EventType::UpdateEphemeralSystemClock); + AddWaiter(m_local_clock_event, EventType::UpdateLocalSystemClock); + AddWaiter(m_network_clock_event, EventType::UpdateNetworkSystemClock); + AddWaiter(m_ephemeral_clock_event, EventType::UpdateEphemeralSystemClock); AddWaiter(&m_timer_steady_clock->GetReadableEvent(), EventType::UpdateSteadyClock); AddWaiter(&m_timer_file_system->GetReadableEvent(), EventType::UpdateFileTimestamp); - AddWaiter(&m_standard_user_auto_correct_clock_event->GetReadableEvent(), - EventType::AutoCorrect); + AddWaiter(m_standard_user_auto_correct_clock_event, EventType::AutoCorrect); } s32 out_index{-1}; @@ -237,7 +235,7 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { m_local_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_local_clock->GetSystemClockContext(context); + auto res = m_local_clock->GetSystemClockContext(&context); ASSERT(res == ResultSuccess); m_set_sys->SetUserSystemClockContext(context); @@ -248,12 +246,12 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { case EventType::UpdateNetworkSystemClock: { m_network_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_network_clock->GetSystemClockContext(context); + auto res = m_network_clock->GetSystemClockContext(&context); ASSERT(res == ResultSuccess); m_set_sys->SetNetworkSystemClockContext(context); s64 time{}; - if (m_network_clock->GetCurrentTime(time) != ResultSuccess) { + if (m_network_clock->GetCurrentTime(&time) != ResultSuccess) { break; } @@ -275,13 +273,13 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { m_ephemeral_clock_event->Clear(); Service::PSC::Time::SystemClockContext context{}; - auto res = m_ephemeral_clock->GetSystemClockContext(context); + auto res = m_ephemeral_clock->GetSystemClockContext(&context); if (res != ResultSuccess) { break; } s64 time{}; - res = m_ephemeral_clock->GetCurrentTime(time); + res = m_ephemeral_clock->GetCurrentTime(&time); if (res != ResultSuccess) { break; } @@ -317,11 +315,11 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { bool automatic_correction{}; auto res = m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled( - automatic_correction); + &automatic_correction); ASSERT(res == ResultSuccess); Service::PSC::Time::SteadyClockTimePoint time_point{}; - res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); + res = m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(&time_point); ASSERT(res == ResultSuccess); m_set_sys->SetUserSystemClockAutomaticCorrectionEnabled(automatic_correction); diff --git a/src/core/hle/service/glue/time/worker.h b/src/core/hle/service/glue/time/worker.h index adbbe6b6d..75e5c4d0f 100755 --- a/src/core/hle/service/glue/time/worker.h +++ b/src/core/hle/service/glue/time/worker.h @@ -49,10 +49,10 @@ private: std::shared_ptr m_ephemeral_clock; StandardSteadyClockResource& m_steady_clock_resource; FileTimestampWorker& m_file_timestamp_worker; - Kernel::KEvent* m_local_clock_event{}; - Kernel::KEvent* m_network_clock_event{}; - Kernel::KEvent* m_ephemeral_clock_event{}; - Kernel::KEvent* m_standard_user_auto_correct_clock_event{}; + Kernel::KReadableEvent* m_local_clock_event{}; + Kernel::KReadableEvent* m_network_clock_event{}; + Kernel::KReadableEvent* m_ephemeral_clock_event{}; + Kernel::KReadableEvent* m_standard_user_auto_correct_clock_event{}; Kernel::KEvent* m_timer_steady_clock{}; std::shared_ptr m_timer_steady_clock_timing_event; Kernel::KEvent* m_timer_file_system{}; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 1e2d2d212..28e3000bd 100755 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -1405,7 +1405,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { system.ServiceManager().GetService("time:u", true); std::shared_ptr timezone_service{}; - static_service->GetTimeZoneService(timezone_service); + static_service->GetTimeZoneService(&timezone_service); Service::PSC::Time::CalendarTime calendar_time{}; Service::PSC::Time::CalendarAdditionalInfo additional_info{}; @@ -1416,7 +1416,7 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { amiibo_date.SetMonth(1); amiibo_date.SetDay(1); - if (timezone_service->ToCalendarTimeWithMyRule(calendar_time, additional_info, posix_time) == + if (timezone_service->ToCalendarTimeWithMyRule(&calendar_time, &additional_info, posix_time) == ResultSuccess) { amiibo_date.SetYear(calendar_time.year); amiibo_date.SetMonth(calendar_time.month); @@ -1431,10 +1431,10 @@ s64 NfcDevice::GetCurrentPosixTime() const { system.ServiceManager().GetService("time:u", true); std::shared_ptr steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); return time_point.time_point; } diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index b60699c45..94a8243b5 100755 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -91,10 +91,10 @@ Result DeviceManager::ListDevices(std::vector& nfp_devices, std::size_t max true); std::shared_ptr steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); const s64 elapsed_time = time_point.time_point - time_since_last_error; if (time_since_last_error != 0 && elapsed_time < MinimumRecoveryTime) { @@ -754,10 +754,10 @@ Result DeviceManager::VerifyDeviceResult(std::shared_ptr device, system.ServiceManager().GetService("time:u", true); std::shared_ptr steady_clock{}; - static_service->GetStandardSteadyClock(steady_clock); + static_service->GetStandardSteadyClock(&steady_clock); Service::PSC::Time::SteadyClockTimePoint time_point{}; - R_ASSERT(steady_clock->GetCurrentTimePoint(time_point)); + R_ASSERT(steady_clock->GetCurrentTimePoint(&time_point)); time_since_last_error = time_point.time_point; } diff --git a/src/core/hle/service/psc/time/common.h b/src/core/hle/service/psc/time/common.h index d17b31143..596828b8b 100755 --- a/src/core/hle/service/psc/time/common.h +++ b/src/core/hle/service/psc/time/common.h @@ -5,6 +5,7 @@ #include #include +#include #include "common/common_types.h" #include "common/intrusive_list.h" @@ -21,8 +22,14 @@ class System; namespace Service::PSC::Time { using ClockSourceId = Common::UUID; +enum class TimeType : u8 { + UserSystemClock = 0, + NetworkSystemClock = 1, + LocalSystemClock = 2, +}; + struct SteadyClockTimePoint { - constexpr bool IdMatches(SteadyClockTimePoint& other) { + constexpr bool IdMatches(const SteadyClockTimePoint& other) const { return clock_source_id == other.clock_source_id; } bool operator==(const SteadyClockTimePoint& other) const = default; @@ -42,12 +49,6 @@ struct SystemClockContext { static_assert(sizeof(SystemClockContext) == 0x20, "SystemClockContext has the wrong size!"); static_assert(std::is_trivial_v); -enum class TimeType : u8 { - UserSystemClock, - NetworkSystemClock, - LocalSystemClock, -}; - struct CalendarTime { s16 year; s8 month; @@ -67,14 +68,10 @@ struct CalendarAdditionalInfo { }; static_assert(sizeof(CalendarAdditionalInfo) == 0x18, "CalendarAdditionalInfo has the wrong size!"); -struct LocationName { - std::array name; -}; +using LocationName = std::array; static_assert(sizeof(LocationName) == 0x24, "LocationName has the wrong size!"); -struct RuleVersion { - std::array version; -}; +using RuleVersion = std::array; static_assert(sizeof(RuleVersion) == 0x10, "RuleVersion has the wrong size!"); struct ClockSnapshot { @@ -152,8 +149,8 @@ constexpr inline std::chrono::nanoseconds ConvertToTimeSpan(s64 ticks) { return std::chrono::nanoseconds(a + b); } -constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTimePoint& a, - SteadyClockTimePoint& b) { +constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, const SteadyClockTimePoint& a, + const SteadyClockTimePoint& b) { R_UNLESS(out_seconds, ResultInvalidArgument); R_UNLESS(a.IdMatches(b), ResultInvalidArgument); R_UNLESS(a.time_point >= 0 || b.time_point <= a.time_point + std::numeric_limits::max(), @@ -166,3 +163,111 @@ constexpr inline Result GetSpanBetweenTimePoints(s64* out_seconds, SteadyClockTi } } // namespace Service::PSC::Time + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(Service::PSC::Time::TimeType type, FormatContext& ctx) { + const string_view name = [type] { + using Service::PSC::Time::TimeType; + switch (type) { + case TimeType::UserSystemClock: + return "UserSystemClock"; + case TimeType::NetworkSystemClock: + return "NetworkSystemClock"; + case TimeType::LocalSystemClock: + return "LocalSystemClock"; + } + return "Invalid"; + }(); + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::SteadyClockTimePoint& time_point, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "time_point={}", time_point.time_point); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::SystemClockContext& context, FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "offset={} steady_time_point={}", context.offset, + context.steady_time_point.time_point); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::CalendarTime& calendar, FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "{}/{}/{} {}:{}:{}", calendar.day, calendar.month, + calendar.year, calendar.hour, calendar.minute, calendar.second); + } +}; + +template <> +struct fmt::formatter + : fmt::formatter { + template + auto format(const Service::PSC::Time::CalendarAdditionalInfo& additional, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), "weekday={} yearday={} name={} is_dst={} ut_offset={}", + additional.day_of_week, additional.day_of_year, + additional.name.data(), additional.is_dst, additional.ut_offset); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const { + std::string_view n{name.data(), name.size()}; + return formatter::format(n, ctx); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const { + std::string_view v{version.data(), version.size()}; + return formatter::format(v, ctx); + } +}; + +template <> +struct fmt::formatter : fmt::formatter { + template + auto format(const Service::PSC::Time::ClockSnapshot& snapshot, FormatContext& ctx) const { + return fmt::format_to( + ctx.out(), + "user_context={} network_context={} user_time={} network_time={} user_calendar_time={} " + "network_calendar_time={} user_calendar_additional_time={} " + "network_calendar_additional_time={} steady_clock_time_point={} location={} " + "is_automatic_correction_enabled={} type={}", + snapshot.user_context, snapshot.network_context, snapshot.user_time, + snapshot.network_time, snapshot.user_calendar_time, snapshot.network_calendar_time, + snapshot.user_calendar_additional_time, snapshot.network_calendar_additional_time, + snapshot.steady_clock_time_point, snapshot.location_name, + snapshot.is_automatic_correction_enabled, snapshot.type); + } +}; + +template <> +struct fmt::formatter + : fmt::formatter { + template + auto format(const Service::PSC::Time::ContinuousAdjustmentTimePoint& time_point, + FormatContext& ctx) const { + return fmt::format_to(ctx.out(), + "rtc_offset={} diff_scale={} shift_amount={} lower={} upper={}", + time_point.rtc_offset, time_point.diff_scale, time_point.shift_amount, + time_point.lower, time_point.upper); + } +}; \ No newline at end of file diff --git a/src/core/hle/service/psc/time/power_state_service.cpp b/src/core/hle/service/psc/time/power_state_service.cpp index b0ae71bf9..ab1d32c70 100755 --- a/src/core/hle/service/psc/time/power_state_service.cpp +++ b/src/core/hle/service/psc/time/power_state_service.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/power_state_service.h" namespace Service::PSC::Time { @@ -11,39 +12,34 @@ IPowerStateRequestHandler::IPowerStateRequestHandler( power_state_request_manager} { // clang-format off static const FunctionInfo functions[] = { - {0, &IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle, "GetPowerStateRequestEventReadableHandle"}, - {1, &IPowerStateRequestHandler::GetAndClearPowerStateRequest, "GetAndClearPowerStateRequest"}, + {0, D<&IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle>, "GetPowerStateRequestEventReadableHandle"}, + {1, D<&IPowerStateRequestHandler::GetAndClearPowerStateRequest>, "GetAndClearPowerStateRequest"}, }; // clang-format on RegisterHandlers(functions); } -void IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx) { +Result IPowerStateRequestHandler::GetPowerStateRequestEventReadableHandle( + OutCopyHandle out_event) { LOG_DEBUG(Service_Time, "called."); - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(m_power_state_request_manager.GetReadableEvent()); + *out_event = &m_power_state_request_manager.GetReadableEvent(); + R_SUCCEED(); } -void IPowerStateRequestHandler::GetAndClearPowerStateRequest(HLERequestContext& ctx) { +Result IPowerStateRequestHandler::GetAndClearPowerStateRequest(Out out_cleared, + Out out_priority) { LOG_DEBUG(Service_Time, "called."); u32 priority{}; auto cleared = m_power_state_request_manager.GetAndClearPowerStateRequest(priority); + *out_cleared = cleared; if (cleared) { - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(priority); - rb.Push(cleared); - return; + *out_priority = priority; } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(cleared); + R_SUCCEED(); } } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/power_state_service.h b/src/core/hle/service/psc/time/power_state_service.h index 3ebfddb79..56e2c4b87 100755 --- a/src/core/hle/service/psc/time/power_state_service.h +++ b/src/core/hle/service/psc/time/power_state_service.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/power_state_request_manager.h" #include "core/hle/service/server_manager.h" @@ -21,10 +22,10 @@ public: ~IPowerStateRequestHandler() override = default; -private: - void GetPowerStateRequestEventReadableHandle(HLERequestContext& ctx); - void GetAndClearPowerStateRequest(HLERequestContext& ctx); + Result GetPowerStateRequestEventReadableHandle(OutCopyHandle out_event); + Result GetAndClearPowerStateRequest(Out out_cleared, Out out_priority); +private: Core::System& m_system; PowerStateRequestManager& m_power_state_request_manager; }; diff --git a/src/core/hle/service/psc/time/service_manager.cpp b/src/core/hle/service/psc/time/service_manager.cpp index 60820aa9b..ec906b723 100755 --- a/src/core/hle/service/psc/time/service_manager.cpp +++ b/src/core/hle/service/psc/time/service_manager.cpp @@ -3,6 +3,7 @@ #include "core/core.h" #include "core/core_timing.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/power_state_service.h" #include "core/hle/service/psc/time/service_manager.h" #include "core/hle/service/psc/time/static.h" @@ -25,24 +26,24 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr, "GetStaticServiceAsUser"}, + {5, D<&ServiceManager::GetStaticServiceAsAdmin>, "GetStaticServiceAsAdmin"}, + {6, D<&ServiceManager::GetStaticServiceAsRepair>, "GetStaticServiceAsRepair"}, + {9, D<&ServiceManager::GetStaticServiceAsServiceManager>, "GetStaticServiceAsServiceManager"}, + {10, D<&ServiceManager::SetupStandardSteadyClockCore>, "SetupStandardSteadyClockCore"}, + {11, D<&ServiceManager::SetupStandardLocalSystemClockCore>, "SetupStandardLocalSystemClockCore"}, + {12, D<&ServiceManager::SetupStandardNetworkSystemClockCore>, "SetupStandardNetworkSystemClockCore"}, + {13, D<&ServiceManager::SetupStandardUserSystemClockCore>, "SetupStandardUserSystemClockCore"}, + {14, D<&ServiceManager::SetupTimeZoneServiceCore>, "SetupTimeZoneServiceCore"}, + {15, D<&ServiceManager::SetupEphemeralNetworkSystemClockCore>, "SetupEphemeralNetworkSystemClockCore"}, + {50, D<&ServiceManager::GetStandardLocalClockOperationEvent>, "GetStandardLocalClockOperationEvent"}, + {51, D<&ServiceManager::GetStandardNetworkClockOperationEventForServiceManager>, "GetStandardNetworkClockOperationEventForServiceManager"}, + {52, D<&ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager>, "GetEphemeralNetworkClockOperationEventForServiceManager"}, + {60, D<&ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent"}, + {100, D<&ServiceManager::SetStandardSteadyClockBaseTime>, "SetStandardSteadyClockBaseTime"}, + {200, D<&ServiceManager::GetClosestAlarmUpdatedEvent>, "GetClosestAlarmUpdatedEvent"}, + {201, D<&ServiceManager::CheckAndSignalAlarms>, "CheckAndSignalAlarms"}, + {202, D<&ServiceManager::GetClosestAlarmInfo>, "GetClosestAlarmInfo "}, }; // clang-format on RegisterHandlers(functions); @@ -52,302 +53,39 @@ ServiceManager::ServiceManager(Core::System& system_, std::shared_ptr( - m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s")); - m_server_manager.RegisterNamedService("time:p", - std::make_shared( - m_system, m_time->m_power_state_request_manager)); - } -} - -void ServiceManager::CheckAndSetupServicesSAndP() { - if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() && - m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() && - m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) { - SetupSAndP(); - } -} - -void ServiceManager::Handle_GetStaticServiceAsUser(HLERequestContext& ctx) { +Result ServiceManager::GetStaticServiceAsUser(OutInterface out_service) { LOG_DEBUG(Service_Time, "called."); - std::shared_ptr service{}; - auto res = GetStaticServiceAsUser(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStaticServiceAsAdmin(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsRepair(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStaticServiceAsRepair(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void ServiceManager::Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStaticServiceAsServiceManager(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void ServiceManager::Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - bool reset_detected; - Common::UUID clock_source_id; - s64 rtc_offset; - s64 internal_offset; - s64 test_offset; - }; - static_assert(sizeof(Parameters) == 0x30); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw()}; - - auto res = SetupStandardSteadyClockCore(params.clock_source_id, params.rtc_offset, - params.internal_offset, params.test_offset, - params.reset_detected); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw()}; - auto time{rp.Pop()}; - - auto res = SetupStandardLocalSystemClockCore(context, time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw()}; - auto accuracy{rp.Pop()}; - - auto res = SetupStandardNetworkSystemClockCore(context, accuracy); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - bool automatic_correction; - SteadyClockTimePoint time_point; - }; - static_assert(sizeof(Parameters) == 0x20); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw()}; - - auto res = SetupStandardUserSystemClockCore(params.time_point, params.automatic_correction); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - struct Parameters { - u32 location_count; - LocationName name; - SteadyClockTimePoint time_point; - RuleVersion rule_version; - }; - static_assert(sizeof(Parameters) == 0x50); - - IPC::RequestParser rp{ctx}; - auto params{rp.PopRaw()}; - - auto rule_buffer{ctx.ReadBuffer()}; - - auto res = SetupTimeZoneServiceCore(params.name, params.time_point, params.rule_version, - params.location_count, rule_buffer); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto res = SetupEphemeralNetworkSystemClockCore(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardLocalClockOperationEvent(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void ServiceManager::Handle_GetStandardNetworkClockOperationEventForServiceManager( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardNetworkClockOperationEventForServiceManager(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_GetEphemeralNetworkClockOperationEventForServiceManager( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetEphemeralNetworkClockOperationEventForServiceManager(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event); -} - -void ServiceManager::Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto base_time{rp.Pop()}; - - auto res = SetStandardSteadyClockBaseTime(base_time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetClosestAlarmUpdatedEvent(&event); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void ServiceManager::Handle_CheckAndSignalAlarms(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto res = CheckAndSignalAlarms(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void ServiceManager::Handle_GetClosestAlarmInfo(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - AlarmInfo alarm_info{}; - bool is_valid{}; - s64 time{}; - auto res = GetClosestAlarmInfo(is_valid, alarm_info, time); - - struct OutParameters { - bool is_valid; - AlarmInfo alarm_info; - s64 time; - }; - static_assert(sizeof(OutParameters) == 0x20); - - OutParameters out_params{ - .is_valid = is_valid, - .alarm_info = alarm_info, - .time = time, - }; - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(OutParameters) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(out_params); -} - -// =============================== Implementations =========================== - -Result ServiceManager::GetStaticService(std::shared_ptr& out_service, - StaticServiceSetupInfo setup_info, const char* name) { - out_service = std::make_shared(m_system, setup_info, m_time, name); - R_SUCCEED(); -} - -Result ServiceManager::GetStaticServiceAsUser(std::shared_ptr& out_service) { R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, "time:u")); } -Result ServiceManager::GetStaticServiceAsAdmin(std::shared_ptr& out_service) { +Result ServiceManager::GetStaticServiceAsAdmin(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, "time:a")); } -Result ServiceManager::GetStaticServiceAsRepair(std::shared_ptr& out_service) { +Result ServiceManager::GetStaticServiceAsRepair(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, "time:r")); } -Result ServiceManager::GetStaticServiceAsServiceManager( - std::shared_ptr& out_service) { +Result ServiceManager::GetStaticServiceAsServiceManager(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + R_RETURN(GetStaticService(out_service, StaticServiceSetupInfo{1, 1, 1, 1, 1, 0}, "time:sm")); } -Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset, - s64 internal_offset, s64 test_offset, - bool is_rtc_reset_detected) { +Result ServiceManager::SetupStandardSteadyClockCore(bool is_rtc_reset_detected, + Common::UUID& clock_source_id, s64 rtc_offset, + s64 internal_offset, s64 test_offset) { + LOG_DEBUG(Service_Time, + "called. is_rtc_reset_detected={} clock_source_id={} rtc_offset={} " + "internal_offset={} test_offset={}", + is_rtc_reset_detected, clock_source_id.RawString(), rtc_offset, internal_offset, + test_offset); + m_steady_clock.Initialize(clock_source_id, rtc_offset, internal_offset, test_offset, is_rtc_reset_detected); auto time = m_steady_clock.GetRawTime(); @@ -365,6 +103,10 @@ Result ServiceManager::SetupStandardSteadyClockCore(Common::UUID& clock_source_i } Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time) { + LOG_DEBUG(Service_Time, + "called. context={} context.steady_time_point.clock_source_id={} time={}", context, + context.steady_time_point.clock_source_id.RawString(), time); + m_local_system_clock.SetContextWriter(m_local_system_context_writer); m_local_system_clock.Initialize(context, time); @@ -374,6 +116,9 @@ Result ServiceManager::SetupStandardLocalSystemClockCore(SystemClockContext& con Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& context, s64 accuracy) { + LOG_DEBUG(Service_Time, "called. context={} steady_time_point.clock_source_id={} accuracy={}", + context, context.steady_time_point.clock_source_id.RawString(), accuracy); + // TODO this is a hack! The network clock should be updated independently, from the ntc service // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot // to avoid it being stuck at 0. @@ -388,8 +133,11 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c R_SUCCEED(); } -Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point, - bool automatic_correction) { +Result ServiceManager::SetupStandardUserSystemClockCore(bool automatic_correction, + SteadyClockTimePoint& time_point) { + LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}", + automatic_correction, time_point, time_point.clock_source_id.RawString()); + // TODO this is a hack! The user clock should be updated independently, from the ntc service // and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot // to avoid it being stuck at 0. @@ -406,10 +154,16 @@ Result ServiceManager::SetupStandardUserSystemClockCore(SteadyClockTimePoint& ti R_SUCCEED(); } -Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, +Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version, + u32 location_count, SteadyClockTimePoint& time_point, - RuleVersion& rule_version, u32 location_count, - std::span rule_buffer) { + InBuffer rule_buffer) { + LOG_DEBUG(Service_Time, + "called. name={} rule_version={} location_count={} time_point={} " + "clock_source_id={}", + name, rule_version, location_count, time_point, + time_point.clock_source_id.RawString()); + if (m_time_zone.ParseBinary(name, rule_buffer) != ResultSuccess) { LOG_ERROR(Service_Time, "Failed to parse time zone binary!"); } @@ -424,6 +178,8 @@ Result ServiceManager::SetupTimeZoneServiceCore(LocationName& name, } Result ServiceManager::SetupEphemeralNetworkSystemClockCore() { + LOG_DEBUG(Service_Time, "called."); + m_ephemeral_network_clock.SetContextWriter(m_ephemeral_system_context_writer); m_ephemeral_network_clock.SetInitialized(); @@ -431,30 +187,41 @@ Result ServiceManager::SetupEphemeralNetworkSystemClockCore() { R_SUCCEED(); } -Result ServiceManager::GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event) { - *out_event = m_local_operation.m_event; +Result ServiceManager::GetStandardLocalClockOperationEvent( + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_local_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetStandardNetworkClockOperationEventForServiceManager( - Kernel::KEvent** out_event) { - *out_event = m_network_operation.m_event; + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_network_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetEphemeralNetworkClockOperationEventForServiceManager( - Kernel::KEvent** out_event) { - *out_event = m_ephemeral_operation.m_event; + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_ephemeral_operation.m_event->GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( - Kernel::KEvent** out_event) { - *out_event = &m_user_system_clock.GetEvent(); + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_user_system_clock.GetEvent().GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) { + LOG_DEBUG(Service_Time, "called. base_time={}", base_time); + m_steady_clock.SetRtcOffset(base_time); auto time = m_steady_clock.GetRawTime(); auto ticks = m_system.CoreTiming().GetClockTicks(); @@ -468,26 +235,63 @@ Result ServiceManager::SetStandardSteadyClockBaseTime(s64 base_time) { R_SUCCEED(); } -Result ServiceManager::GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event) { - *out_event = &m_alarms.GetEvent(); +Result ServiceManager::GetClosestAlarmUpdatedEvent( + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + + *out_event = &m_alarms.GetEvent().GetReadableEvent(); R_SUCCEED(); } Result ServiceManager::CheckAndSignalAlarms() { + LOG_DEBUG(Service_Time, "called."); + m_alarms.CheckAndSignal(); R_SUCCEED(); } -Result ServiceManager::GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time) { +Result ServiceManager::GetClosestAlarmInfo(Out out_is_valid, Out out_info, + Out out_time) { Alarm* alarm{nullptr}; - out_is_valid = m_alarms.GetClosestAlarm(&alarm); - if (out_is_valid) { - out_info = { + *out_is_valid = m_alarms.GetClosestAlarm(&alarm); + if (*out_is_valid) { + *out_info = { .alert_time = alarm->GetAlertTime(), .priority = alarm->GetPriority(), }; - out_time = m_alarms.GetRawTime(); + *out_time = m_alarms.GetRawTime(); } + + LOG_DEBUG(Service_Time, + "called. out_is_valid={} out_info.alert_time={} out_info.priority={}, out_time={}", + *out_is_valid, out_info->alert_time, out_info->priority, *out_time); + + R_SUCCEED(); +} + +void ServiceManager::CheckAndSetupServicesSAndP() { + if (m_local_system_clock.IsInitialized() && m_user_system_clock.IsInitialized() && + m_network_system_clock.IsInitialized() && m_steady_clock.IsInitialized() && + m_time_zone.IsInitialized() && m_ephemeral_network_clock.IsInitialized()) { + SetupSAndP(); + } +} + +void ServiceManager::SetupSAndP() { + if (!m_is_s_and_p_setup) { + m_is_s_and_p_setup = true; + m_server_manager.RegisterNamedService( + "time:s", std::make_shared( + m_system, StaticServiceSetupInfo{0, 0, 1, 0, 0, 0}, m_time, "time:s")); + m_server_manager.RegisterNamedService("time:p", + std::make_shared( + m_system, m_time->m_power_state_request_manager)); + } +} + +Result ServiceManager::GetStaticService(OutInterface out_service, + StaticServiceSetupInfo setup_info, const char* name) { + *out_service = std::make_shared(m_system, setup_info, m_time, name); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/service_manager.h b/src/core/hle/service/psc/time/service_manager.h index 1d9952317..25d361d4f 100755 --- a/src/core/hle/service/psc/time/service_manager.h +++ b/src/core/hle/service/psc/time/service_manager.h @@ -6,6 +6,7 @@ #include #include +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -29,55 +30,38 @@ public: ServerManager* server_manager); ~ServiceManager() override = default; - Result GetStaticServiceAsUser(std::shared_ptr& out_service); - Result GetStaticServiceAsAdmin(std::shared_ptr& out_service); - Result GetStaticServiceAsRepair(std::shared_ptr& out_service); - Result GetStaticServiceAsServiceManager(std::shared_ptr& out_service); - Result SetupStandardSteadyClockCore(Common::UUID& clock_source_id, s64 rtc_offset, - s64 internal_offset, s64 test_offset, - bool is_rtc_reset_detected); + Result GetStaticServiceAsUser(OutInterface out_service); + Result GetStaticServiceAsAdmin(OutInterface out_service); + Result GetStaticServiceAsRepair(OutInterface out_service); + Result GetStaticServiceAsServiceManager(OutInterface out_service); + Result SetupStandardSteadyClockCore(bool is_rtc_reset_detected, Common::UUID& clock_source_id, + s64 rtc_offset, s64 internal_offset, s64 test_offset); Result SetupStandardLocalSystemClockCore(SystemClockContext& context, s64 time); Result SetupStandardNetworkSystemClockCore(SystemClockContext& context, s64 accuracy); - Result SetupStandardUserSystemClockCore(SteadyClockTimePoint& time_point, - bool automatic_correction); - Result SetupTimeZoneServiceCore(LocationName& name, SteadyClockTimePoint& time_point, - RuleVersion& rule_version, u32 location_count, - std::span rule_buffer); + Result SetupStandardUserSystemClockCore(bool automatic_correction, + SteadyClockTimePoint& time_point); + Result SetupTimeZoneServiceCore(LocationName& name, RuleVersion& rule_version, + u32 location_count, SteadyClockTimePoint& time_point, + InBuffer rule_buffer); Result SetupEphemeralNetworkSystemClockCore(); - Result GetStandardLocalClockOperationEvent(Kernel::KEvent** out_event); - Result GetStandardNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event); - Result GetEphemeralNetworkClockOperationEventForServiceManager(Kernel::KEvent** out_event); - Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(Kernel::KEvent** out_event); + Result GetStandardLocalClockOperationEvent(OutCopyHandle out_event); + Result GetStandardNetworkClockOperationEventForServiceManager( + OutCopyHandle out_event); + Result GetEphemeralNetworkClockOperationEventForServiceManager( + OutCopyHandle out_event); + Result GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent( + OutCopyHandle out_event); Result SetStandardSteadyClockBaseTime(s64 base_time); - Result GetClosestAlarmUpdatedEvent(Kernel::KEvent** out_event); + Result GetClosestAlarmUpdatedEvent(OutCopyHandle out_event); Result CheckAndSignalAlarms(); - Result GetClosestAlarmInfo(bool& out_is_valid, AlarmInfo& out_info, s64& out_time); + Result GetClosestAlarmInfo(Out out_is_valid, Out out_info, Out out_time); private: void CheckAndSetupServicesSAndP(); void SetupSAndP(); - Result GetStaticService(std::shared_ptr& out_service, + Result GetStaticService(OutInterface out_service, StaticServiceSetupInfo setup_info, const char* name); - void Handle_GetStaticServiceAsUser(HLERequestContext& ctx); - void Handle_GetStaticServiceAsAdmin(HLERequestContext& ctx); - void Handle_GetStaticServiceAsRepair(HLERequestContext& ctx); - void Handle_GetStaticServiceAsServiceManager(HLERequestContext& ctx); - void Handle_SetupStandardSteadyClockCore(HLERequestContext& ctx); - void Handle_SetupStandardLocalSystemClockCore(HLERequestContext& ctx); - void Handle_SetupStandardNetworkSystemClockCore(HLERequestContext& ctx); - void Handle_SetupStandardUserSystemClockCore(HLERequestContext& ctx); - void Handle_SetupTimeZoneServiceCore(HLERequestContext& ctx); - void Handle_SetupEphemeralNetworkSystemClockCore(HLERequestContext& ctx); - void Handle_GetStandardLocalClockOperationEvent(HLERequestContext& ctx); - void Handle_GetStandardNetworkClockOperationEventForServiceManager(HLERequestContext& ctx); - void Handle_GetEphemeralNetworkClockOperationEventForServiceManager(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedEvent(HLERequestContext& ctx); - void Handle_SetStandardSteadyClockBaseTime(HLERequestContext& ctx); - void Handle_GetClosestAlarmUpdatedEvent(HLERequestContext& ctx); - void Handle_CheckAndSignalAlarms(HLERequestContext& ctx); - void Handle_GetClosestAlarmInfo(HLERequestContext& ctx); - Core::System& m_system; std::shared_ptr m_time; ServerManager& m_server_manager; diff --git a/src/core/hle/service/psc/time/static.cpp b/src/core/hle/service/psc/time/static.cpp index 6f8cf3f88..3ca3311af 100755 --- a/src/core/hle/service/psc/time/static.cpp +++ b/src/core/hle/service/psc/time/static.cpp @@ -1,9 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/clocks/ephemeral_network_system_clock_core.h" #include "core/hle/service/psc/time/clocks/standard_local_system_clock_core.h" #include "core/hle/service/psc/time/clocks/standard_network_system_clock_core.h" @@ -39,358 +41,122 @@ StaticService::StaticService(Core::System& system_, StaticServiceSetupInfo setup m_time->m_shared_memory} { // clang-format off static const FunctionInfo functions[] = { - {0, &StaticService::Handle_GetStandardUserSystemClock, "GetStandardUserSystemClock"}, - {1, &StaticService::Handle_GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, - {2, &StaticService::Handle_GetStandardSteadyClock, "GetStandardSteadyClock"}, - {3, &StaticService::Handle_GetTimeZoneService, "GetTimeZoneService"}, - {4, &StaticService::Handle_GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, - {5, &StaticService::Handle_GetEphemeralNetworkSystemClock, "GetEphemeralNetworkSystemClock"}, - {20, &StaticService::Handle_GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, - {50, &StaticService::Handle_SetStandardSteadyClockInternalOffset, "SetStandardSteadyClockInternalOffset"}, - {51, &StaticService::Handle_GetStandardSteadyClockRtcValue, "GetStandardSteadyClockRtcValue"}, - {100, &StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, - {101, &StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, - {102, &StaticService::Handle_GetStandardUserSystemClockInitialYear, "GetStandardUserSystemClockInitialYear"}, - {200, &StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient, "IsStandardNetworkSystemClockAccuracySufficient"}, - {201, &StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, - {300, &StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, - {400, &StaticService::Handle_GetClockSnapshot, "GetClockSnapshot"}, - {401, &StaticService::Handle_GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, - {500, &StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, - {501, &StaticService::Handle_CalculateSpanBetween, "CalculateSpanBetween"}, + {0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"}, + {1, D<&StaticService::GetStandardNetworkSystemClock>, "GetStandardNetworkSystemClock"}, + {2, D<&StaticService::GetStandardSteadyClock>, "GetStandardSteadyClock"}, + {3, D<&StaticService::GetTimeZoneService>, "GetTimeZoneService"}, + {4, D<&StaticService::GetStandardLocalSystemClock>, "GetStandardLocalSystemClock"}, + {5, D<&StaticService::GetEphemeralNetworkSystemClock>, "GetEphemeralNetworkSystemClock"}, + {20, D<&StaticService::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"}, + {50, D<&StaticService::SetStandardSteadyClockInternalOffset>, "SetStandardSteadyClockInternalOffset"}, + {51, D<&StaticService::GetStandardSteadyClockRtcValue>, "GetStandardSteadyClockRtcValue"}, + {100, D<&StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled>, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, + {101, D<&StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled>, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, + {102, D<&StaticService::GetStandardUserSystemClockInitialYear>, "GetStandardUserSystemClockInitialYear"}, + {200, D<&StaticService::IsStandardNetworkSystemClockAccuracySufficient>, "IsStandardNetworkSystemClockAccuracySufficient"}, + {201, D<&StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime>, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, + {300, D<&StaticService::CalculateMonotonicSystemClockBaseTimePoint>, "CalculateMonotonicSystemClockBaseTimePoint"}, + {400, D<&StaticService::GetClockSnapshot>, "GetClockSnapshot"}, + {401, D<&StaticService::GetClockSnapshotFromSystemClockContext>, "GetClockSnapshotFromSystemClockContext"}, + {500, D<&StaticService::CalculateStandardUserSystemClockDifferenceByUser>, "CalculateStandardUserSystemClockDifferenceByUser"}, + {501, D<&StaticService::CalculateSpanBetween>, "CalculateSpanBetween"}, }; // clang-format on RegisterHandlers(functions); } -Result StaticService::GetClockSnapshotImpl(ClockSnapshot& out_snapshot, - SystemClockContext& user_context, - SystemClockContext& network_context, TimeType type) { - out_snapshot.user_context = user_context; - out_snapshot.network_context = network_context; +Result StaticService::GetStandardUserSystemClock(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); - R_TRY( - m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot.steady_clock_time_point)); - - out_snapshot.is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection(); - - R_TRY(m_time_zone.GetLocationName(out_snapshot.location_name)); - - R_TRY(GetTimeFromTimePointAndContext( - &out_snapshot.user_time, out_snapshot.steady_clock_time_point, out_snapshot.user_context)); - - R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.user_calendar_time, - out_snapshot.user_calendar_additional_time, - out_snapshot.user_time)); - - if (GetTimeFromTimePointAndContext(&out_snapshot.network_time, - out_snapshot.steady_clock_time_point, - out_snapshot.network_context) != ResultSuccess) { - out_snapshot.network_time = 0; - } - - R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot.network_calendar_time, - out_snapshot.network_calendar_additional_time, - out_snapshot.network_time)); - out_snapshot.type = type; - out_snapshot.unk_CE = 0; + *out_service = std::make_shared(m_system, m_user_system_clock, + m_setup_info.can_write_user_clock, + m_setup_info.can_write_uninitialized_clock); R_SUCCEED(); } -void StaticService::Handle_GetStandardUserSystemClock(HLERequestContext& ctx) { +Result StaticService::GetStandardNetworkSystemClock(OutInterface out_service) { LOG_DEBUG(Service_Time, "called."); - std::shared_ptr service{}; - auto res = GetStandardUserSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardSteadyClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardSteadyClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetTimeZoneService(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetTimeZoneService(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetStandardLocalSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetStandardLocalSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - std::shared_ptr service{}; - auto res = GetEphemeralNetworkSystemClock(service); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(res); - rb.PushIpcInterface(std::move(service)); -} - -void StaticService::Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KSharedMemory* shared_memory{}; - auto res = GetSharedMemoryNativeHandle(&shared_memory); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(shared_memory); -} - -void StaticService::Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(m_setup_info.can_write_steady_clock ? ResultNotImplemented : ResultPermissionDenied); -} - -void StaticService::Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void StaticService::Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_enabled{}; - auto res = IsStandardUserSystemClockAutomaticCorrectionEnabled(is_enabled); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(is_enabled); -} - -void StaticService::Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto automatic_correction{rp.Pop()}; - - auto res = SetStandardUserSystemClockAutomaticCorrectionEnabled(automatic_correction); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void StaticService::Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool is_sufficient{}; - auto res = IsStandardNetworkSystemClockAccuracySufficient(is_sufficient); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(is_sufficient); -} - -void StaticService::Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - SteadyClockTimePoint time_point{}; - auto res = GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(time_point); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(time_point); -} - -void StaticService::Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw()}; - - s64 time{}; - auto res = CalculateMonotonicSystemClockBaseTimePoint(time, context); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -void StaticService::Handle_GetClockSnapshot(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto type{rp.PopEnum()}; - - ClockSnapshot snapshot{}; - auto res = GetClockSnapshot(snapshot, type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto clock_type{rp.PopEnum()}; - [[maybe_unused]] auto alignment{rp.Pop()}; - auto user_context{rp.PopRaw()}; - auto network_context{rp.PopRaw()}; - - ClockSnapshot snapshot{}; - auto res = - GetClockSnapshotFromSystemClockContext(snapshot, user_context, network_context, clock_type); - - ctx.WriteBuffer(snapshot); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void StaticService::Handle_CalculateStandardUserSystemClockDifferenceByUser( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - ClockSnapshot a{}; - ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot)); - - s64 difference{}; - auto res = CalculateStandardUserSystemClockDifferenceByUser(difference, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(difference); -} - -void StaticService::Handle_CalculateSpanBetween(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - ClockSnapshot a{}; - ClockSnapshot b{}; - - auto a_buffer{ctx.ReadBuffer(0)}; - auto b_buffer{ctx.ReadBuffer(1)}; - - std::memcpy(&a, a_buffer.data(), sizeof(ClockSnapshot)); - std::memcpy(&b, b_buffer.data(), sizeof(ClockSnapshot)); - - s64 time{}; - auto res = CalculateSpanBetween(time, a, b); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -// =============================== Implementations =========================== - -Result StaticService::GetStandardUserSystemClock(std::shared_ptr& out_service) { - out_service = std::make_shared(m_system, m_user_system_clock, - m_setup_info.can_write_user_clock, - m_setup_info.can_write_uninitialized_clock); + *out_service = std::make_shared(m_system, m_network_system_clock, + m_setup_info.can_write_network_clock, + m_setup_info.can_write_uninitialized_clock); R_SUCCEED(); } -Result StaticService::GetStandardNetworkSystemClock(std::shared_ptr& out_service) { - out_service = std::make_shared(m_system, m_network_system_clock, - m_setup_info.can_write_network_clock, - m_setup_info.can_write_uninitialized_clock); - R_SUCCEED(); -} +Result StaticService::GetStandardSteadyClock(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); -Result StaticService::GetStandardSteadyClock(std::shared_ptr& out_service) { - out_service = + *out_service = std::make_shared(m_system, m_time, m_setup_info.can_write_steady_clock, m_setup_info.can_write_uninitialized_clock); R_SUCCEED(); } -Result StaticService::GetTimeZoneService(std::shared_ptr& out_service) { - out_service = +Result StaticService::GetTimeZoneService(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + + *out_service = std::make_shared(m_system, m_time->m_standard_steady_clock, m_time_zone, m_setup_info.can_write_timezone_device_location); R_SUCCEED(); } -Result StaticService::GetStandardLocalSystemClock(std::shared_ptr& out_service) { - out_service = std::make_shared(m_system, m_local_system_clock, - m_setup_info.can_write_local_clock, - m_setup_info.can_write_uninitialized_clock); +Result StaticService::GetStandardLocalSystemClock(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + + *out_service = std::make_shared(m_system, m_local_system_clock, + m_setup_info.can_write_local_clock, + m_setup_info.can_write_uninitialized_clock); R_SUCCEED(); } -Result StaticService::GetEphemeralNetworkSystemClock(std::shared_ptr& out_service) { - out_service = std::make_shared(m_system, m_ephemeral_network_clock, - m_setup_info.can_write_network_clock, - m_setup_info.can_write_uninitialized_clock); +Result StaticService::GetEphemeralNetworkSystemClock(OutInterface out_service) { + LOG_DEBUG(Service_Time, "called."); + + *out_service = std::make_shared(m_system, m_ephemeral_network_clock, + m_setup_info.can_write_network_clock, + m_setup_info.can_write_uninitialized_clock); R_SUCCEED(); } -Result StaticService::GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory) { +Result StaticService::GetSharedMemoryNativeHandle( + OutCopyHandle out_shared_memory) { + LOG_DEBUG(Service_Time, "called."); + *out_shared_memory = &m_shared_memory.GetKSharedMemory(); R_SUCCEED(); } -Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled) { +Result StaticService::SetStandardSteadyClockInternalOffset(s64 offset_ns) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); + + R_UNLESS(m_setup_info.can_write_steady_clock, ResultPermissionDenied); + + R_RETURN(ResultNotImplemented); +} + +Result StaticService::GetStandardSteadyClockRtcValue(Out out_rtc_value) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); + + R_RETURN(ResultNotImplemented); +} + +Result StaticService::IsStandardUserSystemClockAutomaticCorrectionEnabled( + Out out_is_enabled) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_enabled={}", *out_is_enabled); }); + R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); - out_is_enabled = m_user_system_clock.GetAutomaticCorrection(); + *out_is_enabled = m_user_system_clock.GetAutomaticCorrection(); + R_SUCCEED(); } Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( bool automatic_correction) { + LOG_DEBUG(Service_Time, "called. automatic_correction={}", automatic_correction); + R_UNLESS(m_user_system_clock.IsInitialized() && m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); R_UNLESS(m_setup_info.can_write_user_clock, ResultPermissionDenied); @@ -407,22 +173,35 @@ Result StaticService::SetStandardUserSystemClockAutomaticCorrectionEnabled( R_SUCCEED(); } -Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient) { - out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); +Result StaticService::GetStandardUserSystemClockInitialYear(Out out_year) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); + + R_RETURN(ResultNotImplemented); +} + +Result StaticService::IsStandardNetworkSystemClockAccuracySufficient(Out out_is_sufficient) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_sufficient={}", *out_is_sufficient); }); + + *out_is_sufficient = m_network_system_clock.IsAccuracySufficient(); + R_SUCCEED(); } Result StaticService::GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - SteadyClockTimePoint& out_time_point) { + Out out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); + R_UNLESS(m_user_system_clock.IsInitialized(), ResultClockUninitialized); - m_user_system_clock.GetTimePoint(out_time_point); + m_user_system_clock.GetTimePoint(*out_time_point); R_SUCCEED(); } -Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, +Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(Out out_time, SystemClockContext& context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. context={} out_time={}", context, *out_time); }); + R_UNLESS(m_time->m_standard_steady_clock.IsInitialized(), ResultClockUninitialized); SteadyClockTimePoint time_point{}; @@ -433,12 +212,16 @@ Result StaticService::CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, auto one_second_ns{ std::chrono::duration_cast(std::chrono::seconds(1)).count()}; auto ticks{m_system.CoreTiming().GetClockTicks()}; - auto current_time{ConvertToTimeSpan(ticks).count()}; - out_time = ((context.offset + time_point.time_point) - (current_time / one_second_ns)); + auto current_time_ns{ConvertToTimeSpan(ticks).count()}; + *out_time = ((context.offset + time_point.time_point) - (current_time_ns / one_second_ns)); + R_SUCCEED(); } -Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type) { +Result StaticService::GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. type={} out_snapshot={}", type, *out_snapshot); }); + SystemClockContext user_context{}; R_TRY(m_user_system_clock.GetContext(user_context)); @@ -448,53 +231,101 @@ Result StaticService::GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType typ R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); } -Result StaticService::GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot, +Result StaticService::GetClockSnapshotFromSystemClockContext(TimeType type, + OutClockSnapshot out_snapshot, SystemClockContext& user_context, - SystemClockContext& network_context, - TimeType type) { + SystemClockContext& network_context) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. type={} user_context={} network_context={} out_snapshot={}", type, + user_context, network_context, *out_snapshot); + }); + R_RETURN(GetClockSnapshotImpl(out_snapshot, user_context, network_context, type)); } -Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, - ClockSnapshot& a, - ClockSnapshot& b) { +Result StaticService::CalculateStandardUserSystemClockDifferenceByUser(Out out_difference, + InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. a={} b={} out_difference={}", *a, *b, *out_difference); + }); + auto diff_s = - std::chrono::seconds(b.user_context.offset) - std::chrono::seconds(a.user_context.offset); + std::chrono::seconds(b->user_context.offset) - std::chrono::seconds(a->user_context.offset); - if (a.user_context == b.user_context || - !a.user_context.steady_time_point.IdMatches(b.user_context.steady_time_point)) { - out_time = 0; + if (a->user_context == b->user_context || + !a->user_context.steady_time_point.IdMatches(b->user_context.steady_time_point)) { + *out_difference = 0; R_SUCCEED(); } - if (!a.is_automatic_correction_enabled || !b.is_automatic_correction_enabled) { - out_time = std::chrono::duration_cast(diff_s).count(); + if (!a->is_automatic_correction_enabled || !b->is_automatic_correction_enabled) { + *out_difference = std::chrono::duration_cast(diff_s).count(); R_SUCCEED(); } - if (a.network_context.steady_time_point.IdMatches(a.steady_clock_time_point) || - b.network_context.steady_time_point.IdMatches(b.steady_clock_time_point)) { - out_time = 0; + if (a->network_context.steady_time_point.IdMatches(a->steady_clock_time_point) || + b->network_context.steady_time_point.IdMatches(b->steady_clock_time_point)) { + *out_difference = 0; R_SUCCEED(); } - out_time = std::chrono::duration_cast(diff_s).count(); + *out_difference = std::chrono::duration_cast(diff_s).count(); R_SUCCEED(); } -Result StaticService::CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b) { +Result StaticService::CalculateSpanBetween(Out out_time, InClockSnapshot a, + InClockSnapshot b) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. a={} b={} out_time={}", *a, *b, *out_time); }); + s64 time_s{}; auto res = - GetSpanBetweenTimePoints(&time_s, a.steady_clock_time_point, b.steady_clock_time_point); + GetSpanBetweenTimePoints(&time_s, a->steady_clock_time_point, b->steady_clock_time_point); if (res != ResultSuccess) { - R_UNLESS(a.network_time != 0 && b.network_time != 0, ResultTimeNotFound); - time_s = b.network_time - a.network_time; + R_UNLESS(a->network_time != 0 && b->network_time != 0, ResultTimeNotFound); + time_s = b->network_time - a->network_time; } - out_time = + *out_time = std::chrono::duration_cast(std::chrono::seconds(time_s)).count(); R_SUCCEED(); } +Result StaticService::GetClockSnapshotImpl(OutClockSnapshot out_snapshot, + SystemClockContext& user_context, + SystemClockContext& network_context, TimeType type) { + out_snapshot->user_context = user_context; + out_snapshot->network_context = network_context; + + R_TRY( + m_time->m_standard_steady_clock.GetCurrentTimePoint(out_snapshot->steady_clock_time_point)); + + out_snapshot->is_automatic_correction_enabled = m_user_system_clock.GetAutomaticCorrection(); + + R_TRY(m_time_zone.GetLocationName(out_snapshot->location_name)); + + R_TRY(GetTimeFromTimePointAndContext(&out_snapshot->user_time, + out_snapshot->steady_clock_time_point, + out_snapshot->user_context)); + + R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->user_calendar_time, + out_snapshot->user_calendar_additional_time, + out_snapshot->user_time)); + + if (GetTimeFromTimePointAndContext(&out_snapshot->network_time, + out_snapshot->steady_clock_time_point, + out_snapshot->network_context) != ResultSuccess) { + out_snapshot->network_time = 0; + } + + R_TRY(m_time_zone.ToCalendarTimeWithMyRule(out_snapshot->network_calendar_time, + out_snapshot->network_calendar_additional_time, + out_snapshot->network_time)); + out_snapshot->type = type; + out_snapshot->unk_CE = 0; + R_SUCCEED(); +} + } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/static.h b/src/core/hle/service/psc/time/static.h index 498cd5ab5..120bab259 100755 --- a/src/core/hle/service/psc/time/static.h +++ b/src/core/hle/service/psc/time/static.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/server_manager.h" @@ -29,58 +30,44 @@ class EphemeralNetworkSystemClockCore; class SharedMemory; class StaticService final : public ServiceFramework { + using InClockSnapshot = InLargeData; + using OutClockSnapshot = OutLargeData; + public: explicit StaticService(Core::System& system, StaticServiceSetupInfo setup_info, std::shared_ptr time, const char* name); ~StaticService() override = default; - Result GetStandardUserSystemClock(std::shared_ptr& out_service); - Result GetStandardNetworkSystemClock(std::shared_ptr& out_service); - Result GetStandardSteadyClock(std::shared_ptr& out_service); - Result GetTimeZoneService(std::shared_ptr& out_service); - Result GetStandardLocalSystemClock(std::shared_ptr& out_service); - Result GetEphemeralNetworkSystemClock(std::shared_ptr& out_service); - Result GetSharedMemoryNativeHandle(Kernel::KSharedMemory** out_shared_memory); - Result IsStandardUserSystemClockAutomaticCorrectionEnabled(bool& out_is_enabled); + Result GetStandardUserSystemClock(OutInterface out_service); + Result GetStandardNetworkSystemClock(OutInterface out_service); + Result GetStandardSteadyClock(OutInterface out_service); + Result GetTimeZoneService(OutInterface out_service); + Result GetStandardLocalSystemClock(OutInterface out_service); + Result GetEphemeralNetworkSystemClock(OutInterface out_service); + Result GetSharedMemoryNativeHandle(OutCopyHandle out_shared_memory); + Result SetStandardSteadyClockInternalOffset(s64 offset_ns); + Result GetStandardSteadyClockRtcValue(Out out_rtc_value); + Result IsStandardUserSystemClockAutomaticCorrectionEnabled(Out out_is_enabled); Result SetStandardUserSystemClockAutomaticCorrectionEnabled(bool automatic_correction); - Result IsStandardNetworkSystemClockAccuracySufficient(bool& out_is_sufficient); + Result GetStandardUserSystemClockInitialYear(Out out_year); + Result IsStandardNetworkSystemClockAccuracySufficient(Out out_is_sufficient); Result GetStandardUserSystemClockAutomaticCorrectionUpdatedTime( - SteadyClockTimePoint& out_time_point); - Result CalculateMonotonicSystemClockBaseTimePoint(s64& out_time, SystemClockContext& context); - Result GetClockSnapshot(ClockSnapshot& out_snapshot, TimeType type); - Result GetClockSnapshotFromSystemClockContext(ClockSnapshot& out_snapshot, + Out out_time_point); + Result CalculateMonotonicSystemClockBaseTimePoint(Out out_time, + SystemClockContext& context); + Result GetClockSnapshot(OutClockSnapshot out_snapshot, TimeType type); + Result GetClockSnapshotFromSystemClockContext(TimeType type, OutClockSnapshot out_snapshot, SystemClockContext& user_context, - SystemClockContext& network_context, - TimeType type); - Result CalculateStandardUserSystemClockDifferenceByUser(s64& out_time, ClockSnapshot& a, - ClockSnapshot& b); - Result CalculateSpanBetween(s64& out_time, ClockSnapshot& a, ClockSnapshot& b); + SystemClockContext& network_context); + Result CalculateStandardUserSystemClockDifferenceByUser(Out out_difference, + InClockSnapshot a, InClockSnapshot b); + Result CalculateSpanBetween(Out out_time, InClockSnapshot a, InClockSnapshot b); private: - Result GetClockSnapshotImpl(ClockSnapshot& out_snapshot, SystemClockContext& user_context, + Result GetClockSnapshotImpl(OutClockSnapshot out_snapshot, SystemClockContext& user_context, SystemClockContext& network_context, TimeType type); - void Handle_GetStandardUserSystemClock(HLERequestContext& ctx); - void Handle_GetStandardNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetStandardSteadyClock(HLERequestContext& ctx); - void Handle_GetTimeZoneService(HLERequestContext& ctx); - void Handle_GetStandardLocalSystemClock(HLERequestContext& ctx); - void Handle_GetEphemeralNetworkSystemClock(HLERequestContext& ctx); - void Handle_GetSharedMemoryNativeHandle(HLERequestContext& ctx); - void Handle_SetStandardSteadyClockInternalOffset(HLERequestContext& ctx); - void Handle_GetStandardSteadyClockRtcValue(HLERequestContext& ctx); - void Handle_IsStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_SetStandardUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockInitialYear(HLERequestContext& ctx); - void Handle_IsStandardNetworkSystemClockAccuracySufficient(HLERequestContext& ctx); - void Handle_GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); - void Handle_CalculateMonotonicSystemClockBaseTimePoint(HLERequestContext& ctx); - void Handle_GetClockSnapshot(HLERequestContext& ctx); - void Handle_GetClockSnapshotFromSystemClockContext(HLERequestContext& ctx); - void Handle_CalculateStandardUserSystemClockDifferenceByUser(HLERequestContext& ctx); - void Handle_CalculateSpanBetween(HLERequestContext& ctx); - Core::System& m_system; StaticServiceSetupInfo m_setup_info; std::shared_ptr m_time; diff --git a/src/core/hle/service/psc/time/steady_clock.cpp b/src/core/hle/service/psc/time/steady_clock.cpp index 1ed5c7679..948610a2b 100755 --- a/src/core/hle/service/psc/time/steady_clock.cpp +++ b/src/core/hle/service/psc/time/steady_clock.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/steady_clock.h" namespace Service::PSC::Time { @@ -14,114 +16,40 @@ SteadyClock::SteadyClock(Core::System& system_, std::shared_ptr man can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { - {0, &SteadyClock::Handle_GetCurrentTimePoint, "GetCurrentTimePoint"}, - {2, &SteadyClock::Handle_GetTestOffset, "GetTestOffset"}, - {3, &SteadyClock::Handle_SetTestOffset, "SetTestOffset"}, - {100, &SteadyClock::Handle_GetRtcValue, "GetRtcValue"}, - {101, &SteadyClock::Handle_IsRtcResetDetected, "IsRtcResetDetected"}, - {102, &SteadyClock::Handle_GetSetupResultValue, "GetSetupResultValue"}, - {200, &SteadyClock::Handle_GetInternalOffset, "GetInternalOffset"}, + {0, D<&SteadyClock::GetCurrentTimePoint>, "GetCurrentTimePoint"}, + {2, D<&SteadyClock::GetTestOffset>, "GetTestOffset"}, + {3, D<&SteadyClock::SetTestOffset>, "SetTestOffset"}, + {100, D<&SteadyClock::GetRtcValue>, "GetRtcValue"}, + {101, D<&SteadyClock::IsRtcResetDetected>, "IsRtcResetDetected"}, + {102, D<&SteadyClock::GetSetupResultValue>, "GetSetupResultValue"}, + {200, D<&SteadyClock::GetInternalOffset>, "GetInternalOffset"}, }; // clang-format on RegisterHandlers(functions); } -void SteadyClock::Handle_GetCurrentTimePoint(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result SteadyClock::GetCurrentTimePoint(Out out_time_point) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time_point={}", *out_time_point); }); - SteadyClockTimePoint time_point{}; - auto res = GetCurrentTimePoint(time_point); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SteadyClockTimePoint) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(time_point); -} - -void SteadyClock::Handle_GetTestOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 test_offset{}; - auto res = GetTestOffset(test_offset); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(test_offset); -} - -void SteadyClock::Handle_SetTestOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto test_offset{rp.Pop()}; - - auto res = SetTestOffset(test_offset); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SteadyClock::Handle_GetRtcValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 rtc_value{}; - auto res = GetRtcValue(rtc_value); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(rtc_value); -} - -void SteadyClock::Handle_IsRtcResetDetected(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - bool reset_detected{false}; - auto res = IsRtcResetDetected(reset_detected); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(reset_detected); -} - -void SteadyClock::Handle_GetSetupResultValue(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Result result_value{ResultSuccess}; - auto res = GetSetupResultValue(result_value); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(result_value); -} - -void SteadyClock::Handle_GetInternalOffset(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - s64 internal_offset{}; - auto res = GetInternalOffset(internal_offset); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(internal_offset); -} - -// =============================== Implementations =========================== - -Result SteadyClock::GetCurrentTimePoint(SteadyClockTimePoint& out_time_point) { R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetCurrentTimePoint(out_time_point)); + R_RETURN(m_clock_core.GetCurrentTimePoint(*out_time_point)); } -Result SteadyClock::GetTestOffset(s64& out_test_offset) { +Result SteadyClock::GetTestOffset(Out out_test_offset) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_test_offset={}", *out_test_offset); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_test_offset = m_clock_core.GetTestOffset(); + *out_test_offset = m_clock_core.GetTestOffset(); R_SUCCEED(); } Result SteadyClock::SetTestOffset(s64 test_offset) { + LOG_DEBUG(Service_Time, "called. test_offset={}", test_offset); + R_UNLESS(m_can_write_steady_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -130,34 +58,43 @@ Result SteadyClock::SetTestOffset(s64 test_offset) { R_SUCCEED(); } -Result SteadyClock::GetRtcValue(s64& out_rtc_value) { +Result SteadyClock::GetRtcValue(Out out_rtc_value) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rtc_value={}", *out_rtc_value); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetRtcValue(out_rtc_value)); + R_RETURN(m_clock_core.GetRtcValue(*out_rtc_value)); } -Result SteadyClock::IsRtcResetDetected(bool& out_is_detected) { +Result SteadyClock::IsRtcResetDetected(Out out_is_detected) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_is_detected={}", *out_is_detected); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_is_detected = m_clock_core.IsResetDetected(); + *out_is_detected = m_clock_core.IsResetDetected(); R_SUCCEED(); } -Result SteadyClock::GetSetupResultValue(Result& out_result) { +Result SteadyClock::GetSetupResultValue(Out out_result) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_result=0x{:X}", out_result->raw); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_result = m_clock_core.GetSetupResultValue(); + *out_result = m_clock_core.GetSetupResultValue(); R_SUCCEED(); } -Result SteadyClock::GetInternalOffset(s64& out_internal_offset) { +Result SteadyClock::GetInternalOffset(Out out_internal_offset) { + SCOPE_EXIT( + { LOG_DEBUG(Service_Time, "called. out_internal_offset={}", *out_internal_offset); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - out_internal_offset = m_clock_core.GetInternalOffset(); + *out_internal_offset = m_clock_core.GetInternalOffset(); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/steady_clock.h b/src/core/hle/service/psc/time/steady_clock.h index 115e9b138..025d758a6 100755 --- a/src/core/hle/service/psc/time/steady_clock.h +++ b/src/core/hle/service/psc/time/steady_clock.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -22,23 +23,15 @@ public: ~SteadyClock() override = default; - Result GetCurrentTimePoint(SteadyClockTimePoint& out_time_point); - Result GetTestOffset(s64& out_test_offset); + Result GetCurrentTimePoint(Out out_time_point); + Result GetTestOffset(Out out_test_offset); Result SetTestOffset(s64 test_offset); - Result GetRtcValue(s64& out_rtc_value); - Result IsRtcResetDetected(bool& out_is_detected); - Result GetSetupResultValue(Result& out_result); - Result GetInternalOffset(s64& out_internal_offset); + Result GetRtcValue(Out out_rtc_value); + Result IsRtcResetDetected(Out out_is_detected); + Result GetSetupResultValue(Out out_result); + Result GetInternalOffset(Out out_internal_offset); private: - void Handle_GetCurrentTimePoint(HLERequestContext& ctx); - void Handle_GetTestOffset(HLERequestContext& ctx); - void Handle_SetTestOffset(HLERequestContext& ctx); - void Handle_GetRtcValue(HLERequestContext& ctx); - void Handle_IsRtcResetDetected(HLERequestContext& ctx); - void Handle_GetSetupResultValue(HLERequestContext& ctx); - void Handle_GetInternalOffset(HLERequestContext& ctx); - Core::System& m_system; StandardSteadyClockCore& m_clock_core; diff --git a/src/core/hle/service/psc/time/system_clock.cpp b/src/core/hle/service/psc/time/system_clock.cpp index 13d2f1d11..0695502d5 100755 --- a/src/core/hle/service/psc/time/system_clock.cpp +++ b/src/core/hle/service/psc/time/system_clock.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/system_clock.h" namespace Service::PSC::Time { @@ -13,83 +15,28 @@ SystemClock::SystemClock(Core::System& system_, SystemClockCore& clock_core, boo can_write_uninitialized_clock} { // clang-format off static const FunctionInfo functions[] = { - {0, &SystemClock::Handle_GetCurrentTime, "GetCurrentTime"}, - {1, &SystemClock::Handle_SetCurrentTime, "SetCurrentTime"}, - {2, &SystemClock::Handle_GetSystemClockContext, "GetSystemClockContext"}, - {3, &SystemClock::Handle_SetSystemClockContext, "SetSystemClockContext"}, - {4, &SystemClock::Handle_GetOperationEventReadableHandle, "GetOperationEventReadableHandle"}, + {0, D<&SystemClock::GetCurrentTime>, "GetCurrentTime"}, + {1, D<&SystemClock::SetCurrentTime>, "SetCurrentTime"}, + {2, D<&SystemClock::GetSystemClockContext>, "GetSystemClockContext"}, + {3, D<&SystemClock::SetSystemClockContext>, "SetSystemClockContext"}, + {4, D<&SystemClock::GetOperationEventReadableHandle>, "GetOperationEventReadableHandle"}, }; // clang-format on RegisterHandlers(functions); } -void SystemClock::Handle_GetCurrentTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result SystemClock::GetCurrentTime(Out out_time) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_time={}", *out_time); }); - s64 time{}; - auto res = GetCurrentTime(time); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(res); - rb.Push(time); -} - -void SystemClock::Handle_SetCurrentTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop()}; - - auto res = SetCurrentTime(time); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SystemClock::Handle_GetSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - SystemClockContext context{}; - auto res = GetSystemClockContext(context); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(SystemClockContext) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(context); -} - -void SystemClock::Handle_SetSystemClockContext(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto context{rp.PopRaw()}; - - auto res = SetSystemClockContext(context); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void SystemClock::Handle_GetOperationEventReadableHandle(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - Kernel::KEvent* event{}; - auto res = GetOperationEventReadableHandle(&event); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(res); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -// =============================== Implementations =========================== - -Result SystemClock::GetCurrentTime(s64& out_time) { R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetCurrentTime(&out_time)); + R_RETURN(m_clock_core.GetCurrentTime(out_time.Get())); } Result SystemClock::SetCurrentTime(s64 time) { + LOG_DEBUG(Service_Time, "called. time={}", time); + R_UNLESS(m_can_write_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -97,14 +44,18 @@ Result SystemClock::SetCurrentTime(s64 time) { R_RETURN(m_clock_core.SetCurrentTime(time)); } -Result SystemClock::GetSystemClockContext(SystemClockContext& out_context) { +Result SystemClock::GetSystemClockContext(Out out_context) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_context={}", *out_context); }); + R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); - R_RETURN(m_clock_core.GetContext(out_context)); + R_RETURN(m_clock_core.GetContext(*out_context)); } Result SystemClock::SetSystemClockContext(SystemClockContext& context) { + LOG_DEBUG(Service_Time, "called. context={}", context); + R_UNLESS(m_can_write_clock, ResultPermissionDenied); R_UNLESS(m_can_write_uninitialized_clock || m_clock_core.IsInitialized(), ResultClockUninitialized); @@ -112,7 +63,10 @@ Result SystemClock::SetSystemClockContext(SystemClockContext& context) { R_RETURN(m_clock_core.SetContextAndWrite(context)); } -Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event) { +Result SystemClock::GetOperationEventReadableHandle( + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called."); + if (!m_operation_event) { m_operation_event = std::make_unique(m_system); R_UNLESS(m_operation_event != nullptr, ResultFailed); @@ -120,7 +74,7 @@ Result SystemClock::GetOperationEventReadableHandle(Kernel::KEvent** out_event) m_clock_core.LinkOperationEvent(*m_operation_event); } - *out_event = m_operation_event->m_event; + *out_event = &m_operation_event->m_event->GetReadableEvent(); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/system_clock.h b/src/core/hle/service/psc/time/system_clock.h index f30027e7b..b40d73595 100755 --- a/src/core/hle/service/psc/time/system_clock.h +++ b/src/core/hle/service/psc/time/system_clock.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -22,19 +23,13 @@ public: ~SystemClock() override = default; - Result GetCurrentTime(s64& out_time); + Result GetCurrentTime(Out out_time); Result SetCurrentTime(s64 time); - Result GetSystemClockContext(SystemClockContext& out_context); + Result GetSystemClockContext(Out out_context); Result SetSystemClockContext(SystemClockContext& context); - Result GetOperationEventReadableHandle(Kernel::KEvent** out_event); + Result GetOperationEventReadableHandle(OutCopyHandle out_event); private: - void Handle_GetCurrentTime(HLERequestContext& ctx); - void Handle_SetCurrentTime(HLERequestContext& ctx); - void Handle_GetSystemClockContext(HLERequestContext& ctx); - void Handle_SetSystemClockContext(HLERequestContext& ctx); - void Handle_GetOperationEventReadableHandle(HLERequestContext& ctx); - Core::System& m_system; SystemClockCore& m_clock_core; diff --git a/src/core/hle/service/psc/time/time_zone.cpp b/src/core/hle/service/psc/time/time_zone.cpp index cfee8f866..82ddba42f 100755 --- a/src/core/hle/service/psc/time/time_zone.cpp +++ b/src/core/hle/service/psc/time/time_zone.cpp @@ -5,7 +5,7 @@ namespace Service::PSC::Time { namespace { -constexpr Result ValidateRule(Tz::Rule& rule) { +constexpr Result ValidateRule(const Tz::Rule& rule) { if (rule.typecnt > static_cast(Tz::TZ_MAX_TYPES) || rule.timecnt > static_cast(Tz::TZ_MAX_TIMES) || rule.charcnt > static_cast(Tz::TZ_MAX_CHARS)) { @@ -26,7 +26,7 @@ constexpr Result ValidateRule(Tz::Rule& rule) { R_SUCCEED(); } -constexpr bool GetTimeZoneTime(s64& out_time, Tz::Rule& rule, s64 time, s32 index, +constexpr bool GetTimeZoneTime(s64& out_time, const Tz::Rule& rule, s64 time, s32 index, s32 index_offset) { s32 found_idx{}; s32 expected_index{index + index_offset}; @@ -107,7 +107,7 @@ Result TimeZone::GetTimePoint(SteadyClockTimePoint& out_time_point) { Result TimeZone::ToCalendarTime(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { + const Tz::Rule& rule) { std::scoped_lock l{m_mutex}; R_RETURN(ToCalendarTimeImpl(out_calendar_time, out_additional_info, time, rule)); } @@ -140,8 +140,8 @@ Result TimeZone::ParseBinaryInto(Tz::Rule& out_rule, std::span binary) R_RETURN(ParseBinaryImpl(out_rule, binary)); } -Result TimeZone::ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule) { +Result TimeZone::ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule) { std::scoped_lock l{m_mutex}; auto res = ToPosixTimeImpl(out_count, out_times, out_times_count, calendar, rule, -1); @@ -157,7 +157,7 @@ Result TimeZone::ToPosixTime(u32& out_count, std::span out_times, u32 ou R_RETURN(res); } -Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span out_times, +Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span out_times, u32 out_times_count, CalendarTime& calendar) { std::scoped_lock l{m_mutex}; @@ -183,7 +183,7 @@ Result TimeZone::ParseBinaryImpl(Tz::Rule& out_rule, std::span binary) Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { + const Tz::Rule& rule) { R_TRY(ValidateRule(rule)); Tz::CalendarTimeInternal calendar_internal{}; @@ -212,8 +212,8 @@ Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time, R_SUCCEED(); } -Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule, s32 is_dst) { +Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst) { R_TRY(ValidateRule(rule)); calendar.month -= 1; diff --git a/src/core/hle/service/psc/time/time_zone.h b/src/core/hle/service/psc/time/time_zone.h index ce2acca17..6bd8f2fda 100755 --- a/src/core/hle/service/psc/time/time_zone.h +++ b/src/core/hle/service/psc/time/time_zone.h @@ -32,23 +32,24 @@ public: Result GetTimePoint(SteadyClockTimePoint& out_time_point); Result ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule); + CalendarAdditionalInfo& out_additional_info, s64 time, + const Tz::Rule& rule); Result ToCalendarTimeWithMyRule(CalendarTime& calendar_time, CalendarAdditionalInfo& calendar_additional, s64 time); Result ParseBinary(LocationName& name, std::span binary); Result ParseBinaryInto(Tz::Rule& out_rule, std::span binary); - Result ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span out_times, u32 out_times_count, + Result ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule); + Result ToPosixTimeWithMyRule(u32& out_count, std::span out_times, u32 out_times_count, CalendarTime& calendar); private: Result ParseBinaryImpl(Tz::Rule& out_rule, std::span binary); Result ToCalendarTimeImpl(CalendarTime& out_calendar_time, CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule); - Result ToPosixTimeImpl(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar, Tz::Rule& rule, s32 is_dst); + const Tz::Rule& rule); + Result ToPosixTimeImpl(u32& out_count, std::span out_times, u32 out_times_count, + CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst); bool m_initialized{}; std::recursive_mutex m_mutex; diff --git a/src/core/hle/service/psc/time/time_zone_service.cpp b/src/core/hle/service/psc/time/time_zone_service.cpp index e304c8387..9376a0324 100755 --- a/src/core/hle/service/psc/time/time_zone_service.cpp +++ b/src/core/hle/service/psc/time/time_zone_service.cpp @@ -2,7 +2,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include + +#include "common/scope_exit.h" #include "core/core.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/psc/time/time_zone_service.h" namespace Service::PSC::Time { @@ -14,240 +17,78 @@ TimeZoneService::TimeZoneService(Core::System& system_, StandardSteadyClockCore& can_write_timezone_device_location} { // clang-format off static const FunctionInfo functions[] = { - {0, &TimeZoneService::Handle_GetDeviceLocationName, "GetDeviceLocationName"}, - {1, &TimeZoneService::Handle_SetDeviceLocationName, "SetDeviceLocationName"}, - {2, &TimeZoneService::Handle_GetTotalLocationNameCount, "GetTotalLocationNameCount"}, - {3, &TimeZoneService::Handle_LoadLocationNameList, "LoadLocationNameList"}, - {4, &TimeZoneService::Handle_LoadTimeZoneRule, "LoadTimeZoneRule"}, - {5, &TimeZoneService::Handle_GetTimeZoneRuleVersion, "GetTimeZoneRuleVersion"}, - {6, &TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime, "GetDeviceLocationNameAndUpdatedTime"}, - {7, &TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule, "SetDeviceLocationNameWithTimeZoneRule"}, - {8, &TimeZoneService::Handle_ParseTimeZoneBinary, "ParseTimeZoneBinary"}, - {20, &TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle, "GetDeviceLocationNameOperationEventReadableHandle"}, - {100, &TimeZoneService::Handle_ToCalendarTime, "ToCalendarTime"}, - {101, &TimeZoneService::Handle_ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, - {201, &TimeZoneService::Handle_ToPosixTime, "ToPosixTime"}, - {202, &TimeZoneService::Handle_ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"}, + {0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"}, + {1, D<&TimeZoneService::SetDeviceLocationName>, "SetDeviceLocationName"}, + {2, D<&TimeZoneService::GetTotalLocationNameCount>, "GetTotalLocationNameCount"}, + {3, D<&TimeZoneService::LoadLocationNameList>, "LoadLocationNameList"}, + {4, D<&TimeZoneService::LoadTimeZoneRule>, "LoadTimeZoneRule"}, + {5, D<&TimeZoneService::GetTimeZoneRuleVersion>, "GetTimeZoneRuleVersion"}, + {6, D<&TimeZoneService::GetDeviceLocationNameAndUpdatedTime>, "GetDeviceLocationNameAndUpdatedTime"}, + {7, D<&TimeZoneService::SetDeviceLocationNameWithTimeZoneRule>, "SetDeviceLocationNameWithTimeZoneRule"}, + {8, D<&TimeZoneService::ParseTimeZoneBinary>, "ParseTimeZoneBinary"}, + {20, D<&TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle>, "GetDeviceLocationNameOperationEventReadableHandle"}, + {100, D<&TimeZoneService::ToCalendarTime>, "ToCalendarTime"}, + {101, D<&TimeZoneService::ToCalendarTimeWithMyRule>, "ToCalendarTimeWithMyRule"}, + {201, D<&TimeZoneService::ToPosixTime>, "ToPosixTime"}, + {202, D<&TimeZoneService::ToPosixTimeWithMyRule>, "ToPosixTimeWithMyRule"}, }; // clang-format on RegisterHandlers(functions); } -void TimeZoneService::Handle_GetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetDeviceLocationName(Out out_location_name) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_location_name={}", *out_location_name); }); - LocationName name{}; - auto res = GetDeviceLocationName(name); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(LocationName) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(name); + R_RETURN(m_time_zone.GetLocationName(*out_location_name)); } -void TimeZoneService::Handle_SetDeviceLocationName(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::SetDeviceLocationName(LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::RequestParser rp{ctx}; - [[maybe_unused]] auto name{rp.PopRaw()}; - - if (!m_can_write_timezone_device_location) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultPermissionDenied); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_GetTotalLocationNameCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetTotalLocationNameCount(Out out_count) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_count={}", *out_count); }); - u32 count{}; - auto res = GetTotalLocationNameCount(count); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); + R_RETURN(m_time_zone.GetTotalLocationCount(*out_count)); } -void TimeZoneService::Handle_LoadLocationNameList(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::LoadLocationNameList( + Out out_count, OutArray out_names, u32 index) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_LoadTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule, LocationName& location_name) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); + R_RETURN(ResultNotImplemented); } -void TimeZoneService::Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetTimeZoneRuleVersion(Out out_rule_version) { + SCOPE_EXIT({ LOG_DEBUG(Service_Time, "called. out_rule_version={}", *out_rule_version); }); - RuleVersion rule_version{}; - auto res = GetTimeZoneRuleVersion(rule_version); - - IPC::ResponseBuilder rb{ctx, 2 + sizeof(RuleVersion) / sizeof(u32)}; - rb.Push(res); - rb.PushRaw(rule_version); + R_RETURN(m_time_zone.GetRuleVersion(*out_rule_version)); } -void TimeZoneService::Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime( + Out out_location_name, Out out_time_point) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. out_location_name={} out_time_point={}", + *out_location_name, *out_time_point); + }); - LocationName name{}; - SteadyClockTimePoint time_point{}; - auto res = GetDeviceLocationNameAndUpdatedTime(time_point, name); - - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(LocationName) / sizeof(u32)) + - (sizeof(SteadyClockTimePoint) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(name); - rb.PushRaw(time_point); + R_TRY(m_time_zone.GetLocationName(*out_location_name)); + R_RETURN(m_time_zone.GetTimePoint(*out_time_point)); } -void TimeZoneService::Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); +Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule( + LocationName& location_name, InBuffer binary) { + LOG_DEBUG(Service_Time, "called. location_name={}", location_name); - IPC::RequestParser rp{ctx}; - auto name{rp.PopRaw()}; - - auto binary{ctx.ReadBuffer()}; - auto res = SetDeviceLocationNameWithTimeZoneRule(name, binary); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_ParseTimeZoneBinary(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - auto binary{ctx.ReadBuffer()}; - - Tz::Rule rule{}; - auto res = ParseTimeZoneBinary(rule, binary); - - ctx.WriteBuffer(rule); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void TimeZoneService::Handle_GetDeviceLocationNameOperationEventReadableHandle( - HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNotImplemented); -} - -void TimeZoneService::Handle_ToCalendarTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop()}; - - auto rule_buffer{ctx.ReadBuffer()}; - Tz::Rule rule{}; - std::memcpy(&rule, rule_buffer.data(), sizeof(Tz::Rule)); - - CalendarTime calendar_time{}; - CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTime(calendar_time, additional_info, time, rule); - - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) + - (sizeof(CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(calendar_time); - rb.PushRaw(additional_info); -} - -void TimeZoneService::Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto time{rp.Pop()}; - - CalendarTime calendar_time{}; - CalendarAdditionalInfo additional_info{}; - auto res = ToCalendarTimeWithMyRule(calendar_time, additional_info, time); - - IPC::ResponseBuilder rb{ctx, 2 + (sizeof(CalendarTime) / sizeof(u32)) + - (sizeof(CalendarAdditionalInfo) / sizeof(u32))}; - rb.Push(res); - rb.PushRaw(calendar_time); - rb.PushRaw(additional_info); -} - -void TimeZoneService::Handle_ToPosixTime(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw()}; - - auto binary{ctx.ReadBuffer()}; - - Tz::Rule rule{}; - std::memcpy(&rule, binary.data(), sizeof(Tz::Rule)); - - u32 count{}; - std::array times{}; - u32 times_count{static_cast(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTime(count, times, times_count, calendar, rule); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -void TimeZoneService::Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx) { - LOG_DEBUG(Service_Time, "called."); - - IPC::RequestParser rp{ctx}; - auto calendar{rp.PopRaw()}; - - u32 count{}; - std::array times{}; - u32 times_count{static_cast(ctx.GetWriteBufferSize() / sizeof(s64))}; - - auto res = ToPosixTimeWithMyRule(count, times, times_count, calendar); - - ctx.WriteBuffer(times); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(res); - rb.Push(count); -} - -// =============================== Implementations =========================== - -Result TimeZoneService::GetDeviceLocationName(LocationName& out_location_name) { - R_RETURN(m_time_zone.GetLocationName(out_location_name)); -} - -Result TimeZoneService::GetTotalLocationNameCount(u32& out_count) { - R_RETURN(m_time_zone.GetTotalLocationCount(out_count)); -} - -Result TimeZoneService::GetTimeZoneRuleVersion(RuleVersion& out_rule_version) { - R_RETURN(m_time_zone.GetRuleVersion(out_rule_version)); -} - -Result TimeZoneService::GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point, - LocationName& location_name) { - R_TRY(m_time_zone.GetLocationName(location_name)); - R_RETURN(m_time_zone.GetTimePoint(out_time_point)); -} - -Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name, - std::span binary) { R_UNLESS(m_can_write_timezone_device_location, ResultPermissionDenied); R_TRY(m_time_zone.ParseBinary(location_name, binary)); @@ -258,32 +99,71 @@ Result TimeZoneService::SetDeviceLocationNameWithTimeZoneRule(LocationName& loca R_SUCCEED(); } -Result TimeZoneService::ParseTimeZoneBinary(Tz::Rule& out_rule, std::span binary) { - R_RETURN(m_time_zone.ParseBinaryInto(out_rule, binary)); +Result TimeZoneService::ParseTimeZoneBinary(OutRule out_rule, + InBuffer binary) { + LOG_DEBUG(Service_Time, "called."); + + R_RETURN(m_time_zone.ParseBinaryInto(*out_rule, binary)); } -Result TimeZoneService::ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, - Tz::Rule& rule) { - R_RETURN(m_time_zone.ToCalendarTime(out_calendar_time, out_additional_info, time, rule)); +Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle out_event) { + LOG_DEBUG(Service_Time, "called. This function is not implemented!"); + + R_RETURN(ResultNotImplemented); } -Result TimeZoneService::ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, - s64 time) { - R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(out_calendar_time, out_additional_info, time)); -} +Result TimeZoneService::ToCalendarTime(Out out_calendar_time, + Out out_additional_info, s64 time, + InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); -Result TimeZoneService::ToPosixTime(u32& out_count, std::span out_times, - u32 out_times_count, CalendarTime& calendar_time, - Tz::Rule& rule) { - R_RETURN(m_time_zone.ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule)); -} - -Result TimeZoneService::ToPosixTimeWithMyRule(u32& out_count, std::span out_times, - u32 out_times_count, CalendarTime& calendar_time) { R_RETURN( - m_time_zone.ToPosixTimeWithMyRule(out_count, out_times, out_times_count, calendar_time)); + m_time_zone.ToCalendarTime(*out_calendar_time, *out_additional_info, time, *rule.Get())); +} + +Result TimeZoneService::ToCalendarTimeWithMyRule(Out out_calendar_time, + Out out_additional_info, + s64 time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, "called. time={} out_calendar_time={} out_additional_info={}", time, + *out_calendar_time, *out_additional_info); + }); + + R_RETURN(m_time_zone.ToCalendarTimeWithMyRule(*out_calendar_time, *out_additional_info, time)); +} + +Result TimeZoneService::ToPosixTime(Out out_count, + OutArray out_times, + Out out_times_count, CalendarTime& calendar_time, + InRule rule) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); + + R_RETURN( + m_time_zone.ToPosixTime(*out_count, out_times, *out_times_count, calendar_time, *rule)); +} + +Result TimeZoneService::ToPosixTimeWithMyRule(Out out_count, + OutArray out_times, + Out out_times_count, + CalendarTime& calendar_time) { + SCOPE_EXIT({ + LOG_DEBUG(Service_Time, + "called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} " + "out_times_count={}", + calendar_time, *out_count, out_times[0], out_times[1], *out_times_count); + }); + + R_RETURN( + m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, *out_times_count, calendar_time)); } } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/time_zone_service.h b/src/core/hle/service/psc/time/time_zone_service.h index 074c1d4ae..084e3f907 100755 --- a/src/core/hle/service/psc/time/time_zone_service.h +++ b/src/core/hle/service/psc/time/time_zone_service.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/cmif_types.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/manager.h" @@ -20,45 +21,41 @@ struct Rule; namespace Service::PSC::Time { class TimeZoneService final : public ServiceFramework { + using InRule = InLargeData; + using OutRule = OutLargeData; + public: explicit TimeZoneService(Core::System& system, StandardSteadyClockCore& clock_core, TimeZone& time_zone, bool can_write_timezone_device_location); ~TimeZoneService() override = default; - Result GetDeviceLocationName(LocationName& out_location_name); - Result GetTotalLocationNameCount(u32& out_count); - Result GetTimeZoneRuleVersion(RuleVersion& out_rule_version); - Result GetDeviceLocationNameAndUpdatedTime(SteadyClockTimePoint& out_time_point, - LocationName& location_name); + Result GetDeviceLocationName(Out out_location_name); + Result SetDeviceLocationName(LocationName& location_name); + Result GetTotalLocationNameCount(Out out_count); + Result LoadLocationNameList(Out out_count, + OutArray out_names, + u32 index); + Result LoadTimeZoneRule(OutRule out_rule, LocationName& location_name); + Result GetTimeZoneRuleVersion(Out out_rule_version); + Result GetDeviceLocationNameAndUpdatedTime(Out location_name, + Out out_time_point); Result SetDeviceLocationNameWithTimeZoneRule(LocationName& location_name, - std::span binary); - Result ParseTimeZoneBinary(Tz::Rule& out_rule, std::span binary); - Result ToCalendarTime(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time, Tz::Rule& rule); - Result ToCalendarTimeWithMyRule(CalendarTime& out_calendar_time, - CalendarAdditionalInfo& out_additional_info, s64 time); - Result ToPosixTime(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar_time, Tz::Rule& rule); - Result ToPosixTimeWithMyRule(u32& out_count, std::span out_times, u32 out_times_count, - CalendarTime& calendar_time); + InBuffer binary); + Result ParseTimeZoneBinary(OutRule out_rule, InBuffer binary); + Result GetDeviceLocationNameOperationEventReadableHandle( + OutCopyHandle out_event); + Result ToCalendarTime(Out out_calendar_time, + Out out_additional_info, s64 time, InRule rule); + Result ToCalendarTimeWithMyRule(Out out_calendar_time, + Out out_additional_info, s64 time); + Result ToPosixTime(Out out_count, OutArray out_times, + Out out_times_count, CalendarTime& calendar_time, InRule rule); + Result ToPosixTimeWithMyRule(Out out_count, + OutArray out_times, + Out out_times_count, CalendarTime& calendar_time); private: - void Handle_GetDeviceLocationName(HLERequestContext& ctx); - void Handle_SetDeviceLocationName(HLERequestContext& ctx); - void Handle_GetTotalLocationNameCount(HLERequestContext& ctx); - void Handle_LoadLocationNameList(HLERequestContext& ctx); - void Handle_LoadTimeZoneRule(HLERequestContext& ctx); - void Handle_GetTimeZoneRuleVersion(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameAndUpdatedTime(HLERequestContext& ctx); - void Handle_SetDeviceLocationNameWithTimeZoneRule(HLERequestContext& ctx); - void Handle_ParseTimeZoneBinary(HLERequestContext& ctx); - void Handle_GetDeviceLocationNameOperationEventReadableHandle(HLERequestContext& ctx); - void Handle_ToCalendarTime(HLERequestContext& ctx); - void Handle_ToCalendarTimeWithMyRule(HLERequestContext& ctx); - void Handle_ToPosixTime(HLERequestContext& ctx); - void Handle_ToPosixTimeWithMyRule(HLERequestContext& ctx); - Core::System& m_system; StandardSteadyClockCore& m_clock_core; diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 88a305f03..16ded43bf 100755 --- a/src/core/hle/service/set/setting_formats/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/settings.h" #include "core/hle/service/set/setting_formats/system_settings.h" namespace Service::Set { @@ -52,6 +53,17 @@ SystemSettings DefaultSystemSettings() { settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; settings.vibration_master_volume = 1.0f; + const auto language_code = + available_language_codes[static_cast(::Settings::values.language_index.GetValue())]; + const auto key_code = + std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), + [=](const auto& element) { return element.first == language_code; }); + + settings.keyboard_layout = KeyboardLayout::EnglishUs; + if (key_code != language_to_layout.end()) { + settings.keyboard_layout = key_code->second; + } + return settings; } diff --git a/src/core/hle/service/set/setting_formats/system_settings.h b/src/core/hle/service/set/setting_formats/system_settings.h index af5929fa9..ebc373da5 100755 --- a/src/core/hle/service/set/setting_formats/system_settings.h +++ b/src/core/hle/service/set/setting_formats/system_settings.h @@ -213,10 +213,9 @@ struct SystemSettings { // nn::settings::system::AudioVolume std::array audio_volume_type0; std::array audio_volume_type1; - // nn::settings::system::AudioOutputMode - s32 audio_output_mode_type0; - s32 audio_output_mode_type1; - s32 audio_output_mode_type2; + AudioOutputMode audio_output_mode_hdmi; + AudioOutputMode audio_output_mode_speaker; + AudioOutputMode audio_output_mode_headphone; bool force_mute_on_headphone_removed; INSERT_PADDING_BYTES(0x3); s32 headphone_volume_warning_count; @@ -224,9 +223,8 @@ struct SystemSettings { INSERT_PADDING_BYTES(0x3); // nn::settings::system::AudioVolume std::array audio_volume_type2; - // nn::settings::system::AudioOutputMode - s32 audio_output_mode_type3; - s32 audio_output_mode_type4; + AudioOutputMode audio_output_mode_type3; + AudioOutputMode audio_output_mode_type4; bool hearing_protection_safeguard_flag; INSERT_PADDING_BYTES(0x3); INSERT_PADDING_BYTES(0x4); // Reserved diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 968425319..ceb85b82a 100755 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h @@ -23,9 +23,12 @@ enum class AudioOutputMode : u32 { /// This is nn::settings::system::AudioOutputModeTarget enum class AudioOutputModeTarget : u32 { + None, Hdmi, Speaker, Headphone, + Type3, + Type4, }; /// This is nn::settings::system::AudioVolumeTarget @@ -367,6 +370,12 @@ struct AccountNotificationSettings { static_assert(sizeof(AccountNotificationSettings) == 0x18, "AccountNotificationSettings is an invalid size"); +/// This is nn::settings::factory::BatteryLot +struct BatteryLot { + std::array lot_number; +}; +static_assert(sizeof(BatteryLot) == 0x18, "BatteryLot is an invalid size"); + /// This is nn::settings::system::EulaVersion struct EulaVersion { u32 version; @@ -436,6 +445,12 @@ struct NotificationSettings { }; static_assert(sizeof(NotificationSettings) == 0x18, "NotificationSettings is an invalid size"); +/// This is nn::settings::factory::SerialNumber +struct SerialNumber { + std::array serial_number; +}; +static_assert(sizeof(SerialNumber) == 0x18, "SerialNumber is an invalid size"); + /// This is nn::settings::system::SleepSettings struct SleepSettings { SleepFlag flags; diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index b80655d2f..100cb2db4 100755 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -25,7 +25,7 @@ namespace Service::Set { namespace { -constexpr u32 SETTINGS_VERSION{1u}; +constexpr u32 SETTINGS_VERSION{2u}; constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); struct SettingsHeader { u64 magic; @@ -131,10 +131,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {40, &ISystemSettingsServer::SetTvSettings, "SetTvSettings"}, {41, nullptr, "GetEdid"}, {42, nullptr, "SetEdid"}, - {43, nullptr, "GetAudioOutputMode"}, - {44, nullptr, "SetAudioOutputMode"}, - {45, &ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved, "IsForceMuteOnHeadphoneRemoved"}, - {46, &ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved, "SetForceMuteOnHeadphoneRemoved"}, + {43, &ISystemSettingsServer::GetAudioOutputMode, "GetAudioOutputMode"}, + {44, &ISystemSettingsServer::SetAudioOutputMode, "SetAudioOutputMode"}, + {45, &ISystemSettingsServer::GetSpeakerAutoMuteFlag , "GetSpeakerAutoMuteFlag"}, + {46, &ISystemSettingsServer::SetSpeakerAutoMuteFlag , "SetSpeakerAutoMuteFlag"}, {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"}, {48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"}, {49, nullptr, "GetDataDeletionSettings"}, @@ -155,8 +155,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"}, {65, nullptr, "GetUsb30EnableFlag"}, {66, nullptr, "SetUsb30EnableFlag"}, - {67, nullptr, "GetBatteryLot"}, - {68, nullptr, "GetSerialNumber"}, + {67, &ISystemSettingsServer::GetBatteryLot, "GetBatteryLot"}, + {68, &ISystemSettingsServer::GetSerialNumber, "GetSerialNumber"}, {69, &ISystemSettingsServer::GetNfcEnableFlag, "GetNfcEnableFlag"}, {70, &ISystemSettingsServer::SetNfcEnableFlag, "SetNfcEnableFlag"}, {71, &ISystemSettingsServer::GetSleepSettings, "GetSleepSettings"}, @@ -184,11 +184,11 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {93, nullptr, "AcquireFatalDirtyFlagEventHandle"}, {94, nullptr, "GetFatalDirtyFlags"}, {95, &ISystemSettingsServer::GetAutoUpdateEnableFlag, "GetAutoUpdateEnableFlag"}, - {96, nullptr, "SetAutoUpdateEnableFlag"}, + {96, &ISystemSettingsServer::SetAutoUpdateEnableFlag, "SetAutoUpdateEnableFlag"}, {97, nullptr, "GetNxControllerSettings"}, {98, nullptr, "SetNxControllerSettings"}, {99, &ISystemSettingsServer::GetBatteryPercentageFlag, "GetBatteryPercentageFlag"}, - {100, nullptr, "SetBatteryPercentageFlag"}, + {100, &ISystemSettingsServer::SetBatteryPercentageFlag, "SetBatteryPercentageFlag"}, {101, nullptr, "GetExternalRtcResetFlag"}, {102, nullptr, "SetExternalRtcResetFlag"}, {103, nullptr, "GetUsbFullKeyEnableFlag"}, @@ -208,12 +208,12 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {117, nullptr, "GetHeadphoneVolumeUpdateFlag"}, {118, nullptr, "SetHeadphoneVolumeUpdateFlag"}, {119, nullptr, "NeedsToUpdateHeadphoneVolume"}, - {120, nullptr, "GetPushNotificationActivityModeOnSleep"}, - {121, nullptr, "SetPushNotificationActivityModeOnSleep"}, + {120, &ISystemSettingsServer::GetPushNotificationActivityModeOnSleep, "GetPushNotificationActivityModeOnSleep"}, + {121, &ISystemSettingsServer::SetPushNotificationActivityModeOnSleep, "SetPushNotificationActivityModeOnSleep"}, {122, nullptr, "GetServiceDiscoveryControlSettings"}, {123, nullptr, "SetServiceDiscoveryControlSettings"}, {124, &ISystemSettingsServer::GetErrorReportSharePermission, "GetErrorReportSharePermission"}, - {125, nullptr, "SetErrorReportSharePermission"}, + {125, &ISystemSettingsServer::SetErrorReportSharePermission, "SetErrorReportSharePermission"}, {126, &ISystemSettingsServer::GetAppletLaunchFlags, "GetAppletLaunchFlags"}, {127, &ISystemSettingsServer::SetAppletLaunchFlags, "SetAppletLaunchFlags"}, {128, nullptr, "GetConsoleSixAxisSensorAccelerationBias"}, @@ -225,7 +225,7 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {134, nullptr, "GetConsoleSixAxisSensorAngularVelocityGain"}, {135, nullptr, "SetConsoleSixAxisSensorAngularVelocityGain"}, {136, &ISystemSettingsServer::GetKeyboardLayout, "GetKeyboardLayout"}, - {137, nullptr, "SetKeyboardLayout"}, + {137, &ISystemSettingsServer::SetKeyboardLayout, "SetKeyboardLayout"}, {138, nullptr, "GetWebInspectorFlag"}, {139, nullptr, "GetAllowedSslHosts"}, {140, nullptr, "GetHostFsMountPoint"}, @@ -291,8 +291,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {200, nullptr, "SetButtonConfigRegisteredSettings"}, {201, &ISystemSettingsServer::GetFieldTestingFlag, "GetFieldTestingFlag"}, {202, nullptr, "SetFieldTestingFlag"}, - {203, nullptr, "GetPanelCrcMode"}, - {204, nullptr, "SetPanelCrcMode"}, + {203, &ISystemSettingsServer::GetPanelCrcMode, "GetPanelCrcMode"}, + {204, &ISystemSettingsServer::SetPanelCrcMode, "SetPanelCrcMode"}, {205, nullptr, "GetNxControllerSettingsEx"}, {206, nullptr, "SetNxControllerSettingsEx"}, {207, nullptr, "GetHearingProtectionSafeguardFlag"}, @@ -349,7 +349,7 @@ bool ISystemSettingsServer::LoadSettingsFile(std::filesystem::path& path, auto&& } SettingsHeader hdr{}; file.read(reinterpret_cast(&hdr), sizeof(hdr)); - return hdr.magic == SETTINGS_MAGIC && hdr.version == SETTINGS_VERSION; + return hdr.magic == SETTINGS_MAGIC && hdr.version >= SETTINGS_VERSION; }; if (!exists || !file_size_ok) { @@ -390,7 +390,7 @@ bool ISystemSettingsServer::StoreSettingsFile(std::filesystem::path& path, auto& } auto settings_base = path / "settings"; - auto settings_tmp_file = settings_base; + std::filesystem::path settings_tmp_file = settings_base; settings_tmp_file = settings_tmp_file.replace_extension("tmp"); std::ofstream file(settings_tmp_file, std::ios::binary | std::ios::out); if (!file.is_open()) { @@ -817,7 +817,34 @@ void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) { rb.Push(ResultSuccess); } -void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) { +void ISystemSettingsServer::GetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum()}; + + AudioOutputMode output_mode{}; + const auto result = GetAudioOutputMode(output_mode, target); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(result); + rb.PushEnum(output_mode); +} + +void ISystemSettingsServer::SetAudioOutputMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto target{rp.PopEnum()}; + const auto output_mode{rp.PopEnum()}; + + const auto result = SetAudioOutputMode(target, output_mode); + + LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + +void ISystemSettingsServer::GetSpeakerAutoMuteFlag(HLERequestContext& ctx) { LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}", m_system_settings.force_mute_on_headphone_removed); @@ -826,7 +853,7 @@ void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx rb.PushRaw(m_system_settings.force_mute_on_headphone_removed); } -void ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) { +void ISystemSettingsServer::SetSpeakerAutoMuteFlag(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; m_system_settings.force_mute_on_headphone_removed = rp.PopRaw(); SetSaveNeeded(); @@ -969,6 +996,26 @@ void ISystemSettingsServer::SetPrimaryAlbumStorage(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void ISystemSettingsServer::GetBatteryLot(HLERequestContext& ctx) { + BatteryLot battery_lot = {"YUZUEMULATOR123456789"}; + + LOG_INFO(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 8}; + rb.Push(ResultSuccess); + rb.PushRaw(battery_lot); +} + +void ISystemSettingsServer::GetSerialNumber(HLERequestContext& ctx) { + SerialNumber console_serial = {"YUZ10012345678"}; + + LOG_INFO(Service_SET, "called"); + + IPC::ResponseBuilder rb{ctx, 8}; + rb.Push(ResultSuccess); + rb.PushRaw(console_serial); +} + void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) { LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag); @@ -1132,6 +1179,17 @@ void ISystemSettingsServer::GetAutoUpdateEnableFlag(HLERequestContext& ctx) { rb.Push(m_system_settings.auto_update_enable_flag); } +void ISystemSettingsServer::SetAutoUpdateEnableFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.auto_update_enable_flag = rp.Pop(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, auto_update_flag={}", m_system_settings.auto_update_enable_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { LOG_DEBUG(Service_SET, "called, battery_percentage_flag={}", m_system_settings.battery_percentage_flag); @@ -1141,6 +1199,18 @@ void ISystemSettingsServer::GetBatteryPercentageFlag(HLERequestContext& ctx) { rb.Push(m_system_settings.battery_percentage_flag); } +void ISystemSettingsServer::SetBatteryPercentageFlag(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.battery_percentage_flag = rp.Pop(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, battery_percentage_flag={}", + m_system_settings.battery_percentage_flag); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestContext& ctx) { LOG_DEBUG(Service_SET, "called."); @@ -1164,6 +1234,27 @@ void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestConte rb.Push(offset); } +void ISystemSettingsServer::GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", + m_system_settings.push_notification_activity_mode_on_sleep); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.push_notification_activity_mode_on_sleep); +} + +void ISystemSettingsServer::SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.push_notification_activity_mode_on_sleep = rp.Pop(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, push_notification_activity_mode_on_sleep={}", + m_system_settings.push_notification_activity_mode_on_sleep); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx) { LOG_INFO(Service_SET, "called, error_report_share_permission={}", m_system_settings.error_report_share_permission); @@ -1173,6 +1264,18 @@ void ISystemSettingsServer::GetErrorReportSharePermission(HLERequestContext& ctx rb.PushEnum(m_system_settings.error_report_share_permission); } +void ISystemSettingsServer::SetErrorReportSharePermission(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.error_report_share_permission = rp.PopEnum(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, error_report_share_permission={}", + m_system_settings.error_report_share_permission); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISystemSettingsServer::GetAppletLaunchFlags(HLERequestContext& ctx) { LOG_INFO(Service_SET, "called, applet_launch_flag={}", m_system_settings.applet_launch_flag); @@ -1193,22 +1296,22 @@ void ISystemSettingsServer::SetAppletLaunchFlags(HLERequestContext& ctx) { } void ISystemSettingsServer::GetKeyboardLayout(HLERequestContext& ctx) { - const auto language_code = - available_language_codes[static_cast(::Settings::values.language_index.GetValue())]; - const auto key_code = - std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), - [=](const auto& element) { return element.first == language_code; }); - - KeyboardLayout selected_keyboard_layout = KeyboardLayout::EnglishUs; - if (key_code != language_to_layout.end()) { - selected_keyboard_layout = key_code->second; - } - - LOG_INFO(Service_SET, "called, selected_keyboard_layout={}", selected_keyboard_layout); + LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(static_cast(selected_keyboard_layout)); + rb.Push(static_cast(m_system_settings.keyboard_layout)); +} + +void ISystemSettingsServer::SetKeyboardLayout(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.keyboard_layout = rp.PopRaw(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, keyboard_layout={}", m_system_settings.keyboard_layout); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); } void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx) { @@ -1300,6 +1403,25 @@ void ISystemSettingsServer::GetFieldTestingFlag(HLERequestContext& ctx) { rb.Push(m_system_settings.field_testing_flag); } +void ISystemSettingsServer::GetPanelCrcMode(HLERequestContext& ctx) { + LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(m_system_settings.panel_crc_mode); +} + +void ISystemSettingsServer::SetPanelCrcMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + m_system_settings.panel_crc_mode = rp.PopRaw(); + SetSaveNeeded(); + + LOG_INFO(Service_SET, "called, panel_crc_mode={}", m_system_settings.panel_crc_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISystemSettingsServer::SetupSettings() { auto system_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000050"; @@ -1390,6 +1512,66 @@ Result ISystemSettingsServer::SetVibrationMasterVolume(f32 volume) { R_SUCCEED(); } +Result ISystemSettingsServer::GetAudioOutputMode(AudioOutputMode& out_output_mode, + AudioOutputModeTarget target) const { + switch (target) { + case AudioOutputModeTarget::Hdmi: + out_output_mode = m_system_settings.audio_output_mode_hdmi; + break; + case AudioOutputModeTarget::Speaker: + out_output_mode = m_system_settings.audio_output_mode_speaker; + break; + case AudioOutputModeTarget::Headphone: + out_output_mode = m_system_settings.audio_output_mode_headphone; + break; + case AudioOutputModeTarget::Type3: + out_output_mode = m_system_settings.audio_output_mode_type3; + break; + case AudioOutputModeTarget::Type4: + out_output_mode = m_system_settings.audio_output_mode_type4; + break; + default: + LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); + } + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetAudioOutputMode(AudioOutputModeTarget target, + AudioOutputMode output_mode) { + switch (target) { + case AudioOutputModeTarget::Hdmi: + m_system_settings.audio_output_mode_hdmi = output_mode; + break; + case AudioOutputModeTarget::Speaker: + m_system_settings.audio_output_mode_speaker = output_mode; + break; + case AudioOutputModeTarget::Headphone: + m_system_settings.audio_output_mode_headphone = output_mode; + break; + case AudioOutputModeTarget::Type3: + m_system_settings.audio_output_mode_type3 = output_mode; + break; + case AudioOutputModeTarget::Type4: + m_system_settings.audio_output_mode_type4 = output_mode; + break; + default: + LOG_ERROR(Service_SET, "Invalid audio output mode target {}", target); + } + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetSpeakerAutoMuteFlag(bool& is_auto_mute) const { + is_auto_mute = m_system_settings.force_mute_on_headphone_removed; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetSpeakerAutoMuteFlag(bool is_auto_mute) { + m_system_settings.force_mute_on_headphone_removed = is_auto_mute; + SetSaveNeeded(); + R_SUCCEED(); +} + Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const { out_id = m_private_settings.external_clock_source_id; R_SUCCEED(); diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index acbda8b8c..1982b9723 100755 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -50,6 +50,10 @@ public: Result GetVibrationMasterVolume(f32& out_volume) const; Result SetVibrationMasterVolume(f32 volume); + Result GetAudioOutputMode(AudioOutputMode& out_output_mode, AudioOutputModeTarget target) const; + Result SetAudioOutputMode(AudioOutputModeTarget target, AudioOutputMode output_mode); + Result GetSpeakerAutoMuteFlag(bool& is_auto_mute) const; + Result SetSpeakerAutoMuteFlag(bool auto_mute); Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const; Result SetExternalSteadyClockSourceId(const Common::UUID& id); Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const; @@ -97,8 +101,10 @@ private: void GetSettingsItemValue(HLERequestContext& ctx); void GetTvSettings(HLERequestContext& ctx); void SetTvSettings(HLERequestContext& ctx); - void IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx); - void SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx); + void GetAudioOutputMode(HLERequestContext& ctx); + void SetAudioOutputMode(HLERequestContext& ctx); + void GetSpeakerAutoMuteFlag(HLERequestContext& ctx); + void SetSpeakerAutoMuteFlag(HLERequestContext& ctx); void GetDebugModeFlag(HLERequestContext& ctx); void GetQuestFlag(HLERequestContext& ctx); void SetQuestFlag(HLERequestContext& ctx); @@ -111,6 +117,8 @@ private: void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx); void GetPrimaryAlbumStorage(HLERequestContext& ctx); void SetPrimaryAlbumStorage(HLERequestContext& ctx); + void GetBatteryLot(HLERequestContext& ctx); + void GetSerialNumber(HLERequestContext& ctx); void GetNfcEnableFlag(HLERequestContext& ctx); void SetNfcEnableFlag(HLERequestContext& ctx); void GetSleepSettings(HLERequestContext& ctx); @@ -126,13 +134,19 @@ private: void SetBluetoothEnableFlag(HLERequestContext& ctx); void GetMiiAuthorId(HLERequestContext& ctx); void GetAutoUpdateEnableFlag(HLERequestContext& ctx); + void SetAutoUpdateEnableFlag(HLERequestContext& ctx); void GetBatteryPercentageFlag(HLERequestContext& ctx); + void SetBatteryPercentageFlag(HLERequestContext& ctx); void SetExternalSteadyClockInternalOffset(HLERequestContext& ctx); void GetExternalSteadyClockInternalOffset(HLERequestContext& ctx); + void GetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); + void SetPushNotificationActivityModeOnSleep(HLERequestContext& ctx); void GetErrorReportSharePermission(HLERequestContext& ctx); + void SetErrorReportSharePermission(HLERequestContext& ctx); void GetAppletLaunchFlags(HLERequestContext& ctx); void SetAppletLaunchFlags(HLERequestContext& ctx); void GetKeyboardLayout(HLERequestContext& ctx); + void SetKeyboardLayout(HLERequestContext& ctx); void GetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); void SetDeviceTimeZoneLocationUpdatedTime(HLERequestContext& ctx); void GetUserSystemClockAutomaticCorrectionUpdatedTime(HLERequestContext& ctx); @@ -141,6 +155,8 @@ private: void GetHomeMenuScheme(HLERequestContext& ctx); void GetHomeMenuSchemeModel(HLERequestContext& ctx); void GetFieldTestingFlag(HLERequestContext& ctx); + void GetPanelCrcMode(HLERequestContext& ctx); + void SetPanelCrcMode(HLERequestContext& ctx); bool LoadSettingsFile(std::filesystem::path& path, auto&& default_func); bool StoreSettingsFile(std::filesystem::path& path, auto& settings); diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt index 9a762b266..53ec57c49 100755 --- a/src/dedicated_room/CMakeLists.txt +++ b/src/dedicated_room/CMakeLists.txt @@ -7,8 +7,6 @@ add_executable(yuzu-room yuzu_room.rc ) -create_target_directory_groups(yuzu-room) - target_link_libraries(yuzu-room PRIVATE common network) if (ENABLE_WEB_SERVICE) target_compile_definitions(yuzu-room PRIVATE -DENABLE_WEB_SERVICE) @@ -28,3 +26,5 @@ endif() if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(yuzu-room PRIVATE precompiled_headers.h) endif() + +create_target_directory_groups(yuzu-room) diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp index a2295219a..e78665d31 100755 --- a/src/hid_core/resource_manager.cpp +++ b/src/hid_core/resource_manager.cpp @@ -184,7 +184,7 @@ void ResourceManager::InitializeHidCommonSampler() { keyboard->SetAppletResource(applet_resource, &shared_mutex); const auto settings = - system.ServiceManager().GetService("set:sys"); + system.ServiceManager().GetService("set:sys", true); npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config, settings); six_axis->SetAppletResource(applet_resource, &shared_mutex); diff --git a/src/hid_core/resources/hid_firmware_settings.cpp b/src/hid_core/resources/hid_firmware_settings.cpp index 9c9019e8f..b32c0660a 100755 --- a/src/hid_core/resources/hid_firmware_settings.cpp +++ b/src/hid_core/resources/hid_firmware_settings.cpp @@ -8,7 +8,8 @@ namespace Service::HID { HidFirmwareSettings::HidFirmwareSettings(Core::System& system) { - m_set_sys = system.ServiceManager().GetService("set:sys"); + m_set_sys = + system.ServiceManager().GetService("set:sys", true); LoadSettings(true); } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 6ea1f50d6..3f26bf99b 100755 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -289,8 +289,6 @@ add_library(video_core STATIC vulkan_common/vulkan.h ) -create_target_directory_groups(video_core) - target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder) @@ -365,3 +363,5 @@ endif() if (ANDROID AND ARCHITECTURE_arm64) target_link_libraries(video_core PRIVATE adrenotools) endif() + +create_target_directory_groups(video_core) diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 9fae05e2f..3f5c48e40 100755 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -375,8 +375,6 @@ elseif(WIN32) endif() endif() -create_target_directory_groups(yuzu) - target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core) target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets) target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) @@ -472,3 +470,5 @@ endif() if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(yuzu PRIVATE precompiled_headers.h) endif() + +create_target_directory_groups(yuzu) diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index 5edb71c39..0143d688e 100755 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -28,8 +28,6 @@ add_executable(yuzu-cmd yuzu.rc ) -create_target_directory_groups(yuzu-cmd) - target_link_libraries(yuzu-cmd PRIVATE common core input_common frontend_common) target_link_libraries(yuzu-cmd PRIVATE glad) if (MSVC) @@ -63,3 +61,5 @@ endif() if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(yuzu-cmd PRIVATE precompiled_headers.h) endif() + +create_target_directory_groups(yuzu-cmd)