diff --git a/stratosphere/fatal/source/fatal_task.cpp b/stratosphere/fatal/source/fatal_task.cpp index 9725d02f8..381d3c176 100644 --- a/stratosphere/fatal/source/fatal_task.cpp +++ b/stratosphere/fatal/source/fatal_task.cpp @@ -49,11 +49,11 @@ static void RunTask(IFatalTask *task) { void RunFatalTasks(FatalContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event) { RunTask(new ErrorReportTask(ctx, title_id, error_report, erpt_event)); - /* TODO: RunTask(new PowerControlTask(ctx, title_id, battery_event)); */ + /* TODO: RunTask(new PowerControlTask(ctx, title_id, erpt_event, battery_event)); */ /* TODO: RunTask(new ShowFatalTask(ctx, title_id, battery_event)); */ /* TODO: RunTask(new StopSoundTask(ctx, title_id)); */ /* TODO: RunTask(new BacklightControlTask(ctx, title_id)); */ /* TODO: RunTask(new AdjustClockTask(ctx, title_id)); */ - /* TODO: RunTask(new PowerButtonTask(ctx, title_id, erpt_event)); */ + RunTask(new PowerButtonObserveTask(ctx, title_id, erpt_event)); RunTask(new StateTransitionStopTask(ctx, title_id)); } diff --git a/stratosphere/fatal/source/fatal_task_power.cpp b/stratosphere/fatal/source/fatal_task_power.cpp index 59ffb062b..410fc158a 100644 --- a/stratosphere/fatal/source/fatal_task_power.cpp +++ b/stratosphere/fatal/source/fatal_task_power.cpp @@ -17,6 +17,30 @@ #include #include "fatal_task_power.hpp" +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. */ + + BpcSleepButtonState state; + while (true) { + Result rc = bpcGetSleepButtonState(&state); + if (R_SUCCEEDED(rc) && state == BpcSleepButtonState_Held) { + bpcRebootSystem(); + return; + } + + /* Wait 100 ms between button checks. */ + svcSleepThread(TimeoutHelper::NsToTick(100000000UL)); + } +} + +Result PowerButtonObserveTask::Run() { + WaitForPowerButton(); + return 0; +} + Result StateTransitionStopTask::Run() { /* Nintendo ignores the output of this call... */ spsmPutErrorState(); diff --git a/stratosphere/fatal/source/fatal_task_power.hpp b/stratosphere/fatal/source/fatal_task_power.hpp index e97f71978..bdd5b7155 100644 --- a/stratosphere/fatal/source/fatal_task_power.hpp +++ b/stratosphere/fatal/source/fatal_task_power.hpp @@ -19,6 +19,31 @@ #include #include "fatal_task.hpp" +class PowerControlTask : public IFatalTask { + private: + Event *erpt_event; + Event *battery_event; + public: + PowerControlTask(FatalContext *ctx, u64 title_id, Event *er_evt, Event *bt_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt), battery_event(bt_evt) { } + virtual Result Run() override; + virtual const char *GetName() const override { + return "PowerControlTask"; + } +}; + +class PowerButtonObserveTask : public IFatalTask { + private: + Event *erpt_event; + private: + void WaitForPowerButton(); + public: + PowerButtonObserveTask(FatalContext *ctx, u64 title_id, Event *er_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt) { } + virtual Result Run() override; + virtual const char *GetName() const override { + return "PowerButtonObserveTask"; + } +}; + class StateTransitionStopTask : public IFatalTask { public: StateTransitionStopTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }