mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 04:23:42 +08:00
Share personality alert preference with Android Auto
This commit is contained in:
@@ -100,7 +100,7 @@ DESCRIPTIONS = {
|
||||
'DeveloperSidebar': 'Shows live developer metrics on the right of the Big driving screen. Off gives that space back to the road view.',
|
||||
'DriverCamera': 'Shows the driver camera while reversing.',
|
||||
'StockConfidenceBallWidget': 'Uses StarPilot driving widgets in place of the stock confidence ball.',
|
||||
'HidePersonalityAlerts': 'Hides the alert shown when the driving personality changes.',
|
||||
'HidePersonalityAlerts': 'Hides the alert shown when the driving personality changes on the comma and Android Auto.',
|
||||
'ShowBrakeStatus': 'Colors the steering wheel to show braking and acceleration.',
|
||||
'HideLeadMarker': 'Shows the lead-vehicle indicator on the driving screen.',
|
||||
'LeadInfo': 'Shows the lead vehicle distance or speed beside its indicator.',
|
||||
|
||||
@@ -138,6 +138,8 @@ OnroadLayoutPage.methods.setProjectionLeadInfo.call(leadVm, "Both")
|
||||
assert.equal(leadVm.state.draft.leadInfo, "Speed")
|
||||
assert.equal(leadChanges.length, 2)
|
||||
assert.equal(validDocument({ ...native.document, signalBorder: true }, native.metadata), false, "the comma screen keeps its C4 settings")
|
||||
assert.match(OnroadLayoutPage.template, /Personality alerts follow the comma screen setting\./)
|
||||
assert.doesNotMatch(OnroadLayoutPage.template, /setProjectionDisplay\('hidePersonalityAlerts', value\)/)
|
||||
assert.match(OnroadLayoutPage.template, /Red Blind-Spot Border/)
|
||||
assert.match(OnroadLayoutPage.template, /Amber Signal Border/)
|
||||
const borderChanges = []
|
||||
|
||||
@@ -355,8 +355,7 @@ export const ONROAD_LAYOUT_TEMPLATE = `
|
||||
<div class="gx-layout__subhead"><h4>StarPort screen options</h4></div>
|
||||
<p class="gx-note">Only the StarPort screen uses these. The comma screen has its own options on the Comma tab. Save to apply.</p>
|
||||
<h5 class="gx-layout__display-group">Alerts and borders</h5>
|
||||
<GalaxySettingRow feedback="draft" :row="switchRow('Hide Personality Alerts', state.draft.hidePersonalityAlerts === true)" :index="0"
|
||||
:disabled="!editable || !!state.drag || !!state.layerDrag" :save-value="(index, value) => setProjectionDisplay('hidePersonalityAlerts', value)" />
|
||||
<p class="gx-note">Personality alerts follow the comma screen setting.</p>
|
||||
<GalaxySettingRow feedback="draft" :row="switchRow('Red Blind-Spot Border', state.draft.blindSpotBorder === true)" :index="1"
|
||||
:disabled="!editable || !!state.drag || !!state.layerDrag" :save-value="(index, value) => setProjectionDisplay('blindSpotBorder', value)" />
|
||||
<GalaxySettingRow feedback="draft" :row="switchRow('Amber Signal Border', state.draft.signalBorder === true)" :index="2"
|
||||
|
||||
@@ -137,7 +137,8 @@ def layout_metadata_for_viewport(viewport):
|
||||
return profile
|
||||
|
||||
|
||||
# Android Auto display switches, independent of the comma screen's preferences.
|
||||
# Android Auto display switches. The legacy personality field remains in saved layouts for compatibility;
|
||||
# the shared comma preference controls that notice on every screen.
|
||||
DISPLAY_DEFAULTS = {'blindSpotBorder': False, 'signalBorder': False, 'blindSpotCamera': False,
|
||||
'hidePersonalityAlerts': False, 'wheelPedalFeedback': False,
|
||||
'leadIndicator': False, 'leadInfo': 'Off', 'speedSources': False,
|
||||
@@ -147,7 +148,7 @@ LEAD_INFO_CHOICES = ('Off', 'Distance', 'Speed')
|
||||
|
||||
|
||||
def projection_appearance(appearance, document):
|
||||
"""The comma's onroad appearance with every car-screen choice taken from the AA layout instead."""
|
||||
"""Apply screen-specific choices while retaining the shared personality-alert preference."""
|
||||
from dataclasses import replace
|
||||
from openpilot.starpilot.ui.appearance_preferences import LeadInfoMode
|
||||
lead_indicator = document.get('leadIndicator', False) is True
|
||||
@@ -159,7 +160,6 @@ def projection_appearance(appearance, document):
|
||||
show_lead_indicator=lead_indicator, lead_info_mode=lead_info_mode,
|
||||
show_blindspot_border=document.get('blindSpotBorder', False) is True,
|
||||
show_signal_border=document.get('signalBorder', False) is True,
|
||||
hide_personality_alerts=document.get('hidePersonalityAlerts', False) is True,
|
||||
wheel_pedal_feedback=document.get('wheelPedalFeedback', False) is True)
|
||||
|
||||
|
||||
|
||||
@@ -216,6 +216,19 @@ class TestProjectionLayout(unittest.TestCase):
|
||||
with self.subTest(key=key, value=value), self.assertRaises(ValueError):
|
||||
validate_layout({**document, key: value}, SCREEN)
|
||||
|
||||
def test_legacy_personality_choice_cannot_override_shared_preference(self):
|
||||
from openpilot.starpilot.system.starport.projection_layout import projection_appearance
|
||||
from openpilot.starpilot.ui.appearance_preferences import OnroadAppearance
|
||||
for old_value in (False, True):
|
||||
saved = validate_layout({**default_layout(SCREEN), 'hidePersonalityAlerts': old_value,
|
||||
'wheelPedalFeedback': True}, SCREEN)
|
||||
round_trip = decode_layout(json.dumps(saved).encode(), SCREEN)
|
||||
self.assertEqual(round_trip, saved)
|
||||
for shared_value in (False, True):
|
||||
actual = projection_appearance(OnroadAppearance(hide_personality_alerts=shared_value), round_trip)
|
||||
self.assertIs(actual.hide_personality_alerts, shared_value)
|
||||
self.assertTrue(actual.wheel_pedal_feedback)
|
||||
|
||||
def test_lead_info_starts_off_and_takes_only_known_choices(self):
|
||||
document = default_layout(SCREEN)
|
||||
self.assertEqual((document['leadIndicator'], document['leadInfo']), (False, 'Off'))
|
||||
|
||||
@@ -302,13 +302,13 @@ class TestProjectionLayoutRuntime(unittest.TestCase):
|
||||
appearance = rendered[-1].appearance
|
||||
self.assertEqual((appearance.hide_personality_alerts, appearance.wheel_pedal_feedback, appearance.camera_view,
|
||||
appearance.driver_camera_on_reverse, rendered[-1].reverse_driver_camera),
|
||||
(False, False, CameraViewChoice.DRIVER, True, False), 'the car screen never switches to the driver camera')
|
||||
self.assertIs(adapter.appearance_override(comma).hide_personality_alerts, False, 'the adapter hides notices by AA choice')
|
||||
(True, False, CameraViewChoice.DRIVER, True, False), 'the car screen never switches to the driver camera')
|
||||
self.assertIs(adapter.appearance_override(comma).hide_personality_alerts, True, 'the shared comma preference controls notices')
|
||||
view.apply_layout({**layout, 'hidePersonalityAlerts': True, 'wheelPedalFeedback': True})
|
||||
self.assertEqual(invalidated, [1])
|
||||
view.render()
|
||||
self.assertEqual((rendered[-1].appearance.hide_personality_alerts, rendered[-1].appearance.wheel_pedal_feedback), (True, True))
|
||||
self.assertIs(adapter.appearance_override(OnroadAppearance()).hide_personality_alerts, True)
|
||||
self.assertIs(adapter.appearance_override(OnroadAppearance()).hide_personality_alerts, False, 'stale AA value cannot override the shared choice')
|
||||
|
||||
def test_lead_marker_and_info_follow_the_aa_layout_only(self):
|
||||
from openpilot.starpilot.ui.appearance_preferences import LeadInfoMode, OnroadAppearance
|
||||
|
||||
@@ -127,6 +127,65 @@ class AppearanceSettingsTests(unittest.TestCase):
|
||||
self.assertFalse(onroad_appearance(self.params).hide_personality_alerts)
|
||||
self.assertEqual(path.read_bytes(), b"bad")
|
||||
|
||||
def test_personality_toggle_controls_native_and_existing_projection_layouts(self):
|
||||
from openpilot.starpilot.system.starport.projection_layout import default_layout_for_viewport, projection_appearance, validate_layout_for_viewport
|
||||
from openpilot.starpilot.ui.tests.test_runtime_snapshot import RuntimeSnapshotAdapter
|
||||
|
||||
viewport = (2880, 1080)
|
||||
for profile in (Profile.LARGE, Profile.COMPACT):
|
||||
for hidden in (True, False):
|
||||
request = row_change(self.row("HidePersonalityAlerts", profile))
|
||||
assert request is not None
|
||||
self.assertEqual(request.value, "On" if hidden else "Off")
|
||||
self.assertTrue(self.owner.apply(request))
|
||||
for old_aa_choice in (False, True):
|
||||
layout = default_layout_for_viewport(viewport)
|
||||
layout.update(hidePersonalityAlerts=old_aa_choice, wheelPedalFeedback=True)
|
||||
saved = validate_layout_for_viewport(layout, viewport)
|
||||
self.assertIs(saved['hidePersonalityAlerts'], old_aa_choice)
|
||||
self.assertTrue(saved['wheelPedalFeedback'])
|
||||
ui = ui_fake()
|
||||
ui.params = self.params
|
||||
source = ui.sm.messages['selfdriveState']
|
||||
source.personality = NS(raw=1)
|
||||
source.alertSize, source.alertType = NS(raw=1), 'personalityChanged/warning'
|
||||
source.alertText1 = 'Driving Personality: Standard'
|
||||
for projection in (False, True):
|
||||
with self.subTest(profile=profile, hidden=hidden, legacy_aa=old_aa_choice, projection=projection):
|
||||
adapter = RuntimeSnapshotAdapter(ui)
|
||||
if projection:
|
||||
adapter.appearance_override = lambda appearance, document=saved: projection_appearance(appearance, document)
|
||||
alert = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.alert
|
||||
self.assertEqual(alert.size, AlertSize.NONE if hidden else AlertSize.SMALL)
|
||||
source.alertSize, source.alertStatus = NS(raw=3), NS(raw=2)
|
||||
source.alertText1 = 'Take control'
|
||||
safety = adapter.build(ShellMode.ONROAD, now_ns=NOW).onroad.alert
|
||||
self.assertEqual((safety.size, safety.text1), (AlertSize.FULL, 'Take control'))
|
||||
source.alertSize, source.alertStatus = NS(raw=1), NS(raw=0)
|
||||
source.alertText1 = 'Driving Personality: Standard'
|
||||
|
||||
def test_personality_toggle_refreshes_on_projection_without_reconnect(self):
|
||||
from openpilot.starpilot.system.starport.projection_layout import default_layout_for_viewport, projection_appearance
|
||||
from openpilot.starpilot.ui.tests.test_runtime_snapshot import RuntimeSnapshotAdapter
|
||||
|
||||
ui = ui_fake()
|
||||
ui.params = self.params
|
||||
source = ui.sm.messages['selfdriveState']
|
||||
source.personality = NS(raw=1)
|
||||
source.alertSize, source.alertType = NS(raw=1), 'personalityChanged/warning'
|
||||
source.alertText1 = 'Driving Personality: Standard'
|
||||
# A conflicting old AA-only preference must never pin either state.
|
||||
layout = {**default_layout_for_viewport((2880, 1080)), 'hidePersonalityAlerts': True}
|
||||
adapter = RuntimeSnapshotAdapter(ui)
|
||||
adapter.appearance_override = lambda appearance: projection_appearance(appearance, layout)
|
||||
for second, hidden in enumerate((False, True, False)):
|
||||
self.params.put_bool('HidePersonalityAlerts', hidden, block=True)
|
||||
now = NOW + second * 1_000_000_000
|
||||
ui.sm.logMonoTime['selfdriveState'] = now
|
||||
ui.sm.recv_time['selfdriveState'] = now / 1e9
|
||||
alert = adapter.build(ShellMode.ONROAD, now_ns=now).onroad.alert
|
||||
self.assertEqual(alert.size, AlertSize.NONE if hidden else AlertSize.SMALL)
|
||||
|
||||
def test_developer_sidebar_external_changes_refresh_without_restart(self):
|
||||
from openpilot.starpilot.ui.tests.test_runtime_snapshot import RuntimeSnapshotAdapter
|
||||
ui = ui_fake()
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "4dbca59687f2c0d327a01eee882f48d476e2e02027326b2ae974cedc2fbcadc2", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "6415d5700ffb185d41a3864c8d1522cf283d3599b0aeafc7c7aff58980b536d2", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user