Get Rust SDK Android Example working#859
Conversation
📝 WalkthroughWalkthroughAdds a LiveKit audio capture/playback pipeline to the mobile example: Rust core with JNI/FFI, Android Kotlin App wrappers, MediaManager audio I/O, Compose UI, Android build/tooling updates, new permissions, dependency additions, and IDE/gitignore adjustments. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as User
participant Activity as MainActivity
participant App as Kotlin App
participant JNI as JNI Bridge
participant Rust as Rust Core
participant LiveKit as LiveKit Server
User->>Activity: Tap "Connect" (URL, Token)
Activity->>App: connect(url, token)
App->>JNI: connectNative(url, token)
JNI->>Rust: livekit_connect(url, token)
Rust->>LiveKit: Connect & publish local audio
LiveKit-->>Rust: room events / remote tracks
Rust-->>JNI: status/event callbacks
JNI-->>App: connected status
App-->>Activity: update UI
sequenceDiagram
autonumber
participant Mic as AudioRecord
participant MM as MediaManager
participant App as Kotlin App
participant JNI as JNI Bridge
participant Rust as Rust Core
participant Spk as AudioTrack
Mic->>MM: Capture PCM frames
MM->>App: pushAudio(samples)
App->>JNI: pushAudioNative(samples)
JNI->>Rust: push_audio_capture(samples)
loop Playback cycle
Rust-->>JNI: pull_audio_playback(buffer)
JNI-->>App: pullAudioNative(buffer)
App-->>MM: pullAudio(buffer)
MM-->>Spk: Write PCM to speaker
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🔇 Additional comments (5)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
examples/mobile/src/lib.rs (1)
401-406:⚠️ Potential issue | 🟠 MajorGuard FFI inputs to avoid UB/panics.
Line 401-405 assumes non-null UTF‑8; invalid pointers/UTF‑8 will panic or cause UB.
🛠️ Suggested fix
#[no_mangle] pub extern "C" fn livekit_connect(url: *const c_char, token: *const c_char) { - let (url, token) = unsafe { - let url = CStr::from_ptr(url).to_str().unwrap().to_owned(); - let token = CStr::from_ptr(token).to_str().unwrap().to_owned(); - (url, token) - }; + if url.is_null() || token.is_null() { + return; + } + let url = unsafe { CStr::from_ptr(url) }; + let token = unsafe { CStr::from_ptr(token) }; + let (url, token) = match (url.to_str(), token.to_str()) { + (Ok(u), Ok(t)) => (u.to_owned(), t.to_owned()), + _ => return, + }; super::livekit_connect(url, token); }
🤖 Fix all issues with AI agents
In `@examples/mobile/android/.idea/compiler.xml`:
- Line 4: The compiler.xml currently sets <bytecodeTargetLevel target="21" />
which mismatches build.gradle's Java 17 settings (sourceCompatibility,
targetCompatibility, jvmTarget); fix by making the two consistent—either change
the bytecodeTargetLevel value in compiler.xml to 17 to match build.gradle, or
update build.gradle's sourceCompatibility/targetCompatibility/jvmTarget to 21 if
Java 21 is intended—ensure you update the specific symbol <bytecodeTargetLevel
target="..."/> and the sourceCompatibility/targetCompatibility/jvmTarget entries
so IDE and Gradle targets align.
In `@examples/mobile/android/.idea/deploymentTargetSelector.xml`:
- Line 10: Remove the hardcoded physical device serial entry from the committed
config: delete or replace the <DeviceId ... identifier="serial=R3CW4047CGT" />
line (the DeviceId element containing the serial value "R3CW4047CGT") so no
personal device identifiers are tracked, and add
examples/mobile/android/.idea/deploymentTargetSelector.xml to .gitignore (or
remove the .idea file from repo) to prevent committing machine-specific
IDE/device configs going forward.
In
`@examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt`:
- Around line 109-115: The code currently sets isConnected.value = true and
statusMessage.value = "Connected to room" inside a
Handler(mainLooper).postDelayed(..., 1000), which marks the app connected after
a fixed delay; remove that fixed-delay logic and instead update isConnected and
statusMessage from the actual connection-success callback/event coming from the
native layer (or the LiveKit connection listener) — subscribe to the
room/connection success callback provided by your native binding, call
isConnected.value = true, statusMessage.value = "Connected to room" and
Log.i(TAG, ...) only when that callback fires, and handle connection failure by
setting isConnected false and updating statusMessage accordingly (use the same
identifiers: isConnected, statusMessage, TAG, and replace the
Handler(mainLooper).postDelayed block).
- Around line 35-41: The companion object in MainActivity currently hardcodes a
sensitive JWT in DEFAULT_TOKEN; remove the real token and replace it with a
non-secret placeholder (e.g., "REPLACE_WITH_TOKEN") and update code that reads
DEFAULT_TOKEN to instead load the token at runtime (from secure storage,
BuildConfig field, Intent extras, environment/config, or user input).
Specifically, edit the companion object constant DEFAULT_TOKEN and ensure any
code paths using DEFAULT_TOKEN (in MainActivity) can accept a runtime-supplied
value so secrets are not committed to source control.
In
`@examples/mobile/android/app/src/main/java/io/livekit/rustexample/MediaManager.kt`:
- Around line 240-244: startAll() may leave one audio component running when the
other fails; make it atomic by rolling back any started component on failure.
Call startMicrophone() then startSpeaker(); if startSpeaker() fails but
startMicrophone() returned true, call stopMicrophone() before returning false
(and symmetrically if you call startSpeaker() first). Use startAll(),
startMicrophone(), startSpeaker(), stopMicrophone(), and stopSpeaker() to
implement this rollback and ensure the method returns true only when both starts
succeed.
In `@examples/mobile/android/gradle/wrapper/gradle-wrapper.properties`:
- Line 3: The example project is pinning a pre-release Gradle distribution
("distributionUrl" set to gradle-9.0-milestone-1) which can cause unstable
builds; update the distributionUrl value to use the latest stable Gradle release
(replace "gradle-9.0-milestone-1" with "gradle-9.3.1") so the wrapper points to
the stable bin distribution URL instead of the milestone build.
In `@examples/mobile/src/lib.rs`:
- Around line 112-135: The CI failed rustfmt; run cargo fmt to reformat the
affected lines around the LocalAudioTrack::create_audio_track call and the
room.local_participant().publish_track await chain (the block that constructs
TrackPublishOptions and calls publish_track on LocalTrack::Audio). Re-run
rustfmt/cargo fmt and commit the resulting formatting changes so the
create_audio_track, TrackPublishOptions { ..Default::default() }, and
publish_track(...).await lines conform to the project’s formatter.
- Around line 71-74: The log in function livekit_connect currently prints the
full token (log::info!("Connecting to {} with token {}", url, token)); change
this to avoid leaking credentials by redacting or masking the token before
logging — e.g., log only a safe substring or token length (mask middle
characters) or remove the token from the message entirely; update the log::info
call in livekit_connect to use the masked_token representation instead of the
raw token.
- Around line 466-474: The JNI string conversions in
Java_io_livekit_rustexample_App_connectNative currently call
env.get_string(...).unwrap(), which will panic on JNI errors and cross the FFI
boundary; change this to safely handle the Result by matching or using if let to
detect errors from env.get_string for both url and token, log or report the JNI
error (rather than panicking), and return early from
Java_io_livekit_rustexample_App_connectNative when conversion fails so no panic
crosses FFI; update references to the converted values only after successful
conversion.
🧹 Nitpick comments (2)
examples/mobile/android/.idea/AndroidProjectSystem.xml (1)
1-6: Consider whether.idea/files should be committed.IDE-specific configuration files under
.idea/can cause issues when team members use different IDE versions or configurations. Some files (like this one) are benign, but others in this PR contain local paths or machine-specific settings.Common practice is to either:
- Exclude most
.idea/files via.gitignore(exceptcodeStyles/if team shares formatting)- Or commit them all for IDE consistency across the team
examples/mobile/android/.idea/misc.xml (1)
1-10: Consider excluding.ideafiles from version control.IDE configuration files like
misc.xmlcontain local machine settings (JDK paths, project-specific IDE preferences) that may vary between developers. These files are typically added to.gitignoreto avoid unnecessary merge conflicts and to prevent enforcing specific IDE configurations on contributors.If the intent is to provide a ready-to-use example project, this is acceptable, but consider documenting the JDK 21 requirement in a README instead.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
examples/mobile/android/app/libs/libwebrtc.jaris excluded by!**/*.jarexamples/mobile/android/app/src/main/jniLibs/arm64-v8a/libmobile.sois excluded by!**/*.soexamples/mobile/android/gradle/wrapper/gradle-wrapper.jaris excluded by!**/*.jar
📒 Files selected for processing (21)
examples/mobile/Cargo.tomlexamples/mobile/android/.idea/AndroidProjectSystem.xmlexamples/mobile/android/.idea/codeStyles/Project.xmlexamples/mobile/android/.idea/codeStyles/codeStyleConfig.xmlexamples/mobile/android/.idea/compiler.xmlexamples/mobile/android/.idea/deploymentTargetSelector.xmlexamples/mobile/android/.idea/gradle.xmlexamples/mobile/android/.idea/migrations.xmlexamples/mobile/android/.idea/misc.xmlexamples/mobile/android/.idea/runConfigurations.xmlexamples/mobile/android/.idea/vcs.xmlexamples/mobile/android/app/build.gradleexamples/mobile/android/app/src/main/AndroidManifest.xmlexamples/mobile/android/app/src/main/java/io/livekit/rustexample/App.ktexamples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.ktexamples/mobile/android/app/src/main/java/io/livekit/rustexample/MediaManager.ktexamples/mobile/android/build.gradleexamples/mobile/android/gradle/wrapper/gradle-wrapper.propertiesexamples/mobile/android/gradlewexamples/mobile/android/gradlew.batexamples/mobile/src/lib.rs
🧰 Additional context used
🧬 Code graph analysis (1)
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt (1)
examples/mobile/android/app/src/main/java/io/livekit/rustexample/ui/theme/Theme.kt (1)
RustexampleTheme(40-70)
🪛 Blinter (1.0.102)
examples/mobile/android/gradlew.bat
[error] 88-88: Complex quote escaping error. Explanation: Complex quote patterns may not be handled correctly by the command interpreter. Recommendation: Use triple-quote pattern """text""" for quotes within quoted strings, or escape properly with variables. Context: Complex quote escaping detected
(E028)
🪛 GitHub Actions: Rust Formatting
examples/mobile/src/lib.rs
[error] 117-117: Rustfmt diff detected at line 117. Run 'cargo fmt' to apply formatting changes.
[error] 127-127: Rustfmt diff detected at line 127. Run 'cargo fmt' to apply formatting changes.
🪛 Gitleaks (8.30.0)
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt
[high] 40-40: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.
(jwt)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Test (x86_64-apple-darwin)
- GitHub Check: Test (x86_64-unknown-linux-gnu)
- GitHub Check: Test (x86_64-pc-windows-msvc)
🔇 Additional comments (16)
examples/mobile/android/gradle/wrapper/gradle-wrapper.properties (1)
4-5: LGTM!Adding
networkTimeoutandvalidateDistributionUrlare sensible defaults for more robust wrapper behavior.examples/mobile/android/.idea/migrations.xml (1)
1-10: LGTM!Standard Android Studio migration configuration using portable
$PROJECT_DIR$reference.examples/mobile/android/.idea/gradle.xml (1)
3-9: LGTM!The Gradle configuration updates use portable references (
#GRADLE_LOCAL_JAVA_HOME) and theCHOOSE_PER_TESTrunner provides flexibility for test execution.examples/mobile/android/.idea/vcs.xml (1)
5-6: LGTM!VCS mappings for submodule directories using portable
$PROJECT_DIR$references.examples/mobile/android/.idea/codeStyles/codeStyleConfig.xml (1)
1-5: LGTM!Enabling per-project code style settings ensures consistent formatting across team members.
examples/mobile/Cargo.toml (1)
12-13: LGTM!The
futuresandparking_lotdependencies are well-established crates appropriate for async audio I/O and efficient synchronization in the LiveKit integration.examples/mobile/android/.idea/runConfigurations.xml (1)
1-17: Standard IDE configuration.This suppresses unwanted run configuration suggestions. Same consideration applies as with other
.ideafiles regarding version control inclusion.examples/mobile/android/app/build.gradle (1)
8-8: LGTM!The build configuration updates are well-aligned:
- SDK 34 is the current stable target
- Java 17 compatibility with matching
jvmTarget- Kotlin compiler extension 1.5.8 is compatible with Kotlin 1.9.22
- Dependency versions are recent and consistent
Also applies to: 13-13, 29-34, 40-40, 51-55, 63-63
examples/mobile/android/build.gradle (1)
3-5: LGTM!Plugin version updates are consistent with the app-level build configuration and align with modern Android tooling.
examples/mobile/android/gradlew.bat (3)
16-17: LGTM on license header addition.Adding the SPDX license identifier is a good practice for license clarity.
46-53: Improved error handling.The changes from
==toequfor numeric comparisons (ERRORLEVEL) and redirecting errors to stderr (1>&2) follow Windows batch best practices.Also applies to: 62-66, 81-81
86-89: The original pattern on line 88 is correct; the suggested refactor would change behavior incorrectly.The pattern
if not ""=="%GRADLE_EXIT_CONSOLE%"is a standard, idiomatic Windows batch check for non-empty strings and is documented as a best practice. The suggested alternativeif defined GRADLE_EXIT_CONSOLEis not equivalent: it checks whether the variable is defined (exists), whereas the original checks whether it is non-empty. Usingif definedwould execute the exit regardless of whetherGRADLE_EXIT_CONSOLEis set to an empty value, changing the script's intended behavior. No changes needed on line 88.Likely an incorrect or invalid review comment.
examples/mobile/android/.idea/codeStyles/Project.xml (1)
1-123: LGTM: Project-level code style config is consistent.No issues spotted in this IDE-only configuration.
examples/mobile/android/gradlew (1)
1-251: LGTM: POSIX wrapper update looks standard.No issues found.
examples/mobile/android/app/src/main/AndroidManifest.xml (1)
5-7: LGTM: audio permissions added.Looks appropriate for microphone + audio output use.
examples/mobile/android/app/src/main/java/io/livekit/rustexample/App.kt (1)
1-90: LGTM: native availability guard and API surface look good.No issues found.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt
Show resolved
Hide resolved
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt
Show resolved
Hide resolved
| fun startAll(): Boolean { | ||
| val micStarted = startMicrophone() | ||
| val speakerStarted = startSpeaker() | ||
| return micStarted && speakerStarted | ||
| } |
There was a problem hiding this comment.
Rollback partial audio startup on failure.
startAll() can return false while leaving mic or speaker running (Line 240-244). That’s a privacy/UX risk.
🛠️ Suggested fix
fun startAll(): Boolean {
val micStarted = startMicrophone()
val speakerStarted = startSpeaker()
+ if (!micStarted || !speakerStarted) {
+ if (micStarted) stopMicrophone()
+ if (speakerStarted) stopSpeaker()
+ }
return micStarted && speakerStarted
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fun startAll(): Boolean { | |
| val micStarted = startMicrophone() | |
| val speakerStarted = startSpeaker() | |
| return micStarted && speakerStarted | |
| } | |
| fun startAll(): Boolean { | |
| val micStarted = startMicrophone() | |
| val speakerStarted = startSpeaker() | |
| if (!micStarted || !speakerStarted) { | |
| if (micStarted) stopMicrophone() | |
| if (speakerStarted) stopSpeaker() | |
| } | |
| return micStarted && speakerStarted | |
| } |
🤖 Prompt for AI Agents
In
`@examples/mobile/android/app/src/main/java/io/livekit/rustexample/MediaManager.kt`
around lines 240 - 244, startAll() may leave one audio component running when
the other fails; make it atomic by rolling back any started component on
failure. Call startMicrophone() then startSpeaker(); if startSpeaker() fails but
startMicrophone() returned true, call stopMicrophone() before returning false
(and symmetrically if you call startSpeaker() first). Use startAll(),
startMicrophone(), startSpeaker(), stopMicrophone(), and stopSpeaker() to
implement this rollback and ensure the method returns true only when both starts
succeed.
examples/mobile/android/gradle/wrapper/gradle-wrapper.properties
Outdated
Show resolved
Hide resolved
| /// Connect to a LiveKit room and set up audio handling | ||
| pub fn livekit_connect(url: String, token: String) { | ||
| log::info!("Connecting to {} with token {}", url, token); | ||
|
|
There was a problem hiding this comment.
Redact access tokens from logs.
Line 73 logs the full token, which can leak credentials via logs.
🛠️ Suggested fix
- log::info!("Connecting to {} with token {}", url, token);
+ log::info!("Connecting to {}", url);
+ log::debug!("LiveKit token length: {}", token.len());🤖 Prompt for AI Agents
In `@examples/mobile/src/lib.rs` around lines 71 - 74, The log in function
livekit_connect currently prints the full token (log::info!("Connecting to {}
with token {}", url, token)); change this to avoid leaking credentials by
redacting or masking the token before logging — e.g., log only a safe substring
or token length (mask middle characters) or remove the token from the message
entirely; update the log::info call in livekit_connect to use the masked_token
representation instead of the raw token.
| pub extern "C" fn Java_io_livekit_rustexample_App_connectNative( | ||
| mut env: JNIEnv, | ||
| _: JClass, | ||
| url: JString, | ||
| token: JString, | ||
| ) { | ||
| let url: String = env.get_string(&url).unwrap().into(); | ||
| let token: String = env.get_string(&token).unwrap().into(); | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and read the relevant section
if [ -f "examples/mobile/src/lib.rs" ]; then
echo "=== File exists, reading lines 466-480 ==="
sed -n '466,480p' examples/mobile/src/lib.rs
else
echo "File not found, listing examples directory structure"
find examples -type f -name "*.rs" | head -20
fiRepository: livekit/rust-sdks
Length of output: 533
🏁 Script executed:
# Search for other JNI get_string usage patterns in the file
rg "get_string" examples/mobile/src/lib.rs -A 2 -B 2Repository: livekit/rust-sdks
Length of output: 269
🏁 Script executed:
# Check if there's error handling pattern for JNI errors in the file
rg "unwrap|expect|match.*Err|log::error" examples/mobile/src/lib.rs | head -20Repository: livekit/rust-sdks
Length of output: 933
Avoid panics on invalid JNI strings.
Lines 472-473 unwrap get_string(...) results; JNI errors will panic across the FFI boundary causing undefined behavior.
🛠️ Suggested fix
- let url: String = env.get_string(&url).unwrap().into();
- let token: String = env.get_string(&token).unwrap().into();
+ let url: String = match env.get_string(&url) {
+ Ok(s) => s.into(),
+ Err(e) => {
+ log::error!("Failed to read url JString: {}", e);
+ return;
+ }
+ };
+ let token: String = match env.get_string(&token) {
+ Ok(s) => s.into(),
+ Err(e) => {
+ log::error!("Failed to read token JString: {}", e);
+ return;
+ }
+ };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pub extern "C" fn Java_io_livekit_rustexample_App_connectNative( | |
| mut env: JNIEnv, | |
| _: JClass, | |
| url: JString, | |
| token: JString, | |
| ) { | |
| let url: String = env.get_string(&url).unwrap().into(); | |
| let token: String = env.get_string(&token).unwrap().into(); | |
| pub extern "C" fn Java_io_livekit_rustexample_App_connectNative( | |
| mut env: JNIEnv, | |
| _: JClass, | |
| url: JString, | |
| token: JString, | |
| ) { | |
| let url: String = match env.get_string(&url) { | |
| Ok(s) => s.into(), | |
| Err(e) => { | |
| log::error!("Failed to read url JString: {}", e); | |
| return; | |
| } | |
| }; | |
| let token: String = match env.get_string(&token) { | |
| Ok(s) => s.into(), | |
| Err(e) => { | |
| log::error!("Failed to read token JString: {}", e); | |
| return; | |
| } | |
| }; |
🤖 Prompt for AI Agents
In `@examples/mobile/src/lib.rs` around lines 466 - 474, The JNI string
conversions in Java_io_livekit_rustexample_App_connectNative currently call
env.get_string(...).unwrap(), which will panic on JNI errors and cross the FFI
boundary; change this to safely handle the Result by matching or using if let to
detect errors from env.get_string for both url and token, log or report the JNI
error (rather than panicking), and return early from
Java_io_livekit_rustexample_App_connectNative when conversion fails so no panic
crosses FFI; update references to the converted values only after successful
conversion.
examples/mobile/android/app/src/main/jniLibs/arm64-v8a/libmobile.so
Outdated
Show resolved
Hide resolved
|
would be worth discussing whether we should use libwebrtc native mediadevices vs rewriting them in our example |
@cloudwebrtc mentioned that before, I wonder how the native mediadevice modules can be integrated into Rust SDK, how large the binary will add, and will it cause conflict problems for users who don't want them. I will sync with Duan to understand the details better. And I think it won't be done in this PR. |
|
Hi teams, I cleaned up the PRs by removing those files that should be gitignored instead. Please take another look at the PR. BTW, in case we are going to have the media handling on Rust in the future, I will update the example once that is ready. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt`:
- Around line 95-108: connectToRoom should bail out early when native isn’t
available or credentials are empty: keep the existing app null guard, then add a
preflight that checks if url.isBlank() or token.isBlank(), sets
statusMessage.value to a clear error like "Missing URL or token" and returns;
additionally, if your App object exposes a native-availability flag or method
(e.g., currentApp.isNativeAvailable() or similar), check that and return with
statusMessage.value = "Native not initialized" before initializing MediaManager
or calling currentApp.connect(url, token); update references in this method
(connectToRoom, app/currentApp, mediaManager, statusMessage, currentApp.connect)
accordingly.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
examples/mobile/android/.gitignoreexamples/mobile/android/.idea/gradle.xmlexamples/mobile/android/.idea/misc.xmlexamples/mobile/android/.idea/vcs.xmlexamples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.ktexamples/mobile/android/gradle/wrapper/gradle-wrapper.properties
💤 Files with no reviewable changes (3)
- examples/mobile/android/.idea/gradle.xml
- examples/mobile/android/.idea/vcs.xml
- examples/mobile/android/.idea/misc.xml
🚧 Files skipped from review as they are similar to previous changes (1)
- examples/mobile/android/gradle/wrapper/gradle-wrapper.properties
🧰 Additional context used
🧬 Code graph analysis (1)
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt (1)
examples/mobile/android/app/src/main/java/io/livekit/rustexample/ui/theme/Theme.kt (1)
RustexampleTheme(40-70)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (python)
🔇 Additional comments (1)
examples/mobile/android/.gitignore (1)
10-17: LGTM — ignore entries are appropriate for Android Studio metadata and generated JNI libs.Also applies to: 25-26
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
examples/mobile/android/app/src/main/java/io/livekit/rustexample/MainActivity.kt
Outdated
Show resolved
Hide resolved
|
Any one can take a look ? |
…le/MainActivity.kt Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Chores