diff --git a/.changeset/default-video-degradation-preferences.md b/.changeset/default-video-degradation-preferences.md deleted file mode 100644 index a2ef73564..000000000 --- a/.changeset/default-video-degradation-preferences.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Use source-specific default video degradation preferences: camera tracks default to maintaining framerate, screen share tracks default to maintaining resolution, and other video sources default to balanced. This matches client-sdk-js. Video tracks published with an explicit `source` other than camera or screen share now use balanced rather than WebRTC's implicit choice; set `degradationPreference` on the publish options to override. - -The resolved preference is now also applied to the backup codec's sender. Previously only the primary encoder was configured and the backup encoder let libwebrtc derive a preference implicitly, so the two encoders could adapt along different axes off the same video source. diff --git a/.changeset/development-token-source.md b/.changeset/development-token-source.md deleted file mode 100644 index ecd6dacb7..000000000 --- a/.changeset/development-token-source.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": minor ---- - -Add `TokenSource.fromDevelopmentTokenServer`, the new name for the now-deprecated `TokenSource.fromSandboxTokenServer` (`SandboxTokenServerOptions` is likewise deprecated in favor of `DevelopmentTokenServerOptions`) diff --git a/.changeset/friendly-planes-dance.md b/.changeset/friendly-planes-dance.md deleted file mode 100644 index 4202a4213..000000000 --- a/.changeset/friendly-planes-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Add SDK size documentation to README explaining multi-architecture native libraries and how to measure actual size impact diff --git a/.changeset/sample-apps-token-source.md b/.changeset/sample-apps-token-source.md deleted file mode 100644 index 9e5542f71..000000000 --- a/.changeset/sample-apps-token-source.md +++ /dev/null @@ -1,4 +0,0 @@ ---- ---- - -Use the TokenSource implementations in the sample apps, with a development token server option. Sample-app-only change; no SDK release needed. diff --git a/.changeset/screen-audio-capturer-projection-loss.md b/.changeset/screen-audio-capturer-projection-loss.md deleted file mode 100644 index 2a8470884..000000000 --- a/.changeset/screen-audio-capturer-projection-loss.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fix `ScreenAudioCapturer` crashing the audio thread when its `MediaProjection` is revoked (for example via the system "stop sharing" chip) before the first microphone buffer arrives. `initAudioRecord` now returns false when the `AudioRecord` cannot be created instead of throwing inside WebRTC's audio record thread, where an unhandled exception kills the process; only `startRecording()` was guarded before. `AudioRecord.read` failures are also handled now: the return value was ignored, so once the projection died the buffer's stale contents (the last captured frame) were mixed into the microphone track on every callback, an audible loop until the callback was detached. On a read error the capturer releases its `AudioRecord` and degrades to mic-only audio. - -`releaseAudioResources` is also safe to call while `initAudioRecord` is still running. It runs on the app's thread while init runs on the audio record thread, and it used to observe a null `audioRecord` and do nothing, so the recorder that init went on to publish stayed running until finalization. Leaked recorders hold the playback capture input open, and later capture attempts fail once enough of them accumulate. diff --git a/.changeset/screen-capture-connection-bind-leak.md b/.changeset/screen-capture-connection-bind-leak.md deleted file mode 100644 index b3de0eb7e..000000000 --- a/.changeset/screen-capture-connection-bind-leak.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fix `ScreenCaptureService` staying bound when screen share setup is cancelled. `ScreenCaptureConnection` recorded a binding only once `onServiceConnected` arrived, so a coroutine cancelled before `connect()` returned left the `ServiceConnection` registered, and `BIND_AUTO_CREATE` kept the service alive for the lifetime of the context. `LocalParticipant.setScreenShareEnabled` awaits the bind internally and abandons the track it just created if cancelled, so nothing reached `stop()` on that path. A cancelled connect now releases the binding itself once no caller is left waiting on it, and `stop()` unbinds on the same wider condition. Callers stay tracked until `connect()` actually returns, so a cancellation landing after the service connected but before the caller resumed releases the binding too. This also covers the documented case where `bindService` leaves a connection registered while reporting failure or throwing. - -Two paths that could leave `connect()` suspended forever are fixed as well. `stop()` racing a connect no longer strands the caller, since requesting the bind and registering the waiter now happen under one lock, and a failed `bindService` no longer leaves the state claiming a bind is in flight for the next caller to wait on. diff --git a/.changeset/set-track-enabled-cancellation-cleanup.md b/.changeset/set-track-enabled-cancellation-cleanup.md deleted file mode 100644 index e0ef688aa..000000000 --- a/.changeset/set-track-enabled-cancellation-cleanup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fixed setTrackEnabled leaking track resources when cancelled before the track is published, including the sender negotiated for a failed publish, and LocalScreencastVideoTrack leaking its SurfaceTextureHelper on dispose. diff --git a/.changeset/swift-frogs-drive.md b/.changeset/swift-frogs-drive.md deleted file mode 100644 index 7014c8b0e..000000000 --- a/.changeset/swift-frogs-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fix silent mic race between Room.connect audio publish and setMicrophoneEnabled diff --git a/.changeset/tricky-grapes-compare.md b/.changeset/tricky-grapes-compare.md deleted file mode 100644 index 3dedf82d0..000000000 --- a/.changeset/tricky-grapes-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fix custom RTCConfigurations not picking up server-provided ice servers when user-provided list is empty diff --git a/.changeset/webrtc-init-latch-after-success.md b/.changeset/webrtc-init-latch-after-success.md deleted file mode 100644 index 192bfe1c2..000000000 --- a/.changeset/webrtc-init-latch-after-success.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"client-sdk-android": patch ---- - -Fix: only latch WebRTC initialization after PeerConnectionFactory.initialize succeeds, so a failed native library load stays retryable and surfaces as a catchable exception instead of poisoning the process and crashing on the next LiveKit.create() call. diff --git a/CHANGELOG.md b/CHANGELOG.md index 95184b8ef..a2bb0d460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # client-sdk-android +## 2.28.0 + +### Minor Changes + +- Add `TokenSource.fromDevelopmentTokenServer`, the new name for the now-deprecated `TokenSource.fromSandboxTokenServer` (`SandboxTokenServerOptions` is likewise deprecated in favor of `DevelopmentTokenServerOptions`) - [#994](https://github.com/livekit/client-sdk-android/pull/994) ([@MaxHeimbrock](https://github.com/MaxHeimbrock)) + +### Patch Changes + +- Use source-specific default video degradation preferences: camera tracks default to maintaining framerate, screen share tracks default to maintaining resolution, and other video sources default to balanced. This matches client-sdk-js. Video tracks published with an explicit `source` other than camera or screen share now use balanced rather than WebRTC's implicit choice; set `degradationPreference` on the publish options to override. - [#991](https://github.com/livekit/client-sdk-android/pull/991) ([@xianshijing-lk](https://github.com/xianshijing-lk)) + + The resolved preference is now also applied to the backup codec's sender. Previously only the primary encoder was configured and the backup encoder let libwebrtc derive a preference implicitly, so the two encoders could adapt along different axes off the same video source. + +- Add SDK size documentation to README explaining multi-architecture native libraries and how to measure actual size impact - [#981](https://github.com/livekit/client-sdk-android/pull/981) ([@xianshijing-lk](https://github.com/xianshijing-lk)) + +- Fix `ScreenAudioCapturer` crashing the audio thread when its `MediaProjection` is revoked (for example via the system "stop sharing" chip) before the first microphone buffer arrives. `initAudioRecord` now returns false when the `AudioRecord` cannot be created instead of throwing inside WebRTC's audio record thread, where an unhandled exception kills the process; only `startRecording()` was guarded before. `AudioRecord.read` failures are also handled now: the return value was ignored, so once the projection died the buffer's stale contents (the last captured frame) were mixed into the microphone track on every callback, an audible loop until the callback was detached. On a read error the capturer releases its `AudioRecord` and degrades to mic-only audio. - [#982](https://github.com/livekit/client-sdk-android/pull/982) ([@adrian-niculescu](https://github.com/adrian-niculescu)) + + `releaseAudioResources` is also safe to call while `initAudioRecord` is still running. It runs on the app's thread while init runs on the audio record thread, and it used to observe a null `audioRecord` and do nothing, so the recorder that init went on to publish stayed running until finalization. Leaked recorders hold the playback capture input open, and later capture attempts fail once enough of them accumulate. + +- Fix `ScreenCaptureService` staying bound when screen share setup is cancelled. `ScreenCaptureConnection` recorded a binding only once `onServiceConnected` arrived, so a coroutine cancelled before `connect()` returned left the `ServiceConnection` registered, and `BIND_AUTO_CREATE` kept the service alive for the lifetime of the context. `LocalParticipant.setScreenShareEnabled` awaits the bind internally and abandons the track it just created if cancelled, so nothing reached `stop()` on that path. A cancelled connect now releases the binding itself once no caller is left waiting on it, and `stop()` unbinds on the same wider condition. Callers stay tracked until `connect()` actually returns, so a cancellation landing after the service connected but before the caller resumed releases the binding too. This also covers the documented case where `bindService` leaves a connection registered while reporting failure or throwing. - [#983](https://github.com/livekit/client-sdk-android/pull/983) ([@adrian-niculescu](https://github.com/adrian-niculescu)) + + Two paths that could leave `connect()` suspended forever are fixed as well. `stop()` racing a connect no longer strands the caller, since requesting the bind and registering the waiter now happen under one lock, and a failed `bindService` no longer leaves the state claiming a bind is in flight for the next caller to wait on. + +- Fixed setTrackEnabled leaking track resources when cancelled before the track is published, including the sender negotiated for a failed publish, and LocalScreencastVideoTrack leaking its SurfaceTextureHelper on dispose. - [#986](https://github.com/livekit/client-sdk-android/pull/986) ([@adrian-niculescu](https://github.com/adrian-niculescu)) + +- Fix silent mic race between Room.connect audio publish and setMicrophoneEnabled - [#988](https://github.com/livekit/client-sdk-android/pull/988) ([@MaxHeimbrock](https://github.com/MaxHeimbrock)) + +- Fix custom RTCConfigurations not picking up server-provided ice servers when user-provided list is empty - [#993](https://github.com/livekit/client-sdk-android/pull/993) ([@davidliu](https://github.com/davidliu)) + +- Fix: only latch WebRTC initialization after PeerConnectionFactory.initialize succeeds, so a failed native library load stays retryable and surfaces as a catchable exception instead of poisoning the process and crashing on the next LiveKit.create() call. - [#992](https://github.com/livekit/client-sdk-android/pull/992) ([@shivanshu877](https://github.com/shivanshu877)) + ## 2.27.0 ### Minor Changes diff --git a/README.md b/README.md index fd81df9ce..a5124736a 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ LiveKit for Android is available as a Maven package. ```groovy title="build.gradle" ... dependencies { - def livekit_version = "2.27.0" + def livekit_version = "2.28.0" implementation "io.livekit:livekit-android:$livekit_version" @@ -60,7 +60,7 @@ dependencies { implementation "io.livekit:livekit-android-track-processors:$livekit_version" // Snapshots of the latest development version are available at: - // implementation "io.livekit:livekit-android:2.27.1-SNAPSHOT" + // implementation "io.livekit:livekit-android:2.28.1-SNAPSHOT" } ``` diff --git a/gradle.properties b/gradle.properties index 31667e7d3..f97b4fc8f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ kapt.use.worker.api=true ############################################################### GROUP=io.livekit -VERSION_NAME=2.27.0 +VERSION_NAME=2.28.0 POM_DESCRIPTION=LiveKit Android SDK, WebRTC Rooms diff --git a/package.json b/package.json index 22fec3de5..992325895 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "client-sdk-android", - "version": "2.27.0", + "version": "2.28.0", "repository": "https://github.com/livekit/client-sdk-android.git", "license": "Apache License 2.0", "private": true,