diff --git a/MetaforceInstaller.Core/Services/AdbService.cs b/MetaforceInstaller.Core/Services/AdbService.cs index ddf790f..07ca0ed 100644 --- a/MetaforceInstaller.Core/Services/AdbService.cs +++ b/MetaforceInstaller.Core/Services/AdbService.cs @@ -15,9 +15,15 @@ public class AdbService : IAdbService private readonly ILogger _logger; private readonly AdbClient _adbClient; private DeviceData _deviceData; + private DeviceMonitor? _deviceMonitor; public event EventHandler? ProgressChanged; public event EventHandler? StatusChanged; + public EventHandler? DeviceConnected; + public EventHandler? DeviceDisconnected; + public EventHandler? DeviceChanged; + + public bool IsDeviceConnected => _deviceData != null && _deviceData.State == DeviceState.Online; public AdbService(ILogger? logger = null) { @@ -27,6 +33,46 @@ public class AdbService : IAdbService var serverStatus = server.StartServer(adbPath, restartServerIfNewer: false); _adbClient = new AdbClient(); RefreshDeviceData(); + StartDeviceMonitoring(); + } + + private void StartDeviceMonitoring() + { + try + { + _deviceMonitor = new DeviceMonitor(new AdbSocket(_adbClient.EndPoint)); + _deviceMonitor.DeviceConnected += OnDeviceConnected; + _deviceMonitor.DeviceDisconnected += OnDeviceDisconnected; + _deviceMonitor.DeviceChanged += OnDeviceChanged; + _deviceMonitor.Start(); + + _logger.LogInformation("Device monitoring started"); + } + catch (Exception ex) + { + _logger.LogError($"Failed to start device monitoring: {ex.Message}"); + } + } + + private void OnDeviceConnected(object? sender, DeviceDataEventArgs e) + { + _logger.LogInformation($"Device conn: {e.Device.Serial}"); + RefreshDeviceData(); + DeviceConnected?.Invoke(this, e); + } + + private void OnDeviceDisconnected(object? sender, DeviceDataEventArgs e) + { + _logger.LogInformation($"Device disconnected: {e.Device.Serial}"); + RefreshDeviceData(); + DeviceDisconnected?.Invoke(this, e); + } + + private void OnDeviceChanged(object? sender, DeviceDataEventArgs e) + { + _logger.LogInformation($"Device changed: {e.Device.Serial}"); + RefreshDeviceData(); + DeviceChanged?.Invoke(this, e); } public void RefreshDeviceData() @@ -163,7 +209,7 @@ public class AdbService : IAdbService () => { _adbClient.ExecuteRemoteCommand($"mkdir -p \"{remoteDir}\"", _deviceData, reciever); }, cancellationToken); } - + _logger.LogInformation($"Ensured remote directory: {remoteDir}"); await Task.Run(() => @@ -203,4 +249,15 @@ public class AdbService : IAdbService { return new DeviceInfo(_deviceData.Serial, _deviceData.State.ToString(), _deviceData.Model, _deviceData.Name); } + + public void Dispose() + { + if (_deviceMonitor != null) + { + _deviceMonitor.DeviceConnected -= OnDeviceConnected; + _deviceMonitor.DeviceDisconnected -= OnDeviceDisconnected; + _deviceMonitor.DeviceChanged -= OnDeviceChanged; + _deviceMonitor.Dispose(); + } + } } \ No newline at end of file diff --git a/MetaforceInstaller.UI/ViewModels/MainWindowViewModel.cs b/MetaforceInstaller.UI/ViewModels/MainWindowViewModel.cs index 6a81dcd..6fbef5c 100644 --- a/MetaforceInstaller.UI/ViewModels/MainWindowViewModel.cs +++ b/MetaforceInstaller.UI/ViewModels/MainWindowViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; +using Avalonia.Media; using MetaforceInstaller.Core.Models; namespace MetaforceInstaller.UI.ViewModels; @@ -12,6 +13,42 @@ public class MainWindowViewModel : INotifyPropertyChanged public ObservableCollection Installations { get; set; } = new(); + private bool _isDeviceConnected; + + public bool IsDeviceConnected + { + get => _isDeviceConnected; + set + { + if (_isDeviceConnected != value) + { + _isDeviceConnected = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(StatusColor)); + OnPropertyChanged(nameof(StatusText)); + } + } + } + + private string _deviceSerial = string.Empty; + + public string DeviceSerial + { + get => _deviceSerial; + set + { + if (_deviceSerial != value) + { + _deviceSerial = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(StatusText)); + } + } + } + + public IBrush StatusColor => IsDeviceConnected ? Brushes.Green : Brushes.Red; + public string StatusText => IsDeviceConnected ? $"Connected to {_deviceSerial}" : "Not connected"; + public void LoadInstallations(IEnumerable data) { Installations.Clear(); diff --git a/MetaforceInstaller.UI/Windows/MainWindow.axaml b/MetaforceInstaller.UI/Windows/MainWindow.axaml index eaaf434..9e4547b 100644 --- a/MetaforceInstaller.UI/Windows/MainWindow.axaml +++ b/MetaforceInstaller.UI/Windows/MainWindow.axaml @@ -75,7 +75,10 @@ - \ No newline at end of file diff --git a/MetaforceInstaller.UI/Windows/MainWindow.axaml.cs b/MetaforceInstaller.UI/Windows/MainWindow.axaml.cs index ee23eb4..8ab161b 100644 --- a/MetaforceInstaller.UI/Windows/MainWindow.axaml.cs +++ b/MetaforceInstaller.UI/Windows/MainWindow.axaml.cs @@ -1,8 +1,10 @@ using System; using System.Diagnostics; using System.Reflection; +using AdvancedSharpAdbClient.Models; using Avalonia.Controls; using Avalonia.Interactivity; +using Avalonia.Threading; using MetaforceInstaller.Core.Intefaces; using MetaforceInstaller.Core.Models; using MetaforceInstaller.Core.Services; @@ -14,6 +16,7 @@ public partial class MainWindow : Window { private MainWindowViewModel _viewModel; private IStorageService _storageService; + private AdbService _adbService; public MainWindow() { @@ -21,14 +24,68 @@ public partial class MainWindow : Window _viewModel = new MainWindowViewModel(); _storageService = new StorageService(); + _adbService = new AdbService(); + DataContext = _viewModel; - + VersionLabel.Content = Assembly.GetExecutingAssembly() .GetCustomAttribute()?.Version; NewInstallationButton.Click += OnNewInstalltionClick; - + + _adbService.DeviceConnected += OnAdbDeviceConnected; + _adbService.DeviceDisconnected += OnAdbDeviceDisconnected; + _adbService.DeviceChanged += OnAdbDeviceChanged; + LoadInstallations(); + UpdateDeviceStatus(); + } + + private void UpdateDeviceStatus() + { + var isConnected = _adbService.IsDeviceConnected; + _viewModel.IsDeviceConnected = isConnected; + + if (isConnected) + { + try + { + var deviceInfo = _adbService.GetDeviceInfo(); + _viewModel.DeviceSerial = deviceInfo.SerialNumber; + } + catch + { + _viewModel.DeviceSerial = "Unknown"; + } + } + else + { + _viewModel.DeviceSerial = string.Empty; + } + } + + private void OnAdbDeviceConnected(object? sender, DeviceDataEventArgs e) + { + Dispatcher.UIThread.Post(() => + { + UpdateDeviceStatus(); + }); + } + + private void OnAdbDeviceDisconnected(object? sender, DeviceDataEventArgs e) + { + Dispatcher.UIThread.Post(() => + { + UpdateDeviceStatus(); + }); + } + + private void OnAdbDeviceChanged(object? sender, DeviceDataEventArgs e) + { + Dispatcher.UIThread.Post(() => + { + UpdateDeviceStatus(); + }); } private void LoadInstallations() @@ -52,7 +109,7 @@ public partial class MainWindow : Window Console.WriteLine($"Delete {name}"); } } - + public async void OnLaunchServerClick(object? sender, RoutedEventArgs e) { if (sender is Button button && button.DataContext is InstallationData installationData) @@ -80,4 +137,14 @@ public partial class MainWindow : Window Process.Start(processInfo); } } + + protected override void OnClosed(EventArgs e) + { + _adbService.DeviceConnected -= OnAdbDeviceConnected; + _adbService.DeviceDisconnected -= OnAdbDeviceDisconnected; + _adbService.DeviceChanged -= OnAdbDeviceChanged; + _adbService.Dispose(); + + base.OnClosed(e); + } } \ No newline at end of file