diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-02-24 10:22:34 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-03-05 23:32:30 +0100 |
| commit | 5605ba9037597aeb8577c8a068e19ca1854bb997 (patch) | |
| tree | f742ae88b25f423d16bf8496527e4ef6e8634cec | |
| parent | aefca5230e86aaf03fc3b1daa1c72f90f32fb693 (diff) | |
| download | mullvadvpn-5605ba9037597aeb8577c8a068e19ca1854bb997.tar.xz mullvadvpn-5605ba9037597aeb8577c8a068e19ca1854bb997.zip | |
Push error handling of `get_arch` outwards
| -rw-r--r-- | installer-downloader/src/cacao_impl/mod.rs | 11 | ||||
| -rw-r--r-- | installer-downloader/src/controller.rs | 32 | ||||
| -rw-r--r-- | installer-downloader/src/environment.rs | 36 | ||||
| -rw-r--r-- | installer-downloader/src/lib.rs | 2 | ||||
| -rw-r--r-- | installer-downloader/src/winapi_impl/mod.rs | 16 |
5 files changed, 78 insertions, 19 deletions
diff --git a/installer-downloader/src/cacao_impl/mod.rs b/installer-downloader/src/cacao_impl/mod.rs index e2974d370e..3b607c3295 100644 --- a/installer-downloader/src/cacao_impl/mod.rs +++ b/installer-downloader/src/cacao_impl/mod.rs @@ -1,6 +1,7 @@ use std::sync::Mutex; use cacao::appkit::App; +use installer_downloader::environment::{Environment, Error as EnvError}; use ui::{Action, AppImpl}; mod delegate; @@ -9,8 +10,16 @@ mod ui; pub fn main() { let app = App::new("net.mullvad.downloader", AppImpl::default()); + // Load "global" values and resources + let environment = match Environment::load() { + Ok(env) => env, + Err(EnvError::Arch) => { + unreachable!("The CPU architecture will always be retrievable on macOS") + } + }; + let cb: Mutex<Option<ui::MainThreadCallback>> = Mutex::new(Some(Box::new(|self_| { - crate::controller::initialize_controller(self_); + crate::controller::initialize_controller(self_, environment); }))); cacao::appkit::App::<ui::AppImpl, _>::dispatch_main(Action::QueueMain(cb)); diff --git a/installer-downloader/src/controller.rs b/installer-downloader/src/controller.rs index ff02b3cd0c..ebed872755 100644 --- a/installer-downloader/src/controller.rs +++ b/installer-downloader/src/controller.rs @@ -1,6 +1,7 @@ //! This module implements the actual logic performed by different UI components. use crate::delegate::{AppDelegate, AppDelegateQueue}; +use crate::environment::Environment; use crate::resource; use crate::temp::DirectoryProvider; use crate::ui_downloader::{UiAppDownloader, UiAppDownloaderParameters, UiProgressUpdater}; @@ -8,7 +9,7 @@ use crate::ui_downloader::{UiAppDownloader, UiAppDownloaderParameters, UiProgres use mullvad_update::{ api::VersionInfoProvider, app::{self, AppDownloader}, - version::{Version, VersionArchitecture, VersionInfo, VersionParameters}, + version::{Version, VersionInfo, VersionParameters}, }; use rand::seq::SliceRandom; @@ -29,7 +30,7 @@ enum TaskMessage { pub struct AppController {} /// Public entry function for registering a [AppDelegate]. -pub fn initialize_controller<T: AppDelegate + 'static>(delegate: &mut T) { +pub fn initialize_controller<T: AppDelegate + 'static>(delegate: &mut T, environment: Environment) { use mullvad_update::{api::HttpVersionInfoProvider, app::HttpAppDownloader}; // App downloader to use @@ -48,7 +49,11 @@ pub fn initialize_controller<T: AppDelegate + 'static>(delegate: &mut T) { verifying_key, }; - AppController::initialize::<_, Downloader<T>, _, DirProvider>(delegate, version_provider) + AppController::initialize::<_, Downloader<T>, _, DirProvider>( + delegate, + version_provider, + environment, + ) } /// JSON files should be stored at `<base url>/<platform>.json`. @@ -68,8 +73,11 @@ impl AppController { /// /// Providing the downloader and version info fetcher as type arguments, they're decoupled from /// the logic of [AppController], allowing them to be mocked. - pub fn initialize<D, A, V, DirProvider>(delegate: &mut D, version_provider: V) - where + pub fn initialize<D, A, V, DirProvider>( + delegate: &mut D, + version_provider: V, + environment: Environment, + ) where D: AppDelegate + 'static, V: VersionInfoProvider + Send + 'static, A: From<UiAppDownloaderParameters<D>> + AppDownloader + 'static, @@ -93,6 +101,7 @@ impl AppController { delegate.queue(), task_tx.clone(), version_provider, + environment, )); Self::register_user_action_callbacks(delegate, task_tx); } @@ -125,13 +134,11 @@ async fn fetch_app_version_info<Delegate, VersionProvider>( queue: Delegate::Queue, download_tx: mpsc::Sender<TaskMessage>, version_provider: VersionProvider, + Environment { architecture }: Environment, ) where Delegate: AppDelegate + 'static, VersionProvider: VersionInfoProvider + Send, { - // TODO: Do not unwrap - // TODO: Construct a proper error instead - let architecture = get_arch().unwrap().unwrap(); loop { let version_params = VersionParameters { architecture, @@ -412,12 +419,3 @@ fn select_cdn_url(urls: &[String]) -> Option<&str> { fn format_latest_version(version: &Version) -> String { format!("{}: {}", resource::LATEST_VERSION_PREFIX, version.version) } - -/// Try to map the host's CPU architecture to one of the CPU architectures the Mullvad VPN app -/// supports. -fn get_arch() -> Result<Option<VersionArchitecture>, std::io::Error> { - match talpid_platform_metadata::get_native_arch()?? { - talpid_platform_metadata::Architecture::X86 => VersionArchitecture::X86, - talpid_platform_metadata::Architecture::Arm64 => VersionArchitecture::Arm64, - } -} diff --git a/installer-downloader/src/environment.rs b/installer-downloader/src/environment.rs new file mode 100644 index 0000000000..4b17575912 --- /dev/null +++ b/installer-downloader/src/environment.rs @@ -0,0 +1,36 @@ +use mullvad_update::version::VersionArchitecture; + +/// The environment consists of globals and/or constants which need to be computed at runtime. +pub struct Environment { + pub architecture: mullvad_update::format::Architecture, +} + +pub enum Error { + /// Failed to get the host's CPU architecture. + Arch, +} + +impl Environment { + /// Try to load the environment. + pub fn load() -> Result<Self, Error> { + let architecture = Self::get_arch()?; + + Ok(Environment { architecture }) + } + + /// Try to map the host's CPU architecture to one of the CPU architectures the Mullvad VPN app + /// supports. + fn get_arch() -> Result<VersionArchitecture, Error> { + let arch = talpid_platform_metadata::get_native_arch() + .inspect_err(|err| log::debug!("{err}")) + .map_err(|_| Error::Arch)? + .ok_or(Error::Arch)?; + + let arch = match arch { + talpid_platform_metadata::Architecture::X86 => VersionArchitecture::X86, + talpid_platform_metadata::Architecture::Arm64 => VersionArchitecture::Arm64, + }; + + Ok(arch) + } +} diff --git a/installer-downloader/src/lib.rs b/installer-downloader/src/lib.rs index bde7683cdc..a07d557d67 100644 --- a/installer-downloader/src/lib.rs +++ b/installer-downloader/src/lib.rs @@ -3,6 +3,8 @@ pub mod controller; #[cfg(any(target_os = "windows", target_os = "macos"))] pub mod delegate; #[cfg(any(target_os = "windows", target_os = "macos"))] +pub mod environment; +#[cfg(any(target_os = "windows", target_os = "macos"))] pub mod log; #[cfg(any(target_os = "windows", target_os = "macos"))] pub mod resource; diff --git a/installer-downloader/src/winapi_impl/mod.rs b/installer-downloader/src/winapi_impl/mod.rs index 15a9957c00..fe755009da 100644 --- a/installer-downloader/src/winapi_impl/mod.rs +++ b/installer-downloader/src/winapi_impl/mod.rs @@ -1,3 +1,4 @@ +use installer_downloader::environment::{Environment, Error as EnvError}; use native_windows_gui as nwg; use crate::delegate::{AppDelegate, AppDelegateQueue}; @@ -9,14 +10,27 @@ pub fn main() { nwg::init().expect("Failed to init Native Windows GUI"); nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font"); + // Load "global" values and resources + let environment = match Environment::load() { + Ok(env) => env, + Err(error) => fatal_environment_error(error), + }; + let window = ui::AppWindow::default(); let window = window.layout().unwrap(); let queue = window.borrow().queue(); queue.queue_main(|window| { - crate::controller::initialize_controller(window); + crate::controller::initialize_controller(window, environment); }); nwg::dispatch_thread_events(); } + +fn fatal_environment_error(error: EnvError) -> ! { + let content = match error { + EnvError::Arch => "Failed to detect CPU architecture", + }; + nwg::fatal_message(installer_downloader::resource::WINDOW_TITLE, content) +} |
