apt: Implement additional applet state management. (#6303)
* apt: Implement additional library applet state management. * kernel: Clear process handle table on exit. * apt: Implement system applet commands. * apt: Pop MediaType from command buffers with correct size. * apt: Improve accuracy of parameters and HLE applet lifecycle. * apt: General cleanup. * file_sys: Make system save data open error code more correct. Not sure if this is the exact right error code, but it's at least more correct than before as Game Notes will now create its system save data instead of throwing a fatal error. * apt: Fix launching New 3DS Internet Browser. * frd: Correct fix to GetMyScreenName response.
This commit is contained in:
@ -6,6 +6,7 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
@ -42,24 +43,24 @@ static Core::TimingEventType* applet_update_event = nullptr;
|
||||
/// The interval at which the Applet update callback will be called, 16.6ms
|
||||
static const u64 applet_update_interval_us = 16666;
|
||||
|
||||
ResultCode Applet::Create(Service::APT::AppletId id,
|
||||
std::weak_ptr<Service::APT::AppletManager> manager) {
|
||||
ResultCode Applet::Create(Service::APT::AppletId id, Service::APT::AppletId parent, bool preload,
|
||||
const std::shared_ptr<Service::APT::AppletManager>& manager) {
|
||||
switch (id) {
|
||||
case Service::APT::AppletId::SoftwareKeyboard1:
|
||||
case Service::APT::AppletId::SoftwareKeyboard2:
|
||||
applets[id] = std::make_shared<SoftwareKeyboard>(id, std::move(manager));
|
||||
applets[id] = std::make_shared<SoftwareKeyboard>(id, parent, preload, manager);
|
||||
break;
|
||||
case Service::APT::AppletId::Ed1:
|
||||
case Service::APT::AppletId::Ed2:
|
||||
applets[id] = std::make_shared<MiiSelector>(id, std::move(manager));
|
||||
applets[id] = std::make_shared<MiiSelector>(id, parent, preload, manager);
|
||||
break;
|
||||
case Service::APT::AppletId::Error:
|
||||
case Service::APT::AppletId::Error2:
|
||||
applets[id] = std::make_shared<ErrEula>(id, std::move(manager));
|
||||
applets[id] = std::make_shared<ErrEula>(id, parent, preload, manager);
|
||||
break;
|
||||
case Service::APT::AppletId::Mint:
|
||||
case Service::APT::AppletId::Mint2:
|
||||
applets[id] = std::make_shared<Mint>(id, std::move(manager));
|
||||
applets[id] = std::make_shared<Mint>(id, parent, preload, manager);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Service_APT, "Could not create applet {}", id);
|
||||
@ -68,6 +69,17 @@ ResultCode Applet::Create(Service::APT::AppletId id,
|
||||
ErrorSummary::NotSupported, ErrorLevel::Permanent);
|
||||
}
|
||||
|
||||
Service::APT::AppletAttributes attributes;
|
||||
attributes.applet_pos.Assign(static_cast<u32>(Service::APT::AppletPos::AutoLibrary));
|
||||
attributes.is_home_menu.Assign(false);
|
||||
const auto lock_handle_data = manager->GetLockHandle(attributes);
|
||||
|
||||
manager->Initialize(id, lock_handle_data->corrected_attributes);
|
||||
manager->Enable(lock_handle_data->corrected_attributes);
|
||||
if (preload) {
|
||||
manager->FinishPreloadingLibraryApplet(id);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -80,8 +92,8 @@ std::shared_ptr<Applet> Applet::Get(Service::APT::AppletId id) {
|
||||
|
||||
/// Handles updating the current Applet every time it's called.
|
||||
static void AppletUpdateEvent(u64 applet_id, s64 cycles_late) {
|
||||
Service::APT::AppletId id = static_cast<Service::APT::AppletId>(applet_id);
|
||||
std::shared_ptr<Applet> applet = Applet::Get(id);
|
||||
const auto id = static_cast<Service::APT::AppletId>(applet_id);
|
||||
const auto applet = Applet::Get(id);
|
||||
ASSERT_MSG(applet != nullptr, "Applet doesn't exist! applet_id={:08X}", id);
|
||||
|
||||
applet->Update();
|
||||
@ -96,20 +108,28 @@ static void AppletUpdateEvent(u64 applet_id, s64 cycles_late) {
|
||||
}
|
||||
}
|
||||
|
||||
ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) {
|
||||
ResultCode result = StartImpl(parameter);
|
||||
if (result.IsError())
|
||||
return result;
|
||||
// Schedule the update event
|
||||
Core::System::GetInstance().CoreTiming().ScheduleEvent(
|
||||
usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Applet::IsRunning() const {
|
||||
return is_running;
|
||||
}
|
||||
|
||||
ResultCode Applet::ReceiveParameter(const Service::APT::MessageParameter& parameter) {
|
||||
switch (parameter.signal) {
|
||||
case Service::APT::SignalType::Wakeup: {
|
||||
ResultCode result = Start(parameter);
|
||||
if (!result.IsError()) {
|
||||
// Schedule the update event
|
||||
Core::System::GetInstance().CoreTiming().ScheduleEvent(
|
||||
usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case Service::APT::SignalType::WakeupByCancel:
|
||||
return Finalize();
|
||||
default:
|
||||
return ReceiveParameterImpl(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void Applet::SendParameter(const Service::APT::MessageParameter& parameter) {
|
||||
if (auto locked = manager.lock()) {
|
||||
locked->CancelAndSendParameter(parameter);
|
||||
@ -118,12 +138,15 @@ void Applet::SendParameter(const Service::APT::MessageParameter& parameter) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsLibraryAppletRunning() {
|
||||
// Check the applets map for instances of any applet
|
||||
for (auto itr = applets.begin(); itr != applets.end(); ++itr)
|
||||
if (itr->second != nullptr)
|
||||
return true;
|
||||
return false;
|
||||
void Applet::CloseApplet(std::shared_ptr<Kernel::Object> object, const std::vector<u8>& buffer) {
|
||||
if (auto locked = manager.lock()) {
|
||||
locked->PrepareToCloseLibraryApplet(true, false, false);
|
||||
locked->CloseLibraryApplet(std::move(object), buffer);
|
||||
} else {
|
||||
LOG_ERROR(Service_APT, "called after destructing applet manager");
|
||||
}
|
||||
|
||||
is_running = false;
|
||||
}
|
||||
|
||||
void Init() {
|
||||
|
Reference in New Issue
Block a user