Ver Fonte

service: hid: Introduce proper AppletResource emulation

Narr the Reg há 2 anos atrás
pai
commit
e445ef9d60

+ 2 - 0
src/core/CMakeLists.txt

@@ -541,6 +541,8 @@ add_library(core STATIC
     hle/service/hid/xcd.cpp
     hle/service/hid/xcd.h
     hle/service/hid/errors.h
+    hle/service/hid/controllers/applet_resource.cpp
+    hle/service/hid/controllers/applet_resource.h
     hle/service/hid/controllers/console_six_axis.cpp
     hle/service/hid/controllers/console_six_axis.h
     hle/service/hid/controllers/controller_base.cpp

+ 199 - 0
src/core/hle/service/hid/controllers/applet_resource.cpp

@@ -0,0 +1,199 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/core.h"
+#include "core/hle/kernel/k_shared_memory.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/errors.h"
+
+namespace Service::HID {
+
+AppletResource::AppletResource(Core::System& system_) : system{system_} {}
+
+AppletResource::~AppletResource() = default;
+
+Result AppletResource::CreateAppletResource(u64 aruid) {
+    const u64 index = GetIndexFromAruid(aruid);
+
+    if (index >= AruidIndexMax) {
+        return ResultAruidNotRegistered;
+    }
+
+    if (data[index].flag.is_assigned) {
+        return ResultAruidAlreadyRegistered;
+    }
+
+    // TODO: Here shared memory is created for the process we don't quite emulate this part so
+    // obtain this pointer from system
+    auto& shared_memory = system.Kernel().GetHidSharedMem();
+
+    data[index].shared_memory_handle = &shared_memory;
+    data[index].flag.is_assigned.Assign(true);
+    // TODO: InitializeSixAxisControllerConfig(false);
+    active_aruid = aruid;
+    return ResultSuccess;
+}
+
+Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input) {
+    const u64 index = GetIndexFromAruid(aruid);
+
+    if (index < AruidIndexMax) {
+        return ResultAruidAlreadyRegistered;
+    }
+
+    std::size_t data_index = AruidIndexMax;
+    for (std::size_t i = 0; i < AruidIndexMax; i++) {
+        if (!data[i].flag.is_initialized) {
+            data_index = i;
+            break;
+        }
+    }
+
+    if (data_index == AruidIndexMax) {
+        return ResultAruidNoAvailableEntries;
+    }
+
+    AruidData& aruid_data = data[data_index];
+
+    aruid_data.aruid = aruid;
+    aruid_data.flag.is_initialized.Assign(true);
+    if (enable_input) {
+        aruid_data.flag.enable_pad_input.Assign(true);
+        aruid_data.flag.enable_six_axis_sensor.Assign(true);
+        aruid_data.flag.bit_18.Assign(true);
+        aruid_data.flag.enable_touchscreen.Assign(true);
+    }
+
+    data_index = AruidIndexMax;
+    for (std::size_t i = 0; i < AruidIndexMax; i++) {
+        if (registration_list.flag[i] == RegistrationStatus::Initialized) {
+            if (registration_list.aruid[i] != aruid) {
+                continue;
+            }
+            data_index = i;
+            break;
+        }
+        if (registration_list.flag[i] == RegistrationStatus::None) {
+            data_index = i;
+            break;
+        }
+    }
+
+    if (data_index == AruidIndexMax) {
+        return ResultSuccess;
+    }
+
+    registration_list.flag[data_index] = RegistrationStatus::Initialized;
+    registration_list.aruid[data_index] = aruid;
+
+    return ResultSuccess;
+}
+
+void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
+    u64 index = GetIndexFromAruid(aruid);
+
+    if (index < AruidIndexMax) {
+        if (data[index].flag.is_assigned) {
+            data[index].shared_memory_handle = nullptr;
+            data[index].flag.is_assigned.Assign(false);
+        }
+    }
+
+    index = GetIndexFromAruid(aruid);
+    if (index < AruidIndexMax) {
+        DestroySevenSixAxisTransferMemory();
+        data[index].flag.raw = 0;
+        data[index].aruid = 0;
+
+        index = GetIndexFromAruid(aruid);
+        if (index < AruidIndexMax) {
+            registration_list.flag[index] = RegistrationStatus::PendingDelete;
+        }
+    }
+}
+
+u64 AppletResource::GetActiveAruid() {
+    return active_aruid;
+}
+
+Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
+    u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return ResultAruidNotRegistered;
+    }
+
+    *out_handle = data[index].shared_memory_handle;
+    return ResultSuccess;
+}
+
+u64 AppletResource::GetIndexFromAruid(u64 aruid) {
+    for (std::size_t i = 0; i < AruidIndexMax; i++) {
+        if (registration_list.flag[i] == RegistrationStatus::Initialized &&
+            registration_list.aruid[i] == aruid) {
+            return i;
+        }
+    }
+    return AruidIndexMax;
+}
+
+Result AppletResource::DestroySevenSixAxisTransferMemory() {
+    // TODO
+    return ResultSuccess;
+}
+
+void AppletResource::EnableInput(u64 aruid, bool is_enabled) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.enable_pad_input.Assign(is_enabled);
+    data[index].flag.enable_touchscreen.Assign(is_enabled);
+}
+
+void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.enable_six_axis_sensor.Assign(is_enabled);
+}
+
+void AppletResource::EnablePadInput(u64 aruid, bool is_enabled) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.enable_pad_input.Assign(is_enabled);
+}
+
+void AppletResource::EnableTouchScreen(u64 aruid, bool is_enabled) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.enable_touchscreen.Assign(is_enabled);
+}
+
+void AppletResource::SetIsPalmaConnectable(u64 aruid, bool is_connectable) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.is_palma_connectable.Assign(is_connectable);
+}
+
+void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) {
+    const u64 index = GetIndexFromAruid(aruid);
+    if (index >= AruidIndexMax) {
+        return;
+    }
+
+    data[index].flag.enable_palma_boost_mode.Assign(is_enabled);
+}
+
+} // namespace Service::HID

+ 87 - 0
src/core/hle/service/hid/controllers/applet_resource.h

@@ -0,0 +1,87 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "core/hle/result.h"
+
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KSharedMemory;
+}
+
+namespace Service::HID {
+class AppletResource {
+public:
+    explicit AppletResource(Core::System& system_);
+    ~AppletResource();
+
+    Result CreateAppletResource(u64 aruid);
+
+    Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
+    void UnregisterAppletResourceUserId(u64 aruid);
+
+    u64 GetActiveAruid();
+    Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
+
+    u64 GetIndexFromAruid(u64 aruid);
+
+    Result DestroySevenSixAxisTransferMemory();
+
+    void EnableInput(u64 aruid, bool is_enabled);
+    void EnableSixAxisSensor(u64 aruid, bool is_enabled);
+    void EnablePadInput(u64 aruid, bool is_enabled);
+    void EnableTouchScreen(u64 aruid, bool is_enabled);
+    void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
+    void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
+
+private:
+    static constexpr std::size_t AruidIndexMax = 0x20;
+
+    enum RegistrationStatus : u32 {
+        None,
+        Initialized,
+        PendingDelete,
+    };
+
+    struct DataStatusFlag {
+        union {
+            u32 raw{};
+
+            BitField<0, 1, u32> is_initialized;
+            BitField<1, 1, u32> is_assigned;
+            BitField<16, 1, u32> enable_pad_input;
+            BitField<17, 1, u32> enable_six_axis_sensor;
+            BitField<18, 1, u32> bit_18;
+            BitField<19, 1, u32> is_palma_connectable;
+            BitField<20, 1, u32> enable_palma_boost_mode;
+            BitField<21, 1, u32> enable_touchscreen;
+        };
+    };
+
+    struct AruidRegisterList {
+        std::array<RegistrationStatus, AruidIndexMax> flag{};
+        std::array<u64, AruidIndexMax> aruid{};
+    };
+    static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
+
+    struct AruidData {
+        DataStatusFlag flag{};
+        u64 aruid{};
+        Kernel::KSharedMemory* shared_memory_handle{nullptr};
+    };
+
+    u64 active_aruid{};
+    AruidRegisterList registration_list{};
+    std::array<AruidData, AruidIndexMax> data{};
+
+    Core::System& system;
+};
+} // namespace Service::HID

+ 5 - 0
src/core/hle/service/hid/errors.h

@@ -19,6 +19,11 @@ constexpr Result NpadIsSameType{ErrorModule::HID, 602};
 constexpr Result InvalidNpadId{ErrorModule::HID, 709};
 constexpr Result NpadNotConnected{ErrorModule::HID, 710};
 constexpr Result InvalidArraySize{ErrorModule::HID, 715};
+
+constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044};
+constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046};
+constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047};
+
 constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
 
 } // namespace Service::HID

+ 8 - 0
src/core/hle/service/hid/hid.cpp

@@ -1,6 +1,8 @@
 // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/kernel.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/hle/service/hid/hid_debug_server.h"
 #include "core/hle/service/hid/hid_firmware_settings.h"
@@ -20,6 +22,12 @@ void LoopProcess(Core::System& system) {
     std::shared_ptr<HidFirmwareSettings> firmware_settings =
         std::make_shared<HidFirmwareSettings>();
 
+    // TODO: Remove this hack until this service is emulated properly.
+    const auto process_list = system.Kernel().GetProcessList();
+    if (!process_list.empty()) {
+        resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true);
+    }
+
     server_manager->RegisterNamedService(
         "hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings));
     server_manager->RegisterNamedService(

+ 6 - 1
src/core/hle/service/hid/hid_server.cpp

@@ -224,8 +224,13 @@ void IHidServer::CreateAppletResource(HLERequestContext& ctx) {
 
     LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
 
+    Result result = GetResourceManager()->CreateAppletResource(applet_resource_user_id);
+    if (result.IsSuccess()) {
+        result = GetResourceManager()->GetNpad()->Activate(applet_resource_user_id);
+    }
+
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
+    rb.Push(result);
     rb.PushIpcInterface<IAppletResource>(system, resource_manager);
 }
 

+ 130 - 6
src/core/hle/service/hid/hid_system_server.cpp

@@ -3,6 +3,7 @@
 
 #include "core/hid/hid_core.h"
 #include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/palma.h"
 #include "core/hle/service/hid/controllers/touchscreen.h"
 #include "core/hle/service/hid/errors.h"
 #include "core/hle/service/hid/hid_system_server.h"
@@ -63,13 +64,13 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {329, nullptr, "DetachAbstractedPadAll"},
         {330, nullptr, "CheckAbstractedPadConnection"},
         {500, nullptr, "SetAppletResourceUserId"},
-        {501, nullptr, "RegisterAppletResourceUserId"},
-        {502, nullptr, "UnregisterAppletResourceUserId"},
-        {503, nullptr, "EnableAppletToGetInput"},
+        {501, &IHidSystemServer::RegisterAppletResourceUserId, "RegisterAppletResourceUserId"},
+        {502, &IHidSystemServer::UnregisterAppletResourceUserId, "UnregisterAppletResourceUserId"},
+        {503, &IHidSystemServer::EnableAppletToGetInput, "EnableAppletToGetInput"},
         {504, nullptr, "SetAruidValidForVibration"},
-        {505, nullptr, "EnableAppletToGetSixAxisSensor"},
-        {506, nullptr, "EnableAppletToGetPadInput"},
-        {507, nullptr, "EnableAppletToGetTouchScreen"},
+        {505, &IHidSystemServer::EnableAppletToGetSixAxisSensor, "EnableAppletToGetSixAxisSensor"},
+        {506, &IHidSystemServer::EnableAppletToGetPadInput, "EnableAppletToGetPadInput"},
+        {507, &IHidSystemServer::EnableAppletToGetTouchScreen, "EnableAppletToGetTouchScreen"},
         {510, nullptr, "SetVibrationMasterVolume"},
         {511, nullptr, "GetVibrationMasterVolume"},
         {512, nullptr, "BeginPermitVibrationSession"},
@@ -420,6 +421,129 @@ void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
 }
+void IHidSystemServer::RegisterAppletResourceUserId(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool enable_input;
+        INSERT_PADDING_WORDS_NOINIT(1);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, enable_input={}, applet_resource_user_id={}",
+             parameters.enable_input, parameters.applet_resource_user_id);
+
+    Result result = GetResourceManager()->RegisterAppletResourceUserId(
+        parameters.applet_resource_user_id, parameters.enable_input);
+
+    if (result.IsSuccess()) {
+        // result = GetResourceManager()->GetNpad()->RegisterAppletResourceUserId(
+        //     parameters.applet_resource_user_id);
+    }
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::UnregisterAppletResourceUserId(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    u64 applet_resource_user_id{rp.Pop<u64>()};
+
+    LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+    GetResourceManager()->UnregisterAppletResourceUserId(applet_resource_user_id);
+    // GetResourceManager()->GetNpad()->UnregisterAppletResourceUserId(applet_resource_user_id);
+    // GetResourceManager()->GetPalma()->UnregisterAppletResourceUserId(applet_resource_user_id);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::EnableAppletToGetInput(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool is_enabled;
+        INSERT_PADDING_WORDS_NOINIT(1);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
+             parameters.is_enabled, parameters.applet_resource_user_id);
+
+    GetResourceManager()->EnableInput(parameters.applet_resource_user_id, parameters.is_enabled);
+    // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::EnableAppletToGetSixAxisSensor(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool is_enabled;
+        INSERT_PADDING_WORDS_NOINIT(1);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
+             parameters.is_enabled, parameters.applet_resource_user_id);
+
+    GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id,
+                                            parameters.is_enabled);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::EnableAppletToGetPadInput(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool is_enabled;
+        INSERT_PADDING_WORDS_NOINIT(1);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
+             parameters.is_enabled, parameters.applet_resource_user_id);
+
+    GetResourceManager()->EnablePadInput(parameters.applet_resource_user_id, parameters.is_enabled);
+    // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool is_enabled;
+        INSERT_PADDING_WORDS_NOINIT(1);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
+             parameters.is_enabled, parameters.applet_resource_user_id);
+
+    GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id,
+                                            parameters.is_enabled);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
 
 void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
     LOG_INFO(Service_AM, "(STUBBED) called");

+ 6 - 0
src/core/hle/service/hid/hid_system_server.h

@@ -38,6 +38,12 @@ private:
     void HasLeftRightBattery(HLERequestContext& ctx);
     void GetUniquePadsFromNpad(HLERequestContext& ctx);
     void GetIrSensorState(HLERequestContext& ctx);
+    void RegisterAppletResourceUserId(HLERequestContext& ctx);
+    void UnregisterAppletResourceUserId(HLERequestContext& ctx);
+    void EnableAppletToGetInput(HLERequestContext& ctx);
+    void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx);
+    void EnableAppletToGetPadInput(HLERequestContext& ctx);
+    void EnableAppletToGetTouchScreen(HLERequestContext& ctx);
     void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
     void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
     void GetRegisteredDevices(HLERequestContext& ctx);

+ 56 - 6
src/core/hle/service/hid/resource_manager.cpp

@@ -9,6 +9,7 @@
 #include "core/hle/service/hid/resource_manager.h"
 #include "core/hle/service/ipc_helpers.h"
 
+#include "core/hle/service/hid/controllers/applet_resource.h"
 #include "core/hle/service/hid/controllers/console_six_axis.h"
 #include "core/hle/service/hid/controllers/debug_pad.h"
 #include "core/hle/service/hid/controllers/gesture.h"
@@ -33,7 +34,9 @@ constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 10
 constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000};         // (5ms, 200Hz)
 
 ResourceManager::ResourceManager(Core::System& system_)
-    : system{system_}, service_context{system_, "hid"} {}
+    : system{system_}, service_context{system_, "hid"} {
+    applet_resource = std::make_shared<AppletResource>(system);
+}
 
 ResourceManager::~ResourceManager() = default;
 
@@ -77,6 +80,11 @@ void ResourceManager::Initialize() {
     system.HIDCore().ReloadInputDevices();
     is_initialized = true;
 }
+
+std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
+    return applet_resource;
+}
+
 std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
     return capture_button;
 }
@@ -137,6 +145,46 @@ std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
     return unique_pad;
 }
 
+Result ResourceManager::CreateAppletResource(u64 aruid) {
+    std::scoped_lock lock{shared_mutex};
+    return applet_resource->CreateAppletResource(aruid);
+}
+
+Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
+    std::scoped_lock lock{shared_mutex};
+    return applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
+}
+
+void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
+    std::scoped_lock lock{shared_mutex};
+    applet_resource->UnregisterAppletResourceUserId(aruid);
+}
+
+Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
+    std::scoped_lock lock{shared_mutex};
+    return applet_resource->GetSharedMemoryHandle(out_handle, aruid);
+}
+
+void ResourceManager::EnableInput(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{shared_mutex};
+    applet_resource->EnableInput(aruid, is_enabled);
+}
+
+void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{shared_mutex};
+    applet_resource->EnableSixAxisSensor(aruid, is_enabled);
+}
+
+void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{shared_mutex};
+    applet_resource->EnablePadInput(aruid, is_enabled);
+}
+
+void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{shared_mutex};
+    applet_resource->EnableTouchScreen(aruid, is_enabled);
+}
+
 void ResourceManager::UpdateControllers(std::uintptr_t user_data,
                                         std::chrono::nanoseconds ns_late) {
     auto& core_timing = system.CoreTiming();
@@ -172,14 +220,12 @@ void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose
 }
 
 IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
-    : ServiceFramework{system_, "IAppletResource"} {
+    : ServiceFramework{system_, "IAppletResource"}, resource_manager{resource} {
     static const FunctionInfo functions[] = {
         {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
     };
     RegisterHandlers(functions);
 
-    resource->Initialize();
-
     // Register update callbacks
     npad_update_event = Core::Timing::CreateEvent(
         "HID::UpdatePadCallback",
@@ -233,9 +279,13 @@ IAppletResource::~IAppletResource() {
 void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
     LOG_DEBUG(Service_HID, "called");
 
+    Kernel::KSharedMemory* handle;
+    const u64 applet_resource_user_id = resource_manager->GetAppletResource()->GetActiveAruid();
+    const auto result = resource_manager->GetSharedMemoryHandle(&handle, applet_resource_user_id);
+
     IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
+    rb.Push(result);
+    rb.PushCopyObjects(handle);
 }
 
 } // namespace Service::HID

+ 27 - 0
src/core/hle/service/hid/resource_manager.h

@@ -6,11 +6,20 @@
 #include "core/hle/service/kernel_helpers.h"
 #include "core/hle/service/service.h"
 
+namespace Core {
+class System;
+}
+
 namespace Core::Timing {
 struct EventType;
 }
 
+namespace Kernel {
+class KSharedMemory;
+}
+
 namespace Service::HID {
+class AppletResource;
 class Controller_Stubbed;
 class ConsoleSixAxis;
 class DebugPad;
@@ -38,6 +47,7 @@ public:
 
     void Initialize();
 
+    std::shared_ptr<AppletResource> GetAppletResource() const;
     std::shared_ptr<CaptureButton> GetCaptureButton() const;
     std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
     std::shared_ptr<DebugMouse> GetDebugMouse() const;
@@ -54,6 +64,18 @@ public:
     std::shared_ptr<TouchScreen> GetTouchScreen() const;
     std::shared_ptr<UniquePad> GetUniquePad() const;
 
+    Result CreateAppletResource(u64 aruid);
+
+    Result RegisterAppletResourceUserId(u64 aruid, bool bool_value);
+    void UnregisterAppletResourceUserId(u64 aruid);
+
+    Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
+
+    void EnableInput(u64 aruid, bool is_enabled);
+    void EnableSixAxisSensor(u64 aruid, bool is_enabled);
+    void EnablePadInput(u64 aruid, bool is_enabled);
+    void EnableTouchScreen(u64 aruid, bool is_enabled);
+
     void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
     void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
     void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
@@ -62,6 +84,9 @@ public:
 private:
     bool is_initialized{false};
 
+    mutable std::mutex shared_mutex;
+    std::shared_ptr<AppletResource> applet_resource = nullptr;
+
     std::shared_ptr<CaptureButton> capture_button = nullptr;
     std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
     std::shared_ptr<DebugMouse> debug_mouse = nullptr;
@@ -106,6 +131,8 @@ private:
     std::shared_ptr<Core::Timing::EventType> default_update_event;
     std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
     std::shared_ptr<Core::Timing::EventType> motion_update_event;
+
+    std::shared_ptr<ResourceManager> resource_manager;
 };
 
 } // namespace Service::HID