Skip to content

fix(android): fix view state lifecycle around tunnel/auth#9621

Merged
jamilbk merged 6 commits into
mainfrom
fix/android-screen
Jun 22, 2025
Merged

fix(android): fix view state lifecycle around tunnel/auth#9621
jamilbk merged 6 commits into
mainfrom
fix/android-screen

Conversation

@jamilbk

@jamilbk jamilbk commented Jun 22, 2025

Copy link
Copy Markdown
Member

onViewCreated() is called when the view initializes, and then onResume() is called right after, in addition to anytime the view is shown again.

To prevent showing the VPN permission activity twice, we remove the checkTunnelState() from onViewCreated, allowing only onResume() to call it.

A boolean flag is added to track whether this is the "first" launch of the app in order to determine whether to connectOnStart.

Fixes #9584

Copilot AI review requested due to automatic review settings June 22, 2025 04:53
@vercel

vercel Bot commented Jun 22, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
firezone ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 22, 2025 4:05pm

@jamilbk
jamilbk requested a review from thomaseizinger June 22, 2025 04:53

This comment was marked as outdated.

@thomaseizinger thomaseizinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works. Have you tested all flows and combinations of connectOnStart?

  • Sign in / out
  • Disconnect VPN via system and relaunch app

I think I've tried this or a very similar implementation and there is a routing loop somewhere between the fragments.

@jamilbk

jamilbk commented Jun 22, 2025

Copy link
Copy Markdown
Member Author

Good catch. It appears that the behavior of the TunnelService changed on disconnect and doesn't shutdown any longer. This is causing the isRunning check to return a false positive causing us to go the Session activity erroneously.

Should have a fix in a bit.

@jamilbk jamilbk changed the title fix(android): don't launch VPN permission activity twice fix(android): fix view state lifecycle around tunnel/auth Jun 22, 2025
@jamilbk

jamilbk commented Jun 22, 2025

Copy link
Copy Markdown
Member Author

Tested:

  • ✅ Disconnect from system settings
  • ✅ Token revoked from portal
  • ✅ connect on start on/off with the above
  • ✅ user-initiated sign out / in from app

Comment on lines -32 to -40
val token = repo.getTokenSync()

actionMutableLiveData.postValue(
if (authFlowLaunched || token != null) {
ViewAction.NavigateToSignIn
} else {
authFlowLaunched = true
ViewAction.LaunchAuthFlow("${config.authUrl}/${config.accountSlug}?state=$state&nonce=$nonce&as=client")
},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be from a roundabout way to start the tunnel if the token was provided. I think it can be safely removed - this logic is handled in the checkTunnelState of the SplashViewModel now.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was able to clean up the logic in this file a bit.


stopNetworkMonitoring()
stopDisconnectMonitoring()
stopSelf()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the cause of one loop.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to tie tunnel state UP / DOWN to the service running because there isn't a good way to get the running service instance to call connect on it otherwise.

So we start/stop the service, which is probably correct since it shows/hides the VPN stick foreground notification.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, I didn't know about this.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the splash flow to prevent duplicate VPN permission prompts, introduces a first-launch flag to control tunnel connection, and ensures the VPN service stops itself when disconnected.

  • Call stopSelf() in TunnelService to properly terminate the service
  • Move tunnel state checks entirely into onResume with an isInitialLaunch flag in SplashFragment and simplify SplashViewModel logic
  • Simplify AuthViewModel to always launch the auth flow (removing prior token checks)

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
kotlin/android/app/src/main/java/dev/firezone/android/tunnel/TunnelService.kt Added stopSelf() after stopping monitors
kotlin/android/app/src/main/java/dev/firezone/android/features/splash/ui/SplashViewModel.kt Removed internal launch flag, reordered and clarified state logic
kotlin/android/app/src/main/java/dev/firezone/android/features/splash/ui/SplashFragment.kt Added isInitialLaunch field, moved check into onResume
kotlin/android/app/src/main/java/dev/firezone/android/features/auth/ui/AuthViewModel.kt Always launch auth flow, removed token-based branch
Comments suppressed due to low confidence (1)

kotlin/android/app/src/main/java/dev/firezone/android/features/auth/ui/AuthViewModel.kt:33

  • The previous logic checked for an existing token or prior auth launch before navigating to sign-in, but the new code always starts the auth flow. This could trigger redundant auth attempts even when a valid token exists. Consider restoring the conditional branch to navigate directly to SignIn when repo.getTokenSync() returns a non-null token or the auth flow has already been launched.
                actionMutableLiveData.postValue(

…/splash/ui/SplashViewModel.kt

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>

@thomaseizinger thomaseizinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, thank you for handling this.

Merged via the queue into main with commit 3029e00 Jun 22, 2025
27 checks passed
@jamilbk
jamilbk deleted the fix/android-screen branch June 22, 2025 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Request permission" doesn't reload the screen after allowing

3 participants