Skip to content

Commit 9a399fd

Browse files
Audio optimizations to the thermal state (#880)
1 parent 420ff74 commit 9a399fd

File tree

7 files changed

+107
-66
lines changed

7 files changed

+107
-66
lines changed

DemoApp/Sources/ViewModifiers/MoreControls/DemoMoreControlsViewModifier.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct DemoMoreControlsViewModifier: ViewModifier {
5454

5555
DemoTranscriptionAndClosedCaptionsButtonView(viewModel: viewModel)
5656

57+
DemoMoreThermalStateButtonView()
58+
5759
DemoMoreControlListButtonView(
5860
action: { isStatsPresented = true },
5961
label: "Stats"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// Copyright © 2025 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import StreamVideo
6+
import SwiftUI
7+
8+
struct DemoMoreThermalStateButtonView: View {
9+
10+
@Injected(\.thermalStateObserver) private var thermalStateObserver
11+
@Injected(\.colors) private var colors
12+
@State private var thermalState = ProcessInfo.ThermalState.nominal
13+
14+
var body: some View {
15+
Button {} label: {
16+
Label(
17+
title: { Text(text(for: thermalState)) },
18+
icon: { icon(for: thermalState) }
19+
)
20+
.frame(maxWidth: .infinity)
21+
.padding(.horizontal)
22+
}
23+
.frame(height: 40)
24+
.buttonStyle(.borderless)
25+
.foregroundColor(colors.white)
26+
.background(background(for: thermalState))
27+
.clipShape(Capsule())
28+
.frame(maxWidth: .infinity)
29+
.disabled(true)
30+
.onReceive(thermalStateObserver.statePublisher) { thermalState = $0 }
31+
}
32+
33+
private func text(for thermalState: ProcessInfo.ThermalState) -> String {
34+
switch thermalState {
35+
case .nominal:
36+
return "Nominal"
37+
case .fair:
38+
return "Fair"
39+
case .serious:
40+
return "Serious"
41+
case .critical:
42+
return "Critical"
43+
@unknown default:
44+
return "Unknown"
45+
}
46+
}
47+
48+
@ViewBuilder
49+
private func icon(for thermalState: ProcessInfo.ThermalState) -> some View {
50+
switch thermalState {
51+
case .nominal:
52+
Image(systemName: "thermometer.low")
53+
case .fair:
54+
Image(systemName: "thermometer.medium")
55+
case .serious:
56+
Image(systemName: "thermometer.high")
57+
case .critical:
58+
Image(systemName: "flame")
59+
@unknown default:
60+
Image(systemName: "thermometer.medium.slash")
61+
}
62+
}
63+
64+
@ViewBuilder
65+
private func background(for thermalState: ProcessInfo.ThermalState) -> some View {
66+
switch thermalState {
67+
case .nominal:
68+
Color.blue
69+
case .fair:
70+
Color.green
71+
case .serious:
72+
Color.orange
73+
case .critical:
74+
Color.red
75+
@unknown default:
76+
Color.clear
77+
}
78+
}
79+
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ extension AVAudioSession.CategoryOptions {
1414
appIsInForeground: Bool
1515
) -> AVAudioSession.CategoryOptions {
1616
var result: AVAudioSession.CategoryOptions = [
17-
.allowBluetooth,
18-
.allowBluetoothA2DP,
19-
.allowAirPlay
17+
.allowBluetooth
2018
]
2119

2220
/// - Note:We only add the `defaultToSpeaker` if the following are true:

StreamVideo.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@
363363
408721F12E12741F006A68CB /* DispatchWorkItem+TimerControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408721F02E12741F006A68CB /* DispatchWorkItem+TimerControl.swift */; };
364364
408721F72E127551006A68CB /* TimerPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408721F62E127551006A68CB /* TimerPublisher.swift */; };
365365
408721FA2E127A18006A68CB /* TimerPublisher_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408721F92E127A18006A68CB /* TimerPublisher_Tests.swift */; };
366+
408722392E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408722382E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift */; };
367+
4087223A2E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408722382E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift */; };
366368
408722372E13C91F006A68CB /* AVCaptureDevice.Format+MediaSubType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408722362E13C91F006A68CB /* AVCaptureDevice.Format+MediaSubType.swift */; };
367369
4089378B2C062B17000EEB69 /* StreamUUIDFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4089378A2C062B17000EEB69 /* StreamUUIDFactory.swift */; };
368370
408937912C134305000EEB69 /* View+AlertWithTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408937902C134305000EEB69 /* View+AlertWithTextField.swift */; };
@@ -1938,6 +1940,7 @@
19381940
408721F02E12741F006A68CB /* DispatchWorkItem+TimerControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DispatchWorkItem+TimerControl.swift"; sourceTree = "<group>"; };
19391941
408721F62E127551006A68CB /* TimerPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerPublisher.swift; sourceTree = "<group>"; };
19401942
408721F92E127A18006A68CB /* TimerPublisher_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerPublisher_Tests.swift; sourceTree = "<group>"; };
1943+
408722382E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMoreThermalStateButtonView.swift; sourceTree = "<group>"; };
19411944
408722362E13C91F006A68CB /* AVCaptureDevice.Format+MediaSubType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVCaptureDevice.Format+MediaSubType.swift"; sourceTree = "<group>"; };
19421945
4089378A2C062B17000EEB69 /* StreamUUIDFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamUUIDFactory.swift; sourceTree = "<group>"; };
19431946
408937902C134305000EEB69 /* View+AlertWithTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+AlertWithTextField.swift"; sourceTree = "<group>"; };
@@ -4112,6 +4115,7 @@
41124115
409145F12B68FEF0007F3C17 /* MoreControls */ = {
41134116
isa = PBXGroup;
41144117
children = (
4118+
408722382E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift */,
41154119
40BBC47A2C6227DF002AEF92 /* Extensions */,
41164120
409145F22B68FEF0007F3C17 /* DemoMoreControlsViewModifier.swift */,
41174121
40BBC4782C6227DC002AEF92 /* DemoNoiseCancellationButtonView.swift */,
@@ -7467,6 +7471,7 @@
74677471
409146062B68FF4B007F3C17 /* DemoControls.swift in Sources */,
74687472
4030E5A22A9DF6B6003E8CBA /* Router.swift in Sources */,
74697473
847B47B52A249E7E000714CE /* Examples.swift in Sources */,
7474+
408722392E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift in Sources */,
74707475
40F445F72A9E2AAC004BE3DA /* ReactionsViewModifier.swift in Sources */,
74717476
409145FE2B68FEF0007F3C17 /* DemoVideoCallParticipantModifier.swift in Sources */,
74727477
4093861F2AA0A21800FF5AF4 /* MemoryLogViewer.swift in Sources */,
@@ -7600,6 +7605,7 @@
76007605
849322612908385C0013C029 /* HomeViewController.swift in Sources */,
76017606
40AB35622B738C8100E465CC /* CustomCallView.swift in Sources */,
76027607
40AB35452B738C4100E465CC /* DemoMoreControlListButtonView.swift in Sources */,
7608+
4087223A2E13CD9D006A68CB /* DemoMoreThermalStateButtonView.swift in Sources */,
76037609
40B713692A275F1400D1FE67 /* AppState.swift in Sources */,
76047610
409D2A532D88704D006A55EF /* DemoBroadcastMoreControlsListButtonView.swift in Sources */,
76057611
40AB353C2B738B5700E465CC /* DemoSnapshotViewModel.swift in Sources */,

StreamVideoTests/Utils/AudioSession/Extensions/AVAudioSessionCategoryOptions_Tests.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
1818
appIsInForeground: false
1919
),
2020
[
21-
.allowBluetooth,
22-
.allowBluetoothA2DP,
23-
.allowAirPlay
21+
.allowBluetooth
2422
]
2523
)
2624
}
@@ -33,9 +31,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
3331
appIsInForeground: false
3432
),
3533
[
36-
.allowBluetooth,
37-
.allowBluetoothA2DP,
38-
.allowAirPlay
34+
.allowBluetooth
3935
]
4036
)
4137
}
@@ -48,9 +44,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
4844
appIsInForeground: false
4945
),
5046
[
51-
.allowBluetooth,
52-
.allowBluetoothA2DP,
53-
.allowAirPlay
47+
.allowBluetooth
5448
]
5549
)
5650
}
@@ -63,9 +57,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
6357
appIsInForeground: true
6458
),
6559
[
66-
.allowBluetooth,
67-
.allowBluetoothA2DP,
68-
.allowAirPlay
60+
.allowBluetooth
6961
]
7062
)
7163
}
@@ -79,8 +71,6 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
7971
),
8072
[
8173
.allowBluetooth,
82-
.allowBluetoothA2DP,
83-
.allowAirPlay,
8474
.defaultToSpeaker
8575
]
8676
)
@@ -94,9 +84,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
9484
appIsInForeground: true
9585
),
9686
[
97-
.allowBluetooth,
98-
.allowBluetoothA2DP,
99-
.allowAirPlay
87+
.allowBluetooth
10088
]
10189
)
10290
}
@@ -109,9 +97,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
10997
appIsInForeground: true
11098
),
11199
[
112-
.allowBluetooth,
113-
.allowBluetoothA2DP,
114-
.allowAirPlay
100+
.allowBluetooth
115101
]
116102
)
117103
}
@@ -124,9 +110,7 @@ final class AVAudioSessionCategoryOptionsTests: XCTestCase, @unchecked Sendable
124110
appIsInForeground: false
125111
),
126112
[
127-
.allowBluetooth,
128-
.allowBluetoothA2DP,
129-
.allowAirPlay
113+
.allowBluetooth
130114
]
131115
)
132116
}

StreamVideoTests/Utils/AudioSession/Policies/DefaultAudioSessionPolicyTests.swift

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
3939
XCTAssertEqual(
4040
configuration.options,
4141
[
42-
.allowBluetooth,
43-
.allowBluetoothA2DP,
44-
.allowAirPlay
42+
.allowBluetooth
4543
]
4644
)
4745
XCTAssertEqual(configuration.overrideOutputAudioPort, .speaker)
@@ -62,9 +60,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
6260
XCTAssertEqual(
6361
configuration.options,
6462
[
65-
.allowBluetooth,
66-
.allowBluetoothA2DP,
67-
.allowAirPlay
63+
.allowBluetooth
6864
]
6965
)
7066
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -84,9 +80,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
8480
XCTAssertEqual(
8581
configuration.options,
8682
[
87-
.allowBluetooth,
88-
.allowBluetoothA2DP,
89-
.allowAirPlay
83+
.allowBluetooth
9084
]
9185
)
9286
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -107,9 +101,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
107101
XCTAssertEqual(
108102
configuration.options,
109103
[
110-
.allowBluetooth,
111-
.allowBluetoothA2DP,
112-
.allowAirPlay
104+
.allowBluetooth
113105
]
114106
)
115107
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -132,8 +124,6 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
132124
configuration.options,
133125
[
134126
.allowBluetooth,
135-
.allowBluetoothA2DP,
136-
.allowAirPlay,
137127
.defaultToSpeaker
138128
]
139129
)
@@ -155,9 +145,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
155145
XCTAssertEqual(
156146
configuration.options,
157147
[
158-
.allowBluetooth,
159-
.allowBluetoothA2DP,
160-
.allowAirPlay
148+
.allowBluetooth
161149
]
162150
)
163151
XCTAssertNotNil(configuration.overrideOutputAudioPort)
@@ -178,9 +166,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
178166
XCTAssertEqual(
179167
configuration.options,
180168
[
181-
.allowBluetooth,
182-
.allowBluetoothA2DP,
183-
.allowAirPlay
169+
.allowBluetooth
184170
]
185171
)
186172
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -201,9 +187,7 @@ final class DefaultAudioSessionPolicyTests: XCTestCase, @unchecked Sendable {
201187
XCTAssertEqual(
202188
configuration.options,
203189
[
204-
.allowBluetooth,
205-
.allowBluetoothA2DP,
206-
.allowAirPlay
190+
.allowBluetooth
207191
]
208192
)
209193
XCTAssertNotNil(configuration.overrideOutputAudioPort)

StreamVideoTests/Utils/AudioSession/Policies/OwnCapabilitiesAudioSessionPolicyTests.swift

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
7171
XCTAssertEqual(
7272
configuration.options,
7373
[
74-
.allowBluetooth,
75-
.allowBluetoothA2DP,
76-
.allowAirPlay
74+
.allowBluetooth
7775
]
7876
)
7977
XCTAssertEqual(configuration.overrideOutputAudioPort, AVAudioSession.PortOverride.none)
@@ -98,9 +96,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
9896
XCTAssertEqual(
9997
configuration.options,
10098
[
101-
.allowBluetooth,
102-
.allowBluetoothA2DP,
103-
.allowAirPlay
99+
.allowBluetooth
104100
]
105101
)
106102
XCTAssertEqual(configuration.overrideOutputAudioPort, .speaker)
@@ -184,8 +180,6 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
184180
configuration.options,
185181
[
186182
.allowBluetooth,
187-
.allowBluetoothA2DP,
188-
.allowAirPlay,
189183
.defaultToSpeaker
190184
]
191185
)
@@ -209,9 +203,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
209203
XCTAssertEqual(
210204
configuration.options,
211205
[
212-
.allowBluetooth,
213-
.allowBluetoothA2DP,
214-
.allowAirPlay
206+
.allowBluetooth
215207
]
216208
)
217209
}
@@ -235,9 +227,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
235227
XCTAssertEqual(
236228
configuration.options,
237229
[
238-
.allowBluetooth,
239-
.allowBluetoothA2DP,
240-
.allowAirPlay
230+
.allowBluetooth
241231
]
242232
)
243233
}
@@ -261,9 +251,7 @@ final class OwnCapabilitiesAudioSessionPolicyTests: XCTestCase, @unchecked Senda
261251
XCTAssertEqual(
262252
configuration.options,
263253
[
264-
.allowBluetooth,
265-
.allowBluetoothA2DP,
266-
.allowAirPlay
254+
.allowBluetooth
267255
]
268256
)
269257
}

0 commit comments

Comments
 (0)