diff --git a/.changeset/default-video-degradation-preferences.md b/.changeset/default-video-degradation-preferences.md deleted file mode 100644 index a2ef7356..00000000 --- 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 ecd6dacb..00000000 --- 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 4202a421..00000000 --- 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 9e5542f7..00000000 --- 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 2a847088..00000000 --- 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 b3de0eb7..00000000 --- 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 e0ef688a..00000000 --- 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 7014c8b0..00000000 --- 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 3dedf82d..00000000 --- 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 192bfe1c..00000000 --- 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 95184b8e..a2bb0d46 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 fd81df9c..a5124736 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 31667e7d..f97b4fc8 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 22fec3de..99232589 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,