Merge pull request #3992 from Subv/applets_close

Services/HLE: Implement PrepareToCloseLibraryApplet and CloseLibraryApplet
This commit is contained in:
Ben 2018-07-29 10:34:32 +02:00 committed by GitHub
commit 04bd104c4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 4 deletions

View File

@ -396,6 +396,49 @@ ResultCode AppletManager::StartLibraryApplet(AppletId applet_id,
}
}
ResultCode AppletManager::PrepareToCloseLibraryApplet(bool not_pause, bool exiting,
bool jump_home) {
if (next_parameter) {
return ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet,
ErrorSummary::InvalidState, ErrorLevel::Status);
}
if (!not_pause)
library_applet_closing_command = SignalType::WakeupByPause;
else if (jump_home)
library_applet_closing_command = SignalType::WakeupToJumpHome;
else if (exiting)
library_applet_closing_command = SignalType::WakeupByCancel;
else
library_applet_closing_command = SignalType::WakeupByExit;
return RESULT_SUCCESS;
}
ResultCode AppletManager::CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object,
std::vector<u8> buffer) {
auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
MessageParameter param;
// TODO(Subv): The destination id should be the "current applet slot id", which changes
// constantly depending on what is going on in the system. Most of the time it is the running
// application, but it could be something else if a system applet is launched.
param.destination_id = AppletId::Application;
param.sender_id = slot.applet_id;
param.object = std::move(object);
param.signal = library_applet_closing_command;
param.buffer = std::move(buffer);
ResultCode result = SendParameter(param);
if (library_applet_closing_command != SignalType::WakeupByPause) {
// TODO(Subv): Terminate the running applet title
slot.Reset();
}
return result;
}
ResultVal<AppletManager::AppletInfo> AppletManager::GetAppletInfo(AppletId app_id) {
const auto* slot = GetAppletSlotData(app_id);

View File

@ -128,6 +128,8 @@ public:
ResultCode FinishPreloadingLibraryApplet(AppletId applet_id);
ResultCode StartLibraryApplet(AppletId applet_id, Kernel::SharedPtr<Kernel::Object> object,
const std::vector<u8>& buffer);
ResultCode PrepareToCloseLibraryApplet(bool not_pause, bool exiting, bool jump_home);
ResultCode CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object, std::vector<u8> buffer);
struct AppletInfo {
u64 title_id;
@ -164,6 +166,12 @@ private:
AppletAttributes attributes;
Kernel::SharedPtr<Kernel::Event> notification_event;
Kernel::SharedPtr<Kernel::Event> parameter_event;
void Reset() {
applet_id = AppletId::None;
registered = false;
attributes.raw = 0;
}
};
// Holds data about the concurrently running applets in the system.
@ -172,6 +180,9 @@ private:
// This overload returns nullptr if no applet with the specified id has been started.
AppletSlotData* GetAppletSlotData(AppletId id);
AppletSlotData* GetAppletSlotData(AppletAttributes attributes);
// Command that will be sent to the application when a library applet calls CloseLibraryApplet.
SignalType library_applet_closing_command;
};
} // namespace APT

View File

@ -552,6 +552,31 @@ void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_APT, "(STUBBED) called exiting={}", exiting);
}
void Module::Interface::PrepareToCloseLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x25, 3, 0); // 0x002500C0
bool not_pause = rp.Pop<bool>();
bool exiting = rp.Pop<bool>();
bool jump_to_home = rp.Pop<bool>();
LOG_DEBUG(Service_APT, "called not_pause={} exiting={} jump_to_home={}", not_pause, exiting,
jump_to_home);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(apt->applet_manager->PrepareToCloseLibraryApplet(not_pause, exiting, jump_to_home));
}
void Module::Interface::CloseLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x28, 1, 4); // 0x00280044
u32 parameter_size = rp.Pop<u32>();
auto object = rp.PopGenericObject();
std::vector<u8> buffer = rp.PopStaticBuffer();
LOG_DEBUG(Service_APT, "called size={}", parameter_size);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(apt->applet_manager->CloseLibraryApplet(std::move(object), std::move(buffer)));
}
void Module::Interface::SendCaptureBufferInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x40, 1, 2); // 0x00400042
u32 size = rp.Pop<u32>();

View File

@ -420,6 +420,34 @@ public:
*/
void CancelLibraryApplet(Kernel::HLERequestContext& ctx);
/**
* APT::PrepareToCloseLibraryApplet service function
* Inputs:
* 0 : Command header [0x002500C0]
* 1 : bool, Not pause
* 2 : bool, Caller exiting
* 3 : bool, Jump to home
* Outputs:
* 0 : Header code
* 1 : Result code
*/
void PrepareToCloseLibraryApplet(Kernel::HLERequestContext& ctx);
/**
* APT::CloseLibraryApplet service function
* Inputs:
* 0 : Command header [0x00280044]
* 1 : Buffer size
* 2 : 0x0
* 3 : Object handle
* 4 : (Size << 14) | 2
* 5 : Input buffer virtual address
* Outputs:
* 0 : Header code
* 1 : Result code
*/
void CloseLibraryApplet(Kernel::HLERequestContext& ctx);
/**
* APT::SendCaptureBufferInfo service function
* Inputs:

View File

@ -46,10 +46,10 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
{0x00220040, nullptr, "PrepareToCloseApplication"},
{0x00230040, nullptr, "PrepareToJumpToApplication"},
{0x00240044, nullptr, "JumpToApplication"},
{0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
{0x002500C0, &APT_A::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"},
{0x00260000, nullptr, "PrepareToCloseSystemApplet"},
{0x00270044, nullptr, "CloseApplication"},
{0x00280044, nullptr, "CloseLibraryApplet"},
{0x00280044, &APT_A::CloseLibraryApplet, "CloseLibraryApplet"},
{0x00290044, nullptr, "CloseSystemApplet"},
{0x002A0000, nullptr, "OrderToCloseSystemApplet"},
{0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},

View File

@ -46,10 +46,10 @@ APT_U::APT_U(std::shared_ptr<Module> apt)
{0x00220040, nullptr, "PrepareToCloseApplication"},
{0x00230040, nullptr, "PrepareToJumpToApplication"},
{0x00240044, nullptr, "JumpToApplication"},
{0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
{0x002500C0, &APT_U::PrepareToCloseLibraryApplet, "PrepareToCloseLibraryApplet"},
{0x00260000, nullptr, "PrepareToCloseSystemApplet"},
{0x00270044, nullptr, "CloseApplication"},
{0x00280044, nullptr, "CloseLibraryApplet"},
{0x00280044, &APT_U::CloseLibraryApplet, "CloseLibraryApplet"},
{0x00290044, nullptr, "CloseSystemApplet"},
{0x002A0000, nullptr, "OrderToCloseSystemApplet"},
{0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},