From b55a55e4b4cbe1f999dad9c1888089e0efe1813c Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Sat, 1 Aug 2026 15:25:52 -0500 Subject: [PATCH] reboot --- selfdrive/ui/layouts/settings/device.py | 6 +++- .../settings/tests/test_device_reboot.py | 36 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/layouts/settings/device.py b/selfdrive/ui/layouts/settings/device.py index 96ec6e8df4..1655cdc8f9 100644 --- a/selfdrive/ui/layouts/settings/device.py +++ b/selfdrive/ui/layouts/settings/device.py @@ -16,7 +16,7 @@ from openpilot.selfdrive.ui.onroad.driver_camera_dialog import DriverCameraDialo from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.selfdrive.ui.layouts.onboarding import TrainingGuide from openpilot.selfdrive.ui.widgets.pairing_dialog import PairingDialog -from openpilot.system.hardware import PC, TICI +from openpilot.system.hardware import HARDWARE, PC, TICI from openpilot.system.hardware.hw import Paths from openpilot.system.ui.lib.application import FontWeight, gui_app from openpilot.system.ui.lib.multilang import multilang, tr, tr_noop @@ -282,6 +282,10 @@ class DeviceLayout(Widget): def _perform_reboot(self, result: DialogResult): if result == DialogResult.CONFIRM: self._params.put_bool("DoUserReboot", True) + try: + HARDWARE.reboot() + except Exception: + cloudlog.exception("Direct user-requested reboot failed; manager fallback requested") def _power_off_prompt(self): if ui_state.engaged: diff --git a/selfdrive/ui/layouts/settings/tests/test_device_reboot.py b/selfdrive/ui/layouts/settings/tests/test_device_reboot.py index 137f5cf2f2..8e63683b1c 100644 --- a/selfdrive/ui/layouts/settings/tests/test_device_reboot.py +++ b/selfdrive/ui/layouts/settings/tests/test_device_reboot.py @@ -19,27 +19,59 @@ def _device_layout(): return layout -def test_confirmed_user_reboot_is_written_synchronously(): +class FakeHardware: + def __init__(self, error=None): + self.error = error + self.reboot_calls = 0 + + def reboot(self): + self.reboot_calls += 1 + if self.error is not None: + raise self.error + + +def test_confirmed_user_reboot_is_written_synchronously(monkeypatch): layout = _device_layout() + hardware = FakeHardware() + monkeypatch.setattr(device, "HARDWARE", hardware) layout._perform_reboot(DialogResult.CONFIRM) assert layout._params.writes == [("DoUserReboot", True)] + assert hardware.reboot_calls == 1 def test_confirmed_user_reboot_is_allowed_onroad(monkeypatch): layout = _device_layout() + hardware = FakeHardware() + monkeypatch.setattr(device, "HARDWARE", hardware) monkeypatch.setattr(device.ui_state, "started", True) monkeypatch.setattr(device.ui_state, "ignition", True) layout._perform_reboot(DialogResult.CONFIRM) assert layout._params.writes == [("DoUserReboot", True)] + assert hardware.reboot_calls == 1 -def test_cancelled_user_reboot_is_ignored(): +def test_cancelled_user_reboot_is_ignored(monkeypatch): layout = _device_layout() + hardware = FakeHardware() + monkeypatch.setattr(device, "HARDWARE", hardware) layout._perform_reboot(DialogResult.CANCEL) assert layout._params.writes == [] + assert hardware.reboot_calls == 0 + + +def test_failed_direct_reboot_keeps_manager_fallback(monkeypatch): + layout = _device_layout() + hardware = FakeHardware(RuntimeError("reboot failed")) + monkeypatch.setattr(device, "HARDWARE", hardware) + monkeypatch.setattr(device.cloudlog, "exception", lambda *_args, **_kwargs: None) + + layout._perform_reboot(DialogResult.CONFIRM) + + assert layout._params.writes == [("DoUserReboot", True)] + assert hardware.reboot_calls == 1