Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,62 @@
import importlib.util,json,unittest
from pathlib import Path
spec=importlib.util.spec_from_file_location('audio',Path(__file__).resolve().parents[1]/'runtime/call-audio.py')
audio=importlib.util.module_from_spec(spec);spec.loader.exec_module(audio)
class AudioTests(unittest.TestCase):
def rig(self):
commands=[]
devices={'cards':[{'index':0,'owner_module':1,'name':'droid_card.primary','profiles':{'default':{},'voicecall':{}},'active_profile':'default'}],
'sinks':[{'owner_module':1,'name':'sink.primary_output','ports':[{'name':'output-earpiece'},{'name':'output-parking'},{'name':'output-speaker'}],'active_port':'output-speaker','mute':True}],
'sources':[{'name':'source.droid','mute':True}],
'sink-inputs':[{'index':9,'properties':{'media.role':'phone'}}]}
def command(*args):
commands.append(args)
return ''
route=audio.CallAudio(command)
route.devices=lambda kind:devices[kind]
return route,commands,devices
def test_actual_pulse14_listing_and_routing(self):
fixture=Path(__file__).parent/'fixtures/pulse14'
commands=[]
def command(*args):
commands.append(args)
if args[0]=='list':
return (fixture/(args[1]+'.txt')).read_text() if args[1]!='sink-inputs' else ''
return ''
route=audio.CallAudio(command)
self.assertEqual(len(route.devices('cards')),1)
self.assertEqual(route.devices('cards')[0]['owner_module'],1)
self.assertIn('output-earpiece',route.devices('sinks')[0]['ports'])
route.enter();self.assertTrue(route.active)
route.leave();self.assertIsNone(route.saved)
self.assertIn(('set-sink-port','sink.primary_output','output-earpiece'),commands)
def test_active_call_routes_earpiece_then_restores(self):
route,c,_=self.rig()
route.update([{'state':'active'}]);n=len(c)
route.update([{'state':'active'}]);self.assertEqual(len(c),n)
self.assertIn(('set-card-profile','droid_card.primary','voicecall'),c)
self.assertIn(('set-sink-port','sink.primary_output','output-earpiece'),c)
self.assertNotIn(('set-sink-port','sink.primary_output','output-speaker'),c)
self.assertIn(('set-source-mute','source.droid','0'),c)
route.update([])
self.assertIsNone(route.saved)
self.assertIn(('set-card-profile','droid_card.primary','default'),c)
self.assertIn(('set-source-mute','source.droid','1'),c)
def test_controls_route_speaker_mute_and_phone_stream(self):
route,c,_=self.rig();route.enter()
result=route.control({'operation':'set','speaker':True,'muted':True,'volume':0.8})
self.assertTrue(result['speaker']);self.assertTrue(result['muted'])
self.assertIn(('set-sink-port','sink.primary_output','output-speaker'),c)
self.assertIn(('set-source-mute','source.droid','1'),c)
self.assertIn(('set-sink-input-volume','9','80%'),c)
route.leave();self.assertFalse(route.muted);self.assertFalse(route.speaker)
with self.assertRaisesRegex(ValueError,'NOT_ACTIVE'):route.control({'operation':'set','muted':True})
def test_ringing_alone_does_not_open_microphone(self):
route,c,_=self.rig();route.update([{'state':'incoming'}]);self.assertEqual(c,[])
def test_missing_earpiece_never_falls_back_to_speaker(self):
route,c,d=self.rig();d['sinks'][0]['ports']=[{'name':'output-speaker'}]
with self.assertRaisesRegex(RuntimeError,'EARPIECE'):route.update([{'state':'active'}])
self.assertFalse(any(x[0].startswith('set-') for x in c))
if __name__=='__main__':unittest.main()