7 changed files with 206 additions and 249 deletions
-
4src/core/CMakeLists.txt
-
202src/core/hle/service/am/library_applet_accessor.cpp
-
43src/core/hle/service/am/library_applet_accessor.h
-
2src/core/hle/service/am/library_applet_creator.cpp
-
2src/core/hle/service/am/process_winding_controller.cpp
-
157src/core/hle/service/am/service/library_applet_accessor.cpp
-
45src/core/hle/service/am/service/library_applet_accessor.h
@ -1,202 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "common/scope_exit.h"
|
|||
#include "core/hle/service/am/am_results.h"
|
|||
#include "core/hle/service/am/applet_data_broker.h"
|
|||
#include "core/hle/service/am/frontend/applets.h"
|
|||
#include "core/hle/service/am/library_applet_accessor.h"
|
|||
#include "core/hle/service/am/storage.h"
|
|||
#include "core/hle/service/ipc_helpers.h"
|
|||
|
|||
namespace Service::AM { |
|||
|
|||
ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, |
|||
std::shared_ptr<AppletDataBroker> broker_, |
|||
std::shared_ptr<Applet> applet_) |
|||
: ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)}, |
|||
applet{std::move(applet_)} { |
|||
// clang-format off
|
|||
static const FunctionInfo functions[] = { |
|||
{0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, |
|||
{1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"}, |
|||
{10, &ILibraryAppletAccessor::Start, "Start"}, |
|||
{20, &ILibraryAppletAccessor::RequestExit, "RequestExit"}, |
|||
{25, nullptr, "Terminate"}, |
|||
{30, &ILibraryAppletAccessor::GetResult, "GetResult"}, |
|||
{50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, |
|||
{60, &ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero, "PresetLibraryAppletGpuTimeSliceZero"}, |
|||
{100, &ILibraryAppletAccessor::PushInData, "PushInData"}, |
|||
{101, &ILibraryAppletAccessor::PopOutData, "PopOutData"}, |
|||
{102, nullptr, "PushExtraStorage"}, |
|||
{103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"}, |
|||
{104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"}, |
|||
{105, &ILibraryAppletAccessor::GetPopOutDataEvent, "GetPopOutDataEvent"}, |
|||
{106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"}, |
|||
{110, nullptr, "NeedsToExitProcess"}, |
|||
{120, nullptr, "GetLibraryAppletInfo"}, |
|||
{150, nullptr, "RequestForAppletToGetForeground"}, |
|||
{160, &ILibraryAppletAccessor::GetIndirectLayerConsumerHandle, "GetIndirectLayerConsumerHandle"}, |
|||
}; |
|||
// clang-format on
|
|||
|
|||
RegisterHandlers(functions); |
|||
} |
|||
|
|||
ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; |
|||
|
|||
void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2, 1}; |
|||
rb.Push(ResultSuccess); |
|||
rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle()); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
std::scoped_lock lk{applet->lock}; |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 3}; |
|||
rb.Push(ResultSuccess); |
|||
rb.Push<u32>(broker->IsCompleted()); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(applet->terminate_result); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) { |
|||
LOG_WARNING(Service_AM, "(STUBBED) called"); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(ResultSuccess); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::Start(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
applet->process->Run(); |
|||
FrontendExecute(); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(ResultSuccess); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
ASSERT(applet != nullptr); |
|||
applet->message_queue.RequestExit(); |
|||
FrontendRequestExit(); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(ResultSuccess); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::RequestParser rp{ctx}; |
|||
broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock()); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(ResultSuccess); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
std::shared_ptr<IStorage> data; |
|||
const auto res = broker->GetOutData().Pop(&data); |
|||
|
|||
if (res.IsSuccess()) { |
|||
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
|||
rb.Push(res); |
|||
rb.PushIpcInterface(std::move(data)); |
|||
} else { |
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(res); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::RequestParser rp{ctx}; |
|||
broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock()); |
|||
FrontendExecuteInteractive(); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(ResultSuccess); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
std::shared_ptr<IStorage> data; |
|||
const auto res = broker->GetInteractiveOutData().Pop(&data); |
|||
|
|||
if (res.IsSuccess()) { |
|||
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
|||
rb.Push(res); |
|||
rb.PushIpcInterface(std::move(data)); |
|||
} else { |
|||
IPC::ResponseBuilder rb{ctx, 2}; |
|||
rb.Push(res); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2, 1}; |
|||
rb.Push(ResultSuccess); |
|||
rb.PushCopyObjects(broker->GetOutData().GetEvent()); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 2, 1}; |
|||
rb.Push(ResultSuccess); |
|||
rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent()); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { |
|||
LOG_WARNING(Service_AM, "(STUBBED) called"); |
|||
|
|||
// We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is
|
|||
// actually used anywhere
|
|||
constexpr u64 handle = 0xdeadbeef; |
|||
|
|||
IPC::ResponseBuilder rb{ctx, 4}; |
|||
rb.Push(ResultSuccess); |
|||
rb.Push(handle); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendExecute() { |
|||
if (applet->frontend) { |
|||
applet->frontend->Initialize(); |
|||
applet->frontend->Execute(); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendExecuteInteractive() { |
|||
if (applet->frontend) { |
|||
applet->frontend->ExecuteInteractive(); |
|||
applet->frontend->Execute(); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendRequestExit() { |
|||
if (applet->frontend) { |
|||
applet->frontend->RequestExit(); |
|||
} |
|||
} |
|||
|
|||
} // namespace Service::AM
|
|||
@ -1,43 +0,0 @@ |
|||
// 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::AM { |
|||
|
|||
class AppletDataBroker; |
|||
struct Applet; |
|||
|
|||
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { |
|||
public: |
|||
explicit ILibraryAppletAccessor(Core::System& system_, |
|||
std::shared_ptr<AppletDataBroker> broker_, |
|||
std::shared_ptr<Applet> applet_); |
|||
~ILibraryAppletAccessor(); |
|||
|
|||
protected: |
|||
void GetAppletStateChangedEvent(HLERequestContext& ctx); |
|||
void IsCompleted(HLERequestContext& ctx); |
|||
void GetResult(HLERequestContext& ctx); |
|||
void PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx); |
|||
void Start(HLERequestContext& ctx); |
|||
void RequestExit(HLERequestContext& ctx); |
|||
void PushInData(HLERequestContext& ctx); |
|||
void PopOutData(HLERequestContext& ctx); |
|||
void PushInteractiveInData(HLERequestContext& ctx); |
|||
void PopInteractiveOutData(HLERequestContext& ctx); |
|||
void GetPopOutDataEvent(HLERequestContext& ctx); |
|||
void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); |
|||
void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); |
|||
|
|||
void FrontendExecute(); |
|||
void FrontendExecuteInteractive(); |
|||
void FrontendRequestExit(); |
|||
|
|||
const std::shared_ptr<AppletDataBroker> broker; |
|||
const std::shared_ptr<Applet> applet; |
|||
}; |
|||
|
|||
} // namespace Service::AM |
|||
@ -0,0 +1,157 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "core/hle/service/am/applet_data_broker.h"
|
|||
#include "core/hle/service/am/applet_manager.h"
|
|||
#include "core/hle/service/am/frontend/applets.h"
|
|||
#include "core/hle/service/am/service/library_applet_accessor.h"
|
|||
#include "core/hle/service/am/storage.h"
|
|||
#include "core/hle/service/cmif_serialization.h"
|
|||
|
|||
namespace Service::AM { |
|||
|
|||
ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, |
|||
std::shared_ptr<AppletDataBroker> broker, |
|||
std::shared_ptr<Applet> applet) |
|||
: ServiceFramework{system_, "ILibraryAppletAccessor"}, m_broker{std::move(broker)}, |
|||
m_applet{std::move(applet)} { |
|||
// clang-format off
|
|||
static const FunctionInfo functions[] = { |
|||
{0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"}, |
|||
{1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"}, |
|||
{10, D<&ILibraryAppletAccessor::Start>, "Start"}, |
|||
{20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"}, |
|||
{25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"}, |
|||
{30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"}, |
|||
{50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, |
|||
{60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero"}, |
|||
{100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"}, |
|||
{101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"}, |
|||
{102, nullptr, "PushExtraStorage"}, |
|||
{103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"}, |
|||
{104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"}, |
|||
{105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"}, |
|||
{106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"}, |
|||
{110, nullptr, "NeedsToExitProcess"}, |
|||
{120, nullptr, "GetLibraryAppletInfo"}, |
|||
{150, nullptr, "RequestForAppletToGetForeground"}, |
|||
{160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"}, |
|||
}; |
|||
// clang-format on
|
|||
|
|||
RegisterHandlers(functions); |
|||
} |
|||
|
|||
ILibraryAppletAccessor::~ILibraryAppletAccessor() = default; |
|||
|
|||
Result ILibraryAppletAccessor::GetAppletStateChangedEvent( |
|||
OutCopyHandle<Kernel::KReadableEvent> out_event) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
*out_event = m_broker->GetStateChangedEvent().GetHandle(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
*out_is_completed = m_broker->IsCompleted(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
*out_result = m_applet->terminate_result; |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() { |
|||
LOG_INFO(Service_AM, "(STUBBED) called"); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::Start() { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
m_applet->process->Run(); |
|||
FrontendExecute(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::RequestExit() { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
m_applet->message_queue.RequestExit(); |
|||
FrontendRequestExit(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::Terminate() { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
m_applet->process->Terminate(); |
|||
FrontendRequestExit(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::PushInData(SharedPointer<IStorage> storage) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
m_broker->GetInData().Push(storage); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::PopOutData(Out<SharedPointer<IStorage>> out_storage) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
R_RETURN(m_broker->GetOutData().Pop(out_storage.Get())); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::PushInteractiveInData(SharedPointer<IStorage> storage) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
m_broker->GetInteractiveInData().Push(storage); |
|||
FrontendExecuteInteractive(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
R_RETURN(m_broker->GetInteractiveOutData().Pop(out_storage.Get())); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
*out_event = m_broker->GetOutData().GetEvent(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::GetPopInteractiveOutDataEvent( |
|||
OutCopyHandle<Kernel::KReadableEvent> out_event) { |
|||
LOG_DEBUG(Service_AM, "called"); |
|||
*out_event = m_broker->GetInteractiveOutData().GetEvent(); |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out<u64> out_handle) { |
|||
LOG_WARNING(Service_AM, "(STUBBED) called"); |
|||
|
|||
// We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is
|
|||
// actually used anywhere
|
|||
*out_handle = 0xdeadbeef; |
|||
R_SUCCEED(); |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendExecute() { |
|||
if (m_applet->frontend) { |
|||
m_applet->frontend->Initialize(); |
|||
m_applet->frontend->Execute(); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendExecuteInteractive() { |
|||
if (m_applet->frontend) { |
|||
m_applet->frontend->ExecuteInteractive(); |
|||
m_applet->frontend->Execute(); |
|||
} |
|||
} |
|||
|
|||
void ILibraryAppletAccessor::FrontendRequestExit() { |
|||
if (m_applet->frontend) { |
|||
m_applet->frontend->RequestExit(); |
|||
} |
|||
} |
|||
|
|||
} // namespace Service::AM
|
|||
@ -0,0 +1,45 @@ |
|||
// 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::AM { |
|||
|
|||
class AppletDataBroker; |
|||
struct Applet; |
|||
class IStorage; |
|||
|
|||
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { |
|||
public: |
|||
explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<AppletDataBroker> broker, |
|||
std::shared_ptr<Applet> applet); |
|||
~ILibraryAppletAccessor(); |
|||
|
|||
private: |
|||
Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); |
|||
Result IsCompleted(Out<bool> out_is_completed); |
|||
Result GetResult(Out<Result> out_result); |
|||
Result PresetLibraryAppletGpuTimeSliceZero(); |
|||
Result Start(); |
|||
Result RequestExit(); |
|||
Result Terminate(); |
|||
Result PushInData(SharedPointer<IStorage> storage); |
|||
Result PopOutData(Out<SharedPointer<IStorage>> out_storage); |
|||
Result PushInteractiveInData(SharedPointer<IStorage> storage); |
|||
Result PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage); |
|||
Result GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); |
|||
Result GetPopInteractiveOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); |
|||
Result GetIndirectLayerConsumerHandle(Out<u64> out_handle); |
|||
|
|||
void FrontendExecute(); |
|||
void FrontendExecuteInteractive(); |
|||
void FrontendRequestExit(); |
|||
|
|||
const std::shared_ptr<AppletDataBroker> m_broker; |
|||
const std::shared_ptr<Applet> m_applet; |
|||
}; |
|||
|
|||
} // namespace Service::AM |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue