mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-08-13 22:50:26 +02:00
refactor: cleanup
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::browser::{create_browser, BrowserType, ProxySettings};
|
||||
use crate::browser::ProxySettings;
|
||||
use crate::camoufox_manager::{CamoufoxConfig, CamoufoxManager};
|
||||
use crate::cloud_auth::CLOUD_AUTH;
|
||||
use crate::downloaded_browsers_registry::DownloadedBrowsersRegistry;
|
||||
@@ -98,9 +98,9 @@ impl BrowserRunner {
|
||||
app_handle: tauri::AppHandle,
|
||||
profile: &BrowserProfile,
|
||||
url: Option<String>,
|
||||
local_proxy_settings: Option<&ProxySettings>,
|
||||
_local_proxy_settings: Option<&ProxySettings>,
|
||||
remote_debugging_port: Option<u16>,
|
||||
headless: bool,
|
||||
_headless: bool,
|
||||
) -> Result<BrowserProfile, Box<dyn std::error::Error + Send + Sync>> {
|
||||
// Handle Camoufox profiles using CamoufoxManager
|
||||
if profile.browser == "camoufox" {
|
||||
@@ -613,248 +613,12 @@ impl BrowserRunner {
|
||||
return Ok(updated_profile);
|
||||
}
|
||||
|
||||
// Create browser instance
|
||||
let browser_type = BrowserType::from_str(&profile.browser)
|
||||
.map_err(|_| format!("Invalid browser type: {}", profile.browser))?;
|
||||
let browser = create_browser(browser_type.clone());
|
||||
|
||||
// Get executable path using common helper
|
||||
let executable_path = self
|
||||
.get_browser_executable_path(profile)
|
||||
.expect("Failed to get executable path");
|
||||
|
||||
log::info!("Executable path: {executable_path:?}");
|
||||
|
||||
// Prepare the executable (set permissions, etc.)
|
||||
if let Err(e) = browser.prepare_executable(&executable_path) {
|
||||
log::warn!("Warning: Failed to prepare executable: {e}");
|
||||
// Continue anyway, the error might not be critical
|
||||
}
|
||||
|
||||
// Refresh cloud proxy credentials if needed before resolving
|
||||
let _stored_proxy_settings = self
|
||||
.resolve_proxy_with_refresh(profile.proxy_id.as_ref(), Some(&profile.id.to_string()))
|
||||
.await;
|
||||
|
||||
// Use provided local proxy for Chromium-based browsers launch arguments
|
||||
let proxy_for_launch_args: Option<&ProxySettings> = local_proxy_settings;
|
||||
|
||||
// Get profile data path and launch arguments
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
let profile_data_path = profile.get_profile_data_path(&profiles_dir);
|
||||
let browser_args = browser
|
||||
.create_launch_args(
|
||||
&profile_data_path.to_string_lossy(),
|
||||
proxy_for_launch_args,
|
||||
url,
|
||||
remote_debugging_port,
|
||||
headless,
|
||||
)
|
||||
.expect("Failed to create launch arguments");
|
||||
|
||||
// Launch browser using platform-specific method
|
||||
let child = {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
platform_browser::macos::launch_browser_process(&executable_path, &browser_args).await?
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
platform_browser::windows::launch_browser_process(&executable_path, &browser_args).await?
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
platform_browser::linux::launch_browser_process(&executable_path, &browser_args).await?
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
|
||||
{
|
||||
return Err("Unsupported platform for browser launching".into());
|
||||
}
|
||||
};
|
||||
|
||||
let launcher_pid = child.id();
|
||||
|
||||
log::info!(
|
||||
"Launched browser with launcher PID: {} for profile: {} (ID: {})",
|
||||
launcher_pid,
|
||||
profile.name,
|
||||
profile.id
|
||||
);
|
||||
|
||||
// On macOS, when launching via `open -a`, the child PID is the `open` helper.
|
||||
// Resolve and store the actual browser PID for all browser types.
|
||||
let actual_pid = {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
// Give the browser a moment to start
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
|
||||
|
||||
let system = System::new_all();
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
let profile_data_path = profile.get_profile_data_path(&profiles_dir);
|
||||
let profile_data_path_str = profile_data_path.to_string_lossy();
|
||||
|
||||
let mut resolved_pid = launcher_pid;
|
||||
|
||||
for (pid, process) in system.processes() {
|
||||
let cmd = process.cmd();
|
||||
if cmd.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine if this process matches the intended browser type
|
||||
let exe_name_lower = process.name().to_string_lossy().to_lowercase();
|
||||
let is_correct_browser = match profile.browser.as_str() {
|
||||
"firefox" => {
|
||||
exe_name_lower.contains("firefox")
|
||||
&& !exe_name_lower.contains("developer")
|
||||
&& !exe_name_lower.contains("camoufox")
|
||||
}
|
||||
"firefox-developer" => {
|
||||
// More flexible detection for Firefox Developer Edition
|
||||
(exe_name_lower.contains("firefox") && exe_name_lower.contains("developer"))
|
||||
|| (exe_name_lower.contains("firefox")
|
||||
&& cmd.iter().any(|arg| {
|
||||
let arg_str = arg.to_str().unwrap_or("");
|
||||
arg_str.contains("Developer")
|
||||
|| arg_str.contains("developer")
|
||||
|| arg_str.contains("FirefoxDeveloperEdition")
|
||||
|| arg_str.contains("firefox-developer")
|
||||
}))
|
||||
|| exe_name_lower == "firefox" // Firefox Developer might just show as "firefox"
|
||||
}
|
||||
"zen" => exe_name_lower.contains("zen"),
|
||||
"chromium" => exe_name_lower.contains("chromium") || exe_name_lower.contains("chrome"),
|
||||
"brave" => exe_name_lower.contains("brave") || exe_name_lower.contains("Brave"),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !is_correct_browser {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for profile path match
|
||||
let profile_path_match = if matches!(
|
||||
profile.browser.as_str(),
|
||||
"firefox" | "firefox-developer" | "zen"
|
||||
) {
|
||||
// Firefox-based browsers: look for -profile argument followed by path
|
||||
let mut found_profile_arg = false;
|
||||
for (i, arg) in cmd.iter().enumerate() {
|
||||
if let Some(arg_str) = arg.to_str() {
|
||||
if arg_str == "-profile" && i + 1 < cmd.len() {
|
||||
if let Some(next_arg) = cmd.get(i + 1).and_then(|a| a.to_str()) {
|
||||
if next_arg == profile_data_path_str {
|
||||
found_profile_arg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also check for combined -profile=path format
|
||||
if arg_str == format!("-profile={profile_data_path_str}") {
|
||||
found_profile_arg = true;
|
||||
break;
|
||||
}
|
||||
// Check if the argument is the profile path directly
|
||||
if arg_str == profile_data_path_str {
|
||||
found_profile_arg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
found_profile_arg
|
||||
} else {
|
||||
// Chromium-based browsers: look for --user-data-dir argument
|
||||
cmd.iter().any(|s| {
|
||||
if let Some(arg) = s.to_str() {
|
||||
arg == format!("--user-data-dir={profile_data_path_str}")
|
||||
|| arg == profile_data_path_str
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
if profile_path_match {
|
||||
let pid_u32 = pid.as_u32();
|
||||
if pid_u32 != launcher_pid {
|
||||
resolved_pid = pid_u32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolved_pid
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
launcher_pid
|
||||
}
|
||||
};
|
||||
|
||||
// Update profile with process info and save
|
||||
let mut updated_profile = profile.clone();
|
||||
updated_profile.process_id = Some(actual_pid);
|
||||
updated_profile.last_launch = Some(SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs());
|
||||
|
||||
self.save_process_info(&updated_profile)?;
|
||||
let _ = crate::tag_manager::TAG_MANAGER.lock().map(|tm| {
|
||||
let _ = tm.rebuild_from_profiles(&self.profile_manager.list_profiles().unwrap_or_default());
|
||||
});
|
||||
|
||||
// Apply proxy settings if needed (for Firefox-based browsers)
|
||||
if profile.proxy_id.is_some()
|
||||
&& matches!(
|
||||
browser_type,
|
||||
BrowserType::Firefox | BrowserType::FirefoxDeveloper | BrowserType::Zen
|
||||
)
|
||||
{
|
||||
// Proxy settings for Firefox-based browsers are applied via user.js file
|
||||
// which is already handled in the profile creation process
|
||||
}
|
||||
|
||||
log::info!(
|
||||
"Emitting profile events for successful launch: {} (ID: {})",
|
||||
updated_profile.name,
|
||||
updated_profile.id
|
||||
);
|
||||
|
||||
// Emit profile update event to frontend
|
||||
if let Err(e) = events::emit("profile-updated", &updated_profile) {
|
||||
log::warn!("Warning: Failed to emit profile update event: {e}");
|
||||
}
|
||||
|
||||
// Emit minimal running changed event to frontend with a small delay to ensure UI consistency
|
||||
#[derive(Serialize)]
|
||||
struct RunningChangedPayload {
|
||||
id: String,
|
||||
is_running: bool,
|
||||
}
|
||||
let payload = RunningChangedPayload {
|
||||
id: updated_profile.id.to_string(),
|
||||
is_running: updated_profile.process_id.is_some(),
|
||||
};
|
||||
|
||||
if let Err(e) = events::emit("profile-running-changed", &payload) {
|
||||
log::warn!("Warning: Failed to emit profile running changed event: {e}");
|
||||
} else {
|
||||
log::info!(
|
||||
"Successfully emitted profile-running-changed event for {}: running={}",
|
||||
updated_profile.name,
|
||||
payload.is_running
|
||||
);
|
||||
}
|
||||
|
||||
Ok(updated_profile)
|
||||
Err(format!("Unsupported browser type: {}", profile.browser).into())
|
||||
}
|
||||
|
||||
pub async fn open_url_in_existing_browser(
|
||||
&self,
|
||||
app_handle: tauri::AppHandle,
|
||||
_app_handle: tauri::AppHandle,
|
||||
profile: &BrowserProfile,
|
||||
url: &str,
|
||||
_internal_proxy_settings: Option<&ProxySettings>,
|
||||
@@ -948,134 +712,7 @@ impl BrowserRunner {
|
||||
}
|
||||
}
|
||||
|
||||
// Use the comprehensive browser status check for non-camoufox/wayfern browsers
|
||||
let is_running = self
|
||||
.check_browser_status(app_handle.clone(), profile)
|
||||
.await?;
|
||||
|
||||
if !is_running {
|
||||
return Err("Browser is not running".into());
|
||||
}
|
||||
|
||||
// Get the updated profile with current PID
|
||||
let profiles = self
|
||||
.profile_manager
|
||||
.list_profiles()
|
||||
.expect("Failed to list profiles");
|
||||
let updated_profile = profiles
|
||||
.into_iter()
|
||||
.find(|p| p.id == profile.id)
|
||||
.unwrap_or_else(|| profile.clone());
|
||||
|
||||
// Ensure we have a valid process ID
|
||||
if updated_profile.process_id.is_none() {
|
||||
return Err("No valid process ID found for the browser".into());
|
||||
}
|
||||
|
||||
let browser_type = BrowserType::from_str(&updated_profile.browser)
|
||||
.map_err(|_| format!("Invalid browser type: {}", updated_profile.browser))?;
|
||||
|
||||
// Get browser directory for all platforms - path structure: binaries/<browser>/<version>/
|
||||
let mut browser_dir = self.get_binaries_dir();
|
||||
browser_dir.push(&updated_profile.browser);
|
||||
browser_dir.push(&updated_profile.version);
|
||||
|
||||
match browser_type {
|
||||
BrowserType::Firefox | BrowserType::FirefoxDeveloper | BrowserType::Zen => {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::macos::open_url_in_existing_browser_firefox_like(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::windows::open_url_in_existing_browser_firefox_like(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::linux::open_url_in_existing_browser_firefox_like(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
|
||||
return Err("Unsupported platform".into());
|
||||
}
|
||||
BrowserType::Camoufox => {
|
||||
// Camoufox URL opening is handled differently
|
||||
Err("URL opening in existing Camoufox instance is not supported".into())
|
||||
}
|
||||
BrowserType::Wayfern => {
|
||||
// Wayfern URL opening is handled differently
|
||||
Err("URL opening in existing Wayfern instance is not supported".into())
|
||||
}
|
||||
BrowserType::Chromium | BrowserType::Brave => {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::macos::open_url_in_existing_browser_chromium(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::windows::open_url_in_existing_browser_chromium(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
return platform_browser::linux::open_url_in_existing_browser_chromium(
|
||||
&updated_profile,
|
||||
url,
|
||||
browser_type,
|
||||
&browser_dir,
|
||||
&profiles_dir,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
|
||||
return Err("Unsupported platform".into());
|
||||
}
|
||||
}
|
||||
Err(format!("Unsupported browser type: {}", profile.browser).into())
|
||||
}
|
||||
|
||||
pub async fn launch_browser_with_debugging(
|
||||
@@ -1115,32 +752,6 @@ impl BrowserRunner {
|
||||
|
||||
let internal_proxy_settings = Some(internal_proxy.clone());
|
||||
|
||||
// Configure Firefox profiles to use local proxy
|
||||
{
|
||||
// For Firefox-based browsers, apply PAC/user.js to point to the local proxy
|
||||
if matches!(
|
||||
profile.browser.as_str(),
|
||||
"firefox" | "firefox-developer" | "zen"
|
||||
) {
|
||||
let profiles_dir = self.profile_manager.get_profiles_dir();
|
||||
let profile_path = profiles_dir.join(profile.id.to_string()).join("profile");
|
||||
|
||||
// Provide a dummy upstream (ignored when internal proxy is provided)
|
||||
let dummy_upstream = ProxySettings {
|
||||
proxy_type: "http".to_string(),
|
||||
host: "127.0.0.1".to_string(),
|
||||
port: internal_proxy.port,
|
||||
username: None,
|
||||
password: None,
|
||||
};
|
||||
|
||||
self
|
||||
.profile_manager
|
||||
.apply_proxy_settings_to_profile(&profile_path, &dummy_upstream, Some(&internal_proxy))
|
||||
.map_err(|e| format!("Failed to update profile proxy: {e}"))?;
|
||||
}
|
||||
}
|
||||
|
||||
let result = self
|
||||
.launch_browser_internal(
|
||||
app_handle.clone(),
|
||||
|
||||
Reference in New Issue
Block a user