fatal: Implement configuration based on settings

This commit is contained in:
Michael Scire 2018-11-10 12:38:24 -08:00
parent 5f3187300d
commit f914edeebd
6 changed files with 128 additions and 5 deletions

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include "fatal_types.hpp"
#include "fatal_config.hpp"
static FatalConfig g_fatal_config;
static IEvent *g_fatal_settings_event = nullptr;
FatalConfig *GetFatalConfig() {
return &g_fatal_config;
}
static void UpdateLanguageCode() {
setGetLanguageCode(&GetFatalConfig()->language_code);
}
IEvent *GetFatalSettingsEvent() {
if (g_fatal_settings_event == nullptr) {
Event evt;
if (R_FAILED(setsysBindFatalDirtyFlagEvent(&evt))) {
std::abort();
}
g_fatal_settings_event = LoadReadOnlySystemEvent(evt.revent, [](u64 timeout) {
u64 flags_0, flags_1;
if (R_SUCCEEDED(setsysGetFatalDirtyFlags(&flags_0, &flags_1)) && (flags_0 & 1)) {
UpdateLanguageCode();
}
return 0;
}, true);
}
return g_fatal_settings_event;
}
void InitializeFatalConfig() {
FatalConfig *config = GetFatalConfig();
memset(config, 0, sizeof(*config));
setsysGetSerialNumber(config->serial_number);
setsysGetFirmwareVersion(&config->firmware_version);
UpdateLanguageCode();
setsysGetSettingsItemValue("fatal", "transition_to_fatal", &config->transition_to_fatal, sizeof(config->transition_to_fatal));
setsysGetSettingsItemValue("fatal", "show_extra_info", &config->show_extra_info, sizeof(config->show_extra_info));
setsysGetSettingsItemValue("fatal", "quest_reboot_interval_second", &config->quest_reboot_interval_second, sizeof(config->quest_reboot_interval_second));
setsysGetFlag(SetSysFlag_Quest, &config->quest_flag);
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
struct FatalConfig {
char serial_number[0x18];
SetSysFirmwareVersion firmware_version;
u64 language_code;
u64 quest_reboot_interval_second;
bool transition_to_fatal;
bool show_extra_info;
bool quest_flag;
};
IEvent *GetFatalSettingsEvent();
FatalConfig *GetFatalConfig();
void InitializeFatalConfig();

View file

@ -26,6 +26,7 @@
#include "fatal_types.hpp"
#include "fatal_private.hpp"
#include "fatal_user.hpp"
#include "fatal_config.hpp"
extern "C" {
extern u32 __start__;
@ -65,6 +66,11 @@ void __appInit(void) {
std::abort();
}
rc = setInitialize();
if (R_FAILED(rc)) {
std::abort();
}
rc = setsysInitialize();
if (R_FAILED(rc)) {
std::abort();
@ -118,13 +124,15 @@ void __appExit(void) {
i2cExit();
pminfoExit();
setsysExit();
setExit();
smExit();
}
int main(int argc, char **argv)
{
/* TODO: Load settings from set:sys. */
/* Load settings from set:sys. */
InitializeFatalConfig();
/* TODO: Load shared font. */
/* TODO: Check whether we should throw fatal due to repair process... */
@ -135,6 +143,7 @@ int main(int argc, char **argv)
/* TODO: Create services. */
server_manager->AddWaitable(new ServiceServer<PrivateService>("fatal:p", 4));
server_manager->AddWaitable(new ServiceServer<UserService>("fatal:u", 4));
server_manager->AddWaitable(GetFatalSettingsEvent());
/* Loop forever, servicing our services. */
server_manager->Process();

View file

@ -16,6 +16,7 @@
#include <switch.h>
#include "fatal_task_power.hpp"
#include "fatal_config.hpp"
bool PowerControlTask::TryShutdown() {
/* Set a timeout of 30 seconds. */
@ -91,12 +92,16 @@ void PowerButtonObserveTask::WaitForPowerButton() {
/* Wait up to a second for error report generation to finish. */
eventWait(this->erpt_event, TimeoutHelper::NsToTick(1000000000UL));
/* TODO: Force a reboot after some time if kiosk unit. */
/* Force a reboot after some time if kiosk unit. */
const FatalConfig *config = GetFatalConfig();
TimeoutHelper reboot_helper(config->quest_reboot_interval_second * 1000000000UL);
BpcSleepButtonState state;
while (true) {
Result rc = bpcGetSleepButtonState(&state);
if (R_SUCCEEDED(rc) && state == BpcSleepButtonState_Held) {
if ((R_SUCCEEDED(rc) && state == BpcSleepButtonState_Held) || (config->quest_flag && reboot_helper.TimedOut())) {
bpcRebootSystem();
return;
}

View file

@ -16,6 +16,7 @@
#include <switch.h>
#include "fatal_task_screen.hpp"
#include "fatal_config.hpp"
Result ShowFatalTask::ShowFatal() {
Result rc = 0;

View file

@ -18,6 +18,7 @@
#include "fatal_user.hpp"
#include "fatal_event_manager.hpp"
#include "fatal_task.hpp"
#include "fatal_config.hpp"
static bool g_thrown = false;
@ -37,6 +38,9 @@ Result UserService::ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCp
ctx.error_code = error;
ctx.cpu_ctx = *cpu_ctx;
/* Get config. */
const FatalConfig *config = GetFatalConfig();
/* Get title id. On failure, it'll be zero. */
u64 title_id = 0;
pminfoGetTitleId(&title_id, pid);
@ -63,7 +67,13 @@ Result UserService::ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCp
}
/* Run tasks. */
RunFatalTasks(&ctx, title_id, policy == FatalType_ErrorReportAndErrorScreen, &erpt_event, &battery_event);
if (config->transition_to_fatal) {
RunFatalTasks(&ctx, title_id, policy == FatalType_ErrorReportAndErrorScreen, &erpt_event, &battery_event);
} else {
/* If flag is not set, don't show the fatal screen. */
return 0;
}
}
break;
default: