mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-03-23 01:56:08 -04:00
feat(service/aoc): Implement IContentsServiceManager
- Add IContentsServiceManager class with RequestContentsAuthorizationToken function - Add IAsyncData class for handling asynchronous authorization token operations - Implement CreateContentsServiceManager in IAddOnContentManager (was previously stubbed) - Add support for GetSize, Read, Cancel, and GetSystemEvent operations in IAsyncData - Update CMakeLists.txt to include new source files Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -505,6 +505,8 @@ add_library(core STATIC
|
|||||||
hle/service/am/window_system.h
|
hle/service/am/window_system.h
|
||||||
hle/service/aoc/addon_content_manager.cpp
|
hle/service/aoc/addon_content_manager.cpp
|
||||||
hle/service/aoc/addon_content_manager.h
|
hle/service/aoc/addon_content_manager.h
|
||||||
|
hle/service/aoc/contents_service_manager.cpp
|
||||||
|
hle/service/aoc/contents_service_manager.h
|
||||||
hle/service/aoc/purchase_event_manager.cpp
|
hle/service/aoc/purchase_event_manager.cpp
|
||||||
hle/service/aoc/purchase_event_manager.h
|
hle/service/aoc/purchase_event_manager.h
|
||||||
hle/service/apm/apm.cpp
|
hle/service/apm/apm.cpp
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
#include "core/hle/service/aoc/addon_content_manager.h"
|
#include "core/hle/service/aoc/addon_content_manager.h"
|
||||||
|
#include "core/hle/service/aoc/contents_service_manager.h"
|
||||||
#include "core/hle/service/aoc/purchase_event_manager.h"
|
#include "core/hle/service/aoc/purchase_event_manager.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
@@ -68,7 +70,7 @@ IAddOnContentManager::IAddOnContentManager(Core::System& system_)
|
|||||||
{50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"},
|
{50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"},
|
||||||
{100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"},
|
{100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"},
|
||||||
{101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"},
|
{101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"},
|
||||||
{110, nullptr, "CreateContentsServiceManager"},
|
{110, D<&IAddOnContentManager::CreateContentsServiceManager>, "CreateContentsServiceManager"},
|
||||||
{200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
|
{200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
|
||||||
{300, nullptr, "SetupHostAddOnContent"},
|
{300, nullptr, "SetupHostAddOnContent"},
|
||||||
{301, nullptr, "GetRegisteredAddOnContentPath"},
|
{301, nullptr, "GetRegisteredAddOnContentPath"},
|
||||||
@@ -214,6 +216,15 @@ Result IAddOnContentManager::CreatePermanentEcPurchasedEventManager(
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result IAddOnContentManager::CreateContentsServiceManager(
|
||||||
|
OutInterface<IContentsServiceManager> out_interface) {
|
||||||
|
LOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||||
|
|
||||||
|
*out_interface = std::make_shared<IContentsServiceManager>(system);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
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("aoc:u", std::make_shared<IAddOnContentManager>(system));
|
server_manager->RegisterNamedService("aoc:u", std::make_shared<IAddOnContentManager>(system));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -18,6 +19,7 @@ class KEvent;
|
|||||||
namespace Service::AOC {
|
namespace Service::AOC {
|
||||||
|
|
||||||
class IPurchaseEventManager;
|
class IPurchaseEventManager;
|
||||||
|
class IContentsServiceManager;
|
||||||
|
|
||||||
class IAddOnContentManager final : public ServiceFramework<IAddOnContentManager> {
|
class IAddOnContentManager final : public ServiceFramework<IAddOnContentManager> {
|
||||||
public:
|
public:
|
||||||
@@ -38,6 +40,7 @@ public:
|
|||||||
Result CreateEcPurchasedEventManager(OutInterface<IPurchaseEventManager> out_interface);
|
Result CreateEcPurchasedEventManager(OutInterface<IPurchaseEventManager> out_interface);
|
||||||
Result CreatePermanentEcPurchasedEventManager(
|
Result CreatePermanentEcPurchasedEventManager(
|
||||||
OutInterface<IPurchaseEventManager> out_interface);
|
OutInterface<IPurchaseEventManager> out_interface);
|
||||||
|
Result CreateContentsServiceManager(OutInterface<IContentsServiceManager> out_interface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<u64> add_on_content;
|
std::vector<u64> add_on_content;
|
||||||
|
|||||||
103
src/core/hle/service/aoc/contents_service_manager.cpp
Normal file
103
src/core/hle/service/aoc/contents_service_manager.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/service/aoc/contents_service_manager.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
#include "core/hle/kernel/k_event.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
|
namespace Service::AOC {
|
||||||
|
|
||||||
|
IContentsServiceManager::IContentsServiceManager(Core::System& system_)
|
||||||
|
: ServiceFramework{system_, "IContentsServiceManager"},
|
||||||
|
service_context{system_, "IContentsServiceManager"} {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, D<&IContentsServiceManager::RequestContentsAuthorizationToken>, "RequestContentsAuthorizationToken"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
IContentsServiceManager::~IContentsServiceManager() = default;
|
||||||
|
|
||||||
|
Result IContentsServiceManager::RequestContentsAuthorizationToken(OutInterface<IAsyncData> out_async_data,
|
||||||
|
u64 unknown,
|
||||||
|
InBuffer<BufferAttr_HipcMapAlias> in_buffer) {
|
||||||
|
LOG_WARNING(Service_AOC, "(STUBBED) called with unknown={:016X}, buffer_size={}", unknown, in_buffer.size());
|
||||||
|
|
||||||
|
// Create a new IAsyncData interface to handle the authorization token request
|
||||||
|
*out_async_data = std::make_shared<IAsyncData>(system);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
IAsyncData::IAsyncData(Core::System& system_)
|
||||||
|
: ServiceFramework{system_, "IAsyncData"},
|
||||||
|
service_context{system_, "IAsyncData"},
|
||||||
|
is_complete{false} {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, D<&IAsyncData::GetSize>, "GetSize"},
|
||||||
|
{1, D<&IAsyncData::Read>, "Read"},
|
||||||
|
{2, D<&IAsyncData::Cancel>, "Cancel"},
|
||||||
|
{3, D<&IAsyncData::GetSystemEvent>, "GetSystemEvent"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
async_event = service_context.CreateEvent("IAsyncData:AsyncEvent");
|
||||||
|
|
||||||
|
// Simulate completion immediately for stub
|
||||||
|
data_buffer.resize(0x100, 0);
|
||||||
|
is_complete = true;
|
||||||
|
async_event->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
IAsyncData::~IAsyncData() {
|
||||||
|
service_context.CloseEvent(async_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IAsyncData::GetSize(Out<u64> out_size) {
|
||||||
|
LOG_DEBUG(Service_AOC, "called");
|
||||||
|
|
||||||
|
*out_size = data_buffer.size();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IAsyncData::Read(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, u64 offset, u64 size) {
|
||||||
|
LOG_DEBUG(Service_AOC, "called with offset={:016X}, size={:016X}", offset, size);
|
||||||
|
|
||||||
|
if (offset >= data_buffer.size()) {
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
const u64 read_size = std::min(size, static_cast<u64>(data_buffer.size() - offset));
|
||||||
|
const u64 copy_size = std::min(read_size, out_buffer.size());
|
||||||
|
|
||||||
|
std::memcpy(out_buffer.data(), data_buffer.data() + offset, copy_size);
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IAsyncData::Cancel() {
|
||||||
|
LOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||||
|
|
||||||
|
is_complete = false;
|
||||||
|
async_event->Clear();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IAsyncData::GetSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
|
LOG_DEBUG(Service_AOC, "called");
|
||||||
|
|
||||||
|
*out_event = &async_event->GetReadableEvent();
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::AOC
|
||||||
53
src/core/hle/service/aoc/contents_service_manager.h
Normal file
53
src/core/hle/service/aoc/contents_service_manager.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron 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/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KEvent;
|
||||||
|
class KReadableEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::AOC {
|
||||||
|
|
||||||
|
class IAsyncData;
|
||||||
|
|
||||||
|
class IContentsServiceManager final : public ServiceFramework<IContentsServiceManager> {
|
||||||
|
public:
|
||||||
|
explicit IContentsServiceManager(Core::System& system_);
|
||||||
|
~IContentsServiceManager() override;
|
||||||
|
|
||||||
|
Result RequestContentsAuthorizationToken(OutInterface<IAsyncData> out_async_data,
|
||||||
|
u64 unknown,
|
||||||
|
InBuffer<BufferAttr_HipcMapAlias> in_buffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IAsyncData final : public ServiceFramework<IAsyncData> {
|
||||||
|
public:
|
||||||
|
explicit IAsyncData(Core::System& system_);
|
||||||
|
~IAsyncData() override;
|
||||||
|
|
||||||
|
Result GetSize(Out<u64> out_size);
|
||||||
|
Result Read(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, u64 offset, u64 size);
|
||||||
|
Result Cancel();
|
||||||
|
Result GetSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
Kernel::KEvent* async_event;
|
||||||
|
std::vector<u8> data_buffer;
|
||||||
|
bool is_complete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::AOC
|
||||||
Reference in New Issue
Block a user