diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 5446f7434..f1c765326 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -58,6 +58,9 @@ jobs:
- name: Build and test with Gradle
run: ./gradlew assembleRelease livekit-android-test:testRelease
+ - name: Run Detekt
+ run: ./gradlew livekit-android-sdk:detektRelease
+
- name: Upload AAR
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
@@ -181,7 +184,7 @@ jobs:
if: github.event_name == 'push' && contains(steps.version_name.outputs.version_name,'SNAPSHOT')
run: ./gradlew publishReleasePublicationToMavenRepository
- # Setting up diffuse artifacts
+ # Setting up diffuse artifacts
- name: Setup cache for base source file for diffuse
if: github.event_name == 'push'
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
@@ -189,7 +192,7 @@ jobs:
path: client-sdk-android/diffuse-source-file
key: diffuse-${{ github.sha }}
- # Copy your build artifact under `diffuse-source-file` name which will be saved in cache
+ # Copy your build artifact under `diffuse-source-file` name which will be saved in cache
- name: Copy diffuse source file
run: cp ./livekit-android-sdk/build/outputs/aar/livekit-android-sdk-release.aar diffuse-source-file
if: github.event_name == 'push'
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 70ac3a9f2..4b587e94a 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -4,6 +4,7 @@
+
diff --git a/livekit-android-sdk/detekt-baseline-release.xml b/livekit-android-sdk/detekt-baseline-release.xml
new file mode 100644
index 000000000..ba07c77f6
--- /dev/null
+++ b/livekit-android-sdk/detekt-baseline-release.xml
@@ -0,0 +1,166 @@
+
+
+
+
+ ComplexCondition:LocalParticipant.kt$LocalParticipant$(originalEncoding == null && !simulcast) || width == 0 || height == 0
+ ComplexCondition:PeerConnectionTransport.kt$PeerConnectionTransport$sd.type == SessionDescription.Type.ANSWER && currentOfferId > 0 && offerId > 0 && currentOfferId > offerId
+ ComplexCondition:PreconnectAudioBuffer.kt$sentIdentities.contains(identity) || kind != Participant.Kind.AGENT || state != Participant.State.ACTIVE || identity == null
+ ComplexCondition:RTCEngine.kt$RTCEngine$(connectionState == ConnectionState.CONNECTED || connectionState == ConnectionState.RESUMING) && subscriberConnected && publisherConnected
+ ComplexCondition:RemoteTrackPublication.kt$RemoteTrackPublication$isAutoManaged || !subscribed || quality == videoQuality || track !is VideoTrack
+ ComplexCondition:RemoteTrackPublication.kt$RemoteTrackPublication$isAutoManaged || !subscribed || this.fps == fps || track !is VideoTrack
+ ComplexCondition:RemoteTrackPublication.kt$RemoteTrackPublication$isAutoManaged || !subscribed || videoDimensions == dimensions || track !is VideoTrack
+ ComplexCondition:TextureViewRenderer.kt$TextureViewRenderer$enableFixedSize && rotatedFrameWidth != 0 && rotatedFrameHeight != 0 && width != 0 && height != 0
+ CyclomaticComplexMethod:LocalParticipant.kt$LocalParticipant$@Throws(TrackException.PublishException::class) private suspend fun publishTrackImpl( track: Track, options: TrackPublishOptions, requestConfig: AddTrackRequest.Builder.() -> Unit, encodings: List<RtpParameters.Encoding> = emptyList(), publishListener: PublishListener? = null, ): LocalTrackPublication?
+ CyclomaticComplexMethod:LocalParticipant.kt$LocalParticipant$private fun computeVideoEncodings( isScreenShare: Boolean, dimensions: Track.Dimensions, options: VideoTrackPublishOptions, ): List<RtpParameters.Encoding>
+ CyclomaticComplexMethod:LocalParticipant.kt$LocalParticipant$private suspend fun setTrackEnabled( source: Track.Source, enabled: Boolean, screenCaptureParams: ScreenCaptureParams? = null, ): Boolean
+ CyclomaticComplexMethod:LocalParticipant.kt$LocalParticipant$suspend fun publishVideoTrack( track: LocalVideoTrack, options: VideoTrackPublishOptions = VideoTrackPublishOptions( null, if (track.options.isScreencast) screenShareTrackPublishDefaults else videoTrackPublishDefaults, ), publishListener: PublishListener? = null, ): Boolean
+ CyclomaticComplexMethod:LocalVideoTrack.kt$LocalVideoTrack$private fun setPublishingLayersForSender( sender: RtpSender, qualities: List<LivekitRtc.SubscribedQuality>, )
+ CyclomaticComplexMethod:NetworkInfo.kt$AndroidNetworkInfo$override fun getNetworkType(): NetworkType
+ CyclomaticComplexMethod:PeerConnectionTransport.kt$@VisibleForTesting fun ensureCodecBitrates( media: MediaDescription, trackBitrates: Map<TrackBitrateInfoKey, TrackBitrateInfo>, )
+ CyclomaticComplexMethod:PeerConnectionTransport.kt$PeerConnectionTransport$private suspend fun createAndSendOffer(constraints: MediaConstraints = MediaConstraints())
+ CyclomaticComplexMethod:PreconnectAudioBuffer.kt$@Deprecated("Set AudioTrackPublishDefaults.preconnect = true on the RoomOptions instead.") suspend fun <T> Room.withPreconnectAudio( timeout: Duration = TIMEOUT, topic: String = DEFAULT_TOPIC, onError: ((e: Exception) -> Unit)? = null, operation: suspend () -> T, )
+ CyclomaticComplexMethod:PreconnectAudioBuffer.kt$internal suspend fun Room.startPreconnectAudioJob( roomScope: CoroutineScope, timeout: Duration = TIMEOUT, topic: String = DEFAULT_TOPIC ): () -> Unit
+ CyclomaticComplexMethod:RTCEngine.kt$RTCEngine$@CheckResult internal suspend fun sendData(dataPacket: LivekitModels.DataPacket): Result<Unit>
+ CyclomaticComplexMethod:RTCEngine.kt$RTCEngine$@Synchronized @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) fun reconnect()
+ CyclomaticComplexMethod:RTCEngine.kt$RTCEngine$fun onMessage(dataChannel: DataChannel, buffer: DataChannel.Buffer?)
+ CyclomaticComplexMethod:RTCEngine.kt$RTCEngine$private fun makeRTCConfig( serverResponse: Either<JoinResponse, ReconnectResponse>, connectOptions: ConnectOptions, ): RTCConfiguration
+ CyclomaticComplexMethod:Room.kt$Room$@Throws(Exception::class) suspend fun connect(url: String, token: String, options: ConnectOptions = ConnectOptions())
+ CyclomaticComplexMethod:RoomEvent.kt$fun LivekitModels.DisconnectReason?.convert(): DisconnectReason
+ CyclomaticComplexMethod:SignalClient.kt$SignalClient$private fun handleSignalResponseImpl(ws: WebSocket, response: LivekitRtc.SignalResponse)
+ DoubleMutabilityForCollection:CoroutineSdpObserver.kt$CoroutineSdpObserver$private var pendingCreate = mutableListOf<Continuation<Either<SessionDescription, String?>>>()
+ DoubleMutabilityForCollection:CoroutineSdpObserver.kt$CoroutineSdpObserver$private var pendingSets = mutableListOf<Continuation<Either<Unit, String?>>>()
+ DoubleMutabilityForCollection:E2EEManager.kt$E2EEManager$private var frameCryptors = mutableMapOf<Pair<String, Participant.Identity>, FrameCryptor>()
+ DoubleMutabilityForCollection:PeerConnectionTransport.kt$PeerConnectionTransport$private var trackBitrates = mutableMapOf<TrackBitrateInfoKey, TrackBitrateInfo>()
+ DoubleMutabilityForCollection:RegionUrlProvider.kt$RegionUrlProvider$private var attemptedRegions = mutableSetOf<RegionInfo>()
+ DoubleMutabilityForCollection:Room.kt$Room$private var sidToIdentity = mutableMapOf<Participant.Sid, Participant.Identity>()
+ DoubleMutabilityForCollection:Room.kt$Room$private var transcriptionReceivedTimes = mutableMapOf<String, Long>()
+ EmptyCatchBlock:EndpointTokenSource.kt$EndpointTokenSource.<no name provided>${ }
+ EmptyDefaultConstructor:CachingTokenSource.kt$InMemoryTokenStore$()
+ EmptyDefaultConstructor:LocalScreencastVideoTrack.kt$LocalScreencastVideoTrack.MediaProjectionCallback$()
+ EmptyFunctionBlock:CommunicationWorkaround.kt$NoopCommunicationWorkaround${ }
+ EmptyFunctionBlock:LocalVideoTrack.kt$LocalVideoTrack.<no name provided>.<no name provided>${ }
+ EmptyFunctionBlock:NoAudioHandler.kt$NoAudioHandler${ }
+ EmptyFunctionBlock:PublisherTransportObserver.kt$PublisherTransportObserver${ }
+ EmptyFunctionBlock:RTCEngine.kt$RTCEngine${ }
+ EmptyFunctionBlock:Room.kt$Room${ }
+ EmptyFunctionBlock:SubscriberTransportObserver.kt$SubscriberTransportObserver${ }
+ EmptyFunctionBlock:TextureViewRenderer.kt$TextureViewRenderer${}
+ EmptyFunctionBlock:VideoFrameCapturer.kt$VideoFrameCapturer${ }
+ HasPlatformType:DataChannelManager.kt$DataChannelManager$@get:FlowObservable var state by flowDelegate(dataChannel.state()) private set
+ HasPlatformType:RTCModule.kt$RTCModule$@Provides fun sdpFactory()
+ IgnoredReturnValue:BaseStreamReceiver.kt$BaseStreamReceiver$catch { }
+ InjectDispatcher:CoroutinesModule.kt$CoroutinesModule$Default
+ InjectDispatcher:CoroutinesModule.kt$CoroutinesModule$IO
+ InjectDispatcher:CoroutinesModule.kt$CoroutinesModule$Unconfined
+ InjectDispatcher:NetworkMonitor.kt$NetworkMonitor$IO
+ InstanceOfCheckForException:LocalParticipant.kt$LocalParticipant$e is RpcError
+ LargeClass:LocalParticipant.kt$LocalParticipant : ParticipantOutgoingDataStreamManagerRpcManager
+ LargeClass:RTCEngine.kt$RTCEngine : Listener
+ LargeClass:Room.kt$Room : ListenerParticipantListenerRpcManagerIncomingDataStreamManager
+ LargeClass:SignalClient.kt$SignalClient : WebSocketListener
+ LongMethod:LocalParticipant.kt$LocalParticipant$@Throws(TrackException.PublishException::class) private suspend fun publishTrackImpl( track: Track, options: TrackPublishOptions, requestConfig: AddTrackRequest.Builder.() -> Unit, encodings: List<RtpParameters.Encoding> = emptyList(), publishListener: PublishListener? = null, ): LocalTrackPublication?
+ LongMethod:LocalParticipant.kt$LocalParticipant$override suspend fun performRpc( destinationIdentity: Identity, method: String, payload: String, responseTimeout: Duration, ): String
+ LongMethod:LocalParticipant.kt$LocalParticipant$private fun publishAdditionalCodecForTrack(track: LocalVideoTrack, codec: VideoCodec, options: VideoTrackPublishOptions)
+ LongMethod:LocalParticipant.kt$LocalParticipant$private suspend fun handleIncomingRpcRequest( callerIdentity: Identity, requestId: String, method: String, payload: String, responseTimeout: Duration, version: Int, )
+ LongMethod:LocalParticipant.kt$LocalParticipant$private suspend fun setTrackEnabled( source: Track.Source, enabled: Boolean, screenCaptureParams: ScreenCaptureParams? = null, ): Boolean
+ LongMethod:LocalParticipant.kt$LocalParticipant$suspend fun publishVideoTrack( track: LocalVideoTrack, options: VideoTrackPublishOptions = VideoTrackPublishOptions( null, if (track.options.isScreencast) screenShareTrackPublishDefaults else videoTrackPublishDefaults, ), publishListener: PublishListener? = null, ): Boolean
+ LongMethod:PeerConnectionTransport.kt$PeerConnectionTransport$private suspend fun createAndSendOffer(constraints: MediaConstraints = MediaConstraints())
+ LongMethod:RTCEngine.kt$RTCEngine$@Synchronized @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) fun reconnect()
+ LongMethod:RTCEngine.kt$RTCEngine$fun onMessage(dataChannel: DataChannel, buffer: DataChannel.Buffer?)
+ LongMethod:RTCEngine.kt$RTCEngine$private suspend fun configure(joinResponse: JoinResponse, connectOptions: ConnectOptions)
+ LongMethod:Room.kt$Room$@Synchronized private fun getOrCreateRemoteParticipant( identity: Participant.Identity, info: LivekitModels.ParticipantInfo, ): RemoteParticipant
+ LongMethod:Room.kt$Room$@Throws(Exception::class) suspend fun connect(url: String, token: String, options: ConnectOptions = ConnectOptions())
+ LongMethod:Room.kt$Room$private fun setupLocalParticipantEventHandling()
+ LongMethod:SignalClient.kt$SignalClient$private fun handleSignalResponseImpl(ws: WebSocket, response: LivekitRtc.SignalResponse)
+ LongParameterList:AudioBufferCallbackDispatcher.kt$AudioBufferCallback$(buffer: ByteBuffer, audioFormat: Int, channelCount: Int, sampleRate: Int, bytesRead: Int, captureTimeNs: Long)
+ LongParameterList:KeyProvider.kt$BaseKeyProvider$( ratchetSalt: String = defaultRatchetSalt, uncryptedMagicBytes: String = defaultMagicBytes, ratchetWindowSize: Int = defaultRatchetWindowSize, override var enableSharedKey: Boolean = true, failureTolerance: Int = defaultFailureTolerance, keyRingSize: Int = defaultKeyRingSize, discardFrameWhenCryptorNotReady: Boolean = defaultDiscardFrameWhenCryptorNotReady, keyDerivationAlgorithm: FrameCryptorKeyDerivationAlgorithm = defaultKeyDerivationAlgorithm, )
+ LongParameterList:LiveKitOverrides.kt$AudioOptions$( /** * Override the default output [AudioType]. * * This affects the audio routing and how the audio is handled. Default is [AudioType.CallAudioType]. * * Note: if [audioHandler] is also passed, the values from [audioOutputType] will not be reflected in it, * and must be set yourself. */ val audioOutputType: AudioType? = null, /** * Override the default [AudioHandler]. * * Default is [AudioSwitchHandler]. * * Use [NoAudioHandler] to turn off automatic audio handling or * [AudioFocusHandler] to get simple audio focus handling. */ val audioHandler: AudioHandler? = null, /** * Override the default [AudioDeviceModule]. * * If a non-null value is passed, the library does not * take ownership of the object and will not release it upon [Room.release]. * It is the responsibility of the owner to call [AudioDeviceModule.release] when finished * with it to prevent memory leaks. */ val audioDeviceModule: AudioDeviceModule? = null, /** * Called after default setup to allow for customizations on the [JavaAudioDeviceModule]. * * Not used if [audioDeviceModule] is provided. * * Note: We require setting the [JavaAudioDeviceModule.Builder.setSamplesReadyCallback] to provide * support for [LocalAudioTrack.addSink]. If you wish to grab the audio samples * from the local microphone track, use [LocalAudioTrack.addSink] instead of setting your own * callback. */ val javaAudioDeviceModuleCustomizer: ((builder: JavaAudioDeviceModule.Builder) -> Unit)? = null, /** * On Android 11+, the audio mode will reset itself from [AudioManager.MODE_IN_COMMUNICATION] if * there is no audio playback or capture for 6 seconds (for example when joining a room with * no speakers and the local mic is muted.) This mode reset will cause unexpected * behavior when trying to change the volume, causing it to not properly change the volume. * * We use a workaround by playing a silent audio track to keep the communication mode from * resetting. * * Setting this flag to true will disable the workaround. * * This flag is a no-op when the audio mode is set to anything other than * [AudioManager.MODE_IN_COMMUNICATION]. */ val disableCommunicationModeWorkaround: Boolean = false, /** * Options for processing the mic and incoming audio. */ val audioProcessorOptions: AudioProcessorOptions? = null, /** * Devices may take some time initializing the audio stack for recording. * Prewarming allows starting up the underlying audio recording prior to publish, letting * the audio device be ready immediately when the track is fully published. * * If set to true, disables audio recording prewarming (and the related * [LocalAudioTrack.prewarm] function), and audio resources are only used while the * track is connected and published. Defaults to false. */ val disableAudioPrewarming: Boolean = false, )
+ LongParameterList:LocalAudioTrack.kt$LocalAudioTrack$( @Assisted name: String, @Assisted mediaTrack: livekit.org.webrtc.AudioTrack, @Assisted private val options: LocalAudioTrackOptions, private val audioProcessingController: AudioProcessingController, @Named(InjectionNames.DISPATCHER_DEFAULT) private val dispatcher: CoroutineDispatcher, @Named(InjectionNames.LOCAL_AUDIO_RECORD_SAMPLES_DISPATCHER) private val audioRecordSamplesDispatcher: AudioRecordSamplesDispatcher, @Named(InjectionNames.LOCAL_AUDIO_BUFFER_CALLBACK_DISPATCHER) private val audioBufferCallbackDispatcher: AudioBufferCallbackDispatcher, private val audioRecordPrewarmer: AudioRecordPrewarmer, rtcThreadToken: RTCThreadToken, )
+ LongParameterList:LocalParticipant.kt$LocalParticipant$( @Assisted internal var dynacast: Boolean, internal val engine: RTCEngine, private val peerConnectionFactory: PeerConnectionFactory, private val context: Context, private val eglBase: EglBase, private val screencastVideoTrackFactory: LocalScreencastVideoTrack.Factory, private val videoTrackFactory: LocalVideoTrack.Factory, private val audioTrackFactory: LocalAudioTrack.Factory, private val defaultsManager: DefaultsManager, @Named(InjectionNames.DISPATCHER_DEFAULT) coroutineDispatcher: CoroutineDispatcher, @Named(InjectionNames.SENDER) private val capabilitiesGetter: CapabilitiesGetter, private val outgoingDataStreamManager: OutgoingDataStreamManager, )
+ LongParameterList:LocalParticipant.kt$LocalParticipant$( callerIdentity: Identity, requestId: String, method: String, payload: String, responseTimeout: Duration, version: Int, )
+ LongParameterList:LocalScreencastVideoTrack.kt$LocalScreencastVideoTrack$( @Assisted capturer: VideoCapturer, @Assisted source: VideoSource, @Assisted name: String, @Assisted options: LocalVideoTrackOptions, @Assisted rtcTrack: livekit.org.webrtc.VideoTrack, @Assisted mediaProjectionCallback: MediaProjectionCallback, peerConnectionFactory: PeerConnectionFactory, context: Context, eglBase: EglBase, defaultsManager: DefaultsManager, videoTrackFactory: LocalVideoTrack.Factory, rtcThreadToken: RTCThreadToken, )
+ LongParameterList:LocalScreencastVideoTrack.kt$LocalScreencastVideoTrack.Companion$( mediaProjectionPermissionResultData: Intent, peerConnectionFactory: PeerConnectionFactory, context: Context, name: String, options: LocalVideoTrackOptions, rootEglBase: EglBase, screencastVideoTrackFactory: Factory, videoProcessor: VideoProcessor?, onStop: (Track) -> Unit, )
+ LongParameterList:LocalScreencastVideoTrack.kt$LocalScreencastVideoTrack.Factory$( capturer: VideoCapturer, source: VideoSource, name: String, options: LocalVideoTrackOptions, rtcTrack: livekit.org.webrtc.VideoTrack, mediaProjectionCallback: MediaProjectionCallback, )
+ LongParameterList:LocalVideoTrack.kt$LocalVideoTrack$( @Assisted capturer: VideoCapturer, @Assisted private var source: VideoSource, @Assisted name: String, @Assisted options: LocalVideoTrackOptions, @Assisted rtcTrack: livekit.org.webrtc.VideoTrack, private val peerConnectionFactory: PeerConnectionFactory, private val context: Context, private val eglBase: EglBase, private val defaultsManager: DefaultsManager, private val trackFactory: Factory, /** * If this is assigned, you must ensure that this observer is associated with the [capturer], * as this will be used to receive frames in [addRenderer]. **/ @Assisted private var dispatchObserver: CaptureDispatchObserver? = null, rtcThreadToken: RTCThreadToken, )
+ LongParameterList:LocalVideoTrack.kt$LocalVideoTrack.Companion$( peerConnectionFactory: PeerConnectionFactory, context: Context, name: String, capturer: VideoCapturer, options: LocalVideoTrackOptions = LocalVideoTrackOptions(), rootEglBase: EglBase, trackFactory: Factory, videoProcessor: VideoProcessor? = null, )
+ LongParameterList:LocalVideoTrack.kt$LocalVideoTrack.Companion$( peerConnectionFactory: PeerConnectionFactory, context: Context, name: String, options: LocalVideoTrackOptions, rootEglBase: EglBase, trackFactory: Factory, videoProcessor: VideoProcessor? = null, )
+ LongParameterList:LocalVideoTrack.kt$LocalVideoTrack.Factory$( capturer: VideoCapturer, source: VideoSource, name: String, options: LocalVideoTrackOptions, rtcTrack: livekit.org.webrtc.VideoTrack, dispatchObserver: CaptureDispatchObserver?, )
+ LongParameterList:MixerAudioBufferCallback.kt$MixerAudioBufferCallback$(originalBuffer: ByteBuffer, audioFormat: Int, channelCount: Int, sampleRate: Int, bytesRead: Int, captureTimeNs: Long)
+ LongParameterList:PeerConnectionTransport.kt$PeerConnectionTransport$( @Assisted config: RTCConfiguration, @Assisted pcObserver: PeerConnection.Observer, @Assisted private val listener: Listener?, @Named(InjectionNames.DISPATCHER_IO) private val ioDispatcher: CoroutineDispatcher, connectionFactory: PeerConnectionFactory, private val sdpFactory: SdpFactory, private val rtcThreadToken: RTCThreadToken, )
+ LongParameterList:RTCMetricsManager.kt$( label: MetricLabel, strings: MutableList<String>, samples: List<MetricSample>, identity: Participant.Identity? = null, trackSid: String? = null, rid: String? = null, )
+ LongParameterList:RTCModule.kt$RTCModule$( @Named(InjectionNames.OVERRIDE_AUDIO_DEVICE_MODULE) audioDeviceModuleOverride: AudioDeviceModule?, @Named(InjectionNames.OVERRIDE_JAVA_AUDIO_DEVICE_MODULE_CUSTOMIZER) moduleCustomizer: ((builder: JavaAudioDeviceModule.Builder) -> Unit)?, audioOutputAttributes: AudioAttributes, appContext: Context, closeableManager: CloseableManager, communicationWorkaround: CommunicationWorkaround, @Named(InjectionNames.LOCAL_AUDIO_RECORD_SAMPLES_DISPATCHER) audioRecordSamplesDispatcher: AudioRecordSamplesDispatcher, @Named(InjectionNames.LOCAL_AUDIO_BUFFER_CALLBACK_DISPATCHER) audioBufferCallbackDispatcher: AudioBufferCallbackDispatcher, )
+ LongParameterList:RTCModule.kt$RTCModule$( @Suppress("UNUSED_PARAMETER") @Named(InjectionNames.LIB_WEBRTC_INITIALIZATION) webrtcInitialization: LibWebrtcInitialization, audioDeviceModule: AudioDeviceModule, videoEncoderFactory: VideoEncoderFactory, videoDecoderFactory: VideoDecoderFactory, @Named(InjectionNames.OVERRIDE_PEER_CONNECTION_FACTORY_OPTIONS) peerConnectionFactoryOptions: PeerConnectionFactory.Options?, memoryManager: CloseableManager, audioProcessingFactory: AudioProcessingFactory, )
+ LongParameterList:RTCStatsExt.kt$( trackIdentifier: String, ssrcs: Set<Long?>, codecIds: Set<String?>, localCandidateId: String?, remoteCandidateId: String?, statsMap: Map<String, RTCStats>, )
+ LongParameterList:RemoteParticipant.kt$RemoteParticipant$( mediaTrack: MediaStreamTrack, sid: String, statsGetter: RTCStatsGetter, receiver: RtpReceiver, autoManageVideo: Boolean = false, triesLeft: Int = 20, )
+ LongParameterList:RemoteParticipant.kt$RemoteParticipant$( sid: Sid, identity: Identity? = null, internal val signalClient: SignalClient, private val ioDispatcher: CoroutineDispatcher, defaultDispatcher: CoroutineDispatcher, private val audioTrackFactory: RemoteAudioTrack.Factory, private val videoTrackFactory: RemoteVideoTrack.Factory, )
+ LongParameterList:Room.kt$Room$( @Assisted private val context: Context, internal val engine: RTCEngine, private val eglBase: EglBase, localParticipantFactory: LocalParticipant.Factory, private val defaultsManager: DefaultsManager, @Named(InjectionNames.DISPATCHER_DEFAULT) private val defaultDispatcher: CoroutineDispatcher, @Named(InjectionNames.DISPATCHER_IO) private val ioDispatcher: CoroutineDispatcher, /** * The [AudioHandler] for setting up the audio as need. * * By default, this is an instance of [AudioSwitchHandler]. * * This can be substituted for your own custom implementation through * [LiveKitOverrides.audioOptions] when creating the room with [LiveKit.create]. * * @see [audioSwitchHandler] * @see [AudioSwitchHandler] */ val audioHandler: AudioHandler, private val closeableManager: CloseableManager, private val e2EEManagerFactory: E2EEManager.Factory, private val communicationWorkaround: CommunicationWorkaround, val audioProcessingController: AudioProcessingController, /** * A holder for objects that are used internally within LiveKit. */ val lkObjects: LKObjects, networkCallbackManagerFactory: NetworkCallbackManagerFactory, private val audioDeviceModule: AudioDeviceModule, private val regionUrlProviderFactory: RegionUrlProvider.Factory, private val connectionWarmer: ConnectionWarmer, private val audioRecordPrewarmer: AudioRecordPrewarmer, private val incomingDataStreamManager: IncomingDataStreamManager, private val remoteParticipantFactory: RemoteParticipant.Factory, )
+ MapGetWithNotNullAssertionOperator:LocalParticipant.kt$LocalParticipant$sourcePubLocks[source]!!
+ NestedBlockDepth:ByteStreamSender.kt$@CheckResult suspend fun ByteStreamSender.write(source: Source): Result<Unit>
+ NestedBlockDepth:LocalParticipant.kt$LocalParticipant$@Throws(TrackException.PublishException::class) private suspend fun publishTrackImpl( track: Track, options: TrackPublishOptions, requestConfig: AddTrackRequest.Builder.() -> Unit, encodings: List<RtpParameters.Encoding> = emptyList(), publishListener: PublishListener? = null, ): LocalTrackPublication?
+ NestedBlockDepth:LocalParticipant.kt$LocalParticipant$fun cleanup()
+ NestedBlockDepth:LocalVideoTrack.kt$LocalVideoTrack$internal fun setPublishingCodecs(codecs: List<SubscribedCodec>): List<VideoCodec>
+ NestedBlockDepth:LocalVideoTrack.kt$LocalVideoTrack$private fun setPublishingLayersForSender( sender: RtpSender, qualities: List<LivekitRtc.SubscribedQuality>, )
+ NestedBlockDepth:OutgoingDataStreamManager.kt$OutgoingDataStreamManagerImpl$@CheckResult private suspend fun openStream( info: StreamInfo, destinationIdentities: List<Participant.Identity> = emptyList(), ): Result<Unit>
+ NestedBlockDepth:PeerConnectionTransport.kt$@VisibleForTesting fun ensureCodecBitrates( media: MediaDescription, trackBitrates: Map<TrackBitrateInfoKey, TrackBitrateInfo>, )
+ NestedBlockDepth:RTCEngine.kt$RTCEngine$@CheckResult internal suspend fun sendData(dataPacket: LivekitModels.DataPacket): Result<Unit>
+ NestedBlockDepth:RTCEngine.kt$RTCEngine$private fun makeRTCConfig( serverResponse: Either<JoinResponse, ReconnectResponse>, connectOptions: ConnectOptions, ): RTCConfiguration
+ NestedBlockDepth:Room.kt$Room$override suspend fun onPostReconnect(isFullReconnect: Boolean)
+ NestedBlockDepth:SignalClient.kt$SignalClient$override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?)
+ SwallowedException:EndpointTokenSource.kt$EndpointTokenSource.<no name provided>$e: Exception
+ SwallowedException:FlowExt.kt$e: CancellationException
+ SwallowedException:LocalVideoTrack.kt$LocalVideoTrack$e: Exception
+ SwallowedException:NetworkCallbackManager.kt$NetworkCallbackManagerImpl$e: IllegalArgumentException
+ SwallowedException:RemoteParticipant.kt$RemoteParticipant$e: Exception
+ SwallowedException:TextureViewRenderer.kt$TextureViewRenderer$e: NotFoundException
+ ThrowingExceptionsWithoutMessageOrCause:LKDebugTree.kt$LKDebugTree$Throwable()
+ ThrowingExceptionsWithoutMessageOrCause:SignalClient.kt$SignalClient$Exception()
+ TooManyFunctions:CommunicationWorkaround.kt$CommunicationWorkaroundImpl : CommunicationWorkaround
+ TooManyFunctions:E2EEManager.kt$E2EEManager
+ TooManyFunctions:IncomingDataStreamManager.kt$IncomingDataStreamManagerImpl : IncomingDataStreamManager
+ TooManyFunctions:LKLog.kt$LKLog$Companion
+ TooManyFunctions:LocalParticipant.kt$LocalParticipant : ParticipantOutgoingDataStreamManagerRpcManager
+ TooManyFunctions:LocalVideoTrack.kt$LocalVideoTrack : VideoTrack
+ TooManyFunctions:OverridesModule.kt$OverridesModule
+ TooManyFunctions:Participant.kt$Participant
+ TooManyFunctions:Participant.kt$ParticipantListener
+ TooManyFunctions:PeerConnectionTransport.kt$PeerConnectionTransport
+ TooManyFunctions:PublisherTransportObserver.kt$PublisherTransportObserver : ObserverListenerPeerConnectionStateObservable
+ TooManyFunctions:RTCEngine.kt$RTCEngine : Listener
+ TooManyFunctions:RTCEngine.kt$RTCEngine$Listener
+ TooManyFunctions:RTCMetricsManager.kt$io.livekit.android.room.metrics.RTCMetricsManager.kt
+ TooManyFunctions:RTCModule.kt$RTCModule
+ TooManyFunctions:Room.kt$Room : ListenerParticipantListenerRpcManagerIncomingDataStreamManager
+ TooManyFunctions:SignalClient.kt$SignalClient : WebSocketListener
+ TooManyFunctions:SignalClient.kt$SignalClient$Listener
+ TooManyFunctions:SimulcastVideoEncoderFactoryWrapper.kt$SimulcastVideoEncoderFactoryWrapper$StreamEncoderWrapper : VideoEncoder
+ TooManyFunctions:SubscriberTransportObserver.kt$SubscriberTransportObserver : ObserverPeerConnectionStateObservable
+ TooManyFunctions:TextureViewRenderer.kt$TextureViewRenderer : TextureViewCallbackSurfaceTextureListenerVideoSinkRendererEventsNotifier
+ UnnecessaryNotNullOperator:E2EEManager.kt$E2EEManager$room!!
+ UnnecessaryNotNullOperator:Room.kt$Room$e2eeManager!!
+ UnnecessarySafeCall:E2EEManager.kt$E2EEManager$(publication.track!! as LocalAudioTrack)?.sender
+ UnnecessarySafeCall:E2EEManager.kt$E2EEManager$(publication.track!! as LocalVideoTrack)?.sender
+ UnsafeCallOnNullableType:AudioSwitchHandler.kt$AudioSwitchHandler$thread!!
+ UnsafeCallOnNullableType:CustomAudioProcessingFactory.kt$CustomAudioProcessingFactory.AudioProcessingBridge$buffer!!
+ UnsafeCallOnNullableType:DataPacketBuffer.kt$DataPacketBuffer$item!!
+ UnsafeCallOnNullableType:E2EEManager.kt$E2EEManager$participant.identity!!
+ UnsafeCallOnNullableType:E2EEManager.kt$E2EEManager$publication.track!!
+ UnsafeCallOnNullableType:E2EEManager.kt$E2EEManager$rtpReceiver!!
+ UnsafeCallOnNullableType:E2EEManager.kt$E2EEManager$rtpSender!!
+ UnsafeCallOnNullableType:E2EEManager.kt$E2EEManager$this.room!!
+ UnsafeCallOnNullableType:EncodingUtils.kt$EncodingUtils$encodings.first().scalabilityMode!!
+ UnsafeCallOnNullableType:LocalParticipant.kt$LocalParticipant$options.backupCodec!!
+ UnsafeCallOnNullableType:LocalParticipant.kt$LocalParticipant$sourcePubLocks[source]!!
+ UnsafeCallOnNullableType:LocalParticipant.kt$VideoTrackPublishOptions$backupCodec!!
+ UnsafeCallOnNullableType:LocalScreencastVideoTrack.kt$LocalScreencastVideoTrack.MediaProjectionCallback$track!!
+ UnsafeCallOnNullableType:LocalVideoTrack.kt$LocalVideoTrack$simulcastInfo.sender!!
+ UnsafeCallOnNullableType:PeerConnectionTransport.kt$PeerConnectionTransport$executeBlockingOnRTCThread(rtcThreadToken) { connectionFactory.createPeerConnection( config, pcObserver, ) ?: throw IllegalStateException("peer connection creation failed?") }!!
+ UnsafeCallOnNullableType:RTCEngine.kt$RTCEngine$publisher!!
+ UnsafeCallOnNullableType:RTCEngine.kt$RTCEngine$subscriber!!
+ UnsafeCallOnNullableType:RTCEngine.kt$RTCEngine$url!!
+ UnsafeCallOnNullableType:RTCModule.kt$RTCModule$executeBlockingOnRTCThread(LibWebrtcInitializationThreadToken) { val peerConnectionFactory = PeerConnectionFactory.builder() .setAudioDeviceModule(audioDeviceModule) .setAudioProcessingFactory(audioProcessingFactory) .setVideoEncoderFactory(videoEncoderFactory) .setVideoDecoderFactory(videoDecoderFactory) .apply { if (peerConnectionFactoryOptions != null) { setOptions(peerConnectionFactoryOptions) } } .createPeerConnectionFactory() return@executeBlockingOnRTCThread PeerConnectionFactoryManager(peerConnectionFactory) .apply { memoryManager.registerClosable { executeOnRTCThread(RTCThreadTokenImpl(this)) { dispose() } } } }!!
+ UnsafeCallOnNullableType:Room.kt$Room$e2eeManager!!
+ UnsafeCallOnNullableType:Room.kt$Room$publication.track!!
+ UnsafeCallOnNullableType:SimulcastVideoEncoderFactoryWrapper.kt$SimulcastVideoEncoderFactoryWrapper.StreamEncoderWrapper$streamSettings!!
+ UnsafeCallOnNullableType:TextureViewRenderer.kt$TextureViewRenderer$rendererEvents!!
+
+