Skip to content

Commit 38e099b

Browse files
authored
Fix/speaker state (#970)
1 parent 80705fb commit 38e099b

File tree

9 files changed

+64
-63
lines changed

9 files changed

+64
-63
lines changed

Sources/StreamVideo/Utils/AudioSession/CallAudioSession.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ final class CallAudioSession: @unchecked Sendable {
4646

4747
self.delegate = delegate
4848
self.statsAdapter = statsAdapter
49-
interruptionEffect = .init(audioStore)
50-
routeChangeEffect = .init(
51-
audioStore,
52-
callSettingsPublisher: callSettingsPublisher,
53-
delegate: delegate
54-
)
5549

5650
Publishers
5751
.CombineLatest(callSettingsPublisher, ownCapabilitiesPublisher)
@@ -77,6 +71,13 @@ final class CallAudioSession: @unchecked Sendable {
7771
audioStore.restartAudioSession()
7872
}
7973

74+
interruptionEffect = .init(audioStore)
75+
routeChangeEffect = .init(
76+
audioStore,
77+
callSettingsPublisher: callSettingsPublisher,
78+
delegate: delegate
79+
)
80+
8081
statsAdapter?.trace(.init(audioSession: traceRepresentation))
8182
}
8283

Sources/StreamVideo/Utils/AudioSession/Extensions/AVAudioSession.CategoryOptions+Convenience.swift

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,10 @@ extension AVAudioSession.CategoryOptions {
1313
speakerOn: Bool,
1414
appIsInForeground: Bool
1515
) -> AVAudioSession.CategoryOptions {
16-
var result: AVAudioSession.CategoryOptions = [
17-
.allowBluetooth
16+
[
17+
.allowBluetooth,
18+
.allowBluetoothA2DP
1819
]
19-
20-
/// - Note:We only add the `defaultToSpeaker` if the following are true:
21-
/// - It's required (speakerOn = true)
22-
/// - The app is foregrounded. The reason is that while in CallKit port overrides are being treated
23-
/// as hard overrides and stop CallKit Speaker button from allowing the user to toggle it off.
24-
if videoOn == false, speakerOn == true, appIsInForeground == true {
25-
result.insert(.defaultToSpeaker)
26-
}
27-
28-
return result
2920
}
3021

3122
/// Category options for playback.

Sources/StreamVideo/Utils/AudioSession/Policies/DefaultAudioSessionPolicy.swift

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,17 @@ public struct DefaultAudioSessionPolicy: AudioSessionPolicy {
2323
for callSettings: CallSettings,
2424
ownCapabilities: Set<OwnCapability>
2525
) -> AudioSessionConfiguration {
26-
guard applicationStateAdapter.state == .foreground else {
27-
return .init(
28-
isActive: callSettings.audioOutputOn,
29-
category: .playAndRecord,
30-
mode: .voiceChat,
31-
options: .playAndRecord(
32-
videoOn: callSettings.videoOn,
33-
speakerOn: callSettings.speakerOn,
34-
appIsInForeground: false
35-
),
36-
overrideOutputAudioPort: callSettings.speakerOn
37-
? .speaker
38-
: AVAudioSession.PortOverride.none
39-
)
40-
}
41-
42-
return .init(
26+
.init(
4327
isActive: callSettings.audioOutputOn,
4428
category: .playAndRecord,
4529
mode: .voiceChat,
46-
options: .playAndRecord(
47-
videoOn: callSettings.videoOn,
48-
speakerOn: callSettings.speakerOn,
49-
appIsInForeground: true
50-
),
51-
overrideOutputAudioPort: callSettings.speakerOn ? .speaker : AVAudioSession.PortOverride.none
30+
options: [
31+
.allowBluetooth,
32+
.allowBluetoothA2DP
33+
],
34+
overrideOutputAudioPort: callSettings.speakerOn
35+
? .speaker
36+
: AVAudioSession.PortOverride.none
5237
)
5338
}
5439
}

Sources/StreamVideo/Utils/AudioSession/RTCAudioStore/Effects/RTCAudioStore+RouteChangeEffect.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extension RTCAudioStore {
4848

4949
callSettingsCancellable = callSettingsPublisher
5050
.removeDuplicates()
51+
.dropFirst() // We drop the first one as we allow on init the CallAudioSession to configure as expected.
5152
.sink { [weak self] in self?.activeCallSettings = $0 }
5253
session.add(self)
5354
}

Sources/StreamVideo/WebRTC/v2/WebRTCAuthenticator.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ struct WebRTCAuthenticator: WebRTCAuthenticating {
9898
return result
9999
}()
100100

101+
log.debug("CallSettings when joining speakerOn:\(callSettings.speakerOn)", subsystems: .webRTC)
102+
101103
await coordinator
102104
.stateAdapter
103105
.enqueueCallSettings { _ in callSettings }

StreamVideoTests/Utils/AudioSession/Extensions/AVAudioSessionCategoryOptions_Tests.swift

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
1818
appIsInForeground: false
1919
),
2020
[
21-
.allowBluetooth
21+
.allowBluetooth,
22+
.allowBluetoothA2DP
2223
]
2324
)
2425
}
@@ -31,7 +32,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
3132
appIsInForeground: false
3233
),
3334
[
34-
.allowBluetooth
35+
.allowBluetooth,
36+
.allowBluetoothA2DP
3537
]
3638
)
3739
}
@@ -44,7 +46,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
4446
appIsInForeground: false
4547
),
4648
[
47-
.allowBluetooth
49+
.allowBluetooth,
50+
.allowBluetoothA2DP
4851
]
4952
)
5053
}
@@ -57,7 +60,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
5760
appIsInForeground: true
5861
),
5962
[
60-
.allowBluetooth
63+
.allowBluetooth,
64+
.allowBluetoothA2DP
6165
]
6266
)
6367
}
@@ -71,7 +75,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
7175
),
7276
[
7377
.allowBluetooth,
74-
.defaultToSpeaker
78+
.allowBluetoothA2DP
7579
]
7680
)
7781
}
@@ -84,7 +88,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
8488
appIsInForeground: true
8589
),
8690
[
87-
.allowBluetooth
91+
.allowBluetooth,
92+
.allowBluetoothA2DP
8893
]
8994
)
9095
}
@@ -97,7 +102,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
97102
appIsInForeground: true
98103
),
99104
[
100-
.allowBluetooth
105+
.allowBluetooth,
106+
.allowBluetoothA2DP
101107
]
102108
)
103109
}
@@ -110,7 +116,8 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
110116
appIsInForeground: false
111117
),
112118
[
113-
.allowBluetooth
119+
.allowBluetooth,
120+
.allowBluetoothA2DP
114121
]
115122
)
116123
}

StreamVideoTests/Utils/AudioSession/Policies/DefaultAudioSessionPolicyTests.swift

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
3939
XCTAssertEqual(
4040
configuration.options,
4141
[
42-
.allowBluetooth
42+
.allowBluetooth,
43+
.allowBluetoothA2DP
4344
]
4445
)
4546
XCTAssertEqual(configuration.overrideOutputAudioPort, .speaker)
@@ -60,7 +61,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
6061
XCTAssertEqual(
6162
configuration.options,
6263
[
63-
.allowBluetooth
64+
.allowBluetooth,
65+
.allowBluetoothA2DP
6466
]
6567
)
6668
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -80,7 +82,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
8082
XCTAssertEqual(
8183
configuration.options,
8284
[
83-
.allowBluetooth
85+
.allowBluetooth,
86+
.allowBluetoothA2DP
8487
]
8588
)
8689
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -101,7 +104,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
101104
XCTAssertEqual(
102105
configuration.options,
103106
[
104-
.allowBluetooth
107+
.allowBluetooth,
108+
.allowBluetoothA2DP
105109
]
106110
)
107111
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -124,7 +128,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
124128
configuration.options,
125129
[
126130
.allowBluetooth,
127-
.defaultToSpeaker
131+
.allowBluetoothA2DP
128132
]
129133
)
130134
XCTAssertEqual(configuration.overrideOutputAudioPort, .speaker)
@@ -145,7 +149,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
145149
XCTAssertEqual(
146150
configuration.options,
147151
[
148-
.allowBluetooth
152+
.allowBluetooth,
153+
.allowBluetoothA2DP
149154
]
150155
)
151156
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -166,7 +171,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
166171
XCTAssertEqual(
167172
configuration.options,
168173
[
169-
.allowBluetooth
174+
.allowBluetooth,
175+
.allowBluetoothA2DP
170176
]
171177
)
172178
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -187,7 +193,8 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
187193
XCTAssertEqual(
188194
configuration.options,
189195
[
190-
.allowBluetooth
196+
.allowBluetooth,
197+
.allowBluetoothA2DP
191198
]
192199
)
193200
XCTAssertNotNil(configuration.overrideOutputAudioPort)

StreamVideoTests/Utils/AudioSession/Policies/OwnCapabilitiesAudioSessionPolicyTests.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
7171
XCTAssertEqual(
7272
configuration.options,
7373
[
74-
.allowBluetooth
74+
.allowBluetooth,
75+
.allowBluetoothA2DP
7576
]
7677
)
7778
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -96,7 +97,8 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
9697
XCTAssertEqual(
9798
configuration.options,
9899
[
99-
.allowBluetooth
100+
.allowBluetooth,
101+
.allowBluetoothA2DP
100102
]
101103
)
102104
XCTAssertEqual(configuration.overrideOutputAudioPort, .speaker)
@@ -163,7 +165,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
163165
configuration.options,
164166
[
165167
.allowBluetooth,
166-
.defaultToSpeaker
168+
.allowBluetoothA2DP
167169
]
168170
)
169171
}
@@ -186,7 +188,8 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
186188
XCTAssertEqual(
187189
configuration.options,
188190
[
189-
.allowBluetooth
191+
.allowBluetooth,
192+
.allowBluetoothA2DP
190193
]
191194
)
192195
}
@@ -210,7 +213,8 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
210213
XCTAssertEqual(
211214
configuration.options,
212215
[
213-
.allowBluetooth
216+
.allowBluetooth,
217+
.allowBluetoothA2DP
214218
]
215219
)
216220
}
@@ -234,7 +238,8 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
234238
XCTAssertEqual(
235239
configuration.options,
236240
[
237-
.allowBluetooth
241+
.allowBluetooth,
242+
.allowBluetoothA2DP
238243
]
239244
)
240245
}

StreamVideoTests/Utils/AudioSession/RTCAudioStore/Effects/RouteChangeEffect_Tests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ final class RouteChangeEffect_Tests: XCTestCase, @unchecked Sendable {
109109
CurrentDevice.currentValue = .init { currentDevice }
110110
await fulfillment { CurrentDevice.currentValue.deviceType == currentDevice }
111111
_ = subject
112+
// we send this one to be the one that will be dropped
113+
callSettingsSubject.send(activeCallSettings.withUpdatedAudioOutputState(false))
112114
callSettingsSubject.send(activeCallSettings)
113115
store.session.category = category.rawValue
114116
store.session.currentRoute = updatedRoute

0 commit comments

Comments
 (0)