@@ -133,6 +133,7 @@ export class ProjectionService {
133133 private wirelessPhoneInRange = false
134134 private btInitialQueryDone = false
135135 private isSwitching = false
136+ private sessionActiveSent : boolean | null = null
136137
137138 private readonly onAaConnected = ( ) : void => {
138139 this . refreshAaBtPairedList ( ) . catch ( ( ) => { } )
@@ -241,11 +242,15 @@ export class ProjectionService {
241242 sup . on ( 'stderr' , ( line ) => console . warn ( `[aa-bt!] ${ line } ` ) )
242243 sup . on ( 'error' , ( err ) => console . warn ( `[aa-bt] supervisor error: ${ err . message } ` ) )
243244 this . aaBtSupervisor = sup
245+ this . sessionActiveSent = null
244246 console . log ( '[ProjectionService] starting AA BT/Wi-Fi supervisor' )
245247 sup . start ( this . config )
246248 this . openAaBtSubscription ( )
247249 this . populateAaBtPairedListInitial ( )
248- . then ( ( ) => this . tryAutoConnect ( ) )
250+ . then ( ( ) => {
251+ this . emitTransportState ( )
252+ return this . tryAutoConnect ( )
253+ } )
249254 . catch ( ( ) => { } )
250255 return
251256 }
@@ -257,6 +262,7 @@ export class ProjectionService {
257262 this . closeAaBtSubscription ( )
258263 this . setWirelessPhoneInRange ( false )
259264 this . btInitialQueryDone = false
265+ this . sessionActiveSent = null
260266 }
261267 }
262268
@@ -989,6 +995,22 @@ export class ProjectionService {
989995 type : 'transportState' ,
990996 payload : this . arbiter . getSnapshot ( )
991997 } )
998+ if ( this . aaBtSupervisor ) {
999+ const aaActive = this . started && this . drivers . getAa ( ) !== null
1000+ void this . setSessionActive ( aaActive )
1001+ }
1002+ }
1003+
1004+ /** Tell the BT reconnect worker to pause while an AA session is active. */
1005+ private async setSessionActive ( active : boolean ) : Promise < void > {
1006+ if ( ! this . aaBtSupervisor || this . sessionActiveSent === active ) return
1007+ this . sessionActiveSent = active
1008+ try {
1009+ await this . aaBtSock . setSessionActive ( active )
1010+ } catch ( e ) {
1011+ this . sessionActiveSent = null
1012+ console . warn ( `[ProjectionService] setSessionActive(${ active } ) failed` , e )
1013+ }
9921014 }
9931015
9941016 public async switchTransport ( ) : Promise < { ok : boolean ; active : Transport | null } > {
@@ -1005,6 +1027,11 @@ export class ProjectionService {
10051027 const desired = this . arbiter . getOverride ( )
10061028 if ( ! desired ) break
10071029
1030+ const wasWireless =
1031+ this . started &&
1032+ this . drivers . getAa ( ) !== null &&
1033+ this . drivers . getAa ( ) ?. isWiredMode ( ) === false
1034+
10081035 if ( this . started ) {
10091036 try {
10101037 await this . stop ( )
@@ -1013,8 +1040,16 @@ export class ProjectionService {
10131040 }
10141041 }
10151042
1043+ if ( wasWireless ) {
1044+ // Leaving wireless: kick the phone off the AP
1045+ await this . aaBtSock . deauthApClients ( ) . catch ( ( ) => { } )
1046+ }
1047+
10161048 if ( desired . transport === 'aa' && desired . mode === 'wireless' ) {
10171049 await this . bounceAaBtConnections ( )
1050+ // Give BlueZ a moment to commit the disconnect before we re-wake.
1051+ await new Promise ( ( r ) => setTimeout ( r , 500 ) )
1052+ await this . tryAutoConnect ( )
10181053 }
10191054
10201055 await this . autoStartIfNeeded ( )
@@ -1064,7 +1099,11 @@ export class ProjectionService {
10641099 const connected = devices . find ( ( d ) => d . connected ) ?. mac ?? ''
10651100 const wasSettled = this . btInitialQueryDone
10661101 this . btInitialQueryDone = true
1067- this . setWirelessPhoneInRange ( connected !== '' )
1102+ // During wired AA we deliberately don't auto-wake the phone, so it won't
1103+ // show as BT-connected. Treat any paired device as in-range.
1104+ const wiredAaActive = this . started && this . drivers . getAa ( ) ?. isWiredMode ( ) === true
1105+ const offerable = connected !== '' || ( wiredAaActive && devices . length > 0 )
1106+ this . setWirelessPhoneInRange ( offerable )
10681107 if ( ! wasSettled ) this . autoStartIfNeeded ( ) . catch ( console . error )
10691108
10701109 if ( this . aaDriver ) {
@@ -1126,6 +1165,11 @@ export class ProjectionService {
11261165 // Pick a target from the paired list and fire a single Connect
11271166 private async tryAutoConnect ( ) : Promise < void > {
11281167 if ( ! this . aaBtSupervisor ) return
1168+ // Don't poke the phone over BT while a wired session is already running
1169+ if ( this . started && this . drivers . getAa ( ) ?. isWiredMode ( ) === true ) {
1170+ console . log ( '[ProjectionService] autoconnect: skipped (wired AA session active)' )
1171+ return
1172+ }
11291173
11301174 let devices
11311175 try {
0 commit comments