Skip to content

android: replace broadcast intent with service intent #650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kari-ts
Copy link
Collaborator

@kari-ts kari-ts commented May 15, 2025

We were previously calling startService(intent), which is a direct call consumed by IPNService, but restartVPN was not working as intended because the broadcast receiver was never triggered. Rather than use a broadcast receiver, directly start the service in restartVPN as we do in stopVPN. Also, batch changes to excluded apps so that we don't restart the VPN each time the user toggles an app.

Fixes tailscale/corp#28668

Copy link

review-ai-agent bot commented May 15, 2025

Pull Request Revisions

RevisionDescription
r2
Removed pendingChanges tracking codeDeleted pendingChanges set and related tracking logic in split tunnel app picker view model
r1
Refactored VPN package exclusion logicSimplified package exclusion methods, added debounce mechanism, and introduced a new updateUserDisallowedPackageNames method for managing split tunnel app settings

✅ AI review completed for r2
Help React with emojis to give feedback on AI-generated reviews:
  • 👍 means the feedback was helpful and actionable
  • 👎 means the feedback was incorrect or unhelpful
💬 Replying to feedback with a comment helps us improve the system. Your input also contributes to shaping future interactions with the AI reviewer.

We'd love to hear from you—reach out anytime at [email protected].

Comment on lines +474 to +480
try {
startService(intent)
} catch (illegalStateException: IllegalStateException) {
TSLog.e(TAG, "restartVPN hit IllegalStateException in startService(): $illegalStateException")
} catch (e: Exception) {
TSLog.e(TAG, "restartVPN hit exception in startService(): $e")
}

Choose a reason for hiding this comment

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

In android/src/main/java/com/tailscale/ipn/App.kt's restartVPN method, consider adding a more specific catch for SecurityException which can occur when the VPN service start is disallowed by the user. This would help distinguish between security-related failures and other runtime exceptions, allowing for more targeted error handling.

Comment on lines +49 to +55
ACTION_RESTART_VPN -> {
app.setWantRunning(false){
close()
app.startVPN()
}
START_NOT_STICKY
}

Choose a reason for hiding this comment

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

In android/src/main/java/com/tailscale/ipn/IPNService.kt, the ACTION_RESTART_VPN handling first calls app.setWantRunning(false) followed by close() which no longer contains app.setWantRunning(false). Should we be concerned about this state management change or potential duplicate calls?

viewModelScope.launch {
delay(500) // Wait to batch multiple rapid updates
App.get().updateUserDisallowedPackageNames(excludedPackageNames.value)
}

Choose a reason for hiding this comment

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

In android/src/main/java/com/tailscale/ipn/ui/viewModel/SplitTunnelAppPickerViewModel.kt, the pendingChanges set is added but only used for tracking add/remove operations. Since the actual updates are based on excludedPackageNames.value, can you clarify the purpose of this set? It appears unused in the final update operation.

We were previously calling startService(intent), which is a direct call consumed by IPNService, but restartVPN was not working as intended because the broadcast receiver was never triggered.
Rather than use a broadcast receiver, directly start the service in restartVPN as we do in stopVPN. Also, batch changes to excluded apps so that we don't restart the VPN each time the user toggles an app.

Fixes tailscale/corp#28668

Signed-off-by: kari-ts <[email protected]>
Comment on lines 91 to 94
override fun close() {
app.setWantRunning(false) {}
Notifier.setState(Ipn.State.Stopping)
disconnectVPN()
Libtailscale.serviceDisconnect(this)

Choose a reason for hiding this comment

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

The IPNService.kt close() method no longer calls app.setWantRunning(false), while the ACTION_RESTART_VPN handler does this explicitly. Consider abstracting this state management logic to prevent potential inconsistencies in future modifications.

@kari-ts kari-ts requested a review from barnstar May 15, 2025 20:21
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.

1 participant