tauri-apps / tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
https://tauri.app
Apache License 2.0
85.39k stars 2.58k forks source link

[bug] In Android MainActivity is leaked if a foreground service is running and makes the app unusable on next launch #11609

Open mohit92 opened 2 weeks ago

mohit92 commented 2 weeks ago

Describe the bug

It seems that Tauri Android app don't expect the application process to outlive the MainActivity, which is common in android world if you are running a foreground service

In this case when you relaunch the app, Tauri has two instances of MainActivity and RustWebview which causes TAURI_INVOKE_KEY mismatch causing the app to become unsuable.

Reproduction

Download and build the sample project. Please build it in release mode, as the repro steps require killing the app. Be sure to add your release key and configure local.properties to set up signing keys. Link to the repo: https://github.com/m-byondlabs/screenshare-mobile-tauri

Launch the app, click the "Start Share" button, and allow the prompt to start screen sharing.

You should see a screencast icon indicating that the foreground service is actively capturing the screen recording.

Swipe up to close the MainActivity; you’ll notice that the foreground service continues capturing the screen (this is intended and expected behavior).

Reopen the app and click "Start Share" or "Stop Share." You will observe a log indicating a TAURI_INVOKE_KEY mismatch.

If you generate a heap dump, you’ll find two instances of MainActivity, meaning the previous activity is leaked and remains in memory.

I've verified that my code does not retain any references to the activity, so it appears that the Tauri Plugin manager or another code path in Tauri may be holding onto that instance.

Expected behavior

Once the activity is destroyed, it should not stay in the memory

Full tauri info output

[✔] Environment
    - OS: Mac OS 14.6.1 arm64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.81.0 (eeb90cda1 2024-09-04)
    ✔ cargo: 1.81.0 (2dbb1af80 2024-08-20)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-aarch64-apple-darwin (environment override by RUSTUP_TOOLCHAIN)
    - node: 20.17.0
    - npm: 10.8.2

[-] Packages
    - tauri 🦀: 2.0.4
    - tauri-build 🦀: 2.0.1
    - wry 🦀: 0.46.1
    - tao 🦀: 0.30.3
    - tauri-cli 🦀: 2.0.2
    - @tauri-apps/api : 2.0.2 (outdated, latest: 2.0.3)
    - @tauri-apps/cli : 2.0.2 (outdated, latest: 2.0.4)

[-] Plugins
    - tauri-plugin-shell 🦀: 2.0.1
    - @tauri-apps/plugin-shell : 2.0.0 (outdated, latest: 2.0.1)

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/
    - framework: React
    - bundler: Vite

Stack trace

No response

Additional context

No response

lucasfernog commented 2 weeks ago

we're creating a global reference to the activity here so we probably need to find a way to clean it up.

lucasfernog commented 2 weeks ago

the problem with the invoke keys is wry statics which is a lifecycle issue in this case - since your app is still open in the foreground, the Rust code is still running - and the process is reused when the app is reopened.

lucasfernog commented 2 weeks ago

i'm trying some changes for the memory leak, no luck yet.

lucasfernog commented 2 weeks ago

I think i've fixed it. If you wanna early try it, add the following to the Cargo.toml file:

[patch.crates-io]
tauri = { git = "https://github.com/tauri-apps/tauri", branch = "dev" }
tauri-plugin = { git = "https://github.com/tauri-apps/tauri", branch = "dev" }
tauri-build = { git = "https://github.com/tauri-apps/tauri", branch = "dev" }
tao = { git = "https://github.com/tauri-apps/tao", branch = "fix/android-leak" }
wry = { git = "https://github.com/lucasfernog/wry", branch = "fix/android" }

(to validate if the patches are properly applied, you can see if there's no [patch.unused] in the cargo.lock file