Skip to content

Commit deb1e1c

Browse files
📝 Add docstrings to audio_switch_replacement_same_api
Docstrings generation was requested by @PratimMallick. * #1591 (comment) The following files were modified: * `demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/SettingsMenu.kt` * `demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/MediaManager.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioDeviceManager.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioHandler.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioHandlerFactory.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/LegacyAudioDeviceManager.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/ModernAudioDeviceManager.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/StreamAudioDevice.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/StreamAudioManager.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/StreamAudioSwitch.kt` * `stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/StreamAudioSwitchHandler.kt`
1 parent a57c887 commit deb1e1c

File tree

14 files changed

+496
-109
lines changed

14 files changed

+496
-109
lines changed

demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/SettingsMenu.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,31 @@ import io.getstream.video.android.ui.menu.transcriptions.TranscriptionUiStateMan
7272
import io.getstream.video.android.util.filters.SampleAudioFilter
7373
import java.nio.ByteBuffer
7474

75+
/**
76+
* Displays a settings popup for a Call with device, audio, video filter, transcription, and debug controls.
77+
*
78+
* Provides UI and actions to select audio/video devices and codecs, toggle audio usage and filters,
79+
* control noise cancellation and incoming video visibility, manage recordings/transcriptions, and
80+
* perform debug operations (ICE/SFU actions). The popup dismisses via onDismissed.
81+
*
82+
* @param call The active Call instance whose state and actions the menu manipulates.
83+
* @param selectedVideoFilter Index of the currently selected video filter.
84+
* @param showDebugOptions Whether debug-related menu items should be shown.
85+
* @param noiseCancellationFeatureEnabled Whether the noise-cancellation feature is available.
86+
* @param noiseCancellationEnabled Whether noise cancellation is currently enabled.
87+
* @param onDismissed Callback invoked when the menu should be dismissed.
88+
* @param onSelectVideoFilter Callback invoked with the selected filter index.
89+
* @param onShowFeedback Callback invoked to open feedback UI.
90+
* @param onNoiseCancellation Callback invoked to toggle or configure noise cancellation.
91+
* @param selectedIncomingVideoResolution Currently selected preferred incoming video resolution, or null.
92+
* @param onSelectIncomingVideoResolution Callback invoked with a new preferred incoming video resolution or null.
93+
* @param isIncomingVideoEnabled Whether incoming video is enabled.
94+
* @param onToggleIncomingVideoVisibility Callback invoked to show/hide incoming video.
95+
* @param onShowCallStats Callback invoked to display call statistics.
96+
* @param onSelectScaleType Callback invoked to change the remote video scaling type.
97+
* @param closedCaptionUiState UI state for closed captions.
98+
* @param onClosedCaptionsToggle Callback invoked to toggle closed captions.
99+
*/
75100
@OptIn(ExperimentalPermissionsApi::class)
76101
@Composable
77102
internal fun SettingsMenu(
@@ -429,4 +454,4 @@ private fun SettingsMenuPreview() {
429454
),
430455
)
431456
}
432-
}
457+
}

demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ object StreamVideoInitHelper {
216216
).enqueue()
217217
}
218218

219-
/** Sets up and returns the [StreamVideo] required to connect to the API. */
219+
/**
220+
* Builds a configured StreamVideo instance for the provided API key and user.
221+
*
222+
* @return A ready-to-use StreamVideo configured with the given user, token, logging level, call service registry, notification and telecom settings.
223+
*/
220224
@OptIn(ExperimentalStreamVideoApi::class)
221225
private fun initializeStreamVideo(
222226
context: Context,
@@ -338,4 +342,4 @@ object StreamVideoInitHelper {
338342
useInBuiltAudioSwitch = true,
339343
).build()
340344
}
341-
}
345+
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/Call.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,13 @@ public class Call(
13501350
}
13511351
}
13521352

1353+
/**
1354+
* Observes available microphone devices and ensures an appropriate audio input is selected.
1355+
*
1356+
* When a Bluetooth headset becomes available it is selected; otherwise a wired headset is selected
1357+
* if present. If no headset is available, the previously saved non-headset fallback device is
1358+
* restored when available.
1359+
*/
13531360
private fun monitorHeadset() {
13541361
microphone.devices.onEach { availableDevices ->
13551362
logger.d {
@@ -1780,4 +1787,4 @@ public data class CreateCallOptions(
17801787
}
17811788
return memberRequestList
17821789
}
1783-
}
1790+
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/MediaManager.kt

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,11 @@ class MicrophoneManager(
629629
}
630630

631631
/**
632-
* Select a specific device
632+
* Selects the given audio output device and updates related internal state.
633+
*
634+
* Requests the initialized audio handler to switch to `device`, sets the manager's selected device state, updates the speaker manager status when the speakerphone is (de)selected, and records a non-headset fallback device for future use.
635+
*
636+
* @param device The desired `StreamAudioDevice` to select, or `null` to clear selection.
633637
*/
634638
fun select(device: StreamAudioDevice?) {
635639
logger.i { "selecting device $device" }
@@ -719,7 +723,17 @@ class MicrophoneManager(
719723

720724
fun canHandleDeviceSwitch() = audioUsageProvider.invoke() != AudioAttributes.USAGE_MEDIA
721725

722-
// Internal logic
726+
/**
727+
* Initializes audio routing and device handling for the microphone manager.
728+
*
729+
* Sets up the Android AudioManager and, if device switching is supported and not already initialized,
730+
* creates and starts an AudioHandler configured with a device priority that respects `preferSpeaker`.
731+
* Once device information becomes available (or immediately if already set up), the optional
732+
* `onAudioDevicesUpdate` callback is invoked and internal device/selection state is updated.
733+
*
734+
* @param preferSpeaker When true, prioritizes the speakerphone over the earpiece when building the preferred device list.
735+
* @param onAudioDevicesUpdate Optional callback invoked once the available audio devices and current selection have been populated (or immediately if setup was already completed).
736+
*/
723737
internal fun setup(preferSpeaker: Boolean = false, onAudioDevicesUpdate: (() -> Unit)? = null) {
724738
synchronized(this) {
725739
var capturedOnAudioDevicesUpdate = onAudioDevicesUpdate
@@ -790,11 +804,25 @@ class MicrophoneManager(
790804
}
791805
}
792806

807+
/**
808+
* Ensures audio handler setup (initializing it if necessary) and runs the provided action when audio devices update.
809+
*
810+
* @param preferSpeaker If true, prefer speakerphone in the initial device priority when setting up.
811+
* @param actual Action to invoke when the audio devices are updated.
812+
*/
793813
internal fun enforceSetup(preferSpeaker: Boolean = false, actual: () -> Unit) = setup(
794814
preferSpeaker,
795815
onAudioDevicesUpdate = actual,
796816
)
797817

818+
/**
819+
* Invokes the provided block with the initialized `AudioHandler` if available.
820+
*
821+
* If the audio handler has been initialized, the `then` lambda is called with it;
822+
* otherwise the function logs an error indicating setup() must be called first.
823+
*
824+
* @param then Lambda to execute with the initialized `AudioHandler`.
825+
*/
798826
private fun ifAudioHandlerInitialized(then: (audioHandler: AudioHandler) -> Unit) {
799827
if (this::audioHandler.isInitialized) {
800828
then(this.audioHandler)
@@ -1393,4 +1421,4 @@ class MediaManagerImpl(
13931421
}
13941422
}
13951423

1396-
fun MediaStreamTrack.trySetEnabled(enabled: Boolean) = safeCall { setEnabled(enabled) }
1424+
fun MediaStreamTrack.trySetEnabled(enabled: Boolean) = safeCall { setEnabled(enabled) }

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/StreamVideoBuilder.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,17 @@ public class StreamVideoBuilder @JvmOverloads constructor(
179179
}
180180

181181
/**
182-
* Builds the [StreamVideo] client.
182+
* Constructs and initializes a configured StreamVideo client.
183183
*
184-
* @return The [StreamVideo] client.
184+
* Performs validation, sets up logging and time library, initializes notification and connection modules,
185+
* attempts background coordinator connection and location loading, installs the client as the singleton,
186+
* and returns the created client.
185187
*
186-
* @throws RuntimeException If an instance of the client already exists and [ensureSingleInstance] is set to true.
187-
* @throws IllegalArgumentException If [apiKey] is blank.
188-
* @throws IllegalArgumentException If [user] type is [UserType.Authenticated] and the [user] id is blank.
189-
* @throws IllegalArgumentException If [user] type is [UserType.Authenticated] and both [token] and [tokenProvider] are empty.
190-
* @throws ConnectException If the WebSocket connection fails.
188+
* @return The initialized StreamVideo client.
189+
* @throws RuntimeException If an existing StreamVideo instance is present and `ensureSingleInstance` is true.
190+
* @throws IllegalArgumentException If `apiKey` is blank.
191+
* @throws IllegalArgumentException If `token` is blank.
192+
* @throws IllegalArgumentException If `user` is of type `UserType.Authenticated` and the user id is blank.
191193
*/
192194
public fun build(): StreamVideo {
193195
val lifecycle = ProcessLifecycleOwner.get().lifecycle
@@ -365,4 +367,4 @@ internal val tokenRepository = TokenRepository("")
365367
sealed class GEO {
366368
/** Run calls over our global edge network, this is the default and right for most applications */
367369
object GlobalEdgeNetwork : GEO()
368-
}
370+
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioDeviceManager.kt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@ package io.getstream.video.android.core.audio
2323
*/
2424
internal interface AudioDeviceManager {
2525
/**
26-
* Enumerates available audio devices.
27-
*/
26+
* Lists the currently available audio devices.
27+
*
28+
* @return A list of available StreamAudioDevice instances representing detected audio input/output devices.
29+
*/
2830
fun enumerateDevices(): List<StreamAudioDevice>
2931

3032
/**
31-
* Selects an audio device for routing.
32-
* @param device The device to select
33-
* @return true if selection was successful, false otherwise
34-
*/
33+
* Sets the active audio routing device.
34+
*
35+
* @param device The device to make active for audio routing.
36+
* @return `true` if the device was successfully selected, `false` otherwise.
37+
*/
3538
fun selectDevice(device: StreamAudioDevice): Boolean
3639

3740
/**
@@ -40,17 +43,21 @@ internal interface AudioDeviceManager {
4043
fun clearDevice()
4144

4245
/**
43-
* Gets the currently selected device.
44-
*/
46+
* Returns the currently selected audio device.
47+
*
48+
* @return The selected StreamAudioDevice, or `null` if no device is selected.
49+
*/
4550
fun getSelectedDevice(): StreamAudioDevice?
4651

4752
/**
48-
* Starts the device manager (registers listeners, etc.)
49-
*/
53+
* Initializes the device manager and prepares it for use.
54+
*/
5055
fun start()
5156

5257
/**
53-
* Stops the device manager (unregisters listeners, etc.)
54-
*/
58+
* Releases resources and tears down the device manager.
59+
*
60+
* Stops device monitoring, unregisters listeners or observers, and performs any necessary cleanup so the manager is no longer active. The manager must be started again before it can be used after this call.
61+
*/
5562
fun stop()
56-
}
63+
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioHandler.kt

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,22 @@ public interface AudioHandler {
3333
public fun start()
3434

3535
/**
36-
* Called when a room is disconnected.
37-
*/
36+
* Stops audio device management and releases related resources.
37+
*
38+
* Cancels any pending initialization, stops any active audio switch on the main thread,
39+
* and clears internal references so audio handling is fully stopped when a room is disconnected.
40+
*/
3841
public fun stop()
3942

40-
public fun selectDevice(audioDevice: StreamAudioDevice?)
43+
/**
44+
* Selects the given StreamAudioDevice for audio output.
45+
*
46+
* Converts the provided StreamAudioDevice to its underlying Twilio AudioDevice and applies it.
47+
* Passing `null` clears the current selection.
48+
*
49+
* @param audioDevice The StreamAudioDevice to select, or `null` to clear selection.
50+
*/
51+
public fun selectDevice(audioDevice: StreamAudioDevice?)
4152
}
4253

4354
/**
@@ -77,6 +88,12 @@ public class AudioSwitchHandler(
7788
}
7889
}
7990

91+
/**
92+
* Stops and releases the audio switcher, cancelling any pending initialization.
93+
*
94+
* Cancels any pending main-thread runnables related to audio-switch initialization and schedules
95+
* a main-thread task to stop the active AudioSwitch (if any) and clear its reference.
96+
*/
8097
override fun stop() {
8198
logger.d { "[stop] no args" }
8299
mainThreadHandler.removeCallbacksAndMessages(null)
@@ -86,20 +103,32 @@ public class AudioSwitchHandler(
86103
}
87104
}
88105

106+
/**
107+
* Selects the given StreamAudioDevice for audio output by converting it to Twilio's AudioDevice and delegating to the existing selection logic.
108+
*
109+
* @param audioDevice The StreamAudioDevice to select; pass `null` to clear the current selection.
110+
*/
89111
override fun selectDevice(audioDevice: StreamAudioDevice?) {
90112
val twilioDevice = convertStreamDeviceToTwilioDevice(audioDevice)
91113
selectDevice(twilioDevice)
92114
}
93115

116+
/**
117+
* Selects the given Twilio audio device and applies the change.
118+
*
119+
* @param audioDevice The Twilio `AudioDevice` to select; pass `null` to clear the current selection.
120+
*/
94121
public fun selectDevice(audioDevice: AudioDevice?) {
95122
logger.i { "[selectDevice] audioDevice: $audioDevice" }
96123
audioSwitch?.selectDevice(audioDevice)
97124
audioSwitch?.activate()
98125
}
99126

100127
/**
101-
* Converts a StreamAudioDevice to Twilio's AudioDevice.
102-
* Returns null if the input is null.
128+
* Extracts the underlying Twilio `AudioDevice` from a `StreamAudioDevice`.
129+
*
130+
* @param streamDevice The `StreamAudioDevice` to convert, or `null`.
131+
* @return The contained `AudioDevice`, or `null` if `streamDevice` is `null`.
103132
*/
104133
private fun convertStreamDeviceToTwilioDevice(streamDevice: StreamAudioDevice?): AudioDevice? {
105134
return streamDevice?.audio
@@ -127,4 +156,4 @@ public class AudioSwitchHandler(
127156
}
128157
}
129158
}
130-
}
159+
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/audio/AudioHandlerFactory.kt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,18 @@ import com.twilio.audioswitch.AudioDeviceChangeListener as TwilioAudioDeviceChan
2626
*/
2727
internal object AudioHandlerFactory {
2828
/**
29-
* Creates an AudioHandler instance based on the useInBuiltAudioSwitch flag.
29+
* Create an AudioHandler configured either with the in-built StreamAudioSwitch or the Twilio AudioSwitch.
3030
*
31-
* @param context Android context
32-
* @param preferredStreamAudioDeviceList List of preferred audio device types in priority order
33-
* @param twilioAudioDeviceChangeListener Callback for device changes
34-
* @param useInBuiltAudioSwitch If true, uses custom StreamAudioSwitch; if false, uses Twilio AudioSwitch
35-
* @return An AudioHandler instance
31+
* When `useInBuiltAudioSwitch` is true, returns a StreamAudioSwitchHandler using `preferredStreamAudioDeviceList`
32+
* and `streamAudioDeviceChangeListener`. When false, returns an AudioSwitchHandler with `preferredStreamAudioDeviceList`
33+
* mapped to Twilio `AudioDevice` types (unmapped types fall back to speakerphone) and `twilioAudioDeviceChangeListener`.
34+
*
35+
* @param context Android context used to initialize the audio handler.
36+
* @param preferredStreamAudioDeviceList Preferred StreamAudioDevice classes in priority order.
37+
* @param twilioAudioDeviceChangeListener Callback invoked on Twilio audio device changes (used when not using in-built switch).
38+
* @param streamAudioDeviceChangeListener Callback invoked on Stream audio device changes (used when using in-built switch).
39+
* @param useInBuiltAudioSwitch If true, use the in-built StreamAudioSwitch; otherwise use the Twilio AudioSwitch.
40+
* @return An AudioHandler instance configured according to `useInBuiltAudioSwitch` and the provided preferences/listeners.
3641
*/
3742
fun create(
3843
context: Context,
@@ -69,7 +74,10 @@ internal object AudioHandlerFactory {
6974
}
7075

7176
/**
72-
* Converts a Twilio AudioDevice to StreamAudioDevice.
77+
* Map a Twilio `AudioDevice` to the corresponding `StreamAudioDevice`.
78+
*
79+
* @param twilioDevice The Twilio `AudioDevice` to convert.
80+
* @return A `StreamAudioDevice` instance representing the same physical device as the provided Twilio `AudioDevice`.
7381
*/
7482
private fun convertTwilioDeviceToStreamDevice(twilioDevice: AudioDevice): StreamAudioDevice {
7583
return when (twilioDevice) {
@@ -87,4 +95,4 @@ internal object AudioHandlerFactory {
8795
)
8896
}
8997
}
90-
}
98+
}

0 commit comments

Comments
 (0)