Skip to content
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

Get data directory value at app startup (Android) #6342

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ The settings directory can be changed by setting the `MULLVAD_SETTINGS_DIR` envi
| Linux | `/etc/mullvad-vpn/` |
| macOS | `/etc/mullvad-vpn/` |
| Windows | `%LOCALAPPDATA%\Mullvad VPN\` |
| Android | `/data/data/net.mullvad.mullvadvpn/` |
| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) |

#### Logs

Expand All @@ -343,7 +343,7 @@ The log directory can be changed by setting the `MULLVAD_LOG_DIR` environment va
| Linux | `/var/log/mullvad-vpn/` + systemd |
| macOS | `/var/log/mullvad-vpn/` |
| Windows | `C:\ProgramData\Mullvad VPN\` |
| Android | `/data/data/net.mullvad.mullvadvpn/` |
| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) |

#### Cache

Expand All @@ -354,7 +354,7 @@ The cache directory can be changed by setting the `MULLVAD_CACHE_DIR` environmen
| Linux | `/var/cache/mullvad-vpn/` |
| macOS | `/Library/Caches/mullvad-vpn/` |
| Windows | `C:\ProgramData\Mullvad VPN\cache` |
| Android | `/data/data/net.mullvad.mullvadvpn/cache` |
| Android | [`getCacheDir()`](https://developer.android.com/reference/android/content/Context#getCacheDir()) |

#### RPC address file

Expand All @@ -366,7 +366,7 @@ environment variable.
| Linux | `/var/run/mullvad-vpn` |
| macOS | `/var/run/mullvad-vpn` |
| Windows | `//./pipe/Mullvad VPN` |
| Android | `/data/data/net.mullvad.mullvadvpn/rpc-socket` |
| Android | [`getNoBackupFilesDir()`](https://developer.android.com/reference/android/content/ContextWrapper#getNoBackupFilesDir()) |

### GUI

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package net.mullvad.mullvadvpn.di

import java.io.File
import kotlinx.coroutines.MainScope
import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.constant.GRPC_SOCKET_FILE_NAME
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAME
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
import net.mullvad.mullvadvpn.lib.intent.IntentProvider
import net.mullvad.mullvadvpn.lib.model.BuildVersion
Expand All @@ -15,10 +17,12 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module

val appModule = module {
single(named(RPC_SOCKET_PATH)) { "${androidContext().dataDir.path}/$GRPC_SOCKET_FILE_NAME" }
single(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)) {
File(androidContext().noBackupFilesDir, GRPC_SOCKET_FILE_NAME)
}
single {
ManagementService(
rpcSocketPath = get(named(RPC_SOCKET_PATH)),
rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)),
extensiveLogging = BuildConfig.DEBUG,
scope = MainScope(),
)
Expand All @@ -30,5 +34,3 @@ val appModule = module {
single { VpnPermissionRepository(androidContext()) }
single { ConnectionProxy(get(), get()) }
}

const val RPC_SOCKET_PATH = "RPC_SOCKET"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package net.mullvad.mullvadvpn.lib.common.constant

const val GRPC_SOCKET_FILE_NAMED_ARGUMENT = "RPC_SOCKET"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package net.mullvad.mullvadvpn.lib.common.constant

const val GRPC_SOCKET_FILE_NAME = "rpc-socket"
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.grpc.ConnectivityState
import io.grpc.Status
import io.grpc.StatusException
import io.grpc.android.UdsChannelBuilder
import java.io.File
import java.net.InetAddress
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -127,14 +128,19 @@ import net.mullvad.mullvadvpn.lib.model.wireguardConstraints

@Suppress("TooManyFunctions")
class ManagementService(
rpcSocketPath: String,
rpcSocketFile: File,
private val extensiveLogging: Boolean,
private val scope: CoroutineScope,
) {
private var job: Job? = null

// We expect daemon to create the rpc socket file on the path provided on initialisation
private val channel =
UdsChannelBuilder.forPath(rpcSocketPath, LocalSocketAddress.Namespace.FILESYSTEM).build()
UdsChannelBuilder.forPath(
rpcSocketFile.absolutePath,
LocalSocketAddress.Namespace.FILESYSTEM
)
.build()

val connectionState: StateFlow<GrpcConnectivityState> =
channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private const val RELAYS_FILE = "relays.json"
@SuppressLint("SdCardPath")
class MullvadDaemon(
vpnService: MullvadVpnService,
rpcSocketFile: File,
apiEndpointConfiguration: ApiEndpointConfiguration,
migrateSplitTunneling: MigrateSplitTunneling
) {
Expand All @@ -34,8 +35,9 @@ class MullvadDaemon(

initialize(
vpnService = vpnService,
rpcSocketPath = rpcSocketFile.absolutePath,
filesDirectory = vpnService.filesDir.absolutePath,
cacheDirectory = vpnService.cacheDir.absolutePath,
resourceDirectory = vpnService.filesDir.absolutePath,
apiEndpoint = apiEndpointConfiguration.apiEndpoint()
)
}
Expand Down Expand Up @@ -69,8 +71,9 @@ class MullvadDaemon(

private external fun initialize(
vpnService: MullvadVpnService,
rpcSocketPath: String,
filesDirectory: String,
cacheDirectory: String,
resourceDirectory: String,
apiEndpoint: ApiEndpoint?
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.util.Log
import androidx.core.content.getSystemService
import androidx.lifecycle.lifecycleScope
import arrow.atomic.AtomicInt
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -17,6 +18,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.TAG
Expand All @@ -36,6 +38,7 @@ import net.mullvad.mullvadvpn.service.notifications.ShouldBeOnForegroundProvider
import net.mullvad.talpid.TalpidVpnService
import org.koin.android.ext.android.getKoin
import org.koin.core.context.loadKoinModules
import org.koin.core.qualifier.named

class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
private val _shouldBeOnForeground = MutableStateFlow(false)
Expand All @@ -49,6 +52,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
private lateinit var migrateSplitTunneling: MigrateSplitTunneling
private lateinit var intentProvider: IntentProvider
private lateinit var connectionProxy: ConnectionProxy
private lateinit var rpcSocketFile: File

private lateinit var foregroundNotificationHandler: ForegroundNotificationManager

Expand All @@ -75,6 +79,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
migrateSplitTunneling = get()
intentProvider = get()
connectionProxy = get()
rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT))
}

keyguardManager = getSystemService<KeyguardManager>()!!
Expand All @@ -88,6 +93,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
daemonInstance =
MullvadDaemon(
vpnService = this@MullvadVpnService,
rpcSocketFile = rpcSocketFile,
apiEndpointConfiguration =
intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
?: apiEndpointConfiguration,
Expand Down
4 changes: 2 additions & 2 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2894,8 +2894,8 @@ fn oneshot_map<T1: Send + 'static, T2: Send + 'static>(

/// Remove any old RPC socket (if it exists).
#[cfg(not(windows))]
pub async fn cleanup_old_rpc_socket() {
if let Err(err) = tokio::fs::remove_file(mullvad_paths::get_rpc_socket_path()).await {
pub async fn cleanup_old_rpc_socket(rpc_socket_path: impl AsRef<std::path::Path>) {
if let Err(err) = tokio::fs::remove_file(rpc_socket_path).await {
if err.kind() != std::io::ErrorKind::NotFound {
log::error!("Failed to remove old RPC socket: {}", err);
}
Expand Down
19 changes: 14 additions & 5 deletions mullvad-daemon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use mullvad_daemon::{
management_interface::{ManagementInterfaceEventBroadcaster, ManagementInterfaceServer},
rpc_uniqueness_check, runtime, version, Daemon, DaemonCommandChannel, DaemonCommandSender,
};
use std::{path::PathBuf, thread, time::Duration};
use std::{
path::{Path, PathBuf},
thread,
time::Duration,
};
use talpid_types::ErrorExt;

mod cli;
Expand Down Expand Up @@ -163,7 +167,7 @@ fn get_log_dir(config: &cli::Config) -> Result<Option<PathBuf>, String> {

async fn run_standalone(log_dir: Option<PathBuf>) -> Result<(), String> {
#[cfg(not(windows))]
cleanup_old_rpc_socket().await;
cleanup_old_rpc_socket(mullvad_paths::get_rpc_socket_path()).await;

if !running_as_admin() {
log::warn!("Running daemon as a non-administrator user, clients might refuse to connect");
Expand Down Expand Up @@ -192,14 +196,15 @@ async fn run_standalone(log_dir: Option<PathBuf>) -> Result<(), String> {
async fn create_daemon(
log_dir: Option<PathBuf>,
) -> Result<Daemon<ManagementInterfaceEventBroadcaster>, String> {
let rpc_socket_path = mullvad_paths::get_rpc_socket_path();
let resource_dir = mullvad_paths::get_resource_dir();
let settings_dir = mullvad_paths::settings_dir()
.map_err(|e| e.display_chain_with_msg("Unable to get settings dir"))?;
let cache_dir = mullvad_paths::cache_dir()
.map_err(|e| e.display_chain_with_msg("Unable to get cache dir"))?;

let command_channel = DaemonCommandChannel::new();
let event_listener = spawn_management_interface(command_channel.sender())?;
let event_listener = spawn_management_interface(command_channel.sender(), rpc_socket_path)?;

Daemon::start(
log_dir,
Expand All @@ -215,13 +220,17 @@ async fn create_daemon(

fn spawn_management_interface(
command_sender: DaemonCommandSender,
rpc_socket_path: impl AsRef<Path>,
) -> Result<ManagementInterfaceEventBroadcaster, String> {
let (socket_path, event_broadcaster) = ManagementInterfaceServer::start(command_sender)
let event_broadcaster = ManagementInterfaceServer::start(command_sender, &rpc_socket_path)
.map_err(|error| {
error.display_chain_with_msg("Unable to start management interface server")
})?;

log::info!("Management interface listening on {}", socket_path);
log::info!(
"Management interface listening on {}",
rpc_socket_path.as_ref().display()
);

Ok(event_broadcaster)
}
Expand Down
29 changes: 14 additions & 15 deletions mullvad-daemon/src/management_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use mullvad_types::{
wireguard::{RotationInterval, RotationIntervalError},
};
use std::{
path::Path,
str::FromStr,
sync::{Arc, Mutex},
time::Duration,
Expand Down Expand Up @@ -1024,21 +1025,22 @@ pub struct ManagementInterfaceServer(());
impl ManagementInterfaceServer {
pub fn start(
tunnel_tx: DaemonCommandSender,
) -> Result<(String, ManagementInterfaceEventBroadcaster), Error> {
rpc_socket_path: impl AsRef<Path>,
) -> Result<ManagementInterfaceEventBroadcaster, Error> {
let subscriptions = Arc::<Mutex<Vec<EventsListenerSender>>>::default();

let socket_path = mullvad_paths::get_rpc_socket_path()
.to_string_lossy()
.to_string();

let (server_abort_tx, server_abort_rx) = mpsc::channel(0);
let server = ManagementServiceImpl {
daemon_tx: tunnel_tx,
subscriptions: subscriptions.clone(),
};
let join_handle = mullvad_management_interface::spawn_rpc_server(server, async move {
server_abort_rx.into_future().await;
})
let join_handle = mullvad_management_interface::spawn_rpc_server(
server,
async move {
server_abort_rx.into_future().await;
},
rpc_socket_path,
)
.map_err(Error::SetupError)?;

tokio::spawn(async move {
Expand All @@ -1048,13 +1050,10 @@ impl ManagementInterfaceServer {
log::info!("Management interface shut down");
});

Ok((
socket_path,
ManagementInterfaceEventBroadcaster {
subscriptions,
_close_handle: server_abort_tx,
},
))
Ok(ManagementInterfaceEventBroadcaster {
subscriptions,
_close_handle: server_abort_tx,
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion mullvad-jni/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ log-panics = "2"
nix = "0.23"
rand = "0.8.5"

mullvad-api = { path = "../mullvad-api" }
mullvad-daemon = { path = "../mullvad-daemon" }
mullvad-problem-report = { path = "../mullvad-problem-report" }
mullvad-types = { path = "../mullvad-types" }
mullvad-api = { path = "../mullvad-api" }
talpid-tunnel = { path = "../talpid-tunnel" }
talpid-types = { path = "../talpid-types" }
Loading
Loading