am: rewrite ILibraryAppletAccessor

This commit is contained in:
Liam 2024-02-11 19:56:09 -05:00
parent 2c49ebbeea
commit f9bba8007d
7 changed files with 206 additions and 249 deletions

View file

@ -429,8 +429,6 @@ add_library(core STATIC
hle/service/am/hid_registration.h
hle/service/am/idle.cpp
hle/service/am/idle.h
hle/service/am/library_applet_accessor.cpp
hle/service/am/library_applet_accessor.h
hle/service/am/library_applet_creator.cpp
hle/service/am/library_applet_creator.h
hle/service/am/library_applet_self_accessor.cpp
@ -473,6 +471,8 @@ add_library(core STATIC
hle/service/am/service/global_state_controller.h
hle/service/am/service/home_menu_functions.cpp
hle/service/am/service/home_menu_functions.h
hle/service/am/service/library_applet_accessor.cpp
hle/service/am/service/library_applet_accessor.h
hle/service/am/service/library_applet_proxy.cpp
hle/service/am/service/library_applet_proxy.h
hle/service/am/service/system_applet_proxy.cpp

View file

@ -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

View file

@ -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

View file

@ -6,9 +6,9 @@
#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/library_applet_accessor.h"
#include "core/hle/service/am/library_applet_creator.h"
#include "core/hle/service/am/library_applet_storage.h"
#include "core/hle/service/am/service/library_applet_accessor.h"
#include "core/hle/service/am/storage.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/sm/sm.h"

View file

@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/am/frontend/applets.h"
#include "core/hle/service/am/library_applet_accessor.h"
#include "core/hle/service/am/process_winding_controller.h"
#include "core/hle/service/am/service/library_applet_accessor.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::AM {

View file

@ -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

View file

@ -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