apt: Improve accuracy of applet slot states on system applet launch. (#7456)
This commit is contained in:
		@@ -373,7 +373,10 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
 | 
				
			|||||||
    if (active_slot == AppletSlot::Error) {
 | 
					    if (active_slot == AppletSlot::Error) {
 | 
				
			||||||
        active_slot = slot;
 | 
					        active_slot = slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Wake up the application.
 | 
					        // APT automatically calls enable on the first registered applet.
 | 
				
			||||||
 | 
					        Enable(attributes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Wake up the applet.
 | 
				
			||||||
        SendParameter({
 | 
					        SendParameter({
 | 
				
			||||||
            .sender_id = AppletId::None,
 | 
					            .sender_id = AppletId::None,
 | 
				
			||||||
            .destination_id = app_id,
 | 
					            .destination_id = app_id,
 | 
				
			||||||
@@ -398,7 +401,8 @@ Result AppletManager::Enable(AppletAttributes attributes) {
 | 
				
			|||||||
    auto slot_data = GetAppletSlot(slot);
 | 
					    auto slot_data = GetAppletSlot(slot);
 | 
				
			||||||
    slot_data->registered = true;
 | 
					    slot_data->registered = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (slot_data->attributes.applet_pos == AppletPos::System &&
 | 
					    if (slot_data->applet_id != AppletId::None &&
 | 
				
			||||||
 | 
					        slot_data->attributes.applet_pos == AppletPos::System &&
 | 
				
			||||||
        slot_data->attributes.is_home_menu) {
 | 
					        slot_data->attributes.is_home_menu) {
 | 
				
			||||||
        slot_data->attributes.raw |= attributes.raw;
 | 
					        slot_data->attributes.raw |= attributes.raw;
 | 
				
			||||||
        LOG_DEBUG(Service_APT, "Updated home menu attributes to {:08X}.",
 | 
					        LOG_DEBUG(Service_APT, "Updated home menu attributes to {:08X}.",
 | 
				
			||||||
@@ -786,16 +790,23 @@ Result AppletManager::PrepareToStartSystemApplet(AppletId applet_id) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kernel::Object> object,
 | 
					Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kernel::Object> object,
 | 
				
			||||||
                                        const std::vector<u8>& buffer) {
 | 
					                                        const std::vector<u8>& buffer) {
 | 
				
			||||||
    auto source_applet_id = AppletId::None;
 | 
					    auto source_applet_id = AppletId::Application;
 | 
				
			||||||
    if (last_system_launcher_slot != AppletSlot::Error) {
 | 
					    if (last_system_launcher_slot != AppletSlot::Error) {
 | 
				
			||||||
        const auto slot_data = GetAppletSlot(last_system_launcher_slot);
 | 
					        const auto launcher_slot_data = GetAppletSlot(last_system_launcher_slot);
 | 
				
			||||||
        source_applet_id = slot_data->applet_id;
 | 
					        source_applet_id = launcher_slot_data->applet_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If a system applet is launching another system applet, reset the slot to avoid conflicts.
 | 
					        // APT generally clears and terminates the caller of StartSystemApplet. This helps in
 | 
				
			||||||
        // This is needed because system applets won't necessarily call CloseSystemApplet before
 | 
					        // situations such as a system applet launching another system applet, which would
 | 
				
			||||||
        // exiting.
 | 
					        // otherwise deadlock.
 | 
				
			||||||
        if (last_system_launcher_slot == AppletSlot::SystemApplet) {
 | 
					        // TODO: In real APT, the check for AppletSlot::Application does not exist; there is
 | 
				
			||||||
            slot_data->Reset();
 | 
					        // TODO: something wrong with our implementation somewhere that makes this necessary.
 | 
				
			||||||
 | 
					        // TODO: Otherwise, games that attempt to launch system applets will be cleared and
 | 
				
			||||||
 | 
					        // TODO: emulation will crash.
 | 
				
			||||||
 | 
					        if (!launcher_slot_data->registered ||
 | 
				
			||||||
 | 
					            (last_system_launcher_slot != AppletSlot::Application &&
 | 
				
			||||||
 | 
					             !launcher_slot_data->attributes.no_exit_on_system_applet)) {
 | 
				
			||||||
 | 
					            launcher_slot_data->Reset();
 | 
				
			||||||
 | 
					            // TODO: Implement launcher process termination.
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,6 +152,7 @@ union AppletAttributes {
 | 
				
			|||||||
    u32 raw;
 | 
					    u32 raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BitField<0, 3, AppletPos> applet_pos;
 | 
					    BitField<0, 3, AppletPos> applet_pos;
 | 
				
			||||||
 | 
					    BitField<28, 1, u32> no_exit_on_system_applet;
 | 
				
			||||||
    BitField<29, 1, u32> is_home_menu;
 | 
					    BitField<29, 1, u32> is_home_menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AppletAttributes() : raw(0) {}
 | 
					    AppletAttributes() : raw(0) {}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user