Compare commits

...

11 Commits

Author SHA1 Message Date
yuzubot
e1ea5ba66b Android 255 2024-02-18 20:17:36 +00:00
yuzubot
9b29d2c340 Merge yuzu-emu#13070 2024-02-18 20:17:35 +00:00
yuzubot
f688e8cc5d Merge yuzu-emu#13048 2024-02-18 20:17:35 +00:00
yuzubot
f5322ea1ee Merge yuzu-emu#13035 2024-02-18 20:17:35 +00:00
yuzubot
5c92adbcf6 Merge yuzu-emu#13030 2024-02-18 20:17:35 +00:00
yuzubot
b66fd41ba1 Merge yuzu-emu#13026 2024-02-18 20:17:35 +00:00
yuzubot
2938aa58ed Merge yuzu-emu#13006 2024-02-18 20:17:35 +00:00
yuzubot
78379761cc Merge yuzu-emu#13000 2024-02-18 20:17:35 +00:00
yuzubot
8614751812 Merge yuzu-emu#12749 2024-02-18 20:17:35 +00:00
yuzubot
a224414f0f Merge yuzu-emu#12461 2024-02-18 20:17:35 +00:00
yuzubot
baf65362ab Merge yuzu-emu#10529 2024-02-18 20:17:35 +00:00
190 changed files with 16845 additions and 4531 deletions

View File

@ -1,3 +1,21 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
| [10529](https://github.com/yuzu-emu/yuzu//pull/10529) | [`368bf2211`](https://github.com/yuzu-emu/yuzu//pull/10529/files) | caches: make critical reclamation less eager and possible in more cases | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12461](https://github.com/yuzu-emu/yuzu//pull/12461) | [`acc26667b`](https://github.com/yuzu-emu/yuzu//pull/12461/files) | Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. | [Kelebek1](https://github.com/Kelebek1/) | Yes |
| [12749](https://github.com/yuzu-emu/yuzu//pull/12749) | [`aad4b0d6f`](https://github.com/yuzu-emu/yuzu//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13000](https://github.com/yuzu-emu/yuzu//pull/13000) | [`461eaca7e`](https://github.com/yuzu-emu/yuzu//pull/13000/files) | device_memory_manager: skip unregistered interfaces on invalidate | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13006](https://github.com/yuzu-emu/yuzu//pull/13006) | [`3067bfd12`](https://github.com/yuzu-emu/yuzu//pull/13006/files) | buffer_cache: use mapped range with large vertex buffer size | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13026](https://github.com/yuzu-emu/yuzu//pull/13026) | [`462ea921e`](https://github.com/yuzu-emu/yuzu//pull/13026/files) | shader_recompiler: fix non-const offset for arrayed image types | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13030](https://github.com/yuzu-emu/yuzu//pull/13030) | [`4cbafc1ef`](https://github.com/yuzu-emu/yuzu//pull/13030/files) | service: audio: Rewrite IAudioController to new IPC | [german77](https://github.com/german77/) | Yes |
| [13035](https://github.com/yuzu-emu/yuzu//pull/13035) | [`940a71422`](https://github.com/yuzu-emu/yuzu//pull/13035/files) | vi: manage resources independently of nvnflinger and refactor | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13048](https://github.com/yuzu-emu/yuzu//pull/13048) | [`4cdf18095`](https://github.com/yuzu-emu/yuzu//pull/13048/files) | ns: rewrite for new IPC | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13070](https://github.com/yuzu-emu/yuzu//pull/13070) | [`911ee8fd1`](https://github.com/yuzu-emu/yuzu//pull/13070/files) | am: account for offset in transfer memory storage | [liamwhite](https://github.com/liamwhite/) | Yes |
End of merge log. You can find the original README.md below the break.
-----
<!-- <!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later

View File

@ -314,3 +314,10 @@ endif()
if (NOT TARGET SimpleIni::SimpleIni) if (NOT TARGET SimpleIni::SimpleIni)
add_subdirectory(simpleini) add_subdirectory(simpleini)
endif() endif()
# sse2neon
if (ARCHITECTURE_arm64 AND NOT TARGET sse2neon)
add_library(sse2neon INTERFACE)
target_include_directories(sse2neon INTERFACE sse2neon)
endif()

9282
externals/sse2neon/sse2neon.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -164,6 +164,7 @@ else()
if (MINGW) if (MINGW)
add_definitions(-DMINGW_HAS_SECURE_API) add_definitions(-DMINGW_HAS_SECURE_API)
add_compile_options("-msse4.1")
if (MINGW_STATIC_BUILD) if (MINGW_STATIC_BUILD)
add_definitions(-DQT_STATICPLUGIN) add_definitions(-DQT_STATICPLUGIN)

View File

@ -423,12 +423,12 @@ add_library(core STATIC
hle/service/am/applet_manager.h hle/service/am/applet_manager.h
hle/service/am/applet_message_queue.cpp hle/service/am/applet_message_queue.cpp
hle/service/am/applet_message_queue.h hle/service/am/applet_message_queue.h
hle/service/am/display_layer_manager.cpp
hle/service/am/display_layer_manager.h
hle/service/am/hid_registration.cpp hle/service/am/hid_registration.cpp
hle/service/am/hid_registration.h hle/service/am/hid_registration.h
hle/service/am/library_applet_storage.cpp hle/service/am/library_applet_storage.cpp
hle/service/am/library_applet_storage.h hle/service/am/library_applet_storage.h
hle/service/am/managed_layer_holder.cpp
hle/service/am/managed_layer_holder.h
hle/service/am/process.cpp hle/service/am/process.cpp
hle/service/am/process.h hle/service/am/process.h
hle/service/am/service/all_system_applet_proxies_service.cpp hle/service/am/service/all_system_applet_proxies_service.cpp
@ -481,8 +481,6 @@ add_library(core STATIC
hle/service/am/service/system_applet_proxy.h hle/service/am/service/system_applet_proxy.h
hle/service/am/service/window_controller.cpp hle/service/am/service/window_controller.cpp
hle/service/am/service/window_controller.h hle/service/am/service/window_controller.h
hle/service/am/system_buffer_manager.cpp
hle/service/am/system_buffer_manager.h
hle/service/aoc/aoc_u.cpp hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp hle/service/apm/apm.cpp
@ -491,12 +489,12 @@ add_library(core STATIC
hle/service/apm/apm_controller.h hle/service/apm/apm_controller.h
hle/service/apm/apm_interface.cpp hle/service/apm/apm_interface.cpp
hle/service/apm/apm_interface.h hle/service/apm/apm_interface.h
hle/service/audio/audctl.cpp
hle/service/audio/audctl.h
hle/service/audio/audin_u.cpp hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h hle/service/audio/audin_u.h
hle/service/audio/audio.cpp hle/service/audio/audio.cpp
hle/service/audio/audio.h hle/service/audio/audio.h
hle/service/audio/audio_controller.cpp
hle/service/audio/audio_controller.h
hle/service/audio/audout_u.cpp hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h hle/service/audio/audout_u.h
hle/service/audio/audrec_a.cpp hle/service/audio/audrec_a.cpp
@ -739,15 +737,48 @@ add_library(core STATIC
hle/service/nim/nim.h hle/service/nim/nim.h
hle/service/npns/npns.cpp hle/service/npns/npns.cpp
hle/service/npns/npns.h hle/service/npns/npns.h
hle/service/ns/errors.h hle/service/ns/account_proxy_interface.cpp
hle/service/ns/iplatform_service_manager.cpp hle/service/ns/account_proxy_interface.h
hle/service/ns/iplatform_service_manager.h hle/service/ns/application_manager_interface.cpp
hle/service/ns/application_manager_interface.h
hle/service/ns/application_version_interface.cpp
hle/service/ns/application_version_interface.h
hle/service/ns/content_management_interface.cpp
hle/service/ns/content_management_interface.h
hle/service/ns/develop_interface.cpp
hle/service/ns/develop_interface.h
hle/service/ns/document_interface.cpp
hle/service/ns/document_interface.h
hle/service/ns/download_task_interface.cpp
hle/service/ns/download_task_interface.h
hle/service/ns/dynamic_rights_interface.cpp
hle/service/ns/dynamic_rights_interface.h
hle/service/ns/ecommerce_interface.cpp
hle/service/ns/ecommerce_interface.h
hle/service/ns/factory_reset_interface.cpp
hle/service/ns/factory_reset_interface.h
hle/service/ns/language.cpp hle/service/ns/language.cpp
hle/service/ns/language.h hle/service/ns/language.h
hle/service/ns/ns_results.h
hle/service/ns/ns_types.h
hle/service/ns/ns.cpp hle/service/ns/ns.cpp
hle/service/ns/ns.h hle/service/ns/ns.h
hle/service/ns/pdm_qry.cpp hle/service/ns/platform_service_manager.cpp
hle/service/ns/pdm_qry.h hle/service/ns/platform_service_manager.h
hle/service/ns/query_service.cpp
hle/service/ns/query_service.h
hle/service/ns/read_only_application_control_data_interface.cpp
hle/service/ns/read_only_application_control_data_interface.h
hle/service/ns/read_only_application_record_interface.cpp
hle/service/ns/read_only_application_record_interface.h
hle/service/ns/service_getter_interface.cpp
hle/service/ns/service_getter_interface.h
hle/service/ns/system_update_control.cpp
hle/service/ns/system_update_control.h
hle/service/ns/system_update_interface.cpp
hle/service/ns/system_update_interface.h
hle/service/ns/vulnerability_manager_interface.cpp
hle/service/ns/vulnerability_manager_interface.h
hle/service/nvdrv/core/container.cpp hle/service/nvdrv/core/container.cpp
hle/service/nvdrv/core/container.h hle/service/nvdrv/core/container.h
hle/service/nvdrv/core/heap_mapper.cpp hle/service/nvdrv/core/heap_mapper.cpp
@ -800,12 +831,12 @@ add_library(core STATIC
hle/service/nvnflinger/consumer_base.cpp hle/service/nvnflinger/consumer_base.cpp
hle/service/nvnflinger/consumer_base.h hle/service/nvnflinger/consumer_base.h
hle/service/nvnflinger/consumer_listener.h hle/service/nvnflinger/consumer_listener.h
hle/service/nvnflinger/fb_share_buffer_manager.cpp
hle/service/nvnflinger/fb_share_buffer_manager.h
hle/service/nvnflinger/graphic_buffer_producer.cpp hle/service/nvnflinger/graphic_buffer_producer.cpp
hle/service/nvnflinger/graphic_buffer_producer.h hle/service/nvnflinger/graphic_buffer_producer.h
hle/service/nvnflinger/hos_binder_driver_server.cpp hle/service/nvnflinger/hos_binder_driver_server.cpp
hle/service/nvnflinger/hos_binder_driver_server.h hle/service/nvnflinger/hos_binder_driver_server.h
hle/service/nvnflinger/hos_binder_driver.cpp
hle/service/nvnflinger/hos_binder_driver.h
hle/service/nvnflinger/hardware_composer.cpp hle/service/nvnflinger/hardware_composer.cpp
hle/service/nvnflinger/hardware_composer.h hle/service/nvnflinger/hardware_composer.h
hle/service/nvnflinger/hwc_layer.h hle/service/nvnflinger/hwc_layer.h
@ -815,6 +846,8 @@ add_library(core STATIC
hle/service/nvnflinger/pixel_format.h hle/service/nvnflinger/pixel_format.h
hle/service/nvnflinger/producer_listener.h hle/service/nvnflinger/producer_listener.h
hle/service/nvnflinger/status.h hle/service/nvnflinger/status.h
hle/service/nvnflinger/surface_flinger.cpp
hle/service/nvnflinger/surface_flinger.h
hle/service/nvnflinger/ui/fence.h hle/service/nvnflinger/ui/fence.h
hle/service/nvnflinger/ui/graphic_buffer.cpp hle/service/nvnflinger/ui/graphic_buffer.cpp
hle/service/nvnflinger/ui/graphic_buffer.h hle/service/nvnflinger/ui/graphic_buffer.h
@ -908,6 +941,8 @@ add_library(core STATIC
hle/service/server_manager.h hle/service/server_manager.h
hle/service/service.cpp hle/service/service.cpp
hle/service/service.h hle/service/service.h
hle/service/services.cpp
hle/service/services.h
hle/service/set/setting_formats/appln_settings.cpp hle/service/set/setting_formats/appln_settings.cpp
hle/service/set/setting_formats/appln_settings.h hle/service/set/setting_formats/appln_settings.h
hle/service/set/setting_formats/device_settings.cpp hle/service/set/setting_formats/device_settings.cpp
@ -955,22 +990,26 @@ add_library(core STATIC
hle/service/ssl/ssl_backend.h hle/service/ssl/ssl_backend.h
hle/service/usb/usb.cpp hle/service/usb/usb.cpp
hle/service/usb/usb.h hle/service/usb/usb.h
hle/service/vi/display/vi_display.cpp
hle/service/vi/display/vi_display.h
hle/service/vi/layer/vi_layer.cpp
hle/service/vi/layer/vi_layer.h
hle/service/vi/application_display_service.cpp hle/service/vi/application_display_service.cpp
hle/service/vi/application_display_service.h hle/service/vi/application_display_service.h
hle/service/vi/application_root_service.cpp hle/service/vi/application_root_service.cpp
hle/service/vi/application_root_service.h hle/service/vi/application_root_service.h
hle/service/vi/hos_binder_driver.cpp hle/service/vi/conductor.cpp
hle/service/vi/hos_binder_driver.h hle/service/vi/conductor.h
hle/service/vi/container.cpp
hle/service/vi/container.h
hle/service/vi/display_list.h
hle/service/vi/display.h
hle/service/vi/layer_list.h
hle/service/vi/layer.h
hle/service/vi/manager_display_service.cpp hle/service/vi/manager_display_service.cpp
hle/service/vi/manager_display_service.h hle/service/vi/manager_display_service.h
hle/service/vi/manager_root_service.cpp hle/service/vi/manager_root_service.cpp
hle/service/vi/manager_root_service.h hle/service/vi/manager_root_service.h
hle/service/vi/service_creator.cpp hle/service/vi/service_creator.cpp
hle/service/vi/service_creator.h hle/service/vi/service_creator.h
hle/service/vi/shared_buffer_manager.cpp
hle/service/vi/shared_buffer_manager.h
hle/service/vi/system_display_service.cpp hle/service/vi/system_display_service.cpp
hle/service/vi/system_display_service.h hle/service/vi/system_display_service.h
hle/service/vi/system_root_service.cpp hle/service/vi/system_root_service.cpp
@ -979,6 +1018,8 @@ add_library(core STATIC
hle/service/vi/vi_types.h hle/service/vi/vi_types.h
hle/service/vi/vi.cpp hle/service/vi/vi.cpp
hle/service/vi/vi.h hle/service/vi/vi.h
hle/service/vi/vsync_manager.cpp
hle/service/vi/vsync_manager.h
internal_network/network.cpp internal_network/network.cpp
internal_network/network.h internal_network/network.h
internal_network/network_interface.cpp internal_network/network_interface.cpp

View File

@ -47,6 +47,7 @@
#include "core/hle/service/psc/time/system_clock.h" #include "core/hle/service/psc/time/system_clock.h"
#include "core/hle/service/psc/time/time_zone_service.h" #include "core/hle/service/psc/time/time_zone_service.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/hle/service/services.h"
#include "core/hle/service/set/system_settings_server.h" #include "core/hle/service/set/system_settings_server.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "core/internal_network/network.h" #include "core/internal_network/network.h"
@ -310,7 +311,8 @@ struct System::Impl {
audio_core = std::make_unique<AudioCore::AudioCore>(system); audio_core = std::make_unique<AudioCore::AudioCore>(system);
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel); service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
services = std::make_unique<Service::Services>(service_manager, system); services =
std::make_unique<Service::Services>(service_manager, system, stop_event.get_token());
is_powered_on = true; is_powered_on = true;
exit_locked = false; exit_locked = false;
@ -458,11 +460,10 @@ struct System::Impl {
gpu_core->NotifyShutdown(); gpu_core->NotifyShutdown();
} }
stop_event.request_stop();
core_timing.SyncPause(false);
Network::CancelPendingSocketOperations(); Network::CancelPendingSocketOperations();
kernel.SuspendEmulation(true); kernel.SuspendEmulation(true);
if (services) {
services->KillNVNFlinger();
}
kernel.CloseServices(); kernel.CloseServices();
kernel.ShutdownCores(); kernel.ShutdownCores();
applet_manager.Reset(); applet_manager.Reset();
@ -480,6 +481,7 @@ struct System::Impl {
cpu_manager.Shutdown(); cpu_manager.Shutdown();
debugger.reset(); debugger.reset();
kernel.Shutdown(); kernel.Shutdown();
stop_event = {};
Network::RestartSocketOperations(); Network::RestartSocketOperations();
if (auto room_member = room_network.GetRoomMember().lock()) { if (auto room_member = room_network.GetRoomMember().lock()) {
@ -615,6 +617,7 @@ struct System::Impl {
ExecuteProgramCallback execute_program_callback; ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback; ExitCallback exit_callback;
std::stop_source stop_event;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{}; std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{};

View File

@ -43,6 +43,8 @@ public:
DeviceMemoryManager(const DeviceMemory& device_memory); DeviceMemoryManager(const DeviceMemory& device_memory);
~DeviceMemoryManager(); ~DeviceMemoryManager();
static constexpr bool HAS_FLUSH_INVALIDATION = true;
void BindInterface(DeviceInterface* device_inter); void BindInterface(DeviceInterface* device_inter);
DAddr Allocate(size_t size); DAddr Allocate(size_t size);

View File

@ -522,13 +522,17 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
auto* memory_device_inter = registered_processes[asid.id]; auto* memory_device_inter = registered_processes[asid.id];
const auto release_pending = [&] { const auto release_pending = [&] {
if (uncache_bytes > 0) { if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, if (memory_device_inter != nullptr) {
uncache_bytes, false); MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
uncache_bytes, false);
}
uncache_bytes = 0; uncache_bytes = 0;
} }
if (cache_bytes > 0) { if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, if (memory_device_inter != nullptr) {
cache_bytes, true); MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
cache_bytes, true);
}
cache_bytes = 0; cache_bytes = 0;
} }
}; };

View File

@ -9,7 +9,7 @@
#include "core/file_sys/system_archive/data/font_standard.h" #include "core/file_sys/system_archive/data/font_standard.h"
#include "core/file_sys/system_archive/shared_font.h" #include "core/file_sys/system_archive/shared_font.h"
#include "core/file_sys/vfs/vfs_vector.h" #include "core/file_sys/vfs/vfs_vector.h"
#include "core/hle/service/ns/iplatform_service_manager.h" #include "core/hle/service/ns/platform_service_manager.h"
namespace FileSys::SystemArchive { namespace FileSys::SystemArchive {

View File

@ -44,15 +44,32 @@ public:
GuestMemory() = delete; GuestMemory() = delete;
explicit GuestMemory(M& memory, u64 addr, std::size_t size, explicit GuestMemory(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) Common::ScratchBuffer<T>* backup = nullptr)
: m_memory{memory}, m_addr{addr}, m_size{size} { : m_memory{&memory}, m_addr{addr}, m_size{size} {
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write); static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
if constexpr (FLAGS & GuestMemoryFlags::Read) { if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
if (!this->TrySetSpan()) {
if (backup) {
backup->resize_destructive(this->size());
m_data_span = *backup;
m_span_valid = true;
m_is_data_copy = true;
} else {
m_data_copy.resize(this->size());
m_data_span = std::span(m_data_copy);
m_span_valid = true;
m_is_data_copy = true;
}
}
} else if constexpr (FLAGS & GuestMemoryFlags::Read) {
Read(addr, size, backup); Read(addr, size, backup);
} }
} }
~GuestMemory() = default; ~GuestMemory() = default;
GuestMemory(GuestMemory&& rhs) = default;
GuestMemory& operator=(GuestMemory&& rhs) = default;
T* data() noexcept { T* data() noexcept {
return m_data_span.data(); return m_data_span.data();
} }
@ -109,8 +126,8 @@ public:
} }
if (this->TrySetSpan()) { if (this->TrySetSpan()) {
if constexpr (FLAGS & GuestMemoryFlags::Safe) { if constexpr (FLAGS & GuestMemoryFlags::Safe && M::HAS_FLUSH_INVALIDATION) {
m_memory.FlushRegion(m_addr, this->size_bytes()); m_memory->FlushRegion(m_addr, this->size_bytes());
} }
} else { } else {
if (backup) { if (backup) {
@ -123,9 +140,9 @@ public:
m_is_data_copy = true; m_is_data_copy = true;
m_span_valid = true; m_span_valid = true;
if constexpr (FLAGS & GuestMemoryFlags::Safe) { if constexpr (FLAGS & GuestMemoryFlags::Safe) {
m_memory.ReadBlock(m_addr, this->data(), this->size_bytes()); m_memory->ReadBlock(m_addr, this->data(), this->size_bytes());
} else { } else {
m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes()); m_memory->ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
} }
} }
return m_data_span; return m_data_span;
@ -133,18 +150,19 @@ public:
void Write(std::span<T> write_data) noexcept { void Write(std::span<T> write_data) noexcept {
if constexpr (FLAGS & GuestMemoryFlags::Cached) { if constexpr (FLAGS & GuestMemoryFlags::Cached) {
m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes()); m_memory->WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) { } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes()); m_memory->WriteBlock(m_addr, write_data.data(), this->size_bytes());
} else { } else {
m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes()); m_memory->WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
} }
} }
bool TrySetSpan() noexcept { bool TrySetSpan() noexcept {
if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) { if (u8* ptr = m_memory->GetSpan(m_addr, this->size_bytes()); ptr) {
m_data_span = {reinterpret_cast<T*>(ptr), this->size()}; m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
m_span_valid = true; m_span_valid = true;
m_is_data_copy = false;
return true; return true;
} }
return false; return false;
@ -159,7 +177,7 @@ protected:
return m_addr_changed; return m_addr_changed;
} }
M& m_memory; M* m_memory;
u64 m_addr{}; u64 m_addr{};
size_t m_size{}; size_t m_size{};
std::span<T> m_data_span{}; std::span<T> m_data_span{};
@ -175,17 +193,7 @@ public:
GuestMemoryScoped() = delete; GuestMemoryScoped() = delete;
explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size, explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr) Common::ScratchBuffer<T>* backup = nullptr)
: GuestMemory<M, T, FLAGS>(memory, addr, size, backup) { : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {}
if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
if (!this->TrySetSpan()) {
if (backup) {
this->m_data_span = *backup;
this->m_span_valid = true;
this->m_is_data_copy = true;
}
}
}
}
~GuestMemoryScoped() { ~GuestMemoryScoped() {
if constexpr (FLAGS & GuestMemoryFlags::Write) { if constexpr (FLAGS & GuestMemoryFlags::Write) {
@ -196,15 +204,17 @@ public:
if (this->AddressChanged() || this->IsDataCopy()) { if (this->AddressChanged() || this->IsDataCopy()) {
ASSERT(this->m_span_valid); ASSERT(this->m_span_valid);
if constexpr (FLAGS & GuestMemoryFlags::Cached) { if constexpr (FLAGS & GuestMemoryFlags::Cached) {
this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes()); this->m_memory->WriteBlockCached(this->m_addr, this->data(),
this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) { } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes()); this->m_memory->WriteBlock(this->m_addr, this->data(), this->size_bytes());
} else { } else {
this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes()); this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(),
this->size_bytes());
} }
} else if constexpr ((FLAGS & GuestMemoryFlags::Safe) || } else if constexpr ((FLAGS & GuestMemoryFlags::Safe) ||
(FLAGS & GuestMemoryFlags::Cached)) { (FLAGS & GuestMemoryFlags::Cached)) {
this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes()); this->m_memory->InvalidateRegion(this->m_addr, this->size_bytes());
} }
} }
} }

View File

@ -8,13 +8,13 @@
namespace Service::AM { namespace Service::AM {
void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService( server_manager->RegisterNamedService("appletAE",
"appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger)); std::make_shared<IAllSystemAppletProxiesService>(system));
server_manager->RegisterNamedService( server_manager->RegisterNamedService("appletOE",
"appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger)); std::make_shared<IApplicationProxyService>(system));
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View File

@ -7,12 +7,8 @@ namespace Core {
class System; class System;
} }
namespace Service::Nvnflinger {
class Nvnflinger;
}
namespace Service::AM { namespace Service::AM {
void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); void LoopProcess(Core::System& system);
} // namespace Service::AM } // namespace Service::AM

View File

@ -14,10 +14,9 @@
#include "core/hle/service/am/am_types.h" #include "core/hle/service/am/am_types.h"
#include "core/hle/service/am/applet_message_queue.h" #include "core/hle/service/am/applet_message_queue.h"
#include "core/hle/service/am/display_layer_manager.h"
#include "core/hle/service/am/hid_registration.h" #include "core/hle/service/am/hid_registration.h"
#include "core/hle/service/am/managed_layer_holder.h"
#include "core/hle/service/am/process.h" #include "core/hle/service/am/process.h"
#include "core/hle/service/am/system_buffer_manager.h"
namespace Service::AM { namespace Service::AM {
@ -54,8 +53,7 @@ struct Applet {
HidRegistration hid_registration; HidRegistration hid_registration;
// vi state // vi state
SystemBufferManager system_buffer_manager{}; DisplayLayerManager display_layer_manager{};
ManagedLayerHolder managed_layer_holder{};
// Applet common functions // Applet common functions
Result terminate_result{}; Result terminate_result{};

View File

@ -0,0 +1,151 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/am/display_layer_manager.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/application_display_service.h"
#include "core/hle/service/vi/container.h"
#include "core/hle/service/vi/manager_display_service.h"
#include "core/hle/service/vi/manager_root_service.h"
#include "core/hle/service/vi/shared_buffer_manager.h"
#include "core/hle/service/vi/vi_results.h"
#include "core/hle/service/vi/vi_types.h"
namespace Service::AM {
DisplayLayerManager::DisplayLayerManager() = default;
DisplayLayerManager::~DisplayLayerManager() {
this->Finalize();
}
void DisplayLayerManager::Initialize(Core::System& system, Kernel::KProcess* process,
AppletId applet_id, LibraryAppletMode mode) {
R_ASSERT(system.ServiceManager()
.GetService<VI::IManagerRootService>("vi:m", true)
->GetDisplayService(&m_display_service, VI::Policy::Compositor));
R_ASSERT(m_display_service->GetManagerDisplayService(&m_manager_display_service));
m_process = process;
m_system_shared_buffer_id = 0;
m_system_shared_layer_id = 0;
m_applet_id = applet_id;
m_buffer_sharing_enabled = false;
m_blending_enabled = mode == LibraryAppletMode::PartialForeground ||
mode == LibraryAppletMode::PartialForegroundIndirectDisplay;
}
void DisplayLayerManager::Finalize() {
if (!m_manager_display_service) {
return;
}
// Clean up managed layers.
for (const auto& layer : m_managed_display_layers) {
m_manager_display_service->DestroyManagedLayer(layer);
}
for (const auto& layer : m_managed_display_recording_layers) {
m_manager_display_service->DestroyManagedLayer(layer);
}
// Clean up shared layers.
if (m_buffer_sharing_enabled) {
m_manager_display_service->DestroySharedLayerSession(m_process);
}
m_manager_display_service = nullptr;
m_display_service = nullptr;
}
Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer_id) {
R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed);
// TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display.
u64 display_id;
R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"}));
R_TRY(m_manager_display_service->CreateManagedLayer(
out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()}));
m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id);
m_managed_display_layers.emplace(*out_layer_id);
R_SUCCEED();
}
Result DisplayLayerManager::CreateManagedDisplaySeparableLayer(u64* out_layer_id,
u64* out_recording_layer_id) {
R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed);
// TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display.
// This calls nn::vi::CreateRecordingLayer() which creates another layer.
// Currently we do not support more than 1 layer per display, output 1 layer id for now.
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
// side effects.
*out_recording_layer_id = 0;
R_RETURN(this->CreateManagedDisplayLayer(out_layer_id));
}
Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
// Succeed if already enabled.
R_SUCCEED_IF(m_buffer_sharing_enabled);
// Ensure we can access shared layers.
R_UNLESS(m_manager_display_service != nullptr, VI::ResultOperationFailed);
R_UNLESS(m_applet_id != AppletId::Application, VI::ResultPermissionDenied);
// Create the shared layer.
u64 display_id;
R_TRY(m_display_service->OpenDisplay(&display_id, VI::DisplayName{"Default"}));
R_TRY(m_manager_display_service->CreateSharedLayerSession(m_process, &m_system_shared_buffer_id,
&m_system_shared_layer_id, display_id,
m_blending_enabled));
// We succeeded, so set up remaining state.
m_buffer_sharing_enabled = true;
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
R_SUCCEED();
}
Result DisplayLayerManager::GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
u64* out_system_shared_layer_id) {
R_TRY(this->IsSystemBufferSharingEnabled());
*out_system_shared_buffer_id = m_system_shared_buffer_id;
*out_system_shared_layer_id = m_system_shared_layer_id;
R_SUCCEED();
}
void DisplayLayerManager::SetWindowVisibility(bool visible) {
if (m_visible == visible) {
return;
}
m_visible = visible;
if (m_manager_display_service) {
if (m_system_shared_layer_id) {
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
}
for (const auto layer_id : m_managed_display_layers) {
m_manager_display_service->SetLayerVisibility(m_visible, layer_id);
}
}
}
bool DisplayLayerManager::GetWindowVisibility() const {
return m_visible;
}
Result DisplayLayerManager::WriteAppletCaptureBuffer(bool* out_was_written,
s32* out_fbshare_layer_index) {
R_UNLESS(m_buffer_sharing_enabled, VI::ResultPermissionDenied);
R_RETURN(m_display_service->GetContainer()->GetSharedBufferManager()->WriteAppletCaptureBuffer(
out_was_written, out_fbshare_layer_index));
}
} // namespace Service::AM

View File

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <set>
#include "common/common_types.h"
#include "core/hle/result.h"
#include "core/hle/service/am/am_types.h"
namespace Core {
class System;
}
namespace Kernel {
class KProcess;
}
namespace Service::VI {
class IApplicationDisplayService;
class IManagerDisplayService;
} // namespace Service::VI
namespace Service::AM {
class DisplayLayerManager {
public:
explicit DisplayLayerManager();
~DisplayLayerManager();
void Initialize(Core::System& system, Kernel::KProcess* process, AppletId applet_id,
LibraryAppletMode mode);
void Finalize();
Result CreateManagedDisplayLayer(u64* out_layer_id);
Result CreateManagedDisplaySeparableLayer(u64* out_layer_id, u64* out_recording_layer_id);
Result IsSystemBufferSharingEnabled();
Result GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
u64* out_system_shared_layer_id);
void SetWindowVisibility(bool visible);
bool GetWindowVisibility() const;
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
private:
Kernel::KProcess* m_process{};
std::shared_ptr<VI::IApplicationDisplayService> m_display_service{};
std::shared_ptr<VI::IManagerDisplayService> m_manager_display_service{};
std::set<u64> m_managed_display_layers{};
std::set<u64> m_managed_display_recording_layers{};
u64 m_system_shared_buffer_id{};
u64 m_system_shared_layer_id{};
AppletId m_applet_id{};
bool m_buffer_sharing_enabled{};
bool m_blending_enabled{};
bool m_visible{true};
};
} // namespace Service::AM

View File

@ -22,7 +22,7 @@
#include "core/hle/service/am/frontend/applet_web_browser.h" #include "core/hle/service/am/frontend/applet_web_browser.h"
#include "core/hle/service/am/service/storage.h" #include "core/hle/service/am/service/storage.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/iplatform_service_manager.h" #include "core/hle/service/ns/platform_service_manager.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
namespace Service::AM::Frontend { namespace Service::AM::Frontend {

View File

@ -70,7 +70,7 @@ public:
Result Read(s64 offset, void* buffer, size_t size) override { Result Read(s64 offset, void* buffer, size_t size) override {
R_TRY(ValidateOffset(offset, size, m_size)); R_TRY(ValidateOffset(offset, size, m_size));
m_memory.ReadBlock(m_trmem->GetSourceAddress(), buffer, size); m_memory.ReadBlock(m_trmem->GetSourceAddress() + offset, buffer, size);
R_SUCCEED(); R_SUCCEED();
} }
@ -79,7 +79,7 @@ public:
R_UNLESS(m_is_writable, ResultUnknown); R_UNLESS(m_is_writable, ResultUnknown);
R_TRY(ValidateOffset(offset, size, m_size)); R_TRY(ValidateOffset(offset, size, m_size));
m_memory.WriteBlock(m_trmem->GetSourceAddress(), buffer, size); m_memory.WriteBlock(m_trmem->GetSourceAddress() + offset, buffer, size);
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -1,59 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/am/managed_layer_holder.h"
#include "core/hle/service/nvnflinger/nvnflinger.h"
namespace Service::AM {
ManagedLayerHolder::ManagedLayerHolder() = default;
ManagedLayerHolder::~ManagedLayerHolder() {
if (!m_nvnflinger) {
return;
}
for (const auto& layer : m_managed_display_layers) {
m_nvnflinger->DestroyLayer(layer);
}
for (const auto& layer : m_managed_display_recording_layers) {
m_nvnflinger->DestroyLayer(layer);
}
m_nvnflinger = nullptr;
}
void ManagedLayerHolder::Initialize(Nvnflinger::Nvnflinger* nvnflinger) {
m_nvnflinger = nvnflinger;
}
void ManagedLayerHolder::CreateManagedDisplayLayer(u64* out_layer) {
// TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display.
const auto display_id = m_nvnflinger->OpenDisplay("Default");
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
m_managed_display_layers.emplace(*layer_id);
*out_layer = *layer_id;
}
void ManagedLayerHolder::CreateManagedDisplaySeparableLayer(u64* out_layer,
u64* out_recording_layer) {
// TODO(Subv): Find out how AM determines the display to use, for now just
// create the layer in the Default display.
// This calls nn::vi::CreateRecordingLayer() which creates another layer.
// Currently we do not support more than 1 layer per display, output 1 layer id for now.
// Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
// side effects.
// TODO: Support multiple layers
const auto display_id = m_nvnflinger->OpenDisplay("Default");
const auto layer_id = m_nvnflinger->CreateLayer(*display_id);
m_managed_display_layers.emplace(*layer_id);
*out_layer = *layer_id;
*out_recording_layer = 0;
}
} // namespace Service::AM

View File

@ -1,32 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <set>
#include "common/common_funcs.h"
#include "common/common_types.h"
namespace Service::Nvnflinger {
class Nvnflinger;
}
namespace Service::AM {
class ManagedLayerHolder {
public:
ManagedLayerHolder();
~ManagedLayerHolder();
void Initialize(Nvnflinger::Nvnflinger* nvnflinger);
void CreateManagedDisplayLayer(u64* out_layer);
void CreateManagedDisplaySeparableLayer(u64* out_layer, u64* out_recording_layer);
private:
Nvnflinger::Nvnflinger* m_nvnflinger{};
std::set<u64> m_managed_display_layers{};
std::set<u64> m_managed_display_recording_layers{};
};
} // namespace Service::AM

View File

@ -10,9 +10,8 @@
namespace Service::AM { namespace Service::AM {
IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_)
Nvnflinger::Nvnflinger& nvnflinger) : ServiceFramework{system_, "appletAE"} {
: ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
@ -37,8 +36,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid); applet) { if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
*out_system_applet_proxy = std::make_shared<ISystemAppletProxy>( *out_system_applet_proxy =
system, applet, process_handle.Get(), m_nvnflinger); std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get());
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -53,8 +52,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid); applet) { if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
*out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>( *out_library_applet_proxy =
system, applet, process_handle.Get(), m_nvnflinger); std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get());
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();

View File

@ -8,10 +8,6 @@
namespace Service { namespace Service {
namespace Nvnflinger {
class Nvnflinger;
}
namespace AM { namespace AM {
struct Applet; struct Applet;
@ -22,8 +18,7 @@ class ISystemAppletProxy;
class IAllSystemAppletProxiesService final class IAllSystemAppletProxiesService final
: public ServiceFramework<IAllSystemAppletProxiesService> { : public ServiceFramework<IAllSystemAppletProxiesService> {
public: public:
explicit IAllSystemAppletProxiesService(Core::System& system_, explicit IAllSystemAppletProxiesService(Core::System& system_);
Nvnflinger::Nvnflinger& nvnflinger);
~IAllSystemAppletProxiesService() override; ~IAllSystemAppletProxiesService() override;
private: private:
@ -40,7 +35,6 @@ private:
private: private:
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
Nvnflinger::Nvnflinger& m_nvnflinger;
}; };
} // namespace AM } // namespace AM

View File

@ -16,7 +16,8 @@
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/filesystem/save_data_controller.h" #include "core/hle/service/filesystem/save_data_controller.h"
#include "core/hle/service/glue/glue_manager.h" #include "core/hle/service/glue/glue_manager.h"
#include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/application_manager_interface.h"
#include "core/hle/service/ns/service_getter_interface.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
namespace Service::AM { namespace Service::AM {
@ -163,11 +164,13 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) {
// Call IApplicationManagerInterface implementation. // Call IApplicationManagerInterface implementation.
auto& service_manager = system.ServiceManager(); auto& service_manager = system.ServiceManager();
auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2");
auto app_man = ns_am2->GetApplicationManagerInterface();
std::shared_ptr<NS::IApplicationManagerInterface> app_man;
R_TRY(ns_am2->GetApplicationManagerInterface(&app_man));
// Get desired application language // Get desired application language
u8 desired_language{}; NS::ApplicationLanguage desired_language{};
R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
// Convert to settings language code. // Convert to settings language code.

View File

@ -17,9 +17,9 @@
namespace Service::AM { namespace Service::AM {
IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) Kernel::KProcess* process)
: ServiceFramework{system_, "IApplicationProxy"}, : ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{
m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@ -77,8 +77,7 @@ Result IApplicationProxy::GetWindowController(
Result IApplicationProxy::GetSelfController( Result IApplicationProxy::GetSelfController(
Out<SharedPointer<ISelfController>> out_self_controller) { Out<SharedPointer<ISelfController>> out_self_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_self_controller = *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -22,7 +22,7 @@ class IWindowController;
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public: public:
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); Kernel::KProcess* process);
~IApplicationProxy(); ~IApplicationProxy();
private: private:
@ -40,7 +40,6 @@ private:
Out<SharedPointer<IApplicationFunctions>> out_application_functions); Out<SharedPointer<IApplicationFunctions>> out_application_functions);
private: private:
Nvnflinger::Nvnflinger& m_nvnflinger;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@ -10,9 +10,8 @@
namespace Service::AM { namespace Service::AM {
IApplicationProxyService::IApplicationProxyService(Core::System& system_, IApplicationProxyService::IApplicationProxyService(Core::System& system_)
Nvnflinger::Nvnflinger& nvnflinger) : ServiceFramework{system_, "appletOE"} {
: ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
}; };
@ -28,7 +27,7 @@ Result IApplicationProxyService::OpenApplicationProxy(
if (const auto applet = this->GetAppletFromProcessId(pid)) { if (const auto applet = this->GetAppletFromProcessId(pid)) {
*out_application_proxy = *out_application_proxy =
std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger); std::make_shared<IApplicationProxy>(system, applet, process_handle.Get());
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();

View File

@ -8,10 +8,6 @@
namespace Service { namespace Service {
namespace Nvnflinger {
class Nvnflinger;
}
namespace AM { namespace AM {
struct Applet; struct Applet;
@ -19,7 +15,7 @@ class IApplicationProxy;
class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
public: public:
explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger); explicit IApplicationProxyService(Core::System& system_);
~IApplicationProxyService() override; ~IApplicationProxyService() override;
private: private:
@ -28,7 +24,6 @@ private:
private: private:
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
Nvnflinger::Nvnflinger& m_nvnflinger;
}; };
} // namespace AM } // namespace AM

View File

@ -69,7 +69,7 @@ Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_i
Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer( Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer(
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
out_fbshare_layer_index)); out_fbshare_layer_index));
} }
@ -81,7 +81,7 @@ Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() {
Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer( Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer(
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
out_fbshare_layer_index)); out_fbshare_layer_index));
} }
@ -93,7 +93,7 @@ Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() {
Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer( Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer(
Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) { Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written, R_RETURN(applet->display_layer_manager.WriteAppletCaptureBuffer(out_was_written,
out_fbshare_layer_index)); out_fbshare_layer_index));
} }

View File

@ -135,7 +135,7 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
case LibraryAppletMode::AllForegroundInitiallyHidden: case LibraryAppletMode::AllForegroundInitiallyHidden:
applet->hid_registration.EnableAppletToGetInput(false); applet->hid_registration.EnableAppletToGetInput(false);
applet->focus_state = FocusState::NotInFocus; applet->focus_state = FocusState::NotInFocus;
applet->system_buffer_manager.SetWindowVisibility(false); applet->display_layer_manager.SetWindowVisibility(false);
applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground); applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
break; break;
} }

View File

@ -19,10 +19,9 @@
namespace Service::AM { namespace Service::AM {
ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Kernel::KProcess* process)
Nvnflinger::Nvnflinger& nvnflinger) : ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{
: ServiceFramework{system_, "ILibraryAppletProxy"}, std::move(applet)} {
m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@ -83,8 +82,7 @@ Result ILibraryAppletProxy::GetWindowController(
Result ILibraryAppletProxy::GetSelfController( Result ILibraryAppletProxy::GetSelfController(
Out<SharedPointer<ISelfController>> out_self_controller) { Out<SharedPointer<ISelfController>> out_self_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_self_controller = *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -25,7 +25,7 @@ class IWindowController;
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public: public:
explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); Kernel::KProcess* process);
~ILibraryAppletProxy(); ~ILibraryAppletProxy();
private: private:
@ -47,7 +47,6 @@ private:
Result GetGlobalStateController( Result GetGlobalStateController(
Out<SharedPointer<IGlobalStateController>> out_global_state_controller); Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
Nvnflinger::Nvnflinger& m_nvnflinger;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@ -14,7 +14,8 @@
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/glue/glue_manager.h" #include "core/hle/service/glue/glue_manager.h"
#include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/application_manager_interface.h"
#include "core/hle/service/ns/service_getter_interface.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
namespace Service::AM { namespace Service::AM {
@ -256,11 +257,13 @@ Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(
// Call IApplicationManagerInterface implementation. // Call IApplicationManagerInterface implementation.
auto& service_manager = system.ServiceManager(); auto& service_manager = system.ServiceManager();
auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2"); auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2");
auto app_man = ns_am2->GetApplicationManagerInterface();
std::shared_ptr<NS::IApplicationManagerInterface> app_man;
R_TRY(ns_am2->GetApplicationManagerInterface(&app_man));
// Get desired application language // Get desired application language
u8 desired_language{}; NS::ApplicationLanguage desired_language{};
R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages)); R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
// Convert to settings language code. // Convert to settings language code.

View File

@ -15,9 +15,9 @@
namespace Service::AM { namespace Service::AM {
ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger) Kernel::KProcess* process)
: ServiceFramework{system_, "ISelfController"}, : ServiceFramework{system_, "ISelfController"}, m_process{process}, m_applet{
m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} { std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ISelfController::Exit>, "Exit"}, {0, D<&ISelfController::Exit>, "Exit"},
@ -72,9 +72,16 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
std::scoped_lock lk{m_applet->lock};
m_applet->display_layer_manager.Initialize(system, m_process, m_applet->applet_id,
m_applet->library_applet_mode);
} }
ISelfController::~ISelfController() = default; ISelfController::~ISelfController() {
std::scoped_lock lk{m_applet->lock};
m_applet->display_layer_manager.Finalize();
}
Result ISelfController::Exit() { Result ISelfController::Exit() {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
@ -212,48 +219,42 @@ Result ISelfController::SetAlbumImageOrientation(
Result ISelfController::IsSystemBufferSharingEnabled() { Result ISelfController::IsSystemBufferSharingEnabled() {
LOG_INFO(Service_AM, "called"); LOG_INFO(Service_AM, "called");
R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize(
&m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode)); std::scoped_lock lk{m_applet->lock};
R_THROW(VI::ResultOperationFailed); R_RETURN(m_applet->display_layer_manager.IsSystemBufferSharingEnabled());
} }
Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) { Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
R_TRY(this->IsSystemBufferSharingEnabled());
u64 layer_id; u64 layer_id;
m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id);
R_SUCCEED(); std::scoped_lock lk{m_applet->lock};
R_RETURN(m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id));
} }
Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) { Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) {
LOG_INFO(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
R_TRY(this->IsSystemBufferSharingEnabled()); std::scoped_lock lk{m_applet->lock};
R_RETURN(
m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id); m_applet->display_layer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id));
R_SUCCEED();
} }
Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) { Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) {
LOG_INFO(Service_AM, "called"); LOG_INFO(Service_AM, "called");
m_applet->managed_layer_holder.Initialize(&m_nvnflinger); std::scoped_lock lk{m_applet->lock};
m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id); R_RETURN(m_applet->display_layer_manager.CreateManagedDisplayLayer(out_layer_id));
R_SUCCEED();
} }
Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id, Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
Out<u64> out_recording_layer_id) { Out<u64> out_recording_layer_id) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
m_applet->managed_layer_holder.Initialize(&m_nvnflinger); std::scoped_lock lk{m_applet->lock};
m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id, R_RETURN(m_applet->display_layer_manager.CreateManagedDisplaySeparableLayer(
out_recording_layer_id); out_layer_id, out_recording_layer_id));
R_SUCCEED();
} }
Result ISelfController::SetHandlesRequestToDisplay(bool enable) { Result ISelfController::SetHandlesRequestToDisplay(bool enable) {

View File

@ -23,7 +23,7 @@ struct Applet;
class ISelfController final : public ServiceFramework<ISelfController> { class ISelfController final : public ServiceFramework<ISelfController> {
public: public:
explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet, explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); Kernel::KProcess* process);
~ISelfController() override; ~ISelfController() override;
private: private:
@ -64,7 +64,6 @@ private:
Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option); Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
Result SetRecordVolumeMuted(bool muted); Result SetRecordVolumeMuted(bool muted);
Nvnflinger::Nvnflinger& m_nvnflinger;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@ -19,10 +19,9 @@
namespace Service::AM { namespace Service::AM {
ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Kernel::KProcess* process)
Nvnflinger::Nvnflinger& nvnflinger) : ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{
: ServiceFramework{system_, "ISystemAppletProxy"}, std::move(applet)} {
m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@ -83,8 +82,7 @@ Result ISystemAppletProxy::GetWindowController(
Result ISystemAppletProxy::GetSelfController( Result ISystemAppletProxy::GetSelfController(
Out<SharedPointer<ISelfController>> out_self_controller) { Out<SharedPointer<ISelfController>> out_self_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_self_controller = *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_process);
std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
R_SUCCEED(); R_SUCCEED();
} }

View File

@ -25,7 +25,7 @@ class IWindowController;
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
public: public:
explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger); Kernel::KProcess* process);
~ISystemAppletProxy(); ~ISystemAppletProxy();
private: private:
@ -46,7 +46,6 @@ private:
Result GetGlobalStateController( Result GetGlobalStateController(
Out<SharedPointer<IGlobalStateController>> out_global_state_controller); Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
Nvnflinger::Nvnflinger& m_nvnflinger;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@ -63,7 +63,7 @@ Result IWindowController::RejectToChangeIntoBackground() {
} }
Result IWindowController::SetAppletWindowVisibility(bool visible) { Result IWindowController::SetAppletWindowVisibility(bool visible) {
m_applet->system_buffer_manager.SetWindowVisibility(visible); m_applet->display_layer_manager.SetWindowVisibility(visible);
m_applet->hid_registration.EnableAppletToGetInput(visible); m_applet->hid_registration.EnableAppletToGetInput(visible);
if (visible) { if (visible) {

View File

@ -1,80 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/am/system_buffer_manager.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
#include "core/hle/service/nvnflinger/nvnflinger.h"
#include "core/hle/service/vi/vi_results.h"
namespace Service::AM {
SystemBufferManager::SystemBufferManager() = default;
SystemBufferManager::~SystemBufferManager() {
if (!m_nvnflinger) {
return;
}
// Clean up shared layers.
if (m_buffer_sharing_enabled) {
m_nvnflinger->GetSystemBufferManager().Finalize(m_process);
}
}
bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process,
AppletId applet_id, LibraryAppletMode mode) {
if (m_nvnflinger) {
return m_buffer_sharing_enabled;
}
m_process = process;
m_nvnflinger = nvnflinger;
m_buffer_sharing_enabled = false;
m_system_shared_buffer_id = 0;
m_system_shared_layer_id = 0;
if (applet_id <= AppletId::Application) {
return false;
}
Nvnflinger::LayerBlending blending = Nvnflinger::LayerBlending::None;
if (mode == LibraryAppletMode::PartialForeground ||
mode == LibraryAppletMode::PartialForegroundIndirectDisplay) {
blending = Nvnflinger::LayerBlending::Coverage;
}
const auto display_id = m_nvnflinger->OpenDisplay("Default").value();
const auto res = m_nvnflinger->GetSystemBufferManager().Initialize(
m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blending);
if (res.IsSuccess()) {
m_buffer_sharing_enabled = true;
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
}
return m_buffer_sharing_enabled;
}
void SystemBufferManager::SetWindowVisibility(bool visible) {
if (m_visible == visible) {
return;
}
m_visible = visible;
if (m_nvnflinger) {
m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
}
}
Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written,
s32* out_fbshare_layer_index) {
if (!m_buffer_sharing_enabled) {
return VI::ResultPermissionDenied;
}
return m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(out_was_written,
out_fbshare_layer_index);
}
} // namespace Service::AM

View File

@ -1,52 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <set>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/service/am/am_types.h"
namespace Kernel {
class KProcess;
}
namespace Service::Nvnflinger {
class Nvnflinger;
}
union Result;
namespace Service::AM {
class SystemBufferManager {
public:
SystemBufferManager();
~SystemBufferManager();
bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id,
LibraryAppletMode mode);
void GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id,
u64* out_system_shared_layer_id) {
*out_system_shared_buffer_id = m_system_shared_buffer_id;
*out_system_shared_layer_id = m_system_shared_layer_id;
}
void SetWindowVisibility(bool visible);
Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
private:
Kernel::KProcess* m_process{};
Nvnflinger::Nvnflinger* m_nvnflinger{};
bool m_buffer_sharing_enabled{};
bool m_visible{true};
u64 m_system_shared_buffer_id{};
u64 m_system_shared_layer_id{};
};
} // namespace Service::AM

View File

@ -1,201 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#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 {
AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetTargetVolume"},
{1, nullptr, "SetTargetVolume"},
{2, &AudCtl::GetTargetVolumeMin, "GetTargetVolumeMin"},
{3, &AudCtl::GetTargetVolumeMax, "GetTargetVolumeMax"},
{4, nullptr, "IsTargetMute"},
{5, nullptr, "SetTargetMute"},
{6, nullptr, "IsTargetConnected"},
{7, nullptr, "SetDefaultTarget"},
{8, nullptr, "GetDefaultTarget"},
{9, &AudCtl::GetAudioOutputMode, "GetAudioOutputMode"},
{10, &AudCtl::SetAudioOutputMode, "SetAudioOutputMode"},
{11, nullptr, "SetForceMutePolicy"},
{12, &AudCtl::GetForceMutePolicy, "GetForceMutePolicy"},
{13, &AudCtl::GetOutputModeSetting, "GetOutputModeSetting"},
{14, &AudCtl::SetOutputModeSetting, "SetOutputModeSetting"},
{15, nullptr, "SetOutputTarget"},
{16, nullptr, "SetInputTargetForceEnabled"},
{17, &AudCtl::SetHeadphoneOutputLevelMode, "SetHeadphoneOutputLevelMode"},
{18, &AudCtl::GetHeadphoneOutputLevelMode, "GetHeadphoneOutputLevelMode"},
{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
{21, nullptr, "GetAudioOutputTargetForPlayReport"},
{22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
{23, nullptr, "SetSystemOutputMasterVolume"},
{24, nullptr, "GetSystemOutputMasterVolume"},
{25, nullptr, "GetAudioVolumeDataForPlayReport"},
{26, nullptr, "UpdateHeadphoneSettings"},
{27, nullptr, "SetVolumeMappingTableForDev"},
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{30, &AudCtl::SetSpeakerAutoMuteEnabled, "SetSpeakerAutoMuteEnabled"},
{31, &AudCtl::IsSpeakerAutoMuteEnabled, "IsSpeakerAutoMuteEnabled"},
{32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"},
{34, nullptr, "AcquireTargetNotification"},
{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{37, nullptr, "SetHearingProtectionSafeguardEnabled"},
{38, nullptr, "IsHearingProtectionSafeguardEnabled"},
{39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
{40, nullptr, "GetSystemInformationForDebug"},
{41, nullptr, "SetVolumeButtonLongPressTime"},
{42, nullptr, "SetNativeVolumeForDebug"},
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
{10100, nullptr, "GetAudioVolumeDataForPlayReport"},
{10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"},
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"},
};
// clang-format on
RegisterHandlers(functions);
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
AudCtl::~AudCtl() = default;
void AudCtl::GetTargetVolumeMin(HLERequestContext& ctx) {
LOG_DEBUG(Audio, "called.");
// This service function is currently hardcoded on the
// actual console to this value (as of 8.0.0).
constexpr s32 target_min_volume = 0;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(target_min_volume);
}
void AudCtl::GetTargetVolumeMax(HLERequestContext& ctx) {
LOG_DEBUG(Audio, "called.");
// This service function is currently hardcoded on the
// actual console to this value (as of 8.0.0).
constexpr s32 target_max_volume = 15;
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(target_max_volume);
}
void AudCtl::GetAudioOutputMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
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<Set::AudioOutputModeTarget>()};
const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()};
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");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(ForceMutePolicy::Disable);
}
void AudCtl::GetOutputModeSetting(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
LOG_WARNING(Audio, "(STUBBED) called, target={}", target);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(Set::AudioOutputMode::ch_7_1);
}
void AudCtl::SetOutputModeSetting(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto target{rp.PopEnum<Set::AudioOutputModeTarget>()};
const auto output_mode{rp.PopEnum<Set::AudioOutputMode>()};
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) {
LOG_WARNING(Audio, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(HeadphoneOutputLevelMode::Normal);
}
void AudCtl::SetSpeakerAutoMuteEnabled(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto is_speaker_auto_mute_enabled{rp.Pop<bool>()};
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) {
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(result);
rb.Push<u8>(is_speaker_auto_mute_enabled);
}
} // namespace Service::Audio

View File

@ -1,50 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::Set {
class ISystemSettingsServer;
}
namespace Service::Audio {
class AudCtl final : public ServiceFramework<AudCtl> {
public:
explicit AudCtl(Core::System& system_);
~AudCtl() override;
private:
enum class ForceMutePolicy {
Disable,
SpeakerMuteOnHeadphoneUnplugged,
};
enum class HeadphoneOutputLevelMode {
Normal,
HighPower,
};
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<Service::Set::ISystemSettingsServer> m_set_sys;
};
} // namespace Service::Audio

View File

@ -2,9 +2,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/audio/audctl.h"
#include "core/hle/service/audio/audin_u.h" #include "core/hle/service/audio/audin_u.h"
#include "core/hle/service/audio/audio.h" #include "core/hle/service/audio/audio.h"
#include "core/hle/service/audio/audio_controller.h"
#include "core/hle/service/audio/audout_u.h" #include "core/hle/service/audio/audout_u.h"
#include "core/hle/service/audio/audrec_a.h" #include "core/hle/service/audio/audrec_a.h"
#include "core/hle/service/audio/audrec_u.h" #include "core/hle/service/audio/audrec_u.h"
@ -18,7 +18,7 @@ namespace Service::Audio {
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("audctl", std::make_shared<AudCtl>(system)); server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system));
server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system)); server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system));
server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system));

View File

@ -0,0 +1,174 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/hle/service/audio/audio_controller.h"
#include "core/hle/service/cmif_serialization.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 {
IAudioController::IAudioController(Core::System& system_)
: ServiceFramework{system_, "audctl"}, service_context{system, "audctl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetTargetVolume"},
{1, nullptr, "SetTargetVolume"},
{2, C<&IAudioController::GetTargetVolumeMin>, "GetTargetVolumeMin"},
{3, C<&IAudioController::GetTargetVolumeMax>, "GetTargetVolumeMax"},
{4, nullptr, "IsTargetMute"},
{5, nullptr, "SetTargetMute"},
{6, nullptr, "IsTargetConnected"},
{7, nullptr, "SetDefaultTarget"},
{8, nullptr, "GetDefaultTarget"},
{9, C<&IAudioController::GetAudioOutputMode>, "GetAudioOutputMode"},
{10, C<&IAudioController::SetAudioOutputMode>, "SetAudioOutputMode"},
{11, nullptr, "SetForceMutePolicy"},
{12, C<&IAudioController::GetForceMutePolicy>, "GetForceMutePolicy"},
{13, C<&IAudioController::GetOutputModeSetting>, "GetOutputModeSetting"},
{14, C<&IAudioController::SetOutputModeSetting>, "SetOutputModeSetting"},
{15, nullptr, "SetOutputTarget"},
{16, nullptr, "SetInputTargetForceEnabled"},
{17, C<&IAudioController::SetHeadphoneOutputLevelMode>, "SetHeadphoneOutputLevelMode"},
{18, C<&IAudioController::GetHeadphoneOutputLevelMode>, "GetHeadphoneOutputLevelMode"},
{19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"},
{20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"},
{21, nullptr, "GetAudioOutputTargetForPlayReport"},
{22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"},
{23, nullptr, "SetSystemOutputMasterVolume"},
{24, nullptr, "GetSystemOutputMasterVolume"},
{25, nullptr, "GetAudioVolumeDataForPlayReport"},
{26, nullptr, "UpdateHeadphoneSettings"},
{27, nullptr, "SetVolumeMappingTableForDev"},
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{30, C<&IAudioController::SetSpeakerAutoMuteEnabled>, "SetSpeakerAutoMuteEnabled"},
{31, C<&IAudioController::IsSpeakerAutoMuteEnabled>, "IsSpeakerAutoMuteEnabled"},
{32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"},
{34, C<&IAudioController::AcquireTargetNotification>, "AcquireTargetNotification"},
{35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
{37, nullptr, "SetHearingProtectionSafeguardEnabled"},
{38, nullptr, "IsHearingProtectionSafeguardEnabled"},
{39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
{40, nullptr, "GetSystemInformationForDebug"},
{41, nullptr, "SetVolumeButtonLongPressTime"},
{42, nullptr, "SetNativeVolumeForDebug"},
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
{10100, nullptr, "GetAudioVolumeDataForPlayReport"},
{10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
{10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
{10103, nullptr, "GetAudioOutputTargetForPlayReport"},
{10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
{10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"},
{50000, nullptr, "SetAnalogInputBoostGainForPrototyping"},
};
// clang-format on
RegisterHandlers(functions);
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
notification_event = service_context.CreateEvent("IAudioController:NotificationEvent");
}
IAudioController::~IAudioController() {
service_context.CloseEvent(notification_event);
};
Result IAudioController::GetTargetVolumeMin(Out<s32> out_target_min_volume) {
LOG_DEBUG(Audio, "called.");
// This service function is currently hardcoded on the
// actual console to this value (as of 8.0.0).
*out_target_min_volume = 0;
R_SUCCEED();
}
Result IAudioController::GetTargetVolumeMax(Out<s32> out_target_max_volume) {
LOG_DEBUG(Audio, "called.");
// This service function is currently hardcoded on the
// actual console to this value (as of 8.0.0).
*out_target_max_volume = 15;
R_SUCCEED();
}
Result IAudioController::GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target) {
const auto result = m_set_sys->GetAudioOutputMode(out_output_mode, target);
LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, *out_output_mode);
R_RETURN(result);
}
Result IAudioController::SetAudioOutputMode(Set::AudioOutputModeTarget target,
Set::AudioOutputMode output_mode) {
LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
R_RETURN(m_set_sys->SetAudioOutputMode(target, output_mode));
}
Result IAudioController::GetForceMutePolicy(Out<ForceMutePolicy> out_mute_policy) {
LOG_WARNING(Audio, "(STUBBED) called");
// Removed on FW 13.2.1+
*out_mute_policy = ForceMutePolicy::Disable;
R_SUCCEED();
}
Result IAudioController::GetOutputModeSetting(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target) {
LOG_WARNING(Audio, "(STUBBED) called, target={}", target);
*out_output_mode = Set::AudioOutputMode::ch_7_1;
R_SUCCEED();
}
Result IAudioController::SetOutputModeSetting(Set::AudioOutputModeTarget target,
Set::AudioOutputMode output_mode) {
LOG_INFO(Service_SET, "called, target={}, output_mode={}", target, output_mode);
R_SUCCEED();
}
Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) {
LOG_WARNING(Audio, "(STUBBED) called");
R_SUCCEED();
}
Result IAudioController::GetHeadphoneOutputLevelMode(
Out<HeadphoneOutputLevelMode> out_output_level_mode) {
LOG_INFO(Audio, "called");
*out_output_level_mode = HeadphoneOutputLevelMode::Normal;
R_SUCCEED();
}
Result IAudioController::SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled) {
LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", is_speaker_auto_mute_enabled);
R_RETURN(m_set_sys->SetSpeakerAutoMuteFlag(is_speaker_auto_mute_enabled));
}
Result IAudioController::IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled) {
const auto result = m_set_sys->GetSpeakerAutoMuteFlag(out_is_speaker_auto_mute_enabled);
LOG_INFO(Audio, "called, is_speaker_auto_mute_enabled={}", *out_is_speaker_auto_mute_enabled);
R_RETURN(result);
}
Result IAudioController::AcquireTargetNotification(
OutCopyHandle<Kernel::KReadableEvent> out_notification_event) {
LOG_WARNING(Service_AM, "(STUBBED) called");
*out_notification_event = &notification_event->GetReadableEvent();
R_SUCCEED();
}
} // namespace Service::Audio

View File

@ -0,0 +1,58 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
#include "core/hle/service/set/settings_types.h"
namespace Core {
class System;
}
namespace Service::Set {
class ISystemSettingsServer;
}
namespace Service::Audio {
class IAudioController final : public ServiceFramework<IAudioController> {
public:
explicit IAudioController(Core::System& system_);
~IAudioController() override;
private:
enum class ForceMutePolicy {
Disable,
SpeakerMuteOnHeadphoneUnplugged,
};
enum class HeadphoneOutputLevelMode {
Normal,
HighPower,
};
Result GetTargetVolumeMin(Out<s32> out_target_min_volume);
Result GetTargetVolumeMax(Out<s32> out_target_max_volume);
Result GetAudioOutputMode(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target);
Result SetAudioOutputMode(Set::AudioOutputModeTarget target, Set::AudioOutputMode output_mode);
Result GetForceMutePolicy(Out<ForceMutePolicy> out_mute_policy);
Result GetOutputModeSetting(Out<Set::AudioOutputMode> out_output_mode,
Set::AudioOutputModeTarget target);
Result SetOutputModeSetting(Set::AudioOutputModeTarget target,
Set::AudioOutputMode output_mode);
Result SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode);
Result GetHeadphoneOutputLevelMode(Out<HeadphoneOutputLevelMode> out_output_level_mode);
Result SetSpeakerAutoMuteEnabled(bool is_speaker_auto_mute_enabled);
Result IsSpeakerAutoMuteEnabled(Out<bool> out_is_speaker_auto_mute_enabled);
Result AcquireTargetNotification(OutCopyHandle<Kernel::KReadableEvent> out_notification_event);
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* notification_event;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
};
} // namespace Service::Audio

View File

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ns/account_proxy_interface.h"
namespace Service::NS {
IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
: ServiceFramework{system_, "IAccountProxyInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateUserAccount"},
};
// clang-format on
RegisterHandlers(functions);
}
IAccountProxyInterface::~IAccountProxyInterface() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
public:
explicit IAccountProxyInterface(Core::System& system_);
~IAccountProxyInterface() override;
};
} // namespace Service::NS

View File

@ -0,0 +1,518 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/application_manager_interface.h"
#include "core/hle/service/ns/content_management_interface.h"
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
namespace Service::NS {
IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_)
: ServiceFramework{system_, "IApplicationManagerInterface"},
service_context{system, "IApplicationManagerInterface"},
record_update_system_event{service_context}, sd_card_mount_status_event{service_context},
gamecard_update_detection_event{service_context},
gamecard_mount_status_event{service_context}, gamecard_mount_failure_event{service_context} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IApplicationManagerInterface::ListApplicationRecord>, "ListApplicationRecord"},
{1, nullptr, "GenerateApplicationRecordCount"},
{2, D<&IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent>, "GetApplicationRecordUpdateSystemEvent"},
{3, nullptr, "GetApplicationViewDeprecated"},
{4, nullptr, "DeleteApplicationEntity"},
{5, nullptr, "DeleteApplicationCompletely"},
{6, nullptr, "IsAnyApplicationEntityRedundant"},
{7, nullptr, "DeleteRedundantApplicationEntity"},
{8, nullptr, "IsApplicationEntityMovable"},
{9, nullptr, "MoveApplicationEntity"},
{11, nullptr, "CalculateApplicationOccupiedSize"},
{16, nullptr, "PushApplicationRecord"},
{17, nullptr, "ListApplicationRecordContentMeta"},
{19, nullptr, "LaunchApplicationOld"},
{21, nullptr, "GetApplicationContentPath"},
{22, nullptr, "TerminateApplication"},
{23, nullptr, "ResolveApplicationContentPath"},
{26, nullptr, "BeginInstallApplication"},
{27, nullptr, "DeleteApplicationRecord"},
{30, nullptr, "RequestApplicationUpdateInfo"},
{31, nullptr, "Unknown31"},
{32, nullptr, "CancelApplicationDownload"},
{33, nullptr, "ResumeApplicationDownload"},
{35, nullptr, "UpdateVersionList"},
{36, nullptr, "PushLaunchVersion"},
{37, nullptr, "ListRequiredVersion"},
{38, D<&IApplicationManagerInterface::CheckApplicationLaunchVersion>, "CheckApplicationLaunchVersion"},
{39, nullptr, "CheckApplicationLaunchRights"},
{40, nullptr, "GetApplicationLogoData"},
{41, nullptr, "CalculateApplicationDownloadRequiredSize"},
{42, nullptr, "CleanupSdCard"},
{43, D<&IApplicationManagerInterface::CheckSdCardMountStatus>, "CheckSdCardMountStatus"},
{44, D<&IApplicationManagerInterface::GetSdCardMountStatusChangedEvent>, "GetSdCardMountStatusChangedEvent"},
{45, nullptr, "GetGameCardAttachmentEvent"},
{46, nullptr, "GetGameCardAttachmentInfo"},
{47, nullptr, "GetTotalSpaceSize"},
{48, D<&IApplicationManagerInterface::GetFreeSpaceSize>, "GetFreeSpaceSize"},
{49, nullptr, "GetSdCardRemovedEvent"},
{52, D<&IApplicationManagerInterface::GetGameCardUpdateDetectionEvent>, "GetGameCardUpdateDetectionEvent"},
{53, nullptr, "DisableApplicationAutoDelete"},
{54, nullptr, "EnableApplicationAutoDelete"},
{55, D<&IApplicationManagerInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"},
{56, nullptr, "SetApplicationTerminateResult"},
{57, nullptr, "ClearApplicationTerminateResult"},
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
{59, D<&IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
{62, nullptr, "GetGameCardStopper"},
{63, nullptr, "IsSystemProgramInstalled"},
{64, nullptr, "StartApplyDeltaTask"},
{65, nullptr, "GetRequestServerStopper"},
{66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
{67, nullptr, "CancelApplicationApplyDelta"},
{68, nullptr, "ResumeApplicationApplyDelta"},
{69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
{70, D<&IApplicationManagerInterface::ResumeAll>, "ResumeAll"},
{71, D<&IApplicationManagerInterface::GetStorageSize>, "GetStorageSize"},
{80, nullptr, "RequestDownloadApplication"},
{81, nullptr, "RequestDownloadAddOnContent"},
{82, nullptr, "DownloadApplication"},
{83, nullptr, "CheckApplicationResumeRights"},
{84, nullptr, "GetDynamicCommitEvent"},
{85, nullptr, "RequestUpdateApplication2"},
{86, nullptr, "EnableApplicationCrashReport"},
{87, nullptr, "IsApplicationCrashReportEnabled"},
{90, nullptr, "BoostSystemMemoryResourceLimit"},
{91, nullptr, "DeprecatedLaunchApplication"},
{92, nullptr, "GetRunningApplicationProgramId"},
{93, nullptr, "GetMainApplicationProgramIndex"},
{94, nullptr, "LaunchApplication"},
{95, nullptr, "GetApplicationLaunchInfo"},
{96, nullptr, "AcquireApplicationLaunchInfo"},
{97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"},
{98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{99, nullptr, "LaunchDevMenu"},
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
{103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
{104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
{105, nullptr, "RequestResetToFactorySettingsSecurely"},
{106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
{200, nullptr, "CalculateUserSaveDataStatistics"},
{201, nullptr, "DeleteUserSaveDataAll"},
{210, nullptr, "DeleteUserSystemSaveData"},
{211, nullptr, "DeleteSaveData"},
{220, nullptr, "UnregisterNetworkServiceAccount"},
{221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
{300, nullptr, "GetApplicationShellEvent"},
{301, nullptr, "PopApplicationShellEventInfo"},
{302, nullptr, "LaunchLibraryApplet"},
{303, nullptr, "TerminateLibraryApplet"},
{304, nullptr, "LaunchSystemApplet"},
{305, nullptr, "TerminateSystemApplet"},
{306, nullptr, "LaunchOverlayApplet"},
{307, nullptr, "TerminateOverlayApplet"},
{400, D<&IApplicationManagerInterface::GetApplicationControlData>, "GetApplicationControlData"},
{401, nullptr, "InvalidateAllApplicationControlCache"},
{402, nullptr, "RequestDownloadApplicationControlData"},
{403, nullptr, "GetMaxApplicationControlCacheCount"},
{404, nullptr, "InvalidateApplicationControlCache"},
{405, nullptr, "ListApplicationControlCacheEntryInfo"},
{406, nullptr, "GetApplicationControlProperty"},
{407, nullptr, "ListApplicationTitle"},
{408, nullptr, "ListApplicationIcon"},
{502, nullptr, "RequestCheckGameCardRegistration"},
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
{504, nullptr, "RequestRegisterGameCard"},
{505, D<&IApplicationManagerInterface::GetGameCardMountFailureEvent>, "GetGameCardMountFailureEvent"},
{506, nullptr, "IsGameCardInserted"},
{507, nullptr, "EnsureGameCardAccess"},
{508, nullptr, "GetLastGameCardMountFailureResult"},
{509, nullptr, "ListApplicationIdOnGameCard"},
{510, nullptr, "GetGameCardPlatformRegion"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{602, nullptr, "ListAvailableAddOnContent"},
{603, nullptr, "GetOwnedApplicationContentMetaStatus"},
{604, nullptr, "RegisterContentsExternalKey"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{606, nullptr, "GetContentMetaStorage"},
{607, nullptr, "ListAvailableAddOnContent"},
{609, nullptr, "ListAvailabilityAssuredAddOnContent"},
{610, nullptr, "GetInstalledContentMetaStorage"},
{611, nullptr, "PrepareAddOnContent"},
{700, nullptr, "PushDownloadTaskList"},
{701, nullptr, "ClearTaskStatusList"},
{702, nullptr, "RequestDownloadTaskList"},
{703, nullptr, "RequestEnsureDownloadTask"},
{704, nullptr, "ListDownloadTaskStatus"},
{705, nullptr, "RequestDownloadTaskListData"},
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
{900, nullptr, "GetApplicationRecord"},
{901, nullptr, "GetApplicationRecordProperty"},
{902, nullptr, "EnableApplicationAutoUpdate"},
{903, nullptr, "DisableApplicationAutoUpdate"},
{904, nullptr, "TouchApplication"},
{905, nullptr, "RequestApplicationUpdate"},
{906, D<&IApplicationManagerInterface::IsApplicationUpdateRequested>, "IsApplicationUpdateRequested"},
{907, nullptr, "WithdrawApplicationUpdateRequest"},
{908, nullptr, "ListApplicationRecordInstalledContentMeta"},
{909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
{910, nullptr, "HasApplicationRecord"},
{911, nullptr, "SetPreInstalledApplication"},
{912, nullptr, "ClearPreInstalledApplicationFlag"},
{913, nullptr, "ListAllApplicationRecord"},
{914, nullptr, "HideApplicationRecord"},
{915, nullptr, "ShowApplicationRecord"},
{916, nullptr, "IsApplicationAutoDeleteDisabled"},
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
{1003, nullptr, "RequestVerifyApplication"},
{1004, nullptr, "CorruptContentForDebug"},
{1200, nullptr, "NeedsUpdateVulnerability"},
{1300, D<&IApplicationManagerInterface::IsAnyApplicationEntityInstalled>, "IsAnyApplicationEntityInstalled"},
{1301, nullptr, "DeleteApplicationContentEntities"},
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
{1304, nullptr, "DeleteApplicationContentEntity"},
{1305, nullptr, "TryDeleteRunningApplicationEntity"},
{1306, nullptr, "TryDeleteRunningApplicationCompletely"},
{1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
{1308, nullptr, "DeleteApplicationCompletelyForDebug"},
{1309, nullptr, "CleanupUnavailableAddOnContents"},
{1310, nullptr, "RequestMoveApplicationEntity"},
{1311, nullptr, "EstimateSizeToMove"},
{1312, nullptr, "HasMovableEntity"},
{1313, nullptr, "CleanupOrphanContents"},
{1314, nullptr, "CheckPreconditionSatisfiedToMove"},
{1400, nullptr, "PrepareShutdown"},
{1500, nullptr, "FormatSdCard"},
{1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
{1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
{1504, nullptr, "InsertSdCard"},
{1505, nullptr, "RemoveSdCard"},
{1506, nullptr, "GetSdCardStartupStatus"},
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
{1701, D<&IApplicationManagerInterface::GetApplicationView>, "GetApplicationView"},
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
{1704, D<&IApplicationManagerInterface::GetApplicationViewWithPromotionInfo>, "GetApplicationViewWithPromotionInfo"},
{1705, nullptr, "IsPatchAutoDeletableApplication"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
{1803, nullptr, "ListNotificationTask"},
{1900, nullptr, "IsActiveAccount"},
{1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
{1902, nullptr, "GetApplicationTicketInfo"},
{1903, nullptr, "RequestDownloadApplicationPrepurchasedRightsForAccount"},
{2000, nullptr, "GetSystemDeliveryInfo"},
{2001, nullptr, "SelectLatestSystemDeliveryInfo"},
{2002, nullptr, "VerifyDeliveryProtocolVersion"},
{2003, nullptr, "GetApplicationDeliveryInfo"},
{2004, nullptr, "HasAllContentsToDeliver"},
{2005, nullptr, "CompareApplicationDeliveryInfo"},
{2006, nullptr, "CanDeliverApplication"},
{2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
{2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
{2009, nullptr, "EstimateRequiredSize"},
{2010, nullptr, "RequestReceiveApplication"},
{2011, nullptr, "CommitReceiveApplication"},
{2012, nullptr, "GetReceiveApplicationProgress"},
{2013, nullptr, "RequestSendApplication"},
{2014, nullptr, "GetSendApplicationProgress"},
{2015, nullptr, "CompareSystemDeliveryInfo"},
{2016, nullptr, "ListNotCommittedContentMeta"},
{2017, nullptr, "CreateDownloadTask"},
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
{2050, D<&IApplicationManagerInterface::GetApplicationRightsOnClient>, "GetApplicationRightsOnClient"},
{2051, nullptr, "InvalidateRightsIdCache"},
{2100, D<&IApplicationManagerInterface::GetApplicationTerminateResult>, "GetApplicationTerminateResult"},
{2101, nullptr, "GetRawApplicationTerminateResult"},
{2150, nullptr, "CreateRightsEnvironment"},
{2151, nullptr, "DestroyRightsEnvironment"},
{2152, nullptr, "ActivateRightsEnvironment"},
{2153, nullptr, "DeactivateRightsEnvironment"},
{2154, nullptr, "ForceActivateRightsContextForExit"},
{2155, nullptr, "UpdateRightsEnvironmentStatus"},
{2156, nullptr, "CreateRightsEnvironmentForMicroApplication"},
{2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
{2161, nullptr, "SetUsersToRightsEnvironment"},
{2170, nullptr, "GetRightsEnvironmentStatus"},
{2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
{2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
{2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"},
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
{2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
{2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
{2250, nullptr, "RequestReportActiveELicence"},
{2300, nullptr, "ListEventLog"},
{2350, nullptr, "PerformAutoUpdateByApplicationId"},
{2351, nullptr, "RequestNoDownloadRightsErrorResolution"},
{2352, nullptr, "RequestResolveNoDownloadRightsError"},
{2353, nullptr, "GetApplicationDownloadTaskInfo"},
{2354, nullptr, "PrioritizeApplicationBackgroundTask"},
{2355, nullptr, "PreferStorageEfficientUpdate"},
{2356, nullptr, "RequestStorageEfficientUpdatePreferable"},
{2357, nullptr, "EnableMultiCoreDownload"},
{2358, nullptr, "DisableMultiCoreDownload"},
{2359, nullptr, "IsMultiCoreDownloadEnabled"},
{2400, nullptr, "GetPromotionInfo"},
{2401, nullptr, "CountPromotionInfo"},
{2402, nullptr, "ListPromotionInfo"},
{2403, nullptr, "ImportPromotionJsonForDebug"},
{2404, nullptr, "ClearPromotionInfoForDebug"},
{2500, nullptr, "ConfirmAvailableTime"},
{2510, nullptr, "CreateApplicationResource"},
{2511, nullptr, "GetApplicationResource"},
{2513, nullptr, "LaunchMicroApplication"},
{2514, nullptr, "ClearTaskOfAsyncTaskManager"},
{2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"},
{2516, nullptr, "EnsureApplicationCertificate"},
{2517, nullptr, "CreateApplicationInstance"},
{2518, nullptr, "UpdateQualificationForDebug"},
{2519, nullptr, "IsQualificationTransitionSupported"},
{2520, nullptr, "IsQualificationTransitionSupportedByProcessId"},
{2521, nullptr, "GetRightsUserChangedEvent"},
{2522, nullptr, "IsRomRedirectionAvailable"},
{2800, nullptr, "GetApplicationIdOfPreomia"},
{3000, nullptr, "RegisterDeviceLockKey"},
{3001, nullptr, "UnregisterDeviceLockKey"},
{3002, nullptr, "VerifyDeviceLockKey"},
{3003, nullptr, "HideApplicationIcon"},
{3004, nullptr, "ShowApplicationIcon"},
{3005, nullptr, "HideApplicationTitle"},
{3006, nullptr, "ShowApplicationTitle"},
{3007, nullptr, "EnableGameCard"},
{3008, nullptr, "DisableGameCard"},
{3009, nullptr, "EnableLocalContentShare"},
{3010, nullptr, "DisableLocalContentShare"},
{3011, nullptr, "IsApplicationIconHidden"},
{3012, nullptr, "IsApplicationTitleHidden"},
{3013, nullptr, "IsGameCardEnabled"},
{3014, nullptr, "IsLocalContentShareEnabled"},
{3050, nullptr, "ListAssignELicenseTaskResult"},
{9999, nullptr, "GetApplicationCertificate"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationManagerInterface::~IApplicationManagerInterface() = default;
Result IApplicationManagerInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) {
LOG_DEBUG(Service_NS, "called");
R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlData(
out_buffer, out_actual_size, application_control_source, application_id));
}
Result IApplicationManagerInterface::GetApplicationDesiredLanguage(
Out<ApplicationLanguage> out_desired_language, u32 supported_languages) {
LOG_DEBUG(Service_NS, "called");
R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationDesiredLanguage(
out_desired_language, supported_languages));
}
Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
Out<u64> out_language_code, ApplicationLanguage application_language) {
LOG_DEBUG(Service_NS, "called");
R_RETURN(
IReadOnlyApplicationControlDataInterface(system).ConvertApplicationLanguageToLanguageCode(
out_language_code, application_language));
}
Result IApplicationManagerInterface::ListApplicationRecord(
OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records, Out<s32> out_count,
s32 offset) {
const auto limit = out_records.size();
LOG_WARNING(Service_NS, "(STUBBED) called");
const auto& cache = system.GetContentProviderUnion();
const auto installed_games = cache.ListEntriesFilterOrigin(
std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
size_t i = 0;
u8 ii = 24;
for (const auto& [slot, game] : installed_games) {
if (i >= limit) {
break;
}
if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) {
continue;
}
if (offset > 0) {
offset--;
continue;
}
ApplicationRecord record{};
record.application_id = game.title_id;
record.type = ApplicationRecordType::Installed;
record.unknown = 0; // 2 = needs update
record.unknown2 = ii++;
out_records[i++] = record;
}
*out_count = static_cast<s32>(i);
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
record_update_system_event.Signal();
*out_event = record_update_system_event.GetHandle();
R_SUCCEED();
}
Result IApplicationManagerInterface::GetGameCardMountFailureEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_event = gamecard_mount_failure_event.GetHandle();
R_SUCCEED();
}
Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled(
Out<bool> out_is_any_application_entity_installed) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_is_any_application_entity_installed = true;
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationView(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
const auto size = std::min(out_application_views.size(), application_ids.size());
LOG_WARNING(Service_NS, "(STUBBED) called, size={}", application_ids.size());
for (size_t i = 0; i < size; i++) {
ApplicationView view{};
view.application_id = application_ids[i];
view.unk = 0x70000;
view.flags = 0x401f17;
out_application_views[i] = view;
}
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(
OutArray<ApplicationViewWithPromotionInfo, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
const auto size = std::min(out_application_views.size(), application_ids.size());
LOG_WARNING(Service_NS, "(STUBBED) called, size={}", application_ids.size());
for (size_t i = 0; i < size; i++) {
ApplicationViewWithPromotionInfo view{};
view.view.application_id = application_ids[i];
view.view.unk = 0x70000;
view.view.flags = 0x401f17;
view.promotion = {};
out_application_views[i] = view;
}
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
Common::UUID account_id, u32 flags, u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called, flags={}, application_id={:016X}, account_id={}",
flags, application_id, account_id.FormattedString());
if (!out_rights.empty()) {
out_rights[0] = {
.application_id = application_id,
.uid = account_id,
.flags = 0,
.flags2 = 0,
};
*out_count = 1;
} else {
*out_count = 0;
}
R_SUCCEED();
}
Result IApplicationManagerInterface::CheckSdCardMountStatus() {
LOG_DEBUG(Service_NS, "called");
R_RETURN(IContentManagementInterface(system).CheckSdCardMountStatus());
}
Result IApplicationManagerInterface::GetSdCardMountStatusChangedEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_event = sd_card_mount_status_event.GetHandle();
R_SUCCEED();
}
Result IApplicationManagerInterface::GetFreeSpaceSize(Out<s64> out_free_space_size,
FileSys::StorageId storage_id) {
LOG_DEBUG(Service_NS, "called");
R_RETURN(IContentManagementInterface(system).GetFreeSpaceSize(out_free_space_size, storage_id));
}
Result IApplicationManagerInterface::GetGameCardUpdateDetectionEvent(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_event = gamecard_update_detection_event.GetHandle();
R_SUCCEED();
}
Result IApplicationManagerInterface::ResumeAll() {
LOG_WARNING(Service_NS, "(STUBBED) called");
R_SUCCEED();
}
Result IApplicationManagerInterface::GetStorageSize(Out<s64> out_total_space_size,
Out<s64> out_free_space_size,
FileSys::StorageId storage_id) {
LOG_INFO(Service_NS, "called, storage_id={}", storage_id);
*out_total_space_size = system.GetFileSystemController().GetTotalSpaceSize(storage_id);
*out_free_space_size = system.GetFileSystemController().GetFreeSpaceSize(storage_id);
R_SUCCEED();
}
Result IApplicationManagerInterface::IsApplicationUpdateRequested(Out<bool> out_update_required,
Out<u32> out_update_version,
u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id);
*out_update_required = false;
*out_update_version = 0;
R_SUCCEED();
}
Result IApplicationManagerInterface::CheckApplicationLaunchVersion(u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id);
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationTerminateResult(Out<Result> out_result,
u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called. application_id={:016X}", application_id);
*out_result = ResultSuccess;
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/os/event.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
public:
explicit IApplicationManagerInterface(Core::System& system_);
~IApplicationManagerInterface() override;
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size,
ApplicationControlSource application_control_source,
u64 application_id);
Result GetApplicationDesiredLanguage(Out<ApplicationLanguage> out_desired_language,
u32 supported_languages);
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
ApplicationLanguage application_language);
Result ListApplicationRecord(OutArray<ApplicationRecord, BufferAttr_HipcMapAlias> out_records,
Out<s32> out_count, s32 offset);
Result GetApplicationRecordUpdateSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed);
Result GetApplicationView(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationViewWithPromotionInfo(
OutArray<ApplicationViewWithPromotionInfo, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
Common::UUID account_id, u32 flags, u64 application_id);
Result CheckSdCardMountStatus();
Result GetSdCardMountStatusChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id);
Result GetGameCardUpdateDetectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result ResumeAll();
Result GetStorageSize(Out<s64> out_total_space_size, Out<s64> out_free_space_size,
FileSys::StorageId storage_id);
Result IsApplicationUpdateRequested(Out<bool> out_update_required, Out<u32> out_update_version,
u64 application_id);
Result CheckApplicationLaunchVersion(u64 application_id);
Result GetApplicationTerminateResult(Out<Result> out_result, u64 application_id);
private:
KernelHelpers::ServiceContext service_context;
Event record_update_system_event;
Event sd_card_mount_status_event;
Event gamecard_update_detection_event;
Event gamecard_mount_status_event;
Event gamecard_mount_failure_event;
};
} // namespace Service::NS

View File

@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ns/application_version_interface.h"
namespace Service::NS {
IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_)
: ServiceFramework{system_, "IApplicationVersionInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetLaunchRequiredVersion"},
{1, nullptr, "UpgradeLaunchRequiredVersion"},
{35, nullptr, "UpdateVersionList"},
{36, nullptr, "PushLaunchVersion"},
{37, nullptr, "ListRequiredVersion"},
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
{900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"},
{901, nullptr, "ListDefaultAutoUpdatePolicy"},
{902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"},
{1000, nullptr, "PerformAutoUpdate"},
{1001, nullptr, "ListAutoUpdateSchedule"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationVersionInterface::~IApplicationVersionInterface() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
public:
explicit IApplicationVersionInterface(Core::System& system_);
~IApplicationVersionInterface() override;
};
} // namespace Service::NS

View File

@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/common_funcs.h"
#include "core/core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/content_management_interface.h"
#include "core/hle/service/ns/ns_types.h"
namespace Service::NS {
IContentManagementInterface::IContentManagementInterface(Core::System& system_)
: ServiceFramework{system_, "IContentManagementInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{11, D<&IContentManagementInterface::CalculateApplicationOccupiedSize>, "CalculateApplicationOccupiedSize"},
{43, D<&IContentManagementInterface::CheckSdCardMountStatus>, "CheckSdCardMountStatus"},
{47, D<&IContentManagementInterface::GetTotalSpaceSize>, "GetTotalSpaceSize"},
{48, D<&IContentManagementInterface::GetFreeSpaceSize>, "GetFreeSpaceSize"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{607, nullptr, "IsAnyApplicationRunning"},
};
// clang-format on
RegisterHandlers(functions);
}
IContentManagementInterface::~IContentManagementInterface() = default;
Result IContentManagementInterface::CalculateApplicationOccupiedSize(
Out<ApplicationOccupiedSize> out_size, u64 application_id) {
LOG_WARNING(Service_NS, "(STUBBED) called, application_id={:016X}", application_id);
using namespace Common::Literals;
constexpr ApplicationOccupiedSizeEntity stub_entity{
.storage_id = FileSys::StorageId::SdCard,
.app_size = 8_GiB,
.patch_size = 2_GiB,
.aoc_size = 12_MiB,
};
for (auto& entity : out_size->entities) {
entity = stub_entity;
}
R_SUCCEED();
}
Result IContentManagementInterface::CheckSdCardMountStatus() {
LOG_WARNING(Service_NS, "(STUBBED) called");
R_SUCCEED();
}
Result IContentManagementInterface::GetTotalSpaceSize(Out<s64> out_total_space_size,
FileSys::StorageId storage_id) {
LOG_INFO(Service_NS, "(STUBBED) called, storage_id={}", storage_id);
*out_total_space_size = system.GetFileSystemController().GetTotalSpaceSize(storage_id);
R_SUCCEED();
}
Result IContentManagementInterface::GetFreeSpaceSize(Out<s64> out_free_space_size,
FileSys::StorageId storage_id) {
LOG_INFO(Service_NS, "(STUBBED) called, storage_id={}", storage_id);
*out_free_space_size = system.GetFileSystemController().GetFreeSpaceSize(storage_id);
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> {
public:
explicit IContentManagementInterface(Core::System& system_);
~IContentManagementInterface() override;
public:
Result CalculateApplicationOccupiedSize(Out<ApplicationOccupiedSize> out_size,
u64 application_id);
Result CheckSdCardMountStatus();
Result GetTotalSpaceSize(Out<s64> out_total_space_size, FileSys::StorageId storage_id);
Result GetFreeSpaceSize(Out<s64> out_free_space_size, FileSys::StorageId storage_id);
};
} // namespace Service::NS

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ns/develop_interface.h"
namespace Service::NS {
IDevelopInterface::IDevelopInterface(Core::System& system_) : ServiceFramework{system_, "ns:dev"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "LaunchProgram"},
{1, nullptr, "TerminateProcess"},
{2, nullptr, "TerminateProgram"},
{4, nullptr, "GetShellEvent"},
{5, nullptr, "GetShellEventInfo"},
{6, nullptr, "TerminateApplication"},
{7, nullptr, "PrepareLaunchProgramFromHost"},
{8, nullptr, "LaunchApplicationFromHost"},
{9, nullptr, "LaunchApplicationWithStorageIdForDevelop"},
{10, nullptr, "IsSystemMemoryResourceLimitBoosted"},
{11, nullptr, "GetRunningApplicationProcessIdForDevelop"},
{12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"},
{13, nullptr, "CreateApplicationResourceForDevelop"},
{14, nullptr, "IsPreomiaForDevelop"},
{15, nullptr, "GetApplicationProgramIdFromHost"},
{16, nullptr, "RefreshCachedDebugValues"},
{17, nullptr, "PrepareLaunchApplicationFromHost"},
{18, nullptr, "GetLaunchEvent"},
{19, nullptr, "GetLaunchResult"},
};
// clang-format on
RegisterHandlers(functions);
}
IDevelopInterface::~IDevelopInterface() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IDevelopInterface final : public ServiceFramework<IDevelopInterface> {
public:
explicit IDevelopInterface(Core::System& system_);
~IDevelopInterface() override;
};
} // namespace Service::NS

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/document_interface.h"
namespace Service::NS {
IDocumentInterface::IDocumentInterface(Core::System& system_)
: ServiceFramework{system_, "IDocumentInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{21, nullptr, "GetApplicationContentPath"},
{23, D<&IDocumentInterface::ResolveApplicationContentPath>, "ResolveApplicationContentPath"},
{92, D<&IDocumentInterface::GetRunningApplicationProgramId>, "GetRunningApplicationProgramId"},
};
// clang-format on
RegisterHandlers(functions);
}
IDocumentInterface::~IDocumentInterface() = default;
Result IDocumentInterface::ResolveApplicationContentPath(ContentPath content_path) {
LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}",
content_path.file_system_proxy_type, content_path.program_id);
R_SUCCEED();
}
Result IDocumentInterface::GetRunningApplicationProgramId(Out<u64> out_program_id,
u64 caller_program_id) {
LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id);
*out_program_id = system.GetApplicationProcessProgramID();
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
public:
explicit IDocumentInterface(Core::System& system_);
~IDocumentInterface() override;
private:
Result ResolveApplicationContentPath(ContentPath content_path);
Result GetRunningApplicationProgramId(Out<u64> out_program_id, u64 caller_program_id);
};
} // namespace Service::NS

View File

@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/download_task_interface.h"
namespace Service::NS {
IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
: ServiceFramework{system_, "IDownloadTaskInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{701, nullptr, "ClearTaskStatusList"},
{702, nullptr, "RequestDownloadTaskList"},
{703, nullptr, "RequestEnsureDownloadTask"},
{704, nullptr, "ListDownloadTaskStatus"},
{705, nullptr, "RequestDownloadTaskListData"},
{706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
{707, D<&IDownloadTaskInterface::EnableAutoCommit>, "EnableAutoCommit"},
{708, D<&IDownloadTaskInterface::DisableAutoCommit>, "DisableAutoCommit"},
{709, nullptr, "TriggerDynamicCommitEvent"},
};
// clang-format on
RegisterHandlers(functions);
}
IDownloadTaskInterface::~IDownloadTaskInterface() = default;
Result IDownloadTaskInterface::EnableAutoCommit() {
LOG_WARNING(Service_NS, "(STUBBED) called");
R_SUCCEED();
}
Result IDownloadTaskInterface::DisableAutoCommit() {
LOG_WARNING(Service_NS, "(STUBBED) called");
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
public:
explicit IDownloadTaskInterface(Core::System& system_);
~IDownloadTaskInterface() override;
private:
Result EnableAutoCommit();
Result DisableAutoCommit();
};
} // namespace Service::NS

View File

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/dynamic_rights_interface.h"
namespace Service::NS {
IDynamicRightsInterface::IDynamicRightsInterface(Core::System& system_)
: ServiceFramework{system_, "DynamicRightsInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestApplicationRightsOnServer"},
{1, nullptr, "RequestAssignRights"},
{4, nullptr, "DeprecatedRequestAssignRightsToResume"},
{5, D<&IDynamicRightsInterface::VerifyActivatedRightsOwners>, "VerifyActivatedRightsOwners"},
{6, nullptr, "DeprecatedGetApplicationRightsStatus"},
{7, nullptr, "RequestPrefetchForDynamicRights"},
{8, nullptr, "GetDynamicRightsState"},
{9, nullptr, "RequestApplicationRightsOnServerToResume"},
{10, nullptr, "RequestAssignRightsToResume"},
{11, nullptr, "GetActivatedRightsUsers"},
{12, nullptr, "GetApplicationRightsStatus"},
{13, D<&IDynamicRightsInterface::GetRunningApplicationStatus>, "GetRunningApplicationStatus"},
{14, nullptr, "SelectApplicationLicense"},
{15, nullptr, "RequestContentsAuthorizationToken"},
{16, nullptr, "QualifyUser"},
{17, nullptr, "QualifyUserWithProcessId"},
{18, D<&IDynamicRightsInterface::NotifyApplicationRightsCheckStart>, "NotifyApplicationRightsCheckStart"},
{19, nullptr, "UpdateUserList"},
{20, nullptr, "IsRightsLostUser"},
{21, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
{22, nullptr, "GetLimitedApplicationLicense"},
{23, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
{24, nullptr, "NotifyLimitedApplicationLicenseUpgradableEventForDebug"},
{25, nullptr, "RequestProceedDynamicRightsState"},
};
// clang-format on
RegisterHandlers(functions);
}
IDynamicRightsInterface::~IDynamicRightsInterface() = default;
Result IDynamicRightsInterface::NotifyApplicationRightsCheckStart() {
LOG_WARNING(Service_NS, "(STUBBED) called");
R_SUCCEED();
}
Result IDynamicRightsInterface::GetRunningApplicationStatus(Out<u32> out_status,
u64 rights_handle) {
LOG_WARNING(Service_NS, "(STUBBED) called, rights_handle={:#x}", rights_handle);
*out_status = 0;
R_SUCCEED();
}
Result IDynamicRightsInterface::VerifyActivatedRightsOwners(u64 rights_handle) {
LOG_WARNING(Service_NS, "(STUBBED) called, rights_handle={:#x}", rights_handle);
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IDynamicRightsInterface final : public ServiceFramework<IDynamicRightsInterface> {
public:
explicit IDynamicRightsInterface(Core::System& system_);
~IDynamicRightsInterface() override;
private:
Result NotifyApplicationRightsCheckStart();
Result GetRunningApplicationStatus(Out<u32> out_status, u64 rights_handle);
Result VerifyActivatedRightsOwners(u64 rights_handle);
};
} // namespace Service::NS

View File

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ns/ecommerce_interface.h"
namespace Service::NS {
IECommerceInterface::IECommerceInterface(Core::System& system_)
: ServiceFramework{system_, "IECommerceInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestLinkDevice"},
{1, nullptr, "RequestCleanupAllPreInstalledApplications"},
{2, nullptr, "RequestCleanupPreInstalledApplication"},
{3, nullptr, "RequestSyncRights"},
{4, nullptr, "RequestUnlinkDevice"},
{5, nullptr, "RequestRevokeAllELicense"},
{6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"},
};
// clang-format on
RegisterHandlers(functions);
}
IECommerceInterface::~IECommerceInterface() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
public:
explicit IECommerceInterface(Core::System& system_);
~IECommerceInterface() override;
};
} // namespace Service::NS

View File

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/ns/factory_reset_interface.h"
namespace Service::NS {
IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
: ServiceFramework{system_, "IFactoryResetInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
{103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
{104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
{105, nullptr, "RequestResetToFactorySettingsSecurely"},
{106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
};
// clang-format on
RegisterHandlers(functions);
}
IFactoryResetInterface::~IFactoryResetInterface() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
public:
explicit IFactoryResetInterface(Core::System& system_);
~IFactoryResetInterface() override;
};
} // namespace Service::NS

View File

@ -1,893 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h" #include "core/hle/service/ns/develop_interface.h"
#include "common/settings.h"
#include "core/arm/debug.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/glue/glue_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/errors.h"
#include "core/hle/service/ns/iplatform_service_manager.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/ns.h"
#include "core/hle/service/ns/pdm_qry.h" #include "core/hle/service/ns/platform_service_manager.h"
#include "core/hle/service/ns/query_service.h"
#include "core/hle/service/ns/service_getter_interface.h"
#include "core/hle/service/ns/system_update_interface.h"
#include "core/hle/service/ns/vulnerability_manager_interface.h"
#include "core/hle/service/server_manager.h" #include "core/hle/service/server_manager.h"
#include "core/hle/service/set/settings_server.h"
namespace Service::NS { namespace Service::NS {
IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
: ServiceFramework{system_, "IAccountProxyInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateUserAccount"},
};
// clang-format on
RegisterHandlers(functions);
}
IAccountProxyInterface::~IAccountProxyInterface() = default;
IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_)
: ServiceFramework{system_, "IApplicationManagerInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "ListApplicationRecord"},
{1, nullptr, "GenerateApplicationRecordCount"},
{2, nullptr, "GetApplicationRecordUpdateSystemEvent"},
{3, nullptr, "GetApplicationViewDeprecated"},
{4, nullptr, "DeleteApplicationEntity"},
{5, nullptr, "DeleteApplicationCompletely"},
{6, nullptr, "IsAnyApplicationEntityRedundant"},
{7, nullptr, "DeleteRedundantApplicationEntity"},
{8, nullptr, "IsApplicationEntityMovable"},
{9, nullptr, "MoveApplicationEntity"},
{11, nullptr, "CalculateApplicationOccupiedSize"},
{16, nullptr, "PushApplicationRecord"},
{17, nullptr, "ListApplicationRecordContentMeta"},
{19, nullptr, "LaunchApplicationOld"},
{21, nullptr, "GetApplicationContentPath"},
{22, nullptr, "TerminateApplication"},
{23, nullptr, "ResolveApplicationContentPath"},
{26, nullptr, "BeginInstallApplication"},
{27, nullptr, "DeleteApplicationRecord"},
{30, nullptr, "RequestApplicationUpdateInfo"},
{31, nullptr, "Unknown31"},
{32, nullptr, "CancelApplicationDownload"},
{33, nullptr, "ResumeApplicationDownload"},
{35, nullptr, "UpdateVersionList"},
{36, nullptr, "PushLaunchVersion"},
{37, nullptr, "ListRequiredVersion"},
{38, nullptr, "CheckApplicationLaunchVersion"},
{39, nullptr, "CheckApplicationLaunchRights"},
{40, nullptr, "GetApplicationLogoData"},
{41, nullptr, "CalculateApplicationDownloadRequiredSize"},
{42, nullptr, "CleanupSdCard"},
{43, nullptr, "CheckSdCardMountStatus"},
{44, nullptr, "GetSdCardMountStatusChangedEvent"},
{45, nullptr, "GetGameCardAttachmentEvent"},
{46, nullptr, "GetGameCardAttachmentInfo"},
{47, nullptr, "GetTotalSpaceSize"},
{48, nullptr, "GetFreeSpaceSize"},
{49, nullptr, "GetSdCardRemovedEvent"},
{52, nullptr, "GetGameCardUpdateDetectionEvent"},
{53, nullptr, "DisableApplicationAutoDelete"},
{54, nullptr, "EnableApplicationAutoDelete"},
{55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
{56, nullptr, "SetApplicationTerminateResult"},
{57, nullptr, "ClearApplicationTerminateResult"},
{58, nullptr, "GetLastSdCardMountUnexpectedResult"},
{59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"},
{60, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{61, nullptr, "GetBackgroundDownloadStressTaskInfo"},
{62, nullptr, "GetGameCardStopper"},
{63, nullptr, "IsSystemProgramInstalled"},
{64, nullptr, "StartApplyDeltaTask"},
{65, nullptr, "GetRequestServerStopper"},
{66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
{67, nullptr, "CancelApplicationApplyDelta"},
{68, nullptr, "ResumeApplicationApplyDelta"},
{69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"},
{70, nullptr, "ResumeAll"},
{71, nullptr, "GetStorageSize"},
{80, nullptr, "RequestDownloadApplication"},
{81, nullptr, "RequestDownloadAddOnContent"},
{82, nullptr, "DownloadApplication"},
{83, nullptr, "CheckApplicationResumeRights"},
{84, nullptr, "GetDynamicCommitEvent"},
{85, nullptr, "RequestUpdateApplication2"},
{86, nullptr, "EnableApplicationCrashReport"},
{87, nullptr, "IsApplicationCrashReportEnabled"},
{90, nullptr, "BoostSystemMemoryResourceLimit"},
{91, nullptr, "DeprecatedLaunchApplication"},
{92, nullptr, "GetRunningApplicationProgramId"},
{93, nullptr, "GetMainApplicationProgramIndex"},
{94, nullptr, "LaunchApplication"},
{95, nullptr, "GetApplicationLaunchInfo"},
{96, nullptr, "AcquireApplicationLaunchInfo"},
{97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"},
{98, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{99, nullptr, "LaunchDevMenu"},
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
{103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
{104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
{105, nullptr, "RequestResetToFactorySettingsSecurely"},
{106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
{200, nullptr, "CalculateUserSaveDataStatistics"},
{201, nullptr, "DeleteUserSaveDataAll"},
{210, nullptr, "DeleteUserSystemSaveData"},
{211, nullptr, "DeleteSaveData"},
{220, nullptr, "UnregisterNetworkServiceAccount"},
{221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"},
{300, nullptr, "GetApplicationShellEvent"},
{301, nullptr, "PopApplicationShellEventInfo"},
{302, nullptr, "LaunchLibraryApplet"},
{303, nullptr, "TerminateLibraryApplet"},
{304, nullptr, "LaunchSystemApplet"},
{305, nullptr, "TerminateSystemApplet"},
{306, nullptr, "LaunchOverlayApplet"},
{307, nullptr, "TerminateOverlayApplet"},
{400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"},
{401, nullptr, "InvalidateAllApplicationControlCache"},
{402, nullptr, "RequestDownloadApplicationControlData"},
{403, nullptr, "GetMaxApplicationControlCacheCount"},
{404, nullptr, "InvalidateApplicationControlCache"},
{405, nullptr, "ListApplicationControlCacheEntryInfo"},
{406, nullptr, "GetApplicationControlProperty"},
{407, nullptr, "ListApplicationTitle"},
{408, nullptr, "ListApplicationIcon"},
{502, nullptr, "RequestCheckGameCardRegistration"},
{503, nullptr, "RequestGameCardRegistrationGoldPoint"},
{504, nullptr, "RequestRegisterGameCard"},
{505, nullptr, "GetGameCardMountFailureEvent"},
{506, nullptr, "IsGameCardInserted"},
{507, nullptr, "EnsureGameCardAccess"},
{508, nullptr, "GetLastGameCardMountFailureResult"},
{509, nullptr, "ListApplicationIdOnGameCard"},
{510, nullptr, "GetGameCardPlatformRegion"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{602, nullptr, "ListAvailableAddOnContent"},
{603, nullptr, "GetOwnedApplicationContentMetaStatus"},
{604, nullptr, "RegisterContentsExternalKey"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{606, nullptr, "GetContentMetaStorage"},
{607, nullptr, "ListAvailableAddOnContent"},
{609, nullptr, "ListAvailabilityAssuredAddOnContent"},
{610, nullptr, "GetInstalledContentMetaStorage"},
{611, nullptr, "PrepareAddOnContent"},
{700, nullptr, "PushDownloadTaskList"},
{701, nullptr, "ClearTaskStatusList"},
{702, nullptr, "RequestDownloadTaskList"},
{703, nullptr, "RequestEnsureDownloadTask"},
{704, nullptr, "ListDownloadTaskStatus"},
{705, nullptr, "RequestDownloadTaskListData"},
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
{900, nullptr, "GetApplicationRecord"},
{901, nullptr, "GetApplicationRecordProperty"},
{902, nullptr, "EnableApplicationAutoUpdate"},
{903, nullptr, "DisableApplicationAutoUpdate"},
{904, nullptr, "TouchApplication"},
{905, nullptr, "RequestApplicationUpdate"},
{906, nullptr, "IsApplicationUpdateRequested"},
{907, nullptr, "WithdrawApplicationUpdateRequest"},
{908, nullptr, "ListApplicationRecordInstalledContentMeta"},
{909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"},
{910, nullptr, "HasApplicationRecord"},
{911, nullptr, "SetPreInstalledApplication"},
{912, nullptr, "ClearPreInstalledApplicationFlag"},
{913, nullptr, "ListAllApplicationRecord"},
{914, nullptr, "HideApplicationRecord"},
{915, nullptr, "ShowApplicationRecord"},
{916, nullptr, "IsApplicationAutoDeleteDisabled"},
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
{1003, nullptr, "RequestVerifyApplication"},
{1004, nullptr, "CorruptContentForDebug"},
{1200, nullptr, "NeedsUpdateVulnerability"},
{1300, nullptr, "IsAnyApplicationEntityInstalled"},
{1301, nullptr, "DeleteApplicationContentEntities"},
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
{1304, nullptr, "DeleteApplicationContentEntity"},
{1305, nullptr, "TryDeleteRunningApplicationEntity"},
{1306, nullptr, "TryDeleteRunningApplicationCompletely"},
{1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
{1308, nullptr, "DeleteApplicationCompletelyForDebug"},
{1309, nullptr, "CleanupUnavailableAddOnContents"},
{1310, nullptr, "RequestMoveApplicationEntity"},
{1311, nullptr, "EstimateSizeToMove"},
{1312, nullptr, "HasMovableEntity"},
{1313, nullptr, "CleanupOrphanContents"},
{1314, nullptr, "CheckPreconditionSatisfiedToMove"},
{1400, nullptr, "PrepareShutdown"},
{1500, nullptr, "FormatSdCard"},
{1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
{1502, nullptr, "GetLastSdCardFormatUnexpectedResult"},
{1504, nullptr, "InsertSdCard"},
{1505, nullptr, "RemoveSdCard"},
{1506, nullptr, "GetSdCardStartupStatus"},
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
{1701, nullptr, "GetApplicationView"},
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
{1704, nullptr, "GetApplicationViewWithPromotionInfo"},
{1705, nullptr, "IsPatchAutoDeletableApplication"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
{1803, nullptr, "ListNotificationTask"},
{1900, nullptr, "IsActiveAccount"},
{1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
{1902, nullptr, "GetApplicationTicketInfo"},
{1903, nullptr, "RequestDownloadApplicationPrepurchasedRightsForAccount"},
{2000, nullptr, "GetSystemDeliveryInfo"},
{2001, nullptr, "SelectLatestSystemDeliveryInfo"},
{2002, nullptr, "VerifyDeliveryProtocolVersion"},
{2003, nullptr, "GetApplicationDeliveryInfo"},
{2004, nullptr, "HasAllContentsToDeliver"},
{2005, nullptr, "CompareApplicationDeliveryInfo"},
{2006, nullptr, "CanDeliverApplication"},
{2007, nullptr, "ListContentMetaKeyToDeliverApplication"},
{2008, nullptr, "NeedsSystemUpdateToDeliverApplication"},
{2009, nullptr, "EstimateRequiredSize"},
{2010, nullptr, "RequestReceiveApplication"},
{2011, nullptr, "CommitReceiveApplication"},
{2012, nullptr, "GetReceiveApplicationProgress"},
{2013, nullptr, "RequestSendApplication"},
{2014, nullptr, "GetSendApplicationProgress"},
{2015, nullptr, "CompareSystemDeliveryInfo"},
{2016, nullptr, "ListNotCommittedContentMeta"},
{2017, nullptr, "CreateDownloadTask"},
{2018, nullptr, "GetApplicationDeliveryInfoHash"},
{2050, nullptr, "GetApplicationRightsOnClient"},
{2051, nullptr, "InvalidateRightsIdCache"},
{2100, nullptr, "GetApplicationTerminateResult"},
{2101, nullptr, "GetRawApplicationTerminateResult"},
{2150, nullptr, "CreateRightsEnvironment"},
{2151, nullptr, "DestroyRightsEnvironment"},
{2152, nullptr, "ActivateRightsEnvironment"},
{2153, nullptr, "DeactivateRightsEnvironment"},
{2154, nullptr, "ForceActivateRightsContextForExit"},
{2155, nullptr, "UpdateRightsEnvironmentStatus"},
{2156, nullptr, "CreateRightsEnvironmentForMicroApplication"},
{2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
{2161, nullptr, "SetUsersToRightsEnvironment"},
{2170, nullptr, "GetRightsEnvironmentStatus"},
{2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"},
{2180, nullptr, "RequestExtendRightsInRightsEnvironment"},
{2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"},
{2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"},
{2190, nullptr, "GetRightsEnvironmentHandleForApplication"},
{2199, nullptr, "GetRightsEnvironmentCountForDebug"},
{2200, nullptr, "GetGameCardApplicationCopyIdentifier"},
{2201, nullptr, "GetInstalledApplicationCopyIdentifier"},
{2250, nullptr, "RequestReportActiveELicence"},
{2300, nullptr, "ListEventLog"},
{2350, nullptr, "PerformAutoUpdateByApplicationId"},
{2351, nullptr, "RequestNoDownloadRightsErrorResolution"},
{2352, nullptr, "RequestResolveNoDownloadRightsError"},
{2353, nullptr, "GetApplicationDownloadTaskInfo"},
{2354, nullptr, "PrioritizeApplicationBackgroundTask"},
{2355, nullptr, "PreferStorageEfficientUpdate"},
{2356, nullptr, "RequestStorageEfficientUpdatePreferable"},
{2357, nullptr, "EnableMultiCoreDownload"},
{2358, nullptr, "DisableMultiCoreDownload"},
{2359, nullptr, "IsMultiCoreDownloadEnabled"},
{2400, nullptr, "GetPromotionInfo"},
{2401, nullptr, "CountPromotionInfo"},
{2402, nullptr, "ListPromotionInfo"},
{2403, nullptr, "ImportPromotionJsonForDebug"},
{2404, nullptr, "ClearPromotionInfoForDebug"},
{2500, nullptr, "ConfirmAvailableTime"},
{2510, nullptr, "CreateApplicationResource"},
{2511, nullptr, "GetApplicationResource"},
{2513, nullptr, "LaunchMicroApplication"},
{2514, nullptr, "ClearTaskOfAsyncTaskManager"},
{2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"},
{2516, nullptr, "EnsureApplicationCertificate"},
{2517, nullptr, "CreateApplicationInstance"},
{2518, nullptr, "UpdateQualificationForDebug"},
{2519, nullptr, "IsQualificationTransitionSupported"},
{2520, nullptr, "IsQualificationTransitionSupportedByProcessId"},
{2521, nullptr, "GetRightsUserChangedEvent"},
{2522, nullptr, "IsRomRedirectionAvailable"},
{2800, nullptr, "GetApplicationIdOfPreomia"},
{3000, nullptr, "RegisterDeviceLockKey"},
{3001, nullptr, "UnregisterDeviceLockKey"},
{3002, nullptr, "VerifyDeviceLockKey"},
{3003, nullptr, "HideApplicationIcon"},
{3004, nullptr, "ShowApplicationIcon"},
{3005, nullptr, "HideApplicationTitle"},
{3006, nullptr, "ShowApplicationTitle"},
{3007, nullptr, "EnableGameCard"},
{3008, nullptr, "DisableGameCard"},
{3009, nullptr, "EnableLocalContentShare"},
{3010, nullptr, "DisableLocalContentShare"},
{3011, nullptr, "IsApplicationIconHidden"},
{3012, nullptr, "IsApplicationTitleHidden"},
{3013, nullptr, "IsGameCardEnabled"},
{3014, nullptr, "IsLocalContentShareEnabled"},
{3050, nullptr, "ListAssignELicenseTaskResult"},
{9999, nullptr, "GetApplicationCertificate"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationManagerInterface::~IApplicationManagerInterface() = default;
void IApplicationManagerInterface::GetApplicationControlData(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto flag = rp.PopRaw<u64>();
LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
const auto title_id = rp.PopRaw<u64>();
const auto size = ctx.GetWriteBufferSize();
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
std::vector<u8> out;
if (control.first != nullptr) {
if (size < 0x4000) {
LOG_ERROR(Service_NS,
"output buffer is too small! (actual={:016X}, expected_min=0x4000)", size);
IPC::ResponseBuilder rb{ctx, 2};
// TODO(DarkLordZach): Find a better error code for this.
rb.Push(ResultUnknown);
return;
}
out.resize(0x4000);
const auto bytes = control.first->GetRawBytes();
std::memcpy(out.data(), bytes.data(), bytes.size());
} else {
LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.",
title_id);
out.resize(std::min<u64>(0x4000, size));
}
if (control.second != nullptr) {
if (size < 0x4000 + control.second->GetSize()) {
LOG_ERROR(Service_NS,
"output buffer is too small! (actual={:016X}, expected_min={:016X})", size,
0x4000 + control.second->GetSize());
IPC::ResponseBuilder rb{ctx, 2};
// TODO(DarkLordZach): Find a better error code for this.
rb.Push(ResultUnknown);
return;
}
out.resize(0x4000 + control.second->GetSize());
control.second->Read(out.data() + 0x4000, control.second->GetSize());
} else {
LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.",
title_id);
}
ctx.WriteBuffer(out);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(static_cast<u32>(out.size()));
}
void IApplicationManagerInterface::GetApplicationDesiredLanguage(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto supported_languages = rp.Pop<u32>();
u8 desired_language{};
const auto res = GetApplicationDesiredLanguage(&desired_language, supported_languages);
if (res == ResultSuccess) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(desired_language);
} else {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
}
}
Result IApplicationManagerInterface::GetApplicationDesiredLanguage(u8* out_desired_language,
const u32 supported_languages) {
LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages);
// Get language code from settings
const auto language_code =
Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue()));
// Convert to application language, get priority list
const auto application_language = ConvertToApplicationLanguage(language_code);
if (application_language == std::nullopt) {
LOG_ERROR(Service_NS, "Could not convert application language! language_code={}",
language_code);
return Service::NS::ResultApplicationLanguageNotFound;
}
const auto priority_list = GetApplicationLanguagePriorityList(*application_language);
if (!priority_list) {
LOG_ERROR(Service_NS,
"Could not find application language priorities! application_language={}",
*application_language);
return Service::NS::ResultApplicationLanguageNotFound;
}
// Try to find a valid language.
for (const auto lang : *priority_list) {
const auto supported_flag = GetSupportedLanguageFlag(lang);
if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) {
*out_desired_language = static_cast<u8>(lang);
return ResultSuccess;
}
}
LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
supported_languages);
return Service::NS::ResultApplicationLanguageNotFound;
}
void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto application_language = rp.Pop<u8>();
u64 language_code{};
const auto res = ConvertApplicationLanguageToLanguageCode(&language_code, application_language);
if (res == ResultSuccess) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push(language_code);
} else {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
}
}
Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
u64* out_language_code, u8 application_language) {
const auto language_code =
ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
if (language_code == std::nullopt) {
LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language);
return Service::NS::ResultApplicationLanguageNotFound;
}
*out_language_code = static_cast<u64>(*language_code);
return ResultSuccess;
}
IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_)
: ServiceFramework{system_, "IApplicationVersionInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetLaunchRequiredVersion"},
{1, nullptr, "UpgradeLaunchRequiredVersion"},
{35, nullptr, "UpdateVersionList"},
{36, nullptr, "PushLaunchVersion"},
{37, nullptr, "ListRequiredVersion"},
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
{900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"},
{901, nullptr, "ListDefaultAutoUpdatePolicy"},
{902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"},
{1000, nullptr, "PerformAutoUpdate"},
{1001, nullptr, "ListAutoUpdateSchedule"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationVersionInterface::~IApplicationVersionInterface() = default;
IContentManagementInterface::IContentManagementInterface(Core::System& system_)
: ServiceFramework{system_, "IContentManagementInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{11, nullptr, "CalculateApplicationOccupiedSize"},
{43, nullptr, "CheckSdCardMountStatus"},
{47, &IContentManagementInterface::GetTotalSpaceSize, "GetTotalSpaceSize"},
{48, &IContentManagementInterface::GetFreeSpaceSize, "GetFreeSpaceSize"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{607, nullptr, "IsAnyApplicationRunning"},
};
// clang-format on
RegisterHandlers(functions);
}
IContentManagementInterface::~IContentManagementInterface() = default;
void IContentManagementInterface::GetTotalSpaceSize(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto storage{rp.PopEnum<FileSys::StorageId>()};
LOG_INFO(Service_Capture, "called, storage={}", storage);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(system.GetFileSystemController().GetTotalSpaceSize(storage));
}
void IContentManagementInterface::GetFreeSpaceSize(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto storage{rp.PopEnum<FileSys::StorageId>()};
LOG_INFO(Service_Capture, "called, storage={}", storage);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(system.GetFileSystemController().GetFreeSpaceSize(storage));
}
IDocumentInterface::IDocumentInterface(Core::System& system_)
: ServiceFramework{system_, "IDocumentInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{21, nullptr, "GetApplicationContentPath"},
{23, &IDocumentInterface::ResolveApplicationContentPath, "ResolveApplicationContentPath"},
{92, &IDocumentInterface::GetRunningApplicationProgramId, "GetRunningApplicationProgramId"},
};
// clang-format on
RegisterHandlers(functions);
}
IDocumentInterface::~IDocumentInterface() = default;
void IDocumentInterface::ResolveApplicationContentPath(HLERequestContext& ctx) {
struct ContentPath {
u8 file_system_proxy_type;
u64 program_id;
};
static_assert(sizeof(ContentPath) == 0x10, "ContentPath has wrong size");
IPC::RequestParser rp{ctx};
auto content_path = rp.PopRaw<ContentPath>();
LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}",
content_path.file_system_proxy_type, content_path.program_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IDocumentInterface::GetRunningApplicationProgramId(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto caller_program_id = rp.PopRaw<u64>();
LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(system.GetApplicationProcessProgramID());
}
IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
: ServiceFramework{system_, "IDownloadTaskInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{701, nullptr, "ClearTaskStatusList"},
{702, nullptr, "RequestDownloadTaskList"},
{703, nullptr, "RequestEnsureDownloadTask"},
{704, nullptr, "ListDownloadTaskStatus"},
{705, nullptr, "RequestDownloadTaskListData"},
{706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
{707, nullptr, "EnableAutoCommit"},
{708, nullptr, "DisableAutoCommit"},
{709, nullptr, "TriggerDynamicCommitEvent"},
};
// clang-format on
RegisterHandlers(functions);
}
IDownloadTaskInterface::~IDownloadTaskInterface() = default;
IECommerceInterface::IECommerceInterface(Core::System& system_)
: ServiceFramework{system_, "IECommerceInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestLinkDevice"},
{1, nullptr, "RequestCleanupAllPreInstalledApplications"},
{2, nullptr, "RequestCleanupPreInstalledApplication"},
{3, nullptr, "RequestSyncRights"},
{4, nullptr, "RequestUnlinkDevice"},
{5, nullptr, "RequestRevokeAllELicense"},
{6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"},
};
// clang-format on
RegisterHandlers(functions);
}
IECommerceInterface::~IECommerceInterface() = default;
IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
: ServiceFramework{system_, "IFactoryResetInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
{103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
{104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
{105, nullptr, "RequestResetToFactorySettingsSecurely"},
{106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
};
// clang-format on
RegisterHandlers(functions);
}
IFactoryResetInterface::~IFactoryResetInterface() = default;
IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_)
: ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} {
static const FunctionInfo functions[] = {
{0, &IReadOnlyApplicationRecordInterface::HasApplicationRecord, "HasApplicationRecord"},
{1, nullptr, "NotifyApplicationFailure"},
{2, &IReadOnlyApplicationRecordInterface::IsDataCorruptedResult, "IsDataCorruptedResult"},
};
// clang-format on
RegisterHandlers(functions);
}
IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default;
void IReadOnlyApplicationRecordInterface::HasApplicationRecord(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 program_id = rp.PopRaw<u64>();
LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:X}", program_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(1);
}
void IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto result = rp.PopRaw<Result>();
LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue());
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(0);
}
IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface(
Core::System& system_)
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
{1, nullptr, "GetApplicationDesiredLanguage"},
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"},
};
// clang-format on
RegisterHandlers(functions);
}
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) {
enum class ApplicationControlSource : u8 {
CacheOnly,
Storage,
StorageOnly,
};
struct RequestParameters {
ApplicationControlSource source;
u64 application_id;
};
static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size.");
IPC::RequestParser rp{ctx};
std::vector<u8> nacp_data{};
const auto parameters{rp.PopRaw<RequestParameters>()};
const auto result =
system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id);
if (result == ResultSuccess) {
ctx.WriteBuffer(nacp_data.data(), nacp_data.size());
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{7988, nullptr, "GetDynamicRightsInterface"},
{7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
{7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
{7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"},
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
{7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"},
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
NS::~NS() = default;
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
return GetInterface<IApplicationManagerInterface>(system);
}
class NS_DEV final : public ServiceFramework<NS_DEV> {
public:
explicit NS_DEV(Core::System& system_) : ServiceFramework{system_, "ns:dev"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "LaunchProgram"},
{1, nullptr, "TerminateProcess"},
{2, nullptr, "TerminateProgram"},
{4, nullptr, "GetShellEvent"},
{5, nullptr, "GetShellEventInfo"},
{6, nullptr, "TerminateApplication"},
{7, nullptr, "PrepareLaunchProgramFromHost"},
{8, nullptr, "LaunchApplicationFromHost"},
{9, nullptr, "LaunchApplicationWithStorageIdForDevelop"},
{10, nullptr, "IsSystemMemoryResourceLimitBoosted"},
{11, nullptr, "GetRunningApplicationProcessIdForDevelop"},
{12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"},
{13, nullptr, "CreateApplicationResourceForDevelop"},
{14, nullptr, "IsPreomiaForDevelop"},
{15, nullptr, "GetApplicationProgramIdFromHost"},
{16, nullptr, "RefreshCachedDebugValues"},
{17, nullptr, "PrepareLaunchApplicationFromHost"},
{18, nullptr, "GetLaunchEvent"},
{19, nullptr, "GetLaunchResult"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
public:
explicit ISystemUpdateControl(Core::System& system_)
: ServiceFramework{system_, "ISystemUpdateControl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "HasDownloaded"},
{1, nullptr, "RequestCheckLatestUpdate"},
{2, nullptr, "RequestDownloadLatestUpdate"},
{3, nullptr, "GetDownloadProgress"},
{4, nullptr, "ApplyDownloadedUpdate"},
{5, nullptr, "RequestPrepareCardUpdate"},
{6, nullptr, "GetPrepareCardUpdateProgress"},
{7, nullptr, "HasPreparedCardUpdate"},
{8, nullptr, "ApplyCardUpdate"},
{9, nullptr, "GetDownloadedEulaDataSize"},
{10, nullptr, "GetDownloadedEulaData"},
{11, nullptr, "SetupCardUpdate"},
{12, nullptr, "GetPreparedCardUpdateEulaDataSize"},
{13, nullptr, "GetPreparedCardUpdateEulaData"},
{14, nullptr, "SetupCardUpdateViaSystemUpdater"},
{15, nullptr, "HasReceived"},
{16, nullptr, "RequestReceiveSystemUpdate"},
{17, nullptr, "GetReceiveProgress"},
{18, nullptr, "ApplyReceivedUpdate"},
{19, nullptr, "GetReceivedEulaDataSize"},
{20, nullptr, "GetReceivedEulaData"},
{21, nullptr, "SetupToReceiveSystemUpdate"},
{22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NS_SU final : public ServiceFramework<NS_SU> {
public:
explicit NS_SU(Core::System& system_) : ServiceFramework{system_, "ns:su"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetBackgroundNetworkUpdateState"},
{1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"},
{2, nullptr, "NotifyExFatDriverRequired"},
{3, nullptr, "ClearExFatDriverStatusForDebug"},
{4, nullptr, "RequestBackgroundNetworkUpdate"},
{5, nullptr, "NotifyBackgroundNetworkUpdate"},
{6, nullptr, "NotifyExFatDriverDownloadedForDebug"},
{9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"},
{10, nullptr, "NotifySystemUpdateForContentDelivery"},
{11, nullptr, "PrepareShutdown"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "DestroySystemUpdateTask"},
{17, nullptr, "RequestSendSystemUpdate"},
{18, nullptr, "GetSendSystemUpdateProgress"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void OpenSystemUpdateControl(HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<ISystemUpdateControl>(system);
}
};
class NS_VM final : public ServiceFramework<NS_VM> {
public:
explicit NS_VM(Core::System& system_) : ServiceFramework{system_, "ns:vm"} {
// clang-format off
static const FunctionInfo functions[] = {
{1200, &NS_VM::NeedsUpdateVulnerability, "NeedsUpdateVulnerability"},
{1201, nullptr, "UpdateSafeSystemVersionForDebug"},
{1202, nullptr, "GetSafeSystemVersion"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void NeedsUpdateVulnerability(HLERequestContext& ctx) {
LOG_WARNING(Service_NS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(false);
}
};
void LoopProcess(Core::System& system) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("ns:am2", std::make_shared<NS>("ns:am2", system)); server_manager->RegisterNamedService(
server_manager->RegisterNamedService("ns:ec", std::make_shared<NS>("ns:ec", system)); "ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2"));
server_manager->RegisterNamedService("ns:rid", std::make_shared<NS>("ns:rid", system)); server_manager->RegisterNamedService(
server_manager->RegisterNamedService("ns:rt", std::make_shared<NS>("ns:rt", system)); "ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec"));
server_manager->RegisterNamedService("ns:web", std::make_shared<NS>("ns:web", system)); server_manager->RegisterNamedService(
server_manager->RegisterNamedService("ns:ro", std::make_shared<NS>("ns:ro", system)); "ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid"));
server_manager->RegisterNamedService(
"ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt"));
server_manager->RegisterNamedService(
"ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web"));
server_manager->RegisterNamedService(
"ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro"));
server_manager->RegisterNamedService("ns:dev", std::make_shared<NS_DEV>(system)); server_manager->RegisterNamedService("ns:dev", std::make_shared<IDevelopInterface>(system));
server_manager->RegisterNamedService("ns:su", std::make_shared<NS_SU>(system)); server_manager->RegisterNamedService("ns:su", std::make_shared<ISystemUpdateInterface>(system));
server_manager->RegisterNamedService("ns:vm", std::make_shared<NS_VM>(system)); server_manager->RegisterNamedService("ns:vm",
server_manager->RegisterNamedService("pdm:qry", std::make_shared<PDM_QRY>(system)); std::make_shared<IVulnerabilityManagerInterface>(system));
server_manager->RegisterNamedService("pdm:qry", std::make_shared<IQueryService>(system));
server_manager->RegisterNamedService("pl:s", server_manager->RegisterNamedService("pl:s",
std::make_shared<IPlatformServiceManager>(system, "pl:s")); std::make_shared<IPlatformServiceManager>(system, "pl:s"));

View File

@ -3,141 +3,12 @@
#pragma once #pragma once
#include "core/hle/service/service.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Service { namespace Service::NS {
namespace FileSystem {
class FileSystemController;
} // namespace FileSystem
namespace NS {
class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
public:
explicit IAccountProxyInterface(Core::System& system_);
~IAccountProxyInterface() override;
};
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
public:
explicit IApplicationManagerInterface(Core::System& system_);
~IApplicationManagerInterface() override;
Result GetApplicationDesiredLanguage(u8* out_desired_language, u32 supported_languages);
Result ConvertApplicationLanguageToLanguageCode(u64* out_language_code,
u8 application_language);
private:
void GetApplicationControlData(HLERequestContext& ctx);
void GetApplicationDesiredLanguage(HLERequestContext& ctx);
void ConvertApplicationLanguageToLanguageCode(HLERequestContext& ctx);
};
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
public:
explicit IApplicationVersionInterface(Core::System& system_);
~IApplicationVersionInterface() override;
};
class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> {
public:
explicit IContentManagementInterface(Core::System& system_);
~IContentManagementInterface() override;
private:
void GetTotalSpaceSize(HLERequestContext& ctx);
void GetFreeSpaceSize(HLERequestContext& ctx);
};
class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
public:
explicit IDocumentInterface(Core::System& system_);
~IDocumentInterface() override;
private:
void ResolveApplicationContentPath(HLERequestContext& ctx);
void GetRunningApplicationProgramId(HLERequestContext& ctx);
};
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
public:
explicit IDownloadTaskInterface(Core::System& system_);
~IDownloadTaskInterface() override;
};
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
public:
explicit IECommerceInterface(Core::System& system_);
~IECommerceInterface() override;
};
class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
public:
explicit IFactoryResetInterface(Core::System& system_);
~IFactoryResetInterface() override;
};
class IReadOnlyApplicationRecordInterface final
: public ServiceFramework<IReadOnlyApplicationRecordInterface> {
public:
explicit IReadOnlyApplicationRecordInterface(Core::System& system_);
~IReadOnlyApplicationRecordInterface() override;
private:
void HasApplicationRecord(HLERequestContext& ctx);
void IsDataCorruptedResult(HLERequestContext& ctx);
};
class IReadOnlyApplicationControlDataInterface final
: public ServiceFramework<IReadOnlyApplicationControlDataInterface> {
public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override;
private:
void GetApplicationControlData(HLERequestContext& ctx);
};
class NS final : public ServiceFramework<NS> {
public:
explicit NS(const char* name, Core::System& system_);
~NS() override;
std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
private:
template <typename T, typename... Args>
void PushInterface(HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<T>(system);
}
void PushIApplicationManagerInterface(HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IApplicationManagerInterface>(system);
}
template <typename T, typename... Args>
std::shared_ptr<T> GetInterface(Args&&... args) const {
static_assert(std::is_base_of_v<SessionRequestHandler, T>,
"Not a base of ServiceFrameworkBase");
return std::make_shared<T>(std::forward<Args>(args)...);
}
};
void LoopProcess(Core::System& system); void LoopProcess(Core::System& system);
} // namespace NS } // namespace Service::NS
} // namespace Service

View File

@ -0,0 +1,102 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_funcs.h"
#include "common/uuid.h"
#include "core/file_sys/romfs_factory.h"
namespace Service::NS {
enum class ApplicationRecordType : u8 {
Installing = 2,
Installed = 3,
GameCardNotInserted = 5,
Archived = 0xB,
GameCard = 0x10,
};
enum class ApplicationControlSource : u8 {
CacheOnly = 0,
Storage = 1,
StorageOnly = 2,
};
enum class BackgroundNetworkUpdateState : u8 {
None,
InProgress,
Ready,
};
struct ApplicationRecord {
u64 application_id;
ApplicationRecordType type;
u8 unknown;
INSERT_PADDING_BYTES_NOINIT(0x6);
u8 unknown2;
INSERT_PADDING_BYTES_NOINIT(0x7);
};
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord is an invalid size");
/// ApplicationView
struct ApplicationView {
u64 application_id; ///< ApplicationId.
u32 unk; ///< Unknown.
u32 flags; ///< Flags.
u8 unk_x10[0x10]; ///< Unknown.
u32 unk_x20; ///< Unknown.
u16 unk_x24; ///< Unknown.
u8 unk_x26[0x2]; ///< Unknown.
u8 unk_x28[0x8]; ///< Unknown.
u8 unk_x30[0x10]; ///< Unknown.
u32 unk_x40; ///< Unknown.
u8 unk_x44; ///< Unknown.
u8 unk_x45[0xb]; ///< Unknown.
};
struct ApplicationRightsOnClient {
u64 application_id;
Common::UUID uid;
u8 flags;
u8 flags2;
INSERT_PADDING_BYTES(0x6);
};
/// NsPromotionInfo
struct PromotionInfo {
u64 start_timestamp; ///< POSIX timestamp for the promotion start.
u64 end_timestamp; ///< POSIX timestamp for the promotion end.
s64 remaining_time; ///< Remaining time until the promotion ends, in nanoseconds
///< ({end_timestamp - current_time} converted to nanoseconds).
INSERT_PADDING_BYTES_NOINIT(0x4);
u8 flags; ///< Flags. Bit0: whether the PromotionInfo is valid (including bit1). Bit1 clear:
///< remaining_time is set.
INSERT_PADDING_BYTES_NOINIT(0x3);
};
/// NsApplicationViewWithPromotionInfo
struct ApplicationViewWithPromotionInfo {
ApplicationView view; ///< \ref NsApplicationView
PromotionInfo promotion; ///< \ref NsPromotionInfo
};
struct ApplicationOccupiedSizeEntity {
FileSys::StorageId storage_id;
u64 app_size;
u64 patch_size;
u64 aoc_size;
};
static_assert(sizeof(ApplicationOccupiedSizeEntity) == 0x20,
"ApplicationOccupiedSizeEntity has incorrect size.");
struct ApplicationOccupiedSize {
std::array<ApplicationOccupiedSizeEntity, 4> entities;
};
struct ContentPath {
u8 file_system_proxy_type;
u64 program_id;
};
} // namespace Service::NS

View File

@ -1,67 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <memory>
#include "common/logging/log.h"
#include "common/uuid.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/pdm_qry.h"
#include "core/hle/service/service.h"
namespace Service::NS {
PDM_QRY::PDM_QRY(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "QueryAppletEvent"},
{1, nullptr, "QueryPlayStatistics"},
{2, nullptr, "QueryPlayStatisticsByUserAccountId"},
{3, nullptr, "QueryPlayStatisticsByNetworkServiceAccountId"},
{4, nullptr, "QueryPlayStatisticsByApplicationId"},
{5, &PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId, "QueryPlayStatisticsByApplicationIdAndUserAccountId"},
{6, nullptr, "QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId"},
{7, nullptr, "QueryLastPlayTimeV0"},
{8, nullptr, "QueryPlayEvent"},
{9, nullptr, "GetAvailablePlayEventRange"},
{10, nullptr, "QueryAccountEvent"},
{11, nullptr, "QueryAccountPlayEvent"},
{12, nullptr, "GetAvailableAccountPlayEventRange"},
{13, nullptr, "QueryApplicationPlayStatisticsForSystemV0"},
{14, nullptr, "QueryRecentlyPlayedApplication"},
{15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"},
{16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"},
{17, nullptr, "QueryLastPlayTime"},
{18, nullptr, "QueryApplicationPlayStatisticsForSystem"},
{19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
};
// clang-format on
RegisterHandlers(functions);
}
PDM_QRY::~PDM_QRY() = default;
void PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown = rp.Pop<bool>();
rp.Pop<u8>(); // Padding
const auto application_id = rp.Pop<u64>();
const auto user_account_uid = rp.PopRaw<Common::UUID>();
// TODO(German77): Read statistics of the game
PlayStatistics statistics{
.application_id = application_id,
.total_launches = 1,
};
LOG_WARNING(Service_NS,
"(STUBBED) called. unknown={}. application_id=0x{:016X}, user_account_uid=0x{}",
unknown, application_id, user_account_uid.RawString());
IPC::ResponseBuilder rb{ctx, 12};
rb.Push(ResultSuccess);
rb.PushRaw(statistics);
}
} // namespace Service::NS

View File

@ -18,9 +18,9 @@
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_memory.h" #include "core/hle/kernel/physical_memory.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ns/platform_service_manager.h"
#include "core/hle/service/ns/iplatform_service_manager.h"
namespace Service::NS { namespace Service::NS {
@ -37,11 +37,6 @@ constexpr u32 EXPECTED_MAGIC{0x36f81a1e}; // What we expect the encrypted bfttf
constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000};
constexpr FontRegion EMPTY_REGION{0, 0}; constexpr FontRegion EMPTY_REGION{0, 0};
enum class LoadState : u32 {
Loading = 0,
Done = 1,
};
static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output, static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output,
std::size_t& offset) { std::size_t& offset) {
ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE, ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
@ -138,13 +133,13 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
: ServiceFramework{system_, service_name_}, impl{std::make_unique<Impl>()} { : ServiceFramework{system_, service_name_}, impl{std::make_unique<Impl>()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IPlatformServiceManager::RequestLoad, "RequestLoad"}, {0, D<&IPlatformServiceManager::RequestLoad>, "RequestLoad"},
{1, &IPlatformServiceManager::GetLoadState, "GetLoadState"}, {1, D<&IPlatformServiceManager::GetLoadState>, "GetLoadState"},
{2, &IPlatformServiceManager::GetSize, "GetSize"}, {2, D<&IPlatformServiceManager::GetSize>, "GetSize"},
{3, &IPlatformServiceManager::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"}, {3, D<&IPlatformServiceManager::GetSharedMemoryAddressOffset>, "GetSharedMemoryAddressOffset"},
{4, &IPlatformServiceManager::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, {4, D<&IPlatformServiceManager::GetSharedMemoryNativeHandle>, "GetSharedMemoryNativeHandle"},
{5, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, {5, D<&IPlatformServiceManager::GetSharedFontInOrderOfPriority>, "GetSharedFontInOrderOfPriority"},
{6, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriorityForSystem"}, {6, D<&IPlatformServiceManager::GetSharedFontInOrderOfPriority>, "GetSharedFontInOrderOfPriorityForSystem"},
{100, nullptr, "RequestApplicationFunctionAuthorization"}, {100, nullptr, "RequestApplicationFunctionAuthorization"},
{101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"},
{102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
@ -208,47 +203,33 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
IPlatformServiceManager::~IPlatformServiceManager() = default; IPlatformServiceManager::~IPlatformServiceManager() = default;
void IPlatformServiceManager::RequestLoad(HLERequestContext& ctx) { Result IPlatformServiceManager::RequestLoad(SharedFontType type) {
IPC::RequestParser rp{ctx};
const u32 shared_font_type{rp.Pop<u32>()};
// Games don't call this so all fonts should be loaded // Games don't call this so all fonts should be loaded
LOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); LOG_DEBUG(Service_NS, "called, shared_font_type={}", type);
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
} }
void IPlatformServiceManager::GetLoadState(HLERequestContext& ctx) { Result IPlatformServiceManager::GetLoadState(Out<LoadState> out_load_state, SharedFontType type) {
IPC::RequestParser rp{ctx}; LOG_DEBUG(Service_NS, "called, shared_font_type={}", type);
const u32 font_id{rp.Pop<u32>()}; *out_load_state = LoadState::Loaded;
LOG_DEBUG(Service_NS, "called, font_id={}", font_id); R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(static_cast<u32>(LoadState::Done));
} }
void IPlatformServiceManager::GetSize(HLERequestContext& ctx) { Result IPlatformServiceManager::GetSize(Out<u32> out_size, SharedFontType type) {
IPC::RequestParser rp{ctx}; LOG_DEBUG(Service_NS, "called, shared_font_type={}", type);
const u32 font_id{rp.Pop<u32>()}; *out_size = impl->GetSharedFontRegion(static_cast<size_t>(type)).size;
LOG_DEBUG(Service_NS, "called, font_id={}", font_id); R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(impl->GetSharedFontRegion(font_id).size);
} }
void IPlatformServiceManager::GetSharedMemoryAddressOffset(HLERequestContext& ctx) { Result IPlatformServiceManager::GetSharedMemoryAddressOffset(Out<u32> out_shared_memory_offset,
IPC::RequestParser rp{ctx}; SharedFontType type) {
const u32 font_id{rp.Pop<u32>()}; LOG_DEBUG(Service_NS, "called, shared_font_type={}", type);
LOG_DEBUG(Service_NS, "called, font_id={}", font_id); *out_shared_memory_offset = impl->GetSharedFontRegion(static_cast<size_t>(type)).offset;
R_SUCCEED();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(impl->GetSharedFontRegion(font_id).offset);
} }
void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx) { Result IPlatformServiceManager::GetSharedMemoryNativeHandle(
OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_native_handle) {
// Map backing memory for the font data // Map backing memory for the font data
LOG_DEBUG(Service_NS, "called"); LOG_DEBUG(Service_NS, "called");
@ -256,50 +237,37 @@ void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx
std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(),
impl->shared_font->size()); impl->shared_font->size());
IPC::ResponseBuilder rb{ctx, 2, 1}; // FIXME: this shouldn't belong to the kernel
rb.Push(ResultSuccess); *out_shared_memory_native_handle = &kernel.GetFontSharedMem();
rb.PushCopyObjects(&kernel.GetFontSharedMem()); R_SUCCEED();
} }
void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& ctx) { Result IPlatformServiceManager::GetSharedFontInOrderOfPriority(
OutArray<u32, BufferAttr_HipcMapAlias> out_font_codes,
OutArray<u32, BufferAttr_HipcMapAlias> out_font_offsets,
OutArray<u32, BufferAttr_HipcMapAlias> out_font_sizes, Out<bool> out_fonts_are_loaded,
Out<u32> out_font_count, Set::LanguageCode language_code) {
LOG_DEBUG(Service_NS, "called, language_code={:#x}", language_code);
// The maximum number of elements that can be returned is 6. Regardless of the available fonts // The maximum number of elements that can be returned is 6. Regardless of the available fonts
// or buffer size. // or buffer size.
constexpr std::size_t MaxElementCount = 6; constexpr size_t MaxElementCount = 6;
IPC::RequestParser rp{ctx};
const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
const std::size_t font_codes_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(0));
const std::size_t font_offsets_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(1));
const std::size_t font_sizes_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(2));
LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code);
IPC::ResponseBuilder rb{ctx, 4};
std::vector<u32> font_codes;
std::vector<u32> font_offsets;
std::vector<u32> font_sizes;
// TODO(ogniK): Have actual priority order // TODO(ogniK): Have actual priority order
for (std::size_t i = 0; i < impl->shared_font_regions.size(); i++) { const auto max_size = std::min({MaxElementCount, out_font_codes.size(), out_font_offsets.size(),
font_codes.push_back(static_cast<u32>(i)); out_font_sizes.size(), impl->shared_font_regions.size()});
for (size_t i = 0; i < max_size; i++) {
auto region = impl->GetSharedFontRegion(i); auto region = impl->GetSharedFontRegion(i);
font_offsets.push_back(region.offset);
font_sizes.push_back(region.size); out_font_codes[i] = static_cast<u32>(i);
out_font_offsets[i] = region.offset;
out_font_sizes[i] = region.size;
} }
// Resize buffers if game requests smaller size output *out_fonts_are_loaded = true;
font_codes.resize(std::min(font_codes.size(), font_codes_count)); *out_font_count = static_cast<u32>(max_size);
font_offsets.resize(std::min(font_offsets.size(), font_offsets_count)); R_SUCCEED();
font_sizes.resize(std::min(font_sizes.size(), font_sizes_count));
ctx.WriteBuffer(font_codes, 0);
ctx.WriteBuffer(font_offsets, 1);
ctx.WriteBuffer(font_sizes, 2);
rb.Push(ResultSuccess);
rb.Push<u8>(static_cast<u8>(LoadState::Done)); // Fonts Loaded
rb.Push<u32>(static_cast<u32>(font_codes.size()));
} }
} // namespace Service::NS } // namespace Service::NS

View File

@ -5,7 +5,9 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/hle/service/set/settings_types.h"
namespace Service { namespace Service {
@ -23,6 +25,20 @@ enum class FontArchives : u64 {
ChineseSimple = 0x0100000000000814, ChineseSimple = 0x0100000000000814,
}; };
enum class SharedFontType : u32 {
JapanUSEuropeStandard = 0,
ChineseSimplified = 1,
ExtendedChineseSimplified = 2,
ChineseTraditional = 3,
KoreanHangul = 4,
NintendoExtended = 5,
};
enum class LoadState : u32 {
Loading = 0,
Loaded = 1,
};
constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{ constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{
std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"), std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"),
std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"), std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"),
@ -42,12 +58,17 @@ public:
~IPlatformServiceManager() override; ~IPlatformServiceManager() override;
private: private:
void RequestLoad(HLERequestContext& ctx); Result RequestLoad(SharedFontType type);
void GetLoadState(HLERequestContext& ctx); Result GetLoadState(Out<LoadState> out_load_state, SharedFontType type);
void GetSize(HLERequestContext& ctx); Result GetSize(Out<u32> out_size, SharedFontType type);
void GetSharedMemoryAddressOffset(HLERequestContext& ctx); Result GetSharedMemoryAddressOffset(Out<u32> out_shared_memory_offset, SharedFontType type);
void GetSharedMemoryNativeHandle(HLERequestContext& ctx); Result GetSharedMemoryNativeHandle(
void GetSharedFontInOrderOfPriority(HLERequestContext& ctx); OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_native_handle);
Result GetSharedFontInOrderOfPriority(OutArray<u32, BufferAttr_HipcMapAlias> out_font_codes,
OutArray<u32, BufferAttr_HipcMapAlias> out_font_offsets,
OutArray<u32, BufferAttr_HipcMapAlias> out_font_sizes,
Out<bool> out_fonts_are_loaded, Out<u32> out_font_count,
Set::LanguageCode language_code);
struct Impl; struct Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;

View File

@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "common/uuid.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/query_service.h"
#include "core/hle/service/service.h"
namespace Service::NS {
IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "QueryAppletEvent"},
{1, nullptr, "QueryPlayStatistics"},
{2, nullptr, "QueryPlayStatisticsByUserAccountId"},
{3, nullptr, "QueryPlayStatisticsByNetworkServiceAccountId"},
{4, nullptr, "QueryPlayStatisticsByApplicationId"},
{5, D<&IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId>, "QueryPlayStatisticsByApplicationIdAndUserAccountId"},
{6, nullptr, "QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId"},
{7, nullptr, "QueryLastPlayTimeV0"},
{8, nullptr, "QueryPlayEvent"},
{9, nullptr, "GetAvailablePlayEventRange"},
{10, nullptr, "QueryAccountEvent"},
{11, nullptr, "QueryAccountPlayEvent"},
{12, nullptr, "GetAvailableAccountPlayEventRange"},
{13, nullptr, "QueryApplicationPlayStatisticsForSystemV0"},
{14, nullptr, "QueryRecentlyPlayedApplication"},
{15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"},
{16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"},
{17, nullptr, "QueryLastPlayTime"},
{18, nullptr, "QueryApplicationPlayStatisticsForSystem"},
{19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
};
// clang-format on
RegisterHandlers(functions);
}
IQueryService::~IQueryService() = default;
Result IQueryService::QueryPlayStatisticsByApplicationIdAndUserAccountId(
Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id,
u64 application_id) {
// TODO(German77): Read statistics of the game
*out_play_statistics = {
.application_id = application_id,
.total_launches = 1,
};
LOG_WARNING(Service_NS, "(STUBBED) called. unknown={}. application_id={:016X}, account_id={}",
unknown, application_id, account_id.FormattedString());
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -3,6 +3,8 @@
#pragma once #pragma once
#include "common/uuid.h"
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Service::NS { namespace Service::NS {
@ -20,13 +22,15 @@ struct PlayStatistics {
}; };
static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size"); static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size");
class PDM_QRY final : public ServiceFramework<PDM_QRY> { class IQueryService final : public ServiceFramework<IQueryService> {
public: public:
explicit PDM_QRY(Core::System& system_); explicit IQueryService(Core::System& system_);
~PDM_QRY() override; ~IQueryService() override;
private: private:
void QueryPlayStatisticsByApplicationIdAndUserAccountId(HLERequestContext& ctx); Result QueryPlayStatisticsByApplicationIdAndUserAccountId(
Out<PlayStatistics> out_play_statistics, bool unknown, Common::UUID account_id,
u64 application_id);
}; };
} // namespace Service::NS } // namespace Service::NS

View File

@ -0,0 +1,122 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns_results.h"
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
#include "core/hle/service/set/settings_server.h"
namespace Service::NS {
IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface(
Core::System& system_)
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlData>, "GetApplicationControlData"},
{1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"},
{2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"},
};
// clang-format on
RegisterHandlers(functions);
}
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
application_control_source, application_id);
const FileSys::PatchManager pm{application_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
const auto size = out_buffer.size();
const auto icon_size = control.second ? control.second->GetSize() : 0;
const auto total_size = 0x4000 + icon_size;
if (size < total_size) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)",
size);
R_THROW(ResultUnknown);
}
if (control.first != nullptr) {
const auto bytes = control.first->GetRawBytes();
std::memcpy(out_buffer.data(), bytes.data(), bytes.size());
} else {
LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero",
application_id);
std::memset(out_buffer.data(), 0, 0x4000);
}
if (control.second != nullptr) {
control.second->Read(out_buffer.data() + 0x4000, icon_size);
} else {
LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id);
}
*out_actual_size = static_cast<u32>(total_size);
R_SUCCEED();
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage(
Out<ApplicationLanguage> out_desired_language, u32 supported_languages) {
LOG_INFO(Service_NS, "called with supported_languages={:08X}", supported_languages);
// Get language code from settings
const auto language_code =
Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue()));
// Convert to application language, get priority list
const auto application_language = ConvertToApplicationLanguage(language_code);
if (application_language == std::nullopt) {
LOG_ERROR(Service_NS, "Could not convert application language! language_code={}",
language_code);
R_THROW(Service::NS::ResultApplicationLanguageNotFound);
}
const auto priority_list = GetApplicationLanguagePriorityList(*application_language);
if (!priority_list) {
LOG_ERROR(Service_NS,
"Could not find application language priorities! application_language={}",
*application_language);
R_THROW(Service::NS::ResultApplicationLanguageNotFound);
}
// Try to find a valid language.
for (const auto lang : *priority_list) {
const auto supported_flag = GetSupportedLanguageFlag(lang);
if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) {
*out_desired_language = lang;
R_SUCCEED();
}
}
LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
supported_languages);
R_THROW(Service::NS::ResultApplicationLanguageNotFound);
}
Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode(
Out<u64> out_language_code, ApplicationLanguage application_language) {
const auto language_code = ConvertToLanguageCode(application_language);
if (language_code == std::nullopt) {
LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language);
R_THROW(Service::NS::ResultApplicationLanguageNotFound);
}
*out_language_code = static_cast<u64>(*language_code);
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IReadOnlyApplicationControlDataInterface final
: public ServiceFramework<IReadOnlyApplicationControlDataInterface> {
public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override;
public:
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size,
ApplicationControlSource application_control_source,
u64 application_id);
Result GetApplicationDesiredLanguage(Out<ApplicationLanguage> out_desired_language,
u32 supported_languages);
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
ApplicationLanguage application_language);
};
} // namespace Service::NS

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/read_only_application_record_interface.h"
namespace Service::NS {
IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_)
: ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} {
static const FunctionInfo functions[] = {
{0, D<&IReadOnlyApplicationRecordInterface::HasApplicationRecord>, "HasApplicationRecord"},
{1, nullptr, "NotifyApplicationFailure"},
{2, D<&IReadOnlyApplicationRecordInterface::IsDataCorruptedResult>,
"IsDataCorruptedResult"},
};
// clang-format on
RegisterHandlers(functions);
}
IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default;
Result IReadOnlyApplicationRecordInterface::HasApplicationRecord(
Out<bool> out_has_application_record, u64 program_id) {
LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:016X}", program_id);
*out_has_application_record = true;
R_SUCCEED();
}
Result IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(
Out<bool> out_is_data_corrupted_result, Result result) {
LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue());
*out_is_data_corrupted_result = false;
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IReadOnlyApplicationRecordInterface final
: public ServiceFramework<IReadOnlyApplicationRecordInterface> {
public:
explicit IReadOnlyApplicationRecordInterface(Core::System& system_);
~IReadOnlyApplicationRecordInterface() override;
private:
Result HasApplicationRecord(Out<bool> out_has_application_record, u64 program_id);
Result IsDataCorruptedResult(Out<bool> out_is_data_corrupted_result, Result result);
};
} // namespace Service::NS

View File

@ -0,0 +1,120 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/account_proxy_interface.h"
#include "core/hle/service/ns/application_manager_interface.h"
#include "core/hle/service/ns/application_version_interface.h"
#include "core/hle/service/ns/content_management_interface.h"
#include "core/hle/service/ns/document_interface.h"
#include "core/hle/service/ns/download_task_interface.h"
#include "core/hle/service/ns/dynamic_rights_interface.h"
#include "core/hle/service/ns/ecommerce_interface.h"
#include "core/hle/service/ns/factory_reset_interface.h"
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
#include "core/hle/service/ns/read_only_application_record_interface.h"
#include "core/hle/service/ns/service_getter_interface.h"
namespace Service::NS {
IServiceGetterInterface::IServiceGetterInterface(Core::System& system_, const char* name)
: ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{7988, D<&IServiceGetterInterface::GetDynamicRightsInterface>, "GetDynamicRightsInterface"},
{7989, D<&IServiceGetterInterface::GetReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
{7991, D<&IServiceGetterInterface::GetReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
{7992, D<&IServiceGetterInterface::GetECommerceInterface>, "GetECommerceInterface"},
{7993, D<&IServiceGetterInterface::GetApplicationVersionInterface>, "GetApplicationVersionInterface"},
{7994, D<&IServiceGetterInterface::GetFactoryResetInterface>, "GetFactoryResetInterface"},
{7995, D<&IServiceGetterInterface::GetAccountProxyInterface>, "GetAccountProxyInterface"},
{7996, D<&IServiceGetterInterface::GetApplicationManagerInterface>, "GetApplicationManagerInterface"},
{7997, D<&IServiceGetterInterface::GetDownloadTaskInterface>, "GetDownloadTaskInterface"},
{7998, D<&IServiceGetterInterface::GetContentManagementInterface>, "GetContentManagementInterface"},
{7999, D<&IServiceGetterInterface::GetDocumentInterface>, "GetDocumentInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
IServiceGetterInterface::~IServiceGetterInterface() = default;
Result IServiceGetterInterface::GetDynamicRightsInterface(
Out<SharedPointer<IDynamicRightsInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IDynamicRightsInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetReadOnlyApplicationControlDataInterface(
Out<SharedPointer<IReadOnlyApplicationControlDataInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IReadOnlyApplicationControlDataInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetReadOnlyApplicationRecordInterface(
Out<SharedPointer<IReadOnlyApplicationRecordInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IReadOnlyApplicationRecordInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetECommerceInterface(
Out<SharedPointer<IECommerceInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IECommerceInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetApplicationVersionInterface(
Out<SharedPointer<IApplicationVersionInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IApplicationVersionInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetFactoryResetInterface(
Out<SharedPointer<IFactoryResetInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IFactoryResetInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetAccountProxyInterface(
Out<SharedPointer<IAccountProxyInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IAccountProxyInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetApplicationManagerInterface(
Out<SharedPointer<IApplicationManagerInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IApplicationManagerInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetDownloadTaskInterface(
Out<SharedPointer<IDownloadTaskInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IDownloadTaskInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetContentManagementInterface(
Out<SharedPointer<IContentManagementInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IContentManagementInterface>(system);
R_SUCCEED();
}
Result IServiceGetterInterface::GetDocumentInterface(
Out<SharedPointer<IDocumentInterface>> out_interface) {
LOG_DEBUG(Service_NS, "called");
*out_interface = std::make_shared<IDocumentInterface>(system);
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IDynamicRightsInterface;
class IReadOnlyApplicationControlDataInterface;
class IReadOnlyApplicationRecordInterface;
class IECommerceInterface;
class IApplicationVersionInterface;
class IFactoryResetInterface;
class IAccountProxyInterface;
class IApplicationManagerInterface;
class IDownloadTaskInterface;
class IContentManagementInterface;
class IDocumentInterface;
class IServiceGetterInterface : public ServiceFramework<IServiceGetterInterface> {
public:
explicit IServiceGetterInterface(Core::System& system_, const char* name);
~IServiceGetterInterface() override;
public:
Result GetDynamicRightsInterface(Out<SharedPointer<IDynamicRightsInterface>> out_interface);
Result GetReadOnlyApplicationControlDataInterface(
Out<SharedPointer<IReadOnlyApplicationControlDataInterface>> out_interface);
Result GetReadOnlyApplicationRecordInterface(
Out<SharedPointer<IReadOnlyApplicationRecordInterface>> out_interface);
Result GetECommerceInterface(Out<SharedPointer<IECommerceInterface>> out_interface);
Result GetApplicationVersionInterface(
Out<SharedPointer<IApplicationVersionInterface>> out_interface);
Result GetFactoryResetInterface(Out<SharedPointer<IFactoryResetInterface>> out_interface);
Result GetAccountProxyInterface(Out<SharedPointer<IAccountProxyInterface>> out_interface);
Result GetApplicationManagerInterface(
Out<SharedPointer<IApplicationManagerInterface>> out_interface);
Result GetDownloadTaskInterface(Out<SharedPointer<IDownloadTaskInterface>> out_interface);
Result GetContentManagementInterface(
Out<SharedPointer<IContentManagementInterface>> out_interface);
Result GetDocumentInterface(Out<SharedPointer<IDocumentInterface>> out_interface);
};
} // namespace Service::NS

View File

@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/system_update_control.h"
namespace Service::NS {
ISystemUpdateControl::ISystemUpdateControl(Core::System& system_)
: ServiceFramework{system_, "ISystemUpdateControl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "HasDownloaded"},
{1, nullptr, "RequestCheckLatestUpdate"},
{2, nullptr, "RequestDownloadLatestUpdate"},
{3, nullptr, "GetDownloadProgress"},
{4, nullptr, "ApplyDownloadedUpdate"},
{5, nullptr, "RequestPrepareCardUpdate"},
{6, nullptr, "GetPrepareCardUpdateProgress"},
{7, nullptr, "HasPreparedCardUpdate"},
{8, nullptr, "ApplyCardUpdate"},
{9, nullptr, "GetDownloadedEulaDataSize"},
{10, nullptr, "GetDownloadedEulaData"},
{11, nullptr, "SetupCardUpdate"},
{12, nullptr, "GetPreparedCardUpdateEulaDataSize"},
{13, nullptr, "GetPreparedCardUpdateEulaData"},
{14, nullptr, "SetupCardUpdateViaSystemUpdater"},
{15, nullptr, "HasReceived"},
{16, nullptr, "RequestReceiveSystemUpdate"},
{17, nullptr, "GetReceiveProgress"},
{18, nullptr, "ApplyReceivedUpdate"},
{19, nullptr, "GetReceivedEulaDataSize"},
{20, nullptr, "GetReceivedEulaData"},
{21, nullptr, "SetupToReceiveSystemUpdate"},
{22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"},
};
// clang-format on
RegisterHandlers(functions);
}
ISystemUpdateControl::~ISystemUpdateControl() = default;
} // namespace Service::NS

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
public:
explicit ISystemUpdateControl(Core::System& system_);
~ISystemUpdateControl() override;
};
} // namespace Service::NS

View File

@ -0,0 +1,61 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/system_update_control.h"
#include "core/hle/service/ns/system_update_interface.h"
namespace Service::NS {
ISystemUpdateInterface::ISystemUpdateInterface(Core::System& system_)
: ServiceFramework{system_, "ns:su"}, service_context{system_, "ns:su"},
update_notification_event{service_context} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&ISystemUpdateInterface::GetBackgroundNetworkUpdateState>, "GetBackgroundNetworkUpdateState"},
{1, D<&ISystemUpdateInterface::OpenSystemUpdateControl>, "OpenSystemUpdateControl"},
{2, nullptr, "NotifyExFatDriverRequired"},
{3, nullptr, "ClearExFatDriverStatusForDebug"},
{4, nullptr, "RequestBackgroundNetworkUpdate"},
{5, nullptr, "NotifyBackgroundNetworkUpdate"},
{6, nullptr, "NotifyExFatDriverDownloadedForDebug"},
{9, D<&ISystemUpdateInterface::GetSystemUpdateNotificationEventForContentDelivery>, "GetSystemUpdateNotificationEventForContentDelivery"},
{10, nullptr, "NotifySystemUpdateForContentDelivery"},
{11, nullptr, "PrepareShutdown"},
{12, nullptr, "Unknown12"},
{13, nullptr, "Unknown13"},
{14, nullptr, "Unknown14"},
{15, nullptr, "Unknown15"},
{16, nullptr, "DestroySystemUpdateTask"},
{17, nullptr, "RequestSendSystemUpdate"},
{18, nullptr, "GetSendSystemUpdateProgress"},
};
// clang-format on
RegisterHandlers(functions);
}
ISystemUpdateInterface::~ISystemUpdateInterface() = default;
Result ISystemUpdateInterface::GetBackgroundNetworkUpdateState(
Out<BackgroundNetworkUpdateState> out_background_network_update_state) {
LOG_WARNING(Service_AM, "(STUBBED) called");
*out_background_network_update_state = BackgroundNetworkUpdateState::None;
R_SUCCEED();
}
Result ISystemUpdateInterface::OpenSystemUpdateControl(
Out<SharedPointer<ISystemUpdateControl>> out_system_update_control) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_system_update_control = std::make_shared<ISystemUpdateControl>(system);
R_SUCCEED();
}
Result ISystemUpdateInterface::GetSystemUpdateNotificationEventForContentDelivery(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_event = update_notification_event.GetHandle();
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/ns/ns_types.h"
#include "core/hle/service/os/event.h"
#include "core/hle/service/service.h"
namespace Kernel {
class KReadableEvent;
}
namespace Service::NS {
class ISystemUpdateControl;
class ISystemUpdateInterface final : public ServiceFramework<ISystemUpdateInterface> {
public:
explicit ISystemUpdateInterface(Core::System& system_);
~ISystemUpdateInterface() override;
private:
Result GetBackgroundNetworkUpdateState(
Out<BackgroundNetworkUpdateState> out_background_network_update_state);
Result OpenSystemUpdateControl(
Out<SharedPointer<ISystemUpdateControl>> out_system_update_control);
Result GetSystemUpdateNotificationEventForContentDelivery(
OutCopyHandle<Kernel::KReadableEvent> out_event);
private:
KernelHelpers::ServiceContext service_context;
Event update_notification_event;
};
} // namespace Service::NS

View File

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/ns/vulnerability_manager_interface.h"
namespace Service::NS {
IVulnerabilityManagerInterface::IVulnerabilityManagerInterface(Core::System& system_)
: ServiceFramework{system_, "ns:vm"} {
// clang-format off
static const FunctionInfo functions[] = {
{1200, D<&IVulnerabilityManagerInterface::NeedsUpdateVulnerability>, "NeedsUpdateVulnerability"},
{1201, nullptr, "UpdateSafeSystemVersionForDebug"},
{1202, nullptr, "GetSafeSystemVersion"},
};
// clang-format on
RegisterHandlers(functions);
}
IVulnerabilityManagerInterface::~IVulnerabilityManagerInterface() = default;
Result IVulnerabilityManagerInterface::NeedsUpdateVulnerability(
Out<bool> out_needs_update_vulnerability) {
LOG_WARNING(Service_NS, "(STUBBED) called");
*out_needs_update_vulnerability = false;
R_SUCCEED();
}
} // namespace Service::NS

View File

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/service/cmif_types.h"
#include "core/hle/service/service.h"
namespace Service::NS {
class IVulnerabilityManagerInterface final
: public ServiceFramework<IVulnerabilityManagerInterface> {
public:
explicit IVulnerabilityManagerInterface(Core::System& system_);
~IVulnerabilityManagerInterface() override;
private:
Result NeedsUpdateVulnerability(Out<bool> out_needs_update_vulnerability);
};
} // namespace Service::NS

View File

@ -68,10 +68,7 @@ public:
const SyncpointManager& GetSyncpointManager() const; const SyncpointManager& GetSyncpointManager() const;
struct Host1xDeviceFileData { struct Host1xDeviceFileData {
std::unordered_map<DeviceFD, u32> fd_to_id{};
std::deque<u32> syncpts_accumulated{}; std::deque<u32> syncpts_accumulated{};
u32 nvdec_next_id{};
u32 vic_next_id{};
}; };
Host1xDeviceFileData& Host1xDeviceFile(); Host1xDeviceFileData& Host1xDeviceFile();

View File

@ -8,6 +8,7 @@
#include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h" #include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
@ -21,13 +22,8 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
case 0x1: { case 0x1:
auto& host1x_file = core.Host1xDeviceFile();
if (!host1x_file.fd_to_id.contains(fd)) {
host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++;
}
return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd); return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd);
}
case 0x2: case 0x2:
return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output); return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output);
case 0x3: case 0x3:
@ -72,15 +68,12 @@ void nvhost_nvdec::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream started"); LOG_INFO(Service_NVDRV, "NVDEC video stream started");
system.SetNVDECActive(true); system.SetNVDECActive(true);
sessions[fd] = session_id; sessions[fd] = session_id;
host1x.StartDevice(fd, Tegra::Host1x::ChannelType::NvDec, channel_syncpoint);
} }
void nvhost_nvdec::OnClose(DeviceFD fd) { void nvhost_nvdec::OnClose(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
auto& host1x_file = core.Host1xDeviceFile(); host1x.StopDevice(fd, Tegra::Host1x::ChannelType::NvDec);
const auto iter = host1x_file.fd_to_id.find(fd);
if (iter != host1x_file.fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
system.SetNVDECActive(false); system.SetNVDECActive(false);
auto it = sessions.find(fd); auto it = sessions.find(fd);
if (it != sessions.end()) { if (it != sessions.end()) {

View File

@ -55,8 +55,9 @@ std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size
nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, NvCore::Container& core_, nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, NvCore::Container& core_,
NvCore::ChannelType channel_type_) NvCore::ChannelType channel_type_)
: nvdevice{system_}, core{core_}, syncpoint_manager{core.GetSyncpointManager()}, : nvdevice{system_}, host1x{system_.Host1x()}, core{core_},
nvmap{core.GetNvMapFile()}, channel_type{channel_type_} { syncpoint_manager{core.GetSyncpointManager()}, nvmap{core.GetNvMapFile()},
channel_type{channel_type_} {
auto& syncpts_accumulated = core.Host1xDeviceFile().syncpts_accumulated; auto& syncpts_accumulated = core.Host1xDeviceFile().syncpts_accumulated;
if (syncpts_accumulated.empty()) { if (syncpts_accumulated.empty()) {
channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false); channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false);
@ -95,24 +96,24 @@ NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, De
offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset); offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset);
offset += SliceVectors(data, fence_thresholds, params.fence_count, offset); offset += SliceVectors(data, fence_thresholds, params.fence_count, offset);
auto& gpu = system.GPU();
auto* session = core.GetSession(sessions[fd]); auto* session = core.GetSession(sessions[fd]);
if (gpu.UseNvdec()) { for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
for (std::size_t i = 0; i < syncpt_increments.size(); i++) { const SyncptIncr& syncpt_incr = syncpt_increments[i];
const SyncptIncr& syncpt_incr = syncpt_increments[i]; fence_thresholds[i] =
fence_thresholds[i] = syncpoint_manager.IncrementSyncpointMaxExt(syncpt_incr.id, syncpt_incr.increments);
syncpoint_manager.IncrementSyncpointMaxExt(syncpt_incr.id, syncpt_incr.increments);
}
} }
for (const auto& cmd_buffer : command_buffers) { for (const auto& cmd_buffer : command_buffers) {
const auto object = nvmap.GetHandle(cmd_buffer.memory_id); const auto object = nvmap.GetHandle(cmd_buffer.memory_id);
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); Core::Memory::CpuGuestMemory<Tegra::ChCommandHeader,
session->process->GetMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(), Core::Memory::GuestMemoryFlags::SafeRead>
cmdlist.size() * sizeof(u32)); cmdlist(session->process->GetMemory(), object->address + cmd_buffer.offset,
gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist); cmd_buffer.word_count);
host1x.PushEntries(fd, std::move(cmdlist));
} }
// Some games expect command_buffers to be written back // Some games expect command_buffers to be written back
offset = 0; offset = 0;
offset += WriteVectors(data, command_buffers, offset); offset += WriteVectors(data, command_buffers, offset);

View File

@ -119,6 +119,7 @@ protected:
Kernel::KEvent* QueryEvent(u32 event_id) override; Kernel::KEvent* QueryEvent(u32 event_id) override;
Tegra::Host1x::Host1x& host1x;
u32 channel_syncpoint; u32 channel_syncpoint;
s32_le nvmap_fd{}; s32_le nvmap_fd{};
u32_le submit_timeout{}; u32_le submit_timeout{};

View File

@ -7,6 +7,7 @@
#include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/ioctl_serialization.h" #include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_vic.h" #include "core/hle/service/nvdrv/devices/nvhost_vic.h"
#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h" #include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
@ -21,13 +22,8 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
case 0x1: { case 0x1:
auto& host1x_file = core.Host1xDeviceFile();
if (!host1x_file.fd_to_id.contains(fd)) {
host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++;
}
return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd); return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd);
}
case 0x2: case 0x2:
return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output); return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output);
case 0x3: case 0x3:
@ -70,14 +66,11 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
void nvhost_vic::OnOpen(NvCore::SessionId session_id, DeviceFD fd) { void nvhost_vic::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
sessions[fd] = session_id; sessions[fd] = session_id;
host1x.StartDevice(fd, Tegra::Host1x::ChannelType::VIC, channel_syncpoint);
} }
void nvhost_vic::OnClose(DeviceFD fd) { void nvhost_vic::OnClose(DeviceFD fd) {
auto& host1x_file = core.Host1xDeviceFile(); host1x.StopDevice(fd, Tegra::Host1x::ChannelType::VIC);
const auto iter = host1x_file.fd_to_id.find(fd);
if (iter != host1x_file.fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
sessions.erase(fd); sessions.erase(fd);
} }

View File

@ -42,7 +42,7 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
module.service_context.CloseEvent(event); module.service_context.CloseEvent(event);
} }
void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
auto module = std::make_shared<Module>(system); auto module = std::make_shared<Module>(system);
const auto NvdrvInterfaceFactoryForApplication = [&, module] { const auto NvdrvInterfaceFactoryForApplication = [&, module] {
@ -62,7 +62,6 @@ void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules); server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules);
server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting); server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting);
server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
nvnflinger.SetNVDrvInstance(module);
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View File

@ -10,13 +10,11 @@
#include <span> #include <span>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvdrv/nvdata.h"
#include "core/hle/service/nvnflinger/ui/fence.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -27,10 +25,6 @@ namespace Kernel {
class KEvent; class KEvent;
} }
namespace Service::Nvnflinger {
class Nvnflinger;
}
namespace Service::Nvidia { namespace Service::Nvidia {
namespace NvCore { namespace NvCore {
@ -99,7 +93,6 @@ public:
private: private:
friend class EventInterface; friend class EventInterface;
friend class Service::Nvnflinger::Nvnflinger;
/// Manages syncpoints on the host /// Manages syncpoints on the host
NvCore::Container container; NvCore::Container container;
@ -118,6 +111,6 @@ private:
std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
}; };
void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); void LoopProcess(Core::System& system);
} // namespace Service::Nvidia } // namespace Service::Nvidia

View File

@ -263,8 +263,10 @@ NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char*
} }
NVDRV::~NVDRV() { NVDRV::~NVDRV() {
auto& container = nvdrv->GetContainer(); if (is_initialized) {
container.CloseSession(session_id); auto& container = nvdrv->GetContainer();
container.CloseSession(session_id);
}
} }
} // namespace Service::Nvidia } // namespace Service::Nvidia

View File

@ -16,6 +16,10 @@ public:
explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name); explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name);
~NVDRV() override; ~NVDRV() override;
std::shared_ptr<Module> GetModule() const {
return nvdrv;
}
private: private:
void Open(HLERequestContext& ctx); void Open(HLERequestContext& ctx);
void Ioctl1(HLERequestContext& ctx); void Ioctl1(HLERequestContext& ctx);

View File

@ -20,29 +20,12 @@ class HLERequestContext;
namespace Service::android { namespace Service::android {
enum class TransactionId {
RequestBuffer = 1,
SetBufferCount = 2,
DequeueBuffer = 3,
DetachBuffer = 4,
DetachNextBuffer = 5,
AttachBuffer = 6,
QueueBuffer = 7,
CancelBuffer = 8,
Query = 9,
Connect = 10,
Disconnect = 11,
AllocateBuffers = 13,
SetPreallocatedBuffer = 14,
GetBufferHistory = 17,
};
class IBinder { class IBinder {
public: public:
virtual ~IBinder() = default; virtual ~IBinder() = default;
virtual void Transact(android::TransactionId code, u32 flags, std::span<const u8> parcel_data, virtual void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply,
std::span<u8> parcel_reply) = 0; u32 flags) = 0;
virtual Kernel::KReadableEvent& GetNativeHandle() = 0; virtual Kernel::KReadableEvent* GetNativeHandle(u32 type_id) = 0;
}; };
} // namespace Service::android } // namespace Service::android

View File

@ -12,7 +12,7 @@
namespace Service::android { namespace Service::android {
BufferItemConsumer::BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer_) BufferItemConsumer::BufferItemConsumer(std::shared_ptr<BufferQueueConsumer> consumer_)
: ConsumerBase{std::move(consumer_)} {} : ConsumerBase{std::move(consumer_)} {}
Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when,

View File

@ -19,7 +19,7 @@ class BufferItem;
class BufferItemConsumer final : public ConsumerBase { class BufferItemConsumer final : public ConsumerBase {
public: public:
explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer); explicit BufferItemConsumer(std::shared_ptr<BufferQueueConsumer> consumer);
Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when,
bool wait_for_fence = true); bool wait_for_fence = true);
Status ReleaseBuffer(const BufferItem& item, const Fence& release_fence); Status ReleaseBuffer(const BufferItem& item, const Fence& release_fence);

View File

@ -4,12 +4,13 @@
// Parts of this implementation were based on: // Parts of this implementation were based on:
// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp // https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp
#include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/service/nvnflinger/buffer_item.h" #include "core/hle/service/nvnflinger/buffer_item.h"
#include "core/hle/service/nvnflinger/buffer_queue_consumer.h" #include "core/hle/service/nvnflinger/buffer_queue_consumer.h"
#include "core/hle/service/nvnflinger/buffer_queue_core.h" #include "core/hle/service/nvnflinger/buffer_queue_core.h"
#include "core/hle/service/nvnflinger/parcel.h"
#include "core/hle/service/nvnflinger/producer_listener.h" #include "core/hle/service/nvnflinger/producer_listener.h"
#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
namespace Service::android { namespace Service::android {
@ -254,4 +255,77 @@ Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
return Status::NoError; return Status::NoError;
} }
void BufferQueueConsumer::Transact(u32 code, std::span<const u8> parcel_data,
std::span<u8> parcel_reply, u32 flags) {
// Values used by BnGraphicBufferConsumer onTransact
enum class TransactionId {
AcquireBuffer = 1,
DetachBuffer = 2,
AttachBuffer = 3,
ReleaseBuffer = 4,
ConsumerConnect = 5,
ConsumerDisconnect = 6,
GetReleasedBuffers = 7,
SetDefaultBufferSize = 8,
SetDefaultMaxBufferCount = 9,
DisableAsyncBuffer = 10,
SetMaxAcquiredBufferCount = 11,
SetConsumerName = 12,
SetDefaultBufferFormat = 13,
SetConsumerUsageBits = 14,
SetTransformHint = 15,
GetSidebandStream = 16,
Unknown18 = 18,
Unknown20 = 20,
};
Status status{Status::NoError};
InputParcel parcel_in{parcel_data};
OutputParcel parcel_out{};
switch (static_cast<TransactionId>(code)) {
case TransactionId::AcquireBuffer: {
BufferItem item;
const s64 present_when = parcel_in.Read<s64>();
status = AcquireBuffer(&item, std::chrono::nanoseconds{present_when});
// TODO: can't write this directly, needs a flattener for the sp<GraphicBuffer>
// parcel_out.WriteFlattened(item);
UNREACHABLE();
}
case TransactionId::ReleaseBuffer: {
const s32 slot = parcel_in.Read<s32>();
const u64 frame_number = parcel_in.Read<u64>();
const auto release_fence = parcel_in.ReadFlattened<Fence>();
status = ReleaseBuffer(slot, frame_number, release_fence);
break;
}
case TransactionId::GetReleasedBuffers: {
u64 slot_mask = 0;
status = GetReleasedBuffers(&slot_mask);
parcel_out.Write(slot_mask);
break;
}
default:
ASSERT_MSG(false, "called, code={} flags={}", code, flags);
break;
}
parcel_out.Write(status);
const auto serialized = parcel_out.Serialize();
std::memcpy(parcel_reply.data(), serialized.data(),
std::min(parcel_reply.size(), serialized.size()));
}
Kernel::KReadableEvent* BufferQueueConsumer::GetNativeHandle(u32 type_id) {
ASSERT_MSG(false, "called, type_id={}", type_id);
return nullptr;
}
} // namespace Service::android } // namespace Service::android

View File

@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/service/nvnflinger/binder.h"
#include "core/hle/service/nvnflinger/buffer_queue_defs.h" #include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/status.h" #include "core/hle/service/nvnflinger/status.h"
@ -19,10 +20,10 @@ class BufferItem;
class BufferQueueCore; class BufferQueueCore;
class IConsumerListener; class IConsumerListener;
class BufferQueueConsumer final { class BufferQueueConsumer final : public IBinder {
public: public:
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
~BufferQueueConsumer(); ~BufferQueueConsumer() override;
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
@ -30,6 +31,11 @@ public:
Status Disconnect(); Status Disconnect();
Status GetReleasedBuffers(u64* out_slot_mask); Status GetReleasedBuffers(u64* out_slot_mask);
void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply,
u32 flags) override;
Kernel::KReadableEvent* GetNativeHandle(u32 type_id) override;
private: private:
std::shared_ptr<BufferQueueCore> core; std::shared_ptr<BufferQueueCore> core;
BufferQueueDefs::SlotsType& slots; BufferQueueDefs::SlotsType& slots;

View File

@ -6,12 +6,9 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/hle_ipc.h"
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nvnflinger/buffer_queue_core.h" #include "core/hle/service/nvnflinger/buffer_queue_core.h"
#include "core/hle/service/nvnflinger/buffer_queue_producer.h" #include "core/hle/service/nvnflinger/buffer_queue_producer.h"
@ -19,7 +16,6 @@
#include "core/hle/service/nvnflinger/parcel.h" #include "core/hle/service/nvnflinger/parcel.h"
#include "core/hle/service/nvnflinger/ui/graphic_buffer.h" #include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
#include "core/hle/service/nvnflinger/window.h" #include "core/hle/service/nvnflinger/window.h"
#include "core/hle/service/vi/vi.h"
namespace Service::android { namespace Service::android {
@ -807,13 +803,31 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
return Status::NoError; return Status::NoError;
} }
void BufferQueueProducer::Transact(TransactionId code, u32 flags, std::span<const u8> parcel_data, void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
std::span<u8> parcel_reply) { std::span<u8> parcel_reply, u32 flags) {
// Values used by BnGraphicBufferProducer onTransact
enum class TransactionId {
RequestBuffer = 1,
SetBufferCount = 2,
DequeueBuffer = 3,
DetachBuffer = 4,
DetachNextBuffer = 5,
AttachBuffer = 6,
QueueBuffer = 7,
CancelBuffer = 8,
Query = 9,
Connect = 10,
Disconnect = 11,
AllocateBuffers = 13,
SetPreallocatedBuffer = 14,
GetBufferHistory = 17,
};
Status status{Status::NoError}; Status status{Status::NoError};
InputParcel parcel_in{parcel_data}; InputParcel parcel_in{parcel_data};
OutputParcel parcel_out{}; OutputParcel parcel_out{};
switch (code) { switch (static_cast<TransactionId>(code)) {
case TransactionId::Connect: { case TransactionId::Connect: {
const auto enable_listener = parcel_in.Read<bool>(); const auto enable_listener = parcel_in.Read<bool>();
const auto api = parcel_in.Read<NativeWindowApi>(); const auto api = parcel_in.Read<NativeWindowApi>();
@ -923,8 +937,8 @@ void BufferQueueProducer::Transact(TransactionId code, u32 flags, std::span<cons
std::min(parcel_reply.size(), serialized.size())); std::min(parcel_reply.size(), serialized.size()));
} }
Kernel::KReadableEvent& BufferQueueProducer::GetNativeHandle() { Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) {
return buffer_wait_event->GetReadableEvent(); return &buffer_wait_event->GetReadableEvent();
} }
} // namespace Service::android } // namespace Service::android

View File

@ -45,12 +45,12 @@ public:
explicit BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_, explicit BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_,
std::shared_ptr<BufferQueueCore> buffer_queue_core_, std::shared_ptr<BufferQueueCore> buffer_queue_core_,
Service::Nvidia::NvCore::NvMap& nvmap_); Service::Nvidia::NvCore::NvMap& nvmap_);
~BufferQueueProducer(); ~BufferQueueProducer() override;
void Transact(android::TransactionId code, u32 flags, std::span<const u8> parcel_data, void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply,
std::span<u8> parcel_reply) override; u32 flags) override;
Kernel::KReadableEvent& GetNativeHandle() override; Kernel::KReadableEvent* GetNativeHandle(u32 type_id) override;
public: public:
Status RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf); Status RequestBuffer(s32 slot, std::shared_ptr<GraphicBuffer>* buf);

Some files were not shown because too many files have changed in this diff Show More