Skip to content

Commit

Permalink
Fix no permission disconnected notification
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawa committed Nov 22, 2024
1 parent 2f2d4ce commit 3d8ecdf
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.navigation.NavHostController
Expand All @@ -18,6 +19,8 @@ import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.rememberNavHostEngine
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
import net.mullvad.mullvadvpn.compose.util.CreateVpnProfile
import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe
import net.mullvad.mullvadvpn.lib.model.PrepareError
import net.mullvad.mullvadvpn.viewmodel.DaemonScreenEvent
import net.mullvad.mullvadvpn.viewmodel.NoDaemonViewModel
import net.mullvad.mullvadvpn.viewmodel.VpnPermissionSideEffect
Expand Down Expand Up @@ -65,11 +68,22 @@ fun MullvadApp() {
// Ask for VPN Permission
val launchVpnPermission =
rememberLauncherForActivityResult(CreateVpnProfile()) { _ -> permissionVm.connect() }
val context = LocalContext.current
LaunchedEffect(Unit) {
permissionVm.uiSideEffect.collect {
if (it is VpnPermissionSideEffect.ShowDialog) {
// TODO fix this
// launchVpnPermission.launch(Unit)
if (it is VpnPermissionSideEffect.RequestVpnProfile) {
context
.prepareVpnSafe()
.fold(
{
if (it is PrepareError.NotPrepared) {
launchVpnPermission.launch(it.prepareIntent)
} else {
permissionVm.connect()
}
},
{ permissionVm.connect() },
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class VpnPermissionViewModel(
intentProvider.intents
.filter { it?.action == KEY_REQUEST_VPN_PERMISSION }
.distinctUntilChanged()
.map { VpnPermissionSideEffect.ShowDialog }
.map { VpnPermissionSideEffect.RequestVpnProfile }
.shareIn(viewModelScope, SharingStarted.WhileSubscribed())

fun connect() {
Expand All @@ -30,5 +30,5 @@ class VpnPermissionViewModel(
}

sealed interface VpnPermissionSideEffect {
data object ShowDialog : VpnPermissionSideEffect
data object RequestVpnProfile : VpnPermissionSideEffect
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.mullvad.mullvadvpn.lib.model

import android.content.Intent

sealed interface NotificationAction {

sealed interface AccountExpiry : NotificationAction {
Expand All @@ -15,6 +17,6 @@ sealed interface NotificationAction {

data object Dismiss : Tunnel

data object RequestPermission : Tunnel
data class RequestPermission(val prepareIntent: Intent) : Tunnel
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ internal fun NotificationAction.Tunnel.toCompatAction(context: Context): Notific
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
setAction(KEY_REQUEST_VPN_PERMISSION)
putExtra("intent", prepareIntent)
}

PendingIntent.getActivity(context, 1, intent, SdkUtils.getSupportedPendingIntentFlags())
Expand All @@ -90,15 +91,15 @@ fun NotificationAction.Tunnel.titleResource() =
when (this) {
NotificationAction.Tunnel.Cancel -> R.string.cancel
NotificationAction.Tunnel.Connect,
NotificationAction.Tunnel.RequestPermission -> R.string.connect
is NotificationAction.Tunnel.RequestPermission -> R.string.connect
NotificationAction.Tunnel.Disconnect -> R.string.disconnect
NotificationAction.Tunnel.Dismiss -> R.string.dismiss
}

fun NotificationAction.Tunnel.toKey() =
when (this) {
NotificationAction.Tunnel.Connect -> KEY_CONNECT_ACTION
NotificationAction.Tunnel.RequestPermission -> KEY_REQUEST_VPN_PERMISSION
is NotificationAction.Tunnel.RequestPermission -> KEY_REQUEST_VPN_PERMISSION
NotificationAction.Tunnel.Cancel,
NotificationAction.Tunnel.Disconnect,
NotificationAction.Tunnel.Dismiss -> KEY_DISCONNECT_ACTION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,12 @@ class TunnelStateNotificationProvider(
private fun NotificationTunnelState.toAction(): NotificationAction.Tunnel =
when (this) {
is NotificationTunnelState.Disconnected -> {
when (prepareError) {
when (val error = prepareError) {
is PrepareError.OtherAlwaysOnApp,
is PrepareError.LegacyLockdown,
null -> NotificationAction.Tunnel.Connect
is PrepareError.NotPrepared -> NotificationAction.Tunnel.RequestPermission
is PrepareError.NotPrepared ->
NotificationAction.Tunnel.RequestPermission(error.prepareIntent)
}
}
NotificationTunnelState.Disconnecting -> NotificationAction.Tunnel.Connect
Expand Down
14 changes: 14 additions & 0 deletions mullvad-daemon/src/access_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ impl Daemon {
/// different kinds of testing contexts, such as testing
/// [`AccessMethodSetting`]s or on the fly testing of
/// [`talpid_types::net::proxy::CustomProxy`]s.
#[cfg(not(target_os = "android"))]
pub(crate) async fn test_access_method(
proxy: talpid_types::net::AllowedEndpoint,
access_method_selector: api::AccessModeSelectorHandle,
Expand Down Expand Up @@ -177,6 +178,19 @@ impl Daemon {
result
}

#[cfg(target_os = "android")]
pub(crate) async fn test_access_method(
_: talpid_types::net::AllowedEndpoint,
_: api::AccessModeSelectorHandle,
_: crate::DaemonEventSender<(
api::AccessMethodEvent,
futures::channel::oneshot::Sender<()>,
)>,
api_proxy: ApiProxy,
) -> Result<bool, Error> {
Self::perform_api_request(api_proxy).await
}

/// Create an [`ApiProxy`] which will perform all REST requests against one
/// specific endpoint `connection_mode`.
pub fn create_limited_api_proxy(&mut self, connection_mode: ApiConnectionMode) -> ApiProxy {
Expand Down
7 changes: 6 additions & 1 deletion mullvad-daemon/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub enum AccessMethodEvent {
setting: AccessMethodSetting,
/// The endpoint which represents how to connect to the Mullvad API and
/// which clients are allowed to initiate such a connection.
#[cfg(not(target_os = "android"))]
endpoint: AllowedEndpoint,
},
/// Emitted when the the firewall should be updated.
Expand All @@ -63,6 +64,7 @@ pub enum AccessMethodEvent {
/// should be opaque to any client, it should not produce any unwanted noise
/// and as such it is *not* broadcasted after the daemon is done processing
/// this [`AccessMethodEvent::Allow`].
#[cfg(not(target_os = "android"))]
Allow { endpoint: AllowedEndpoint },
}

Expand Down Expand Up @@ -419,10 +421,13 @@ impl AccessModeSelector {
// created from this `AccessModeSelector` instance. As such, the
// completion channel is discarded in this instance.
let setting = resolved.setting.clone();
#[cfg(not(target_os = "android"))]
let endpoint = resolved.endpoint.clone();
let daemon_sender = self.access_method_event_sender.clone();
tokio::spawn(async move {
let _ = AccessMethodEvent::New { setting, endpoint }
let _ = AccessMethodEvent::New { setting,
#[cfg(not(target_os = "android"))]
endpoint }
.send(daemon_sender)
.await;
});
Expand Down
5 changes: 1 addition & 4 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,10 +1418,7 @@ impl Daemon {

#[cfg(target_os = "android")]
match event {
AccessMethodEvent::Allow { endpoint } => {
let _ = endpoint_active_tx.send(());
}
AccessMethodEvent::New { setting, endpoint } => {
AccessMethodEvent::New { setting, .. } => {
// Announce to all clients listening for updates of the
// currently active access method. The announcement should be
// made after the firewall policy has been updated, since the
Expand Down
2 changes: 2 additions & 0 deletions talpid-core/src/tunnel_state_machine/error_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{
};
#[cfg(target_os = "macos")]
use crate::dns::DnsConfig;
#[cfg(not(target_os = "android"))]
use crate::firewall::FirewallPolicy;
use futures::StreamExt;
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -73,6 +74,7 @@ impl ErrorState {
)
}

#[cfg(not(target_os = "android"))]
fn set_firewall_policy(
shared_values: &mut SharedTunnelStateValues,
) -> Result<(), FirewallPolicyError> {
Expand Down

0 comments on commit 3d8ecdf

Please sign in to comment.