Skip to content

Commit 4f9fc88

Browse files
author
Steveice10
authored
apt: Improve accuracy of applet slot states on system applet launch. (#7456)
1 parent d857743 commit 4f9fc88

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

src/core/hle/service/apt/applet_manager.cpp

+22-11
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,10 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
373373
if (active_slot == AppletSlot::Error) {
374374
active_slot = slot;
375375

376-
// Wake up the application.
376+
// APT automatically calls enable on the first registered applet.
377+
Enable(attributes);
378+
379+
// Wake up the applet.
377380
SendParameter({
378381
.sender_id = AppletId::None,
379382
.destination_id = app_id,
@@ -398,7 +401,8 @@ Result AppletManager::Enable(AppletAttributes attributes) {
398401
auto slot_data = GetAppletSlot(slot);
399402
slot_data->registered = true;
400403

401-
if (slot_data->attributes.applet_pos == AppletPos::System &&
404+
if (slot_data->applet_id != AppletId::None &&
405+
slot_data->attributes.applet_pos == AppletPos::System &&
402406
slot_data->attributes.is_home_menu) {
403407
slot_data->attributes.raw |= attributes.raw;
404408
LOG_DEBUG(Service_APT, "Updated home menu attributes to {:08X}.",
@@ -786,16 +790,23 @@ Result AppletManager::PrepareToStartSystemApplet(AppletId applet_id) {
786790

787791
Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kernel::Object> object,
788792
const std::vector<u8>& buffer) {
789-
auto source_applet_id = AppletId::None;
793+
auto source_applet_id = AppletId::Application;
790794
if (last_system_launcher_slot != AppletSlot::Error) {
791-
const auto slot_data = GetAppletSlot(last_system_launcher_slot);
792-
source_applet_id = slot_data->applet_id;
793-
794-
// If a system applet is launching another system applet, reset the slot to avoid conflicts.
795-
// This is needed because system applets won't necessarily call CloseSystemApplet before
796-
// exiting.
797-
if (last_system_launcher_slot == AppletSlot::SystemApplet) {
798-
slot_data->Reset();
795+
const auto launcher_slot_data = GetAppletSlot(last_system_launcher_slot);
796+
source_applet_id = launcher_slot_data->applet_id;
797+
798+
// APT generally clears and terminates the caller of StartSystemApplet. This helps in
799+
// situations such as a system applet launching another system applet, which would
800+
// otherwise deadlock.
801+
// TODO: In real APT, the check for AppletSlot::Application does not exist; there is
802+
// TODO: something wrong with our implementation somewhere that makes this necessary.
803+
// TODO: Otherwise, games that attempt to launch system applets will be cleared and
804+
// TODO: emulation will crash.
805+
if (!launcher_slot_data->registered ||
806+
(last_system_launcher_slot != AppletSlot::Application &&
807+
!launcher_slot_data->attributes.no_exit_on_system_applet)) {
808+
launcher_slot_data->Reset();
809+
// TODO: Implement launcher process termination.
799810
}
800811
}
801812

src/core/hle/service/apt/applet_manager.h

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ union AppletAttributes {
152152
u32 raw;
153153

154154
BitField<0, 3, AppletPos> applet_pos;
155+
BitField<28, 1, u32> no_exit_on_system_applet;
155156
BitField<29, 1, u32> is_home_menu;
156157

157158
AppletAttributes() : raw(0) {}

0 commit comments

Comments
 (0)