Files
firestar5683 a82935f326 User interfaces and Android Auto
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services.

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com>
Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com>
Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: Shane Smiskol <shane@smiskol.com>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>
Co-authored-by: stef <19478336+stefpi@users.noreply.github.com>
Co-authored-by: whoisdomi <dcantu83@gmail.com>

Co-authored-by: Intelli <contact@intelli.software>
Co-authored-by: pharmacomaniac <blittle65@gmail.com>

Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

104 lines
5.5 KiB
Python

from dataclasses import replace
from types import SimpleNamespace as NS
from unittest.mock import Mock, patch
from openpilot.starpilot.favorites.actions import (
BOOKMARK, INCREASE_SPEED, DECREASE_SPEED, TRAFFIC, SWITCHBACK, SCREEN_OFF, mapped_actions,
)
from openpilot.starpilot.ui.onroad import axis_status_color
from openpilot.starpilot.conditional_mode.policy import ModeChoice
from openpilot.starpilot.ui.onroad_state import OnroadState, SpeedLimitObservation
def test_catalog_contains_real_native_mode_speed_and_bookmark_callbacks_only():
actions = mapped_actions(lambda *_: NS(rows=[]), Mock(), lambda: NS(rows=[]), Mock())
for key in (BOOKMARK, INCREASE_SPEED, DECREASE_SPEED, TRAFFIC, SWITCHBACK, SCREEN_OFF):
assert key in actions
assert not actions[key].available # Native session installs qualified callbacks.
assert '__starpilot_controller_action__:force_coasting' not in actions
assert '__starpilot_controller_action__:engage_openpilot' not in actions
def test_border_distinguishes_traffic_switchback_manual_chill_and_experimental():
state = OnroadState(True, True, 15, 80, SpeedLimitObservation())
state = replace(state, lateral_active=True, longitudinal_active=True)
def color():
result = axis_status_color(state)
return result.r, result.g, result.b
state = replace(state, traffic_mode=True)
assert color() == (201, 34, 49)
state = replace(state, switchback_mode=True)
assert color() == (139, 108, 197)
state = replace(state, traffic_mode=False, switchback_mode=False)
state = replace(state, conditional_effective=NS(choice=ModeChoice.CEM, reason='manual_chill', effective_experimental=False))
assert color() == (255, 214, 0)
for reason in ('manual_experimental', 'automatic'):
state = replace(state, conditional_effective=NS(choice=ModeChoice.CEM, reason=reason, effective_experimental=True))
assert color() == (218, 111, 37)
state = replace(state, longitudinal_overridden=True)
assert color() == (145, 155, 149)
def test_actual_native_callbacks_recheck_safety_and_current_producer():
from openpilot.starpilot.ui import runtime_app
from openpilot.selfdrive.ui import ui_state as device_module
sm, cp = {'deviceState': NS(startedMonoTime=0)}, NS(carFingerprint='qualified', flags=0, pcmCruise=True)
params = NS(get_bool=lambda _: False)
ui = NS(CP=cp, params=params, sm=sm, has_longitudinal_control=True, personality=0, started_frame=1)
state = OnroadState(True, True, 15, 80, SpeedLimitObservation())
session = runtime_app.StarShellSession.__new__(runtime_app.StarShellSession)
session.snapshot = Mock(return_value=NS(onroad=state))
session._favorite_authority = Mock(return_value=True)
session._conditional_favorite_active = Mock(return_value=False)
session.mode_actions = Mock()
session.mode_actions.dispatch.return_value = True
bookmark, personality, experimental, sender = Mock(return_value=True), Mock(), Mock(), Mock()
device = NS(awake=True, toggle_screen_off=Mock(return_value=True))
with patch.object(runtime_app, 'ui_state', ui), patch.object(device_module, 'device', device), \
patch.object(runtime_app, 'mode_action_authority', return_value=True), \
patch.object(runtime_app, 'producer_available', return_value=True), \
patch.object(runtime_app, '_slc_action_publisher', return_value=sender):
actions = session.native_favorite_actions(bookmark, personality, experimental)
assert actions[BOOKMARK].invoke()
assert actions[SCREEN_OFF].invoke()
assert actions[TRAFFIC].invoke()
assert actions[SWITCHBACK].invoke()
assert [call.args[0] for call in session.mode_actions.dispatch.call_args_list] == ['traffic', 'switchback']
session._favorite_authority.return_value = False
assert not actions[SWITCHBACK].invoke()
assert session.mode_actions.dispatch.call_count == 2
bookmark.assert_called_once()
device.toggle_screen_off.assert_called_once()
def test_alpha_off_wheel_editor_restricts_choices_and_rechecks_actual_cp():
import tempfile
from openpilot.common.params import Params
from opendbc.car.car_helpers import interfaces
from opendbc.car.hyundai.values import CAR, HyundaiFlags
from openpilot.starpilot.ui.conditional_feature import ConditionalFeature
from openpilot.starpilot.ui.feature_settings_state import FeatureSettingsRequest
with tempfile.TemporaryDirectory() as directory:
params = Params(directory)
cp = interfaces[CAR.HYUNDAI_IONIQ_6].get_non_essential_params(CAR.HYUNDAI_IONIQ_6)
cp.openpilotLongitudinalControl = False
cp.flags = int(HyundaiFlags.CANFD_LKA_STEER_MSG)
owner = NS(params=params, authority=lambda group: group == 'switchback_wheel',
vehicle_params=lambda: cp, vehicle_fingerprint=lambda: cp.carFingerprint)
feature = ConditionalFeature(owner)
rows = feature.wheel_rows()
assert len(rows) == 6
row = rows[0]
assert row.available and row.choices == ('Off', 'Switchback Mode')
request = FeatureSettingsRequest(row.key, row.source, 'Switchback Mode', dependencies=row.dependencies,
vehicle_fingerprint=row.vehicle_fingerprint, capability=row.capability)
assert feature.apply(request)
from pathlib import Path
assert Path(params.get_param_path('ModeButtonControl')).read_bytes() == b'7'
new_row = feature.wheel_rows()[0]
assert not feature.apply(replace(request, expected=new_row.source, dependencies=new_row.dependencies,
value='Toggle traffic mode'))
cp.carFingerprint = 'unknown'
assert not feature.apply(request)
assert feature.wheel_rows() == []