From efe8812d48fe783c3c8871da0c54b7ef916b4998 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 9 Apr 2020 04:04:23 +0300 Subject: Added application information to login response. Several improvements and fixed. --- .../Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI') diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs index 66b982ffe..4b7d8978e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/ExternalBridgeViewVM.cs @@ -139,6 +139,9 @@ namespace Tango.PPC.UI.ViewModels if (!e.Request.Intent.RequiresPassword() || e.Request.Password == Settings.ExternalBridgePassword) { + e.ApplicationInformation.Version = ApplicationManager.Version.ToString(); + e.ApplicationInformation.StartupDate = ApplicationManager.StartUpDate.ToUniversalTime().ToString(); + e.Confirmed = true; Connection = e; -- cgit v1.3.1 From 76ebe53d89a1b0cbf21d66dc9f26dc95cc7b3be9 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 13 Apr 2020 03:41:41 +0300 Subject: FSE TUP --- .../Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj | 16 ++ .../Modules/Tango.FSE.Upgrade/ViewModelLocator.cs | 18 ++ .../ApplicationUpgradeGeneratedViewVM.cs | 182 +++++++++++++++++++++ .../ViewModels/ApplicationUpgradeViewVM.cs | 42 ++++- .../ViewModels/FirmwareUpgradeGeneratedViewVM.cs | 13 ++ .../Views/ApplicationUpgradeGeneratedView.xaml | 69 ++++++++ .../Views/ApplicationUpgradeGeneratedView.xaml.cs | 28 ++++ .../Views/FirmwareUpgradeGeneratedView.xaml | 16 ++ .../Views/FirmwareUpgradeGeneratedView.xaml.cs | 28 ++++ .../Modules/Tango.FSE.Upgrade/Views/MainView.xaml | 2 + .../FileSystem/FileSystemHandler.cs | 10 ++ .../FileSystem/IFileSystemProvider.cs | 9 + .../Navigation/INavigationBlocker.cs | 7 + .../Navigation/INavigationManager.cs | 13 +- .../RemoteUpgrade/IRemoteUpgradeManager.cs | 7 + .../FileSystem/DefaultFileSystemProvider.cs | 19 ++- .../Navigation/DefaultNavigationManager.cs | 81 +++++++-- .../RemoteUpgrade/DefaultRemoteUpgradeManager.cs | 99 ++++++++++- .../MachineUpdate/MachineUpdateManager.cs | 2 + .../StartRemoteApplicationRemoteUpgradeRequest.cs | 15 ++ .../StartRemoteApplicationRemoteUpgradeResponse.cs | 23 +++ .../PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj | 2 + .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 110 ++++++++++++- 23 files changed, 782 insertions(+), 29 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeRequest.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeResponse.cs (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj index daca836b7..fd8b99820 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj @@ -84,9 +84,17 @@ + + + ApplicationUpgradeGeneratedView.xaml + ApplicationUpgradeView.xaml + + + FirmwareUpgradeGeneratedView.xaml + FirmwareUpgradeView.xaml @@ -173,10 +181,18 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs index 739562ce3..1c6999c6d 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs @@ -16,6 +16,8 @@ namespace Tango.FSE.Upgrade TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); } public static MainViewVM MainViewVM @@ -49,5 +51,21 @@ namespace Tango.FSE.Upgrade return TangoIOC.Default.GetInstance(); } } + + public static ApplicationUpgradeGeneratedViewVM ApplicationUpgradeGeneratedViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } + + public static FirmwareUpgradeGeneratedViewVM FirmwareUpgradeGeneratedViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs new file mode 100644 index 000000000..f5dbb7270 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs @@ -0,0 +1,182 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.FSE.Common; +using Tango.FSE.Common.Navigation; +using Tango.FSE.Common.RemoteUpgrade; +using Tango.FSE.Upgrade.Views; +using static Tango.FSE.Upgrade.ViewModels.ApplicationUpgradeGeneratedViewVM; + +namespace Tango.FSE.Upgrade.ViewModels +{ + public class ApplicationUpgradeGeneratedViewVM : FSEViewModel, INavigationObjectReceiver + { + public class NavigationObject + { + public Machine SelectedMachine { get; set; } + public bool UpgradeNow { get; set; } + public String TupFileLocation { get; set; } + } + + private String _tupFileLocation; + public String TupFileLocation + { + get { return _tupFileLocation; } + set { _tupFileLocation = value; RaisePropertyChangedAuto(); } + } + + private bool _canUpgradeNow; + public bool CanUpgradeNow + { + get { return _canUpgradeNow; } + set { _canUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _canUpgradeNowError; + public String CanUpgradeNowError + { + get { return _canUpgradeNowError; } + set { _canUpgradeNowError = value; RaisePropertyChangedAuto(); } + } + + private bool _isUpgradeNow; + public bool IsUpgradeNow + { + get { return _isUpgradeNow; } + set { _isUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private Machine _selectedMachine; + public Machine SelectedMachine + { + get { return _selectedMachine; } + set { _selectedMachine = value; RaisePropertyChangedAuto(); } + } + + private RemoteUpgradeHandler _handler; + public RemoteUpgradeHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand StartUpgradeCommand { get; set; } + public RelayCommand ShowPackageInExplorerCommand { get; set; } + + public ApplicationUpgradeGeneratedViewVM() + { + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + StartUpgradeCommand = new RelayCommand(StartUpgrade, () => CanUpgradeNow && Handler.Status != RemoteUpgradeHandlerStatus.Completed); + ShowPackageInExplorerCommand = new RelayCommand(ShowPackageInExplorer); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); + MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); + } + + private void InvalidateCanUpgradeNow() + { + CanUpgradeNowError = null; + + if (!IsUpgradeNow) return; + + if (SelectedMachine == null) + { + CanUpgradeNow = false; + CanUpgradeNowError = "Target machine not specified."; + return; + } + + if (!MachineProvider.IsConnected) + { + CanUpgradeNow = false; + CanUpgradeNowError = "The selected machine is not currently connected."; + return; + } + + if (MachineProvider.Machine.Guid != SelectedMachine.Guid) + { + CanUpgradeNow = false; + CanUpgradeNowError = "The selected machine is different from the one currently connected."; + return; + } + + if (!MachineProvider.ConnectionType.IsRemote()) + { + CanUpgradeNow = false; + CanUpgradeNowError = "The current machine connection type does not support remote upgrade."; + return; + } + + CanUpgradeNow = true; + } + + private async void StartUpgrade() + { + try + { + IsFree = false; + Handler = await RemoteUpgradeManager.PerformRemoteApplicationUpgrade(TupFileLocation); + await Handler.WaitForCompletion(); + await Task.Delay(5000); + InvalidateRelayCommands(); + await NotificationProvider.ShowSuccess("Remote upgrade completed successfully!"); + + if (IsVisible) + { + await NavigationManager.NavigateTo(nameof(WelcomeView), false); + } + } + catch (OperationCanceledException) + { + //Aborted... + } + catch (Exception ex) + { + LogManager.Log("Error occurred while executing remote application upgrade."); + await NotificationProvider.ShowError($"Error occurred while executing the remote application upgrade.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void ShowPackageInExplorer() + { + throw new NotImplementedException(); + } + + public void OnNavigatedToWithObject(NavigationObject obj) + { + SelectedMachine = obj.SelectedMachine; + IsUpgradeNow = obj.UpgradeNow; + TupFileLocation = obj.TupFileLocation; + InvalidateCanUpgradeNow(); + } + + public override Task OnNavigateBackRequest() + { + if (IsFree) + { + return base.OnNavigateBackRequest(); + } + else + { + Task.Delay(100).ContinueWith((x) => + { + NavigationManager.NavigateTo(NavigationView.Home); + }, TaskScheduler.FromCurrentSynchronizationContext()); + + return Task.FromResult(false); + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs index c120b3f74..f7dae41e7 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core.Commands; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; +using Tango.FSE.Upgrade.Views; namespace Tango.FSE.Upgrade.ViewModels { @@ -25,6 +27,13 @@ namespace Tango.FSE.Upgrade.ViewModels public Machine SelectedMachine { get; set; } } + private ApplicationUpgradeMode _upgradeMode; + public ApplicationUpgradeMode UpgradeMode + { + get { return _upgradeMode; } + set { _upgradeMode = value; RaisePropertyChangedAuto(); } + } + private List _tangoVersions; public List TangoVersions { @@ -86,8 +95,19 @@ namespace Tango.FSE.Upgrade.ViewModels try { IsFree = false; - Handler = await RemoteUpgradeManager.CreateTupFile(SelectedVersion, SelectedMachine.SerialNumber, TupFileLocation); - await Handler.WaitForCompletion(); + //Handler = await RemoteUpgradeManager.CreateTupFile(SelectedVersion, SelectedMachine.SerialNumber, TupFileLocation); + //await Handler.WaitForCompletion(); + + await NavigationManager.NavigateWithObject< + UpgradeModule, + ApplicationUpgradeGeneratedView, + ApplicationUpgradeGeneratedViewVM.NavigationObject>( + new ApplicationUpgradeGeneratedViewVM.NavigationObject() + { + UpgradeNow = UpgradeMode == ApplicationUpgradeMode.ConnectedMachine, + SelectedMachine = SelectedMachine, + TupFileLocation = TupFileLocation + }, false); } catch (OperationCanceledException) { @@ -123,9 +143,27 @@ namespace Tango.FSE.Upgrade.ViewModels } } + public override Task OnNavigateBackRequest() + { + if (IsFree) + { + return base.OnNavigateBackRequest(); + } + else + { + Task.Delay(100).ContinueWith((x) => + { + NavigationManager.NavigateTo(NavigationView.Home); + }, TaskScheduler.FromCurrentSynchronizationContext()); + + return Task.FromResult(false); + } + } + public void OnNavigatedToWithObject(NavigationObject obj) { SelectedMachine = obj.SelectedMachine; + UpgradeMode = obj.ApplicationUpgradeMode; } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs new file mode 100644 index 000000000..3d190aa01 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Common; + +namespace Tango.FSE.Upgrade.ViewModels +{ + public class FirmwareUpgradeGeneratedViewVM : FSEViewModel + { + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml new file mode 100644 index 000000000..d70b496e7 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml @@ -0,0 +1,69 @@ + + + + Application Upgrade Ready! + + + Your machine application and firmware upgrade is ready. + + + + + You have chosen to upgrade the currently connected machine. + press 'start upgrade' to start upgrading remotely. + That is not currently possible due to the following reason: + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml.cs new file mode 100644 index 000000000..1bcc56b92 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.Upgrade.Views +{ + /// + /// Interaction logic for ApplicationUpgradeGeneratedView.xaml + /// + public partial class ApplicationUpgradeGeneratedView : UserControl + { + public ApplicationUpgradeGeneratedView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml new file mode 100644 index 000000000..08bb74b6b --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml @@ -0,0 +1,16 @@ + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml.cs new file mode 100644 index 000000000..687e8ca92 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.Upgrade.Views +{ + /// + /// Interaction logic for FirmwareUpgradeGeneratedView.xaml + /// + public partial class FirmwareUpgradeGeneratedView : UserControl + { + public FirmwareUpgradeGeneratedView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml index f06753409..efc9913ea 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml @@ -51,6 +51,8 @@ + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs index e74395ade..9cceb4fa3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/FileSystemHandler.cs @@ -14,6 +14,7 @@ namespace Tango.FSE.Common.FileSystem private FileSystemHandlerStatus _statusBeforePause; private System.Timers.Timer _transferRateTimer; private double _lastPosition; + private TaskCompletionSource _completionSource; public event EventHandler StatusChanged; @@ -93,6 +94,7 @@ namespace Tango.FSE.Common.FileSystem public FileSystemHandler(FileSystemHandlerType type, FileSystemItem fileSystemItem, String destination, Action abortAction) { + _completionSource = new TaskCompletionSource(); Type = type; FileSystemItem = fileSystemItem; Destination = destination; @@ -133,16 +135,19 @@ namespace Tango.FSE.Common.FileSystem { Status = FileSystemHandlerStatus.Failed; FailedException = exception; + _completionSource.SetException(exception); } internal void RaiseAborted() { Status = FileSystemHandlerStatus.Aborted; + _completionSource.SetException(new OperationCanceledException("File system operation aborted.")); } internal void RaiseCompleted() { Status = FileSystemHandlerStatus.Completed; + _completionSource.SetResult(Status); } public void Abort() @@ -150,5 +155,10 @@ namespace Tango.FSE.Common.FileSystem Status = FileSystemHandlerStatus.Aborted; _abortAction?.Invoke(); } + + public Task WaitForCompletion() + { + return _completionSource.Task; + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs index 169b1f771..cade631fa 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FileSystem/IFileSystemProvider.cs @@ -60,6 +60,15 @@ namespace Tango.FSE.Common.FileSystem /// Task Upload(String localSourcePath, FileSystemItem remoteFolder); + /// + /// Uploads the specified local file or folder. + /// + /// The local source path. + /// The remote destination path. + /// + /// Could not locate the local file or directory to upload. + Task Upload(String localSourcePath, String remotePath); + /// /// Copies the specified remote file or folder to the specified target remote folder. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs index 1cb81412c..0a96200ea 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationBlocker.cs @@ -17,5 +17,12 @@ namespace Tango.FSE.Common.Navigation /// /// Task OnNavigateOutRequest(); + + /// + /// Called before the navigation system navigates back from this object. + /// Return false to abort the navigation. + /// + /// + Task OnNavigateBackRequest(); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs index f22a2f931..e80d3e1f1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/INavigationManager.cs @@ -86,12 +86,6 @@ namespace Tango.FSE.Common.Navigation /// The view path. Task NavigateTo(bool pushToHistory = true, params String[] viewPath) where T : IFSEModule; - /// - /// Navigates to the specified module and view by full path (e.g Jobs.JobsView). - /// - /// The full path. - Task NavigateTo(String fullPath, bool pushToHistory = true, Action onNavigating = null, Action onNavigated = null); - /// /// Navigates to the specified module and view with the specified object and expecting a return parameter. /// The view must be of type INavigationResultProvider. @@ -121,5 +115,12 @@ namespace Tango.FSE.Common.Navigation /// Clears the navigation back history except the specified view type. /// void ClearHistoryExcept(); + + /// + /// Deletes the specified history item. + /// + /// The type of the module. + /// The type of the view. + void DeleteHistoryItem() where TModule : IFSEModule; } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs index 20bc9b3db..4d2389dc6 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs @@ -34,5 +34,12 @@ namespace Tango.FSE.Common.RemoteUpgrade /// The file path. /// Task CreateTfpFile(TangoVersion tangoVersion, String targetFilePath); + + /// + /// Performs a remote application upgrade using the specified .tup file. + /// + /// The .tup file. + /// + Task PerformRemoteApplicationUpgrade(String tupFile); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs index 3ab27fe1e..49dc35f72 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/FileSystem/DefaultFileSystemProvider.cs @@ -530,8 +530,21 @@ namespace Tango.FSE.UI.FileSystem /// Could not locate the local file or directory to upload. public Task Upload(String localSourcePath, FileSystemItem remoteFolder) { - String operationId = String.Empty; String destination = Path.Combine(remoteFolder.Path, Path.GetFileName(localSourcePath)); + return Upload(localSourcePath, destination); + } + + /// + /// Uploads the specified local file or folder. + /// + /// The local source path. + /// The remote destination path. + /// + /// Could not locate the local file or directory to upload. + public Task Upload(String localSourcePath, String remotePath) + { + String operationId = String.Empty; + String destination = remotePath; bool isFolder = false; bool aborted = false; @@ -539,13 +552,13 @@ namespace Tango.FSE.UI.FileSystem if (Directory.Exists(localSourcePath)) { - LogManager.Log($"Uploading local folder '{localSourcePath}' to remote path '{remoteFolder.Path}'..."); + LogManager.Log($"Uploading local folder '{localSourcePath}' to remote path '{destination}'..."); sourceItem = new FolderItem() { Path = localSourcePath }; isFolder = true; } else if (File.Exists(localSourcePath)) { - LogManager.Log($"Uploading local file '{localSourcePath}' to remote path '{remoteFolder.Path}'..."); + LogManager.Log($"Uploading local file '{localSourcePath}' to remote path '{destination}'..."); sourceItem = new FileItem() { Path = localSourcePath }; isFolder = false; } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs index fc196b239..0013986fe 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Navigation/DefaultNavigationManager.cs @@ -44,7 +44,6 @@ namespace Tango.FSE.UI.Navigation private Object _currentVM; private String _lastFullPath; private bool _preventHistory; - private bool _navigating_back; private Stack _navigationHistory; @@ -116,6 +115,7 @@ namespace Tango.FSE.UI.Navigation if (view == NavigationView.Home) { _navigationHistory.Clear(); + RaisePropertyChanged(nameof(CanNavigateBack)); _lastFullPath = null; var firstModule = _moduleLoader.UserModules.SingleOrDefault(x => x.Name == "Internal Module"); @@ -233,7 +233,7 @@ namespace Tango.FSE.UI.Navigation /// Navigates to the specified module and view by full path (e.g Jobs.JobsView). /// /// The full path. - public async Task NavigateTo(String fullPath, bool pushToHistory = true, Action onNavigating = null, Action onNavigated = null) + private async Task NavigateTo(String fullPath, bool pushToHistory = true, Action onNavigating = null, Action onNavigated = null, bool navigatingBack = false) { try { @@ -253,22 +253,37 @@ namespace Tango.FSE.UI.Navigation if (path.Length == 1 && path[0] == CurrentModule.Name) return true; - LogManager.Log($"Navigating to: {fullPath}..."); - var fromVM = _currentVM; if (_currentVM != null && _currentVM is INavigationBlocker) { - if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + if (navigatingBack) + { + if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) + { + return false; + } + } + else { - return false; + if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) + { + return false; + } } } + LogManager.Log($"Navigating to: {fullPath}..."); + if (pushToHistory && _lastFullPath != null && !_preventHistory) { - _navigationHistory.Push(_lastFullPath); + if (_navigationHistory.Count == 0 || _navigationHistory.Peek() != _lastFullPath) + { + _navigationHistory.Push(_lastFullPath); + } RaisePropertyChanged(nameof(CanNavigateBack)); + + DistinctNavigationHistory(); } _lastFullPath = fullPath; @@ -376,7 +391,8 @@ namespace Tango.FSE.UI.Navigation } catch (Exception ex) { - await _notificationProvider.ShowError($"Error navigating to '{fullPath}'."); + LogManager.Log(ex, $"Error navigating to '{fullPath}'."); + _notificationProvider.PushErrorReportingSnackbar(ex, "Navigation Error", $"Error navigating to '{fullPath}'."); return false; } } @@ -479,25 +495,34 @@ namespace Tango.FSE.UI.Navigation { LogManager.Log("Navigating back..."); - _navigating_back = true; + if (_navigationHistory.Count > 0) + { + while (_navigationHistory.Peek() == _lastFullPath) + { + _navigationHistory.Pop(); + } + } + + RaisePropertyChanged(nameof(CanNavigateBack)); if (_navigationHistory.Count > 0) { String first = _navigationHistory.Pop(); _preventHistory = true; - if (await NavigateTo(first)) + if (await NavigateTo(first, true, null, null, true)) { RaisePropertyChanged(nameof(CanNavigateBack)); _preventHistory = false; - _navigating_back = false; return true; } else { - _navigationHistory.Push(first); + if (_navigationHistory.Count == 0 || _navigationHistory.Peek() != first) + { + _navigationHistory.Push(first); + } _preventHistory = false; - _navigating_back = false; RaisePropertyChanged(nameof(CanNavigateBack)); return false; } @@ -507,7 +532,6 @@ namespace Tango.FSE.UI.Navigation await NavigateTo(NavigationView.Home); RaisePropertyChanged(nameof(CanNavigateBack)); _preventHistory = false; - _navigating_back = false; return true; } } @@ -532,6 +556,7 @@ namespace Tango.FSE.UI.Navigation var history_list = _navigationHistory.ToList(); history_list = history_list.Where(x => x.Contains(typeof(T).Name)).Distinct().ToList(); + history_list.Reverse(); _navigationHistory.Clear(); foreach (var item in history_list) @@ -578,5 +603,33 @@ namespace Tango.FSE.UI.Navigation awaiter.Action(); } } + + public void DeleteHistoryItem() where TModule : IFSEModule + { + var history_list = _navigationHistory.ToList(); + history_list = history_list.Where(x => x != typeof(TModule).Name + "." + typeof(TView).Name).ToList(); + history_list.Reverse(); + _navigationHistory.Clear(); + + foreach (var item in history_list) + { + _navigationHistory.Push(item); + } + } + + private void DistinctNavigationHistory() + { + var history_list = _navigationHistory.Distinct().ToList(); + history_list = history_list.ToList(); + history_list.Reverse(); + _navigationHistory.Clear(); + + foreach (var item in history_list) + { + _navigationHistory.Push(item); + } + + RaisePropertyChanged(nameof(CanNavigateBack)); + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs index 83cf6ecf7..eb57717cb 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs @@ -14,14 +14,17 @@ using Tango.Core.DB; using Tango.Core.DI; using Tango.Core.ExtensionMethods; using Tango.Core.Threading; +using Tango.FileSystem; using Tango.FSE.BL.Web; using Tango.FSE.Common; using Tango.FSE.Common.Authentication; using Tango.FSE.Common.Connection; +using Tango.FSE.Common.FileSystem; using Tango.FSE.Common.MachineUpdates; using Tango.FSE.Common.RemoteUpgrade; using Tango.FSE.Web.Messages; using Tango.PPC.Common.Publish; +using Tango.PPC.Shared.RemoteUpgrade; using Tango.PPC.Shared.Updates; using Tango.SQLExaminer; using Tango.Transport; @@ -39,6 +42,7 @@ namespace Tango.FSE.UI.RemoteUpgrade private IMachineProvider MachineProvider { get; set; } private FSEWebClient WebClient { get; set; } private IAuthenticationProvider AuthenticationProvider { get; set; } + private IFileSystemProvider FileSystemProvider { get; set; } /// /// Initializes a new instance of the class. @@ -46,11 +50,12 @@ namespace Tango.FSE.UI.RemoteUpgrade /// The authentication provider. /// The machine provider. /// The web client. - public DefaultRemoteUpgradeManager(IAuthenticationProvider authenticationProvider, IMachineProvider machineProvider, FSEWebClient webClient) + public DefaultRemoteUpgradeManager(IAuthenticationProvider authenticationProvider, IMachineProvider machineProvider, FSEWebClient webClient, IFileSystemProvider fileSystemProvider) { AuthenticationProvider = authenticationProvider; MachineProvider = machineProvider; WebClient = webClient; + FileSystemProvider = fileSystemProvider; } /// @@ -388,5 +393,97 @@ namespace Tango.FSE.UI.RemoteUpgrade return Task.FromResult(handler); } + + /// + /// Performs a remote application upgrade using the specified .tup file. + /// + /// The .tup file. + /// + public Task PerformRemoteApplicationUpgrade(string tupFile) + { + RemoteUpgradeHandler handler = new RemoteUpgradeHandler(() => { }); + + ThreadFactory.StartNew(() => + { + try + { + Thread.Sleep(100); + + LogManager.Log($"Starting remote application upgrade for the currently connected machine '{MachineProvider.Machine.SerialNumber}'..."); + + handler.UpdateProgress("Validating machine connection state..."); + LogManager.Log("Validating machine connection state..."); + + if (!MachineProvider.IsConnected) + { + throw new InvalidOperationException("Machine is disconnected."); + } + + if (!MachineProvider.ConnectionType.IsRemote()) + { + throw new InvalidOperationException("The current machine connection does not support remote application upgrade."); + } + + if (!File.Exists(tupFile)) + { + throw new FileNotFoundException("Could not locate the specified package file."); + } + + handler.UpdateProgress("Uploading application package file..."); + + LogManager.Log("Retrieving remote temporary folder..."); + var remoteTempFolder = FileSystemProvider.GetFolder("%temp%").Result as FileSystemItem; + var remoteTempFile = Path.Combine(remoteTempFolder.Path, Path.GetTempFileName()); + + LogManager.Log("Uploading tup file to remote machine..."); + var uploadHandler = FileSystemProvider.Upload(tupFile, remoteTempFile).Result; + uploadHandler.PropertyChanged += (_, __) => + { + handler.UpdateProgress("Uploading application package file...", false, uploadHandler.Position, uploadHandler.Length); + }; + var status = uploadHandler.WaitForCompletion().Result; + LogManager.Log("Tup upload completed successfully. Sending remote upgrade request..."); + + TaskCompletionSource completionSource = new TaskCompletionSource(); + + MachineProvider.MachineOperator.SendGenericContinuousRequest(new StartRemoteApplicationRemoteUpgradeRequest() + { + RemoteTupFilePath = remoteTempFile, + SetupFirmware = true, + SetupFPGA = true + }, new TransportContinuousRequestConfig() + { + ContinuousTimeout = TimeSpan.FromSeconds(30), + Timeout = TimeSpan.FromSeconds(10) + }).Subscribe((response) => + { + //Response.. + handler.Message = response.Message; + handler.IsIndeterminate = response.IsIndeterminate; + handler.Progress = response.Progress; + handler.Maximum = response.Maximum; + }, (ex) => + { + //Failed + completionSource.SetException(ex); + }, () => + { + //Completed + completionSource.SetResult(true); + }); + + var waitForCompletion = completionSource.Task.Result; + + handler.RaiseCompleted(); + } + catch (Exception ex) + { + handler.UpdateProgress($"Remote application upgrade failed. {ex.Message}", false, 0, 100); + handler.RaiseFailed(ex); + } + }); + + return Task.FromResult(handler); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs index 9a12552bc..2dfea3ff3 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -35,6 +35,8 @@ using Tango.PPC.Common.ExternalBridge; using Tango.Integration.ExternalBridge; using Tango.BL.DTO; using Tango.PPC.Shared.Updates; +using Tango.PPC.Shared.RemoteUpgrade; +using Tango.Core.Threading; namespace Tango.PPC.Common.MachineUpdate { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeRequest.cs new file mode 100644 index 000000000..035e08775 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.RemoteUpgrade +{ + public class StartRemoteApplicationRemoteUpgradeRequest + { + public String RemoteTupFilePath { get; set; } + public bool SetupFirmware { get; set; } = true; + public bool SetupFPGA { get; set; } = true; + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeResponse.cs new file mode 100644 index 000000000..ce8010793 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeResponse.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.RemoteUpgrade +{ + public class StartRemoteApplicationRemoteUpgradeResponse + { + public String Message { get; set; } + public bool IsIndeterminate { get; set; } + public double Progress { get; set; } + public double Maximum { get; set; } + + public StartRemoteApplicationRemoteUpgradeResponse() + { + Message = "Initializing..."; + IsIndeterminate = true; + Maximum = 100; + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj index 96c18129a..04012cf7b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj @@ -80,6 +80,8 @@ Settings.settings True + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs index 3942a1b84..8a8b87c97 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -5,24 +5,29 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Tango.BL; using Tango.Core.Commands; using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; +using Tango.Core.Threading; using Tango.Explorer; +using Tango.Integration.ExternalBridge; using Tango.PMR.FirmwareUpgrade; using Tango.PPC.Common; +using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Common.MachineUpdate; using Tango.PPC.Common.Publish; using Tango.PPC.Common.Web; +using Tango.PPC.Shared.RemoteUpgrade; using Tango.PPC.UI.Dialogs; using Tango.PPC.UI.Notifications.NotificationItems; using Tango.PPC.UI.ViewsContracts; namespace Tango.PPC.UI.ViewModels { - public class MachineUpdateViewVM : PPCViewModel + public class MachineUpdateViewVM : PPCViewModel, IExternalBridgeRequestHandler { public enum MachineUpdateView { @@ -114,9 +119,10 @@ namespace Tango.PPC.UI.ViewModels #region Constructors - public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager) + public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager, IPPCExternalBridgeService externalBridge) { MachineUpdateManager = machineUpdateManager; + externalBridge.RegisterRequestHandler(this); CompleteCommand = new RelayCommand(CompleteUpdate); UpdateCommand = new RelayCommand(Update); @@ -491,7 +497,7 @@ namespace Tango.PPC.UI.ViewModels LogManager.Log("Firmware upgrade from package completed."); _update_result = new MachineUpdateResult() { - RequiresBinariesUpdate = false, + RequiresBinariesUpdate = false, }; await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -540,5 +546,103 @@ namespace Tango.PPC.UI.ViewModels } #endregion + + #region External Bridge Handler + + [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteApplicationRemoteUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnStartRemoteApplicationRemoteUpgradeRequest(StartRemoteApplicationRemoteUpgradeRequest request, String token, ExternalBridgeReceiver receiver) + { + await receiver.SendGenericResponse(new StartRemoteApplicationRemoteUpgradeResponse(), token); + + bool stopReporting = false; + + try + { + ThreadFactory.StartNew(async () => + { + while (!stopReporting) + { + if (MachineUpdateManager.Status != null) + { + try + { + await receiver.SendGenericResponse(new StartRemoteApplicationRemoteUpgradeResponse() + { + Message = MachineUpdateManager.Status.Message, + IsIndeterminate = MachineUpdateManager.Status.IsIntermediate, + Maximum = MachineUpdateManager.Status.Total, + Progress = MachineUpdateManager.Status.Progress + }, token); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error sending remote upgrade progress."); + } + } + + Thread.Sleep(500); + } + }); + + InvokeUI(() => + { + NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); + NavigateTo(MachineUpdateView.UpdateProgressView); + }); + + LogManager.Log("Starting machine update from package..."); + + try + { + _update_result = await MachineUpdateManager.UpdateFromTUP(request.RemoteTupFilePath, request.SetupFirmware, request.SetupFPGA); + LogManager.Log("Machine update from package completed."); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateCompletedView); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, "Machine update from package failed."); + FailedError = ex.FlattenMessage(); + + InvokeUI(() => + { + NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); + }); + } + + await receiver.SendGenericResponse(new StartRemoteApplicationRemoteUpgradeResponse() + { + IsIndeterminate = false, + Maximum = 100, + Progress = 100, + Message = "Completed" + }, token, new Transport.TransportResponseConfig() + { + Completed = true + }); + } + catch (Exception ex) + { + await receiver.SendErrorResponse(ex, token); + } + finally + { + try + { + File.Delete(request.RemoteTupFilePath); + } + catch { } + } + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + + } + + #endregion } } -- cgit v1.3.1 From 8f738753289dcb7118162122c5404d2a02b305f7 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 14 Apr 2020 06:23:25 +0300 Subject: FSE Tup/Tfp & WaitForReconnection. --- .../ViewModels/FileSystemViewVM.cs | 13 +- .../FSE/Modules/Tango.FSE.Upgrade/App.xaml | 2 + .../Tango.FSE.Upgrade/Images/flash_drive.png | Bin 0 -> 1005 bytes .../Tango.FSE.Upgrade/Images/upgrade_remotely.png | Bin 0 -> 1514 bytes .../Navigation/RemoteUpgradeNavigationManager.cs | 19 ++ .../Navigation/RemoteUpgradeView.cs | 17 ++ .../Tango.FSE.Upgrade/RemoteUpgradeViewModel.cs | 15 + .../Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj | 11 + .../Modules/Tango.FSE.Upgrade/Themes/Generic.xaml | 17 ++ .../Modules/Tango.FSE.Upgrade/ViewModelLocator.cs | 3 + .../ApplicationUpgradeGeneratedViewVM.cs | 136 +++++++-- .../ViewModels/ApplicationUpgradeViewVM.cs | 91 +++--- .../ViewModels/FirmwareUpgradeGeneratedViewVM.cs | 227 ++++++++++++++- .../ViewModels/FirmwareUpgradeViewVM.cs | 92 +++--- .../Tango.FSE.Upgrade/ViewModels/MainViewVM.cs | 19 +- .../Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs | 41 +-- .../Views/ApplicationUpgradeGeneratedView.xaml | 94 ++++--- .../Views/ApplicationUpgradeView.xaml | 79 +++--- .../Views/FirmwareUpgradeGeneratedView.xaml | 64 ++++- .../Views/FirmwareUpgradeView.xaml | 103 +++---- .../Modules/Tango.FSE.Upgrade/Views/MainView.xaml | 17 +- .../Tango.FSE.Upgrade/Views/MainView.xaml.cs | 3 + .../Tango.FSE.Upgrade/Views/WelcomeView.xaml | 78 +++-- .../Tango.FSE.BL/Services/TangoVersionsService.cs | 85 ++++++ .../Connection/IMachineProvider.cs | 9 + .../FSE/Tango.FSE.Common/Images/arrow_right.png | Bin 0 -> 827 bytes .../IModularNavigationNavigationManager.cs | 18 ++ .../Navigation/ModularNavigationFSEViewModel.cs | 15 + .../Navigation/ModularNavigationManager.cs | 158 +++++++++++ .../RemoteUpgrade/IRemoteUpgradeManager.cs | 7 + .../RemoteUpgrade/RemoteUpgradeHandler.cs | 5 + .../FSE/Tango.FSE.Common/Resources/Images.xaml | 1 + .../FSE/Tango.FSE.Common/Resources/Styles.xaml | 20 ++ .../Tango.FSE.Common/Storage/IStorageProvider.cs | 7 + .../FSE/Tango.FSE.Common/Tango.FSE.Common.csproj | 7 +- .../Visual_Studio/FSE/Tango.FSE.UI/App.xaml.cs | 59 ++-- .../Connection/DefaultMachineProvider.cs | 86 +++++- .../Dialogs/MachineWaitForConnectionView.xaml | 45 +++ .../Dialogs/MachineWaitForConnectionView.xaml.cs | 28 ++ .../Dialogs/MachineWaitForConnectionViewVM.cs | 86 ++++++ .../Tango.FSE.UI/Modules/DefaultFSEModuleLoader.cs | 13 + .../Navigation/DefaultNavigationManager.cs | 1 - .../RemoteUpgrade/DefaultRemoteUpgradeManager.cs | 313 +++++++++++++++++---- .../Tango.FSE.UI/Storage/DefaultStorageProvider.cs | 22 ++ .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 8 + .../StartRemoteApplicationRemoteUpgradeRequest.cs | 15 - .../StartRemoteApplicationRemoteUpgradeResponse.cs | 23 -- .../StartRemoteApplicationUpgradeRequest.cs | 15 + .../StartRemoteApplicationUpgradeResponse.cs | 23 ++ .../StartRemoteFirmwareUpgradeRequest.cs | 13 + .../StartRemoteFirmwareUpgradeResponse.cs | 23 ++ .../PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj | 6 +- .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 131 ++++++++- Software/Visual_Studio/Tango.Core/DI/TangoIOC.cs | 14 + .../VersionPackageDescriptorExtensions.cs | 2 +- .../Visual_Studio/Tango.SharedUI/DialogViewVM.cs | 17 ++ 56 files changed, 1931 insertions(+), 485 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/flash_drive.png create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/upgrade_remotely.png create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeNavigationManager.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeView.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/RemoteUpgradeViewModel.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Themes/Generic.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Images/arrow_right.png create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/IModularNavigationNavigationManager.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationFSEViewModel.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationManager.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/MachineWaitForConnectionView.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/MachineWaitForConnectionView.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/MachineWaitForConnectionViewVM.cs delete mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeRequest.cs delete mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationRemoteUpgradeResponse.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationUpgradeRequest.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteApplicationUpgradeResponse.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteFirmwareUpgradeRequest.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/RemoteUpgrade/StartRemoteFirmwareUpgradeResponse.cs (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs index 6dea5c146..4ed6629b5 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/FileSystemViewVM.cs @@ -377,20 +377,9 @@ namespace Tango.FSE.PPCConsole.ViewModels private async void OpenFileSystemHandlerDestination(FileSystemHandler handler) { - String destination = String.Empty; - if (handler.Type == FileSystemHandlerType.FileDownload || handler.Type == FileSystemHandlerType.FolderDownload) { - if (File.Exists(handler.Destination) || Directory.Exists(handler.Destination)) - { - destination = handler.Destination; - Process.Start("explorer.exe", string.Format("/select,\"{0}\"", destination)); - } - else - { - destination = Path.GetDirectoryName(handler.Destination); - Process.Start("explorer.exe", destination); - } + await StorageProvider.ShowInExplorer(handler.Destination); } else { diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/App.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/App.xaml index 4a079ca2b..82b6fac3a 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/App.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/App.xaml @@ -10,6 +10,8 @@ + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/flash_drive.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/flash_drive.png new file mode 100644 index 000000000..af5e22a3c Binary files /dev/null and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/flash_drive.png differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/upgrade_remotely.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/upgrade_remotely.png new file mode 100644 index 000000000..1b60afb24 Binary files /dev/null and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/upgrade_remotely.png differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeNavigationManager.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeNavigationManager.cs new file mode 100644 index 000000000..7fccff816 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeNavigationManager.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.FSE.Common.Navigation; +using Tango.FSE.Upgrade.Views; +using Tango.SharedUI.Controls; + +namespace Tango.FSE.Upgrade.Navigation +{ + public class RemoteUpgradeNavigationManager : ModularNavigationManager + { + public RemoteUpgradeNavigationManager(FrameworkElement navigationControlParent) : base(navigationControlParent) + { + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeView.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeView.cs new file mode 100644 index 000000000..059d717f5 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Navigation/RemoteUpgradeView.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.Upgrade.Navigation +{ + public enum RemoteUpgradeView + { + WelcomeView, + ApplicationUpgradeView, + ApplicationUpgradeGeneratedView, + FirmwareUpgradeView, + FirmwareUpgradeGeneratedView + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/RemoteUpgradeViewModel.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/RemoteUpgradeViewModel.cs new file mode 100644 index 000000000..074fc5f87 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/RemoteUpgradeViewModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Common.Navigation; +using Tango.FSE.Upgrade.Navigation; + +namespace Tango.FSE.Upgrade +{ + public class RemoteUpgradeViewModel : ModularNavigationFSEViewModel + { + + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj index fd8b99820..a3acc4b19 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj @@ -78,6 +78,9 @@ + + + @@ -181,6 +184,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -226,6 +233,10 @@ + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Themes/Generic.xaml new file mode 100644 index 000000000..0bf1f9ffc --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Themes/Generic.xaml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs index 1c6999c6d..1ccb2330c 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModelLocator.cs @@ -4,7 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.DI; +using Tango.FSE.Upgrade.Navigation; using Tango.FSE.Upgrade.ViewModels; +using Tango.FSE.Upgrade.Views; namespace Tango.FSE.Upgrade { @@ -12,6 +14,7 @@ namespace Tango.FSE.Upgrade { static ViewModelLocator() { + TangoIOC.Default.Register(new RemoteUpgradeNavigationManager(MainView.Instance)); TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs index f5dbb7270..093937228 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeGeneratedViewVM.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using Tango.Core.Commands; +using Tango.Core.IO; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; using Tango.FSE.Common.RemoteUpgrade; @@ -13,20 +15,28 @@ using static Tango.FSE.Upgrade.ViewModels.ApplicationUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels { - public class ApplicationUpgradeGeneratedViewVM : FSEViewModel, INavigationObjectReceiver + public class ApplicationUpgradeGeneratedViewVM : RemoteUpgradeViewModel, INavigationObjectReceiver { public class NavigationObject { + public TangoVersion SelectedVersion { get; set; } public Machine SelectedMachine { get; set; } public bool UpgradeNow { get; set; } - public String TupFileLocation { get; set; } + public TemporaryFile TemporaryTupFile { get; set; } } private String _tupFileLocation; public String TupFileLocation { get { return _tupFileLocation; } - set { _tupFileLocation = value; RaisePropertyChangedAuto(); } + set { _tupFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private TemporaryFile _temporaryTupFile; + public TemporaryFile TemporaryTupFile + { + get { return _temporaryTupFile; } + set { _temporaryTupFile = value; InvalidateRelayCommands(); } } private bool _canUpgradeNow; @@ -50,6 +60,20 @@ namespace Tango.FSE.Upgrade.ViewModels set { _isUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } + private bool _isUpgradeNowSelected; + public bool IsUpgradeNowSelected + { + get { return _isUpgradeNowSelected; } + set { _isUpgradeNowSelected = value; RaisePropertyChangedAuto(); } + } + + private TangoVersion _selectedVersion; + public TangoVersion SelectedVersion + { + get { return _selectedVersion; } + set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + private Machine _selectedMachine; public Machine SelectedMachine { @@ -64,14 +88,23 @@ namespace Tango.FSE.Upgrade.ViewModels set { _handler = value; RaisePropertyChangedAuto(); } } + private bool _isCompleted; + public bool IsCompleted + { + get { return _isCompleted; } + set { _isCompleted = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + public RelayCommand StartUpgradeCommand { get; set; } - public RelayCommand ShowPackageInExplorerCommand { get; set; } + public RelayCommand SaveTupFileCommand { get; set; } + public RelayCommand SelectTupFileLocationCommand { get; set; } public ApplicationUpgradeGeneratedViewVM() { Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; StartUpgradeCommand = new RelayCommand(StartUpgrade, () => CanUpgradeNow && Handler.Status != RemoteUpgradeHandlerStatus.Completed); - ShowPackageInExplorerCommand = new RelayCommand(ShowPackageInExplorer); + SaveTupFileCommand = new RelayCommand(SaveTupFile, () => TupFileLocation != null); + SelectTupFileLocationCommand = new RelayCommand(SelectTupFileLocation, () => SelectedVersion != null && SelectedMachine != null); } public override void OnApplicationStarted() @@ -81,15 +114,26 @@ namespace Tango.FSE.Upgrade.ViewModels MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); } + private async void SelectTupFileLocation() + { + String fileName = $"{SelectedMachine.SerialNumber}_Update_{DateTime.Now.Date.ToFileName()}_v{SelectedVersion.Version}.tup"; + var result = await StorageProvider.SaveFile("Select update package location", "Tango Update Package|*.tup", fileName, ".tup"); + if (result) + { + TupFileLocation = result.SelectedItem; + } + } + private void InvalidateCanUpgradeNow() { CanUpgradeNowError = null; - if (!IsUpgradeNow) return; + if (!IsUpgradeNowSelected) return; if (SelectedMachine == null) { CanUpgradeNow = false; + IsUpgradeNowSelected = false; CanUpgradeNowError = "Target machine not specified."; return; } @@ -97,6 +141,7 @@ namespace Tango.FSE.Upgrade.ViewModels if (!MachineProvider.IsConnected) { CanUpgradeNow = false; + IsUpgradeNowSelected = false; CanUpgradeNowError = "The selected machine is not currently connected."; return; } @@ -104,6 +149,7 @@ namespace Tango.FSE.Upgrade.ViewModels if (MachineProvider.Machine.Guid != SelectedMachine.Guid) { CanUpgradeNow = false; + IsUpgradeNowSelected = false; CanUpgradeNowError = "The selected machine is different from the one currently connected."; return; } @@ -111,6 +157,7 @@ namespace Tango.FSE.Upgrade.ViewModels if (!MachineProvider.ConnectionType.IsRemote()) { CanUpgradeNow = false; + IsUpgradeNowSelected = false; CanUpgradeNowError = "The current machine connection type does not support remote upgrade."; return; } @@ -123,16 +170,10 @@ namespace Tango.FSE.Upgrade.ViewModels try { IsFree = false; - Handler = await RemoteUpgradeManager.PerformRemoteApplicationUpgrade(TupFileLocation); + Handler = await RemoteUpgradeManager.PerformRemoteApplicationUpgrade(TemporaryTupFile); await Handler.WaitForCompletion(); - await Task.Delay(5000); - InvalidateRelayCommands(); - await NotificationProvider.ShowSuccess("Remote upgrade completed successfully!"); - - if (IsVisible) - { - await NavigationManager.NavigateTo(nameof(WelcomeView), false); - } + IsCompleted = true; + await MachineProvider.DisconnectAndWaitForReconnection(TimeSpan.FromSeconds(20), TimeSpan.FromMinutes(1)); } catch (OperationCanceledException) { @@ -140,43 +181,78 @@ namespace Tango.FSE.Upgrade.ViewModels } catch (Exception ex) { - LogManager.Log("Error occurred while executing remote application upgrade."); - await NotificationProvider.ShowError($"Error occurred while executing the remote application upgrade.\n{ex.FlattenMessage()}"); + LogManager.Log(ex, "Error occurred while executing remote application upgrade."); } finally { + await TemporaryTupFile.DeleteAsync(); IsFree = true; + InvalidateRelayCommands(); } } - private void ShowPackageInExplorer() + private async void SaveTupFile() { - throw new NotImplementedException(); + try + { + File.Copy(TemporaryTupFile, TupFileLocation, true); + TemporaryTupFile.Delete(); + IsCompleted = true; + await NotificationProvider.ShowSuccess("Application upgrade package saved successfully."); + await ModularNavigationManager.NavigateBack(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error copying temporary tup file to selected location."); + await NotificationProvider.ShowError($"Error occurred while trying to save the application package file.\n{ex.FlattenMessage()}"); + } } public void OnNavigatedToWithObject(NavigationObject obj) { + SelectedVersion = obj.SelectedVersion; SelectedMachine = obj.SelectedMachine; IsUpgradeNow = obj.UpgradeNow; - TupFileLocation = obj.TupFileLocation; + IsUpgradeNowSelected = IsUpgradeNow; + TemporaryTupFile = obj.TemporaryTupFile; InvalidateCanUpgradeNow(); + InvalidateRelayCommands(); } - public override Task OnNavigateBackRequest() + public override void OnBeforeNavigatedTo() { - if (IsFree) - { - return base.OnNavigateBackRequest(); - } - else + base.OnBeforeNavigatedTo(); + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + IsCompleted = false; + SelectedVersion = null; + SelectedMachine = null; + IsUpgradeNow = false; + IsUpgradeNowSelected = false; + TemporaryTupFile = null; + InvalidateCanUpgradeNow(); + InvalidateRelayCommands(); + } + + public async override Task OnNavigateBackRequest() + { + if (!IsCompleted) { - Task.Delay(100).ContinueWith((x) => + var abort = await NotificationProvider.ShowWarningQuestion("Are you sure you want to abort the upgrade operation?"); + + if (Handler.CanAbort) + { + Handler.Abort(); + } + else { - NavigationManager.NavigateTo(NavigationView.Home); - }, TaskScheduler.FromCurrentSynchronizationContext()); + await NotificationProvider.ShowWarning("Cannot abort the operation at this stage."); + return false; + } - return Task.FromResult(false); + return abort; } + + return true; } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs index f7dae41e7..acad83d25 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs @@ -13,7 +13,7 @@ using Tango.FSE.Upgrade.Views; namespace Tango.FSE.Upgrade.ViewModels { - public class ApplicationUpgradeViewVM : FSEViewModel, INavigationObjectReceiver + public class ApplicationUpgradeViewVM : RemoteUpgradeViewModel, INavigationObjectReceiver { public enum ApplicationUpgradeMode { @@ -48,13 +48,6 @@ namespace Tango.FSE.Upgrade.ViewModels set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } - private String _tupFileLocation; - public String TupFileLocation - { - get { return _tupFileLocation; } - set { _tupFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } - } - private Machine _selectedMachine; public Machine SelectedMachine { @@ -69,25 +62,11 @@ namespace Tango.FSE.Upgrade.ViewModels set { _handler = value; RaisePropertyChangedAuto(); } } - public RelayCommand SelectTupFileLocationCommand { get; set; } - public RelayCommand GeneratePackageCommand { get; set; } public ApplicationUpgradeViewVM() { - SelectTupFileLocationCommand = new RelayCommand(SelectTupFileLocation, () => SelectedVersion != null && SelectedMachine != null); - GeneratePackageCommand = new RelayCommand(GeneratePackage, () => SelectedVersion != null && SelectedMachine != null && TupFileLocation != null); - Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; - } - - private async void SelectTupFileLocation() - { - String fileName = $"{SelectedMachine.SerialNumber}_Update_{DateTime.Now.Date.ToFileName()}_v{SelectedVersion.Version}.tup"; - var result = await StorageProvider.SaveFile("Select update package location", "Tango Update Package|*.tup", fileName, ".tup"); - if (result) - { - TupFileLocation = result.SelectedItem; - } + GeneratePackageCommand = new RelayCommand(GeneratePackage, () => SelectedVersion != null && SelectedMachine != null); } private async void GeneratePackage() @@ -95,19 +74,19 @@ namespace Tango.FSE.Upgrade.ViewModels try { IsFree = false; - //Handler = await RemoteUpgradeManager.CreateTupFile(SelectedVersion, SelectedMachine.SerialNumber, TupFileLocation); - //await Handler.WaitForCompletion(); - - await NavigationManager.NavigateWithObject< - UpgradeModule, - ApplicationUpgradeGeneratedView, - ApplicationUpgradeGeneratedViewVM.NavigationObject>( - new ApplicationUpgradeGeneratedViewVM.NavigationObject() - { - UpgradeNow = UpgradeMode == ApplicationUpgradeMode.ConnectedMachine, - SelectedMachine = SelectedMachine, - TupFileLocation = TupFileLocation - }, false); + + var temporaryTupFile = TemporaryManager.CreateImaginaryFile(".tup"); + + Handler = await RemoteUpgradeManager.CreateTupFile(SelectedVersion, SelectedMachine.SerialNumber, temporaryTupFile); + await Handler.WaitForCompletion(); + + await ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.ApplicationUpgradeGeneratedView, new ApplicationUpgradeGeneratedViewVM.NavigationObject() + { + SelectedVersion = SelectedVersion, + UpgradeNow = UpgradeMode == ApplicationUpgradeMode.ConnectedMachine, + SelectedMachine = SelectedMachine, + TemporaryTupFile = temporaryTupFile + }, false); } catch (OperationCanceledException) { @@ -115,8 +94,7 @@ namespace Tango.FSE.Upgrade.ViewModels } catch (Exception ex) { - LogManager.Log("Error generating remote upgrade package."); - await NotificationProvider.ShowError($"Error occurred while trying to generate the update package.\n{ex.FlattenMessage()}"); + LogManager.Log(ex, "Error generating remote upgrade package."); } finally { @@ -143,21 +121,29 @@ namespace Tango.FSE.Upgrade.ViewModels } } - public override Task OnNavigateBackRequest() + public async override Task OnNavigateBackRequest() { - if (IsFree) - { - return base.OnNavigateBackRequest(); - } - else + if (!IsFree) { - Task.Delay(100).ContinueWith((x) => + var abort = await NotificationProvider.ShowWarningQuestion("Are you sure you want to abort the upgrade operation?"); + + if (abort) { - NavigationManager.NavigateTo(NavigationView.Home); - }, TaskScheduler.FromCurrentSynchronizationContext()); + if (Handler.CanAbort) + { + Handler.Abort(); + } + else + { + await NotificationProvider.ShowError("Cannot abort the operation at the this stage."); + return false; + } + } - return Task.FromResult(false); + return abort; } + + return true; } public void OnNavigatedToWithObject(NavigationObject obj) @@ -165,5 +151,14 @@ namespace Tango.FSE.Upgrade.ViewModels SelectedMachine = obj.SelectedMachine; UpgradeMode = obj.ApplicationUpgradeMode; } + + public override void OnBeforeNavigatedTo() + { + base.OnBeforeNavigatedTo(); + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + SelectedMachine = null; + UpgradeMode = ApplicationUpgradeMode.OtherMachine; + InvalidateRelayCommands(); + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs index 3d190aa01..9537eb7d3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeGeneratedViewVM.cs @@ -1,13 +1,238 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; using Tango.FSE.Common; +using Tango.FSE.Common.Navigation; +using Tango.FSE.Common.RemoteUpgrade; +using static Tango.FSE.Upgrade.ViewModels.FirmwareUpgradeGeneratedViewVM; namespace Tango.FSE.Upgrade.ViewModels { - public class FirmwareUpgradeGeneratedViewVM : FSEViewModel + public class FirmwareUpgradeGeneratedViewVM : RemoteUpgradeViewModel, INavigationObjectReceiver { + public class NavigationObject + { + public TangoVersion SelectedVersion { get; set; } + public String TfpFileLocation { get; set; } + public bool IsExistingTfpFile { get; set; } + } + + private bool _isUsingExistingTfp; + public bool IsUsingExistingTfp + { + get { return _isUsingExistingTfp; } + set { _isUsingExistingTfp = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _tfpFileLocation; + public String TfpFileLocation + { + get { return _tfpFileLocation; } + set { _tfpFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _tfpFileLocationToSave; + public String TfpFileLocationToSave + { + get { return _tfpFileLocationToSave; } + set { _tfpFileLocationToSave = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private TangoVersion _selectedVersion; + public TangoVersion SelectedVersion + { + get { return _selectedVersion; } + set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _canUpgradeNow; + public bool CanUpgradeNow + { + get { return _canUpgradeNow; } + set { _canUpgradeNow = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _canUpgradeNowError; + public String CanUpgradeNowError + { + get { return _canUpgradeNowError; } + set { _canUpgradeNowError = value; RaisePropertyChangedAuto(); } + } + + private bool _isUpgradeNowSelected; + public bool IsUpgradeNowSelected + { + get { return _isUpgradeNowSelected; } + set { _isUpgradeNowSelected = value; RaisePropertyChangedAuto(); } + } + + private RemoteUpgradeHandler _handler; + public RemoteUpgradeHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + private bool _isCompleted; + public bool IsCompleted + { + get { return _isCompleted; } + set { _isCompleted = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + public RelayCommand StartUpgradeCommand { get; set; } + public RelayCommand SaveTfpFileCommand { get; set; } + public RelayCommand SelectTfpFileLocationCommand { get; set; } + + public FirmwareUpgradeGeneratedViewVM() + { + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + StartUpgradeCommand = new RelayCommand(StartUpgrade, () => CanUpgradeNow && Handler.Status != RemoteUpgradeHandlerStatus.Completed); + SaveTfpFileCommand = new RelayCommand(SaveTfpFile, () => TfpFileLocationToSave != null && !IsUsingExistingTfp); + SelectTfpFileLocationCommand = new RelayCommand(SelectTfpFileLocation, () => SelectedVersion != null); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + MachineProvider.MachineConnected += (_, __) => InvalidateCanUpgradeNow(); + MachineProvider.MachineDisconnected += (_, __) => InvalidateCanUpgradeNow(); + } + + private void InvalidateCanUpgradeNow() + { + CanUpgradeNowError = null; + + if (!IsUpgradeNowSelected) return; + + if (!MachineProvider.IsConnected) + { + CanUpgradeNow = false; + IsUpgradeNowSelected = false; + CanUpgradeNowError = "No active machine connection detected for remote upgrade."; + return; + } + + if (!MachineProvider.ConnectionType.IsRemote()) + { + CanUpgradeNow = false; + IsUpgradeNowSelected = false; + CanUpgradeNowError = "The current machine connection type does not support remote upgrade."; + return; + } + + CanUpgradeNow = true; + } + + private async void SaveTfpFile() + { + try + { + File.Copy(TfpFileLocation, TfpFileLocationToSave, true); + try + { + File.Delete(TfpFileLocation); + } + catch { } + IsCompleted = true; + await NotificationProvider.ShowSuccess("Firmware upgrade package saved successfully."); + await ModularNavigationManager.NavigateBack(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error copying temporary tfp file to selected location."); + await NotificationProvider.ShowError($"Error occurred while trying to save the firmware package file.\n{ex.FlattenMessage()}"); + } + } + + private async void StartUpgrade() + { + try + { + IsFree = false; + Handler = await RemoteUpgradeManager.PerformRemoteFirmwareUpgrade(TfpFileLocation); + await Handler.WaitForCompletion(); + IsCompleted = true; + await MachineProvider.DisconnectAndWaitForReconnection(TimeSpan.FromSeconds(20), TimeSpan.FromMinutes(1)); + } + catch (OperationCanceledException) + { + //Aborted... + } + catch (Exception ex) + { + LogManager.Log(ex, "Error occurred while executing remote firmware upgrade."); + } + finally + { + if (!IsUsingExistingTfp) + { + try + { + File.Delete(TfpFileLocation); + } + catch { } + } + + IsFree = true; + InvalidateRelayCommands(); + } + } + + private async void SelectTfpFileLocation() + { + String fileName = $"firmware_package_v{SelectedVersion.FirmwareVersion}.tfp"; + var result = await StorageProvider.SaveFile("Select firmware package location", "Tango Firmware Package|*.tfp", fileName, ".tfp"); + if (result) + { + TfpFileLocationToSave = result.SelectedItem; + } + } + + public override void OnBeforeNavigatedTo() + { + base.OnBeforeNavigatedTo(); + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + IsCompleted = false; + SelectedVersion = null; + IsUpgradeNowSelected = true; + TfpFileLocation = null; + InvalidateCanUpgradeNow(); + InvalidateRelayCommands(); + } + + public void OnNavigatedToWithObject(FirmwareUpgradeGeneratedViewVM.NavigationObject obj) + { + SelectedVersion = obj.SelectedVersion; + TfpFileLocation = obj.TfpFileLocation; + IsUsingExistingTfp = obj.IsExistingTfpFile; + } + + public async override Task OnNavigateBackRequest() + { + if (!IsCompleted) + { + var abort = await NotificationProvider.ShowWarningQuestion("Are you sure you want to abort the upgrade operation?"); + + if (Handler.CanAbort) + { + Handler.Abort(); + } + else + { + await NotificationProvider.ShowWarning("Cannot abort the operation at this stage."); + return false; + } + + return abort; + } + + return true; + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs index 0a2d0fdb3..fd07c7f6e 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs @@ -10,7 +10,7 @@ using Tango.FSE.Common.RemoteUpgrade; namespace Tango.FSE.Upgrade.ViewModels { - public class FirmwareUpgradeViewVM : FSEViewModel + public class FirmwareUpgradeViewVM : RemoteUpgradeViewModel { private List _tangoVersions; public List TangoVersions @@ -26,18 +26,18 @@ namespace Tango.FSE.Upgrade.ViewModels set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } - private String _tfpFileLocation; - public String TfpFileLocation + private bool _useExistingTfpFile; + public bool UseExistingTfpFile { - get { return _tfpFileLocation; } - set { _tfpFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + get { return _useExistingTfpFile; } + set { _useExistingTfpFile = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private String _existingTfpFileLocation; public String ExistingTfpFileLocation { get { return _existingTfpFileLocation; } - set { _existingTfpFileLocation = value; RaisePropertyChangedAuto(); } + set { _existingTfpFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } private RemoteUpgradeHandler _handler; @@ -47,25 +47,17 @@ namespace Tango.FSE.Upgrade.ViewModels set { _handler = value; RaisePropertyChangedAuto(); } } - private bool _useExistingTfpFile; - public bool UseExistingTfpFile - { - get { return _useExistingTfpFile; } - set { _useExistingTfpFile = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } - } - - public RelayCommand SelectTfpFileLocationCommand { get; set; } - public RelayCommand SelectExistingTfpFileLocationCommand { get; set; } public RelayCommand GeneratePackageCommand { get; set; } + public RelayCommand ContinueCommand { get; set; } + public FirmwareUpgradeViewVM() { - SelectTfpFileLocationCommand = new RelayCommand(SelectTfpFileLocation, () => SelectedVersion != null); SelectExistingTfpFileLocationCommand = new RelayCommand(SelectExistingTfpFileLocation); - GeneratePackageCommand = new RelayCommand(GeneratePackage, () => SelectedVersion != null && (TfpFileLocation != null || (UseExistingTfpFile && ExistingTfpFileLocation != null))); - Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + GeneratePackageCommand = new RelayCommand(GeneratePackage, () => SelectedVersion != null); + ContinueCommand = new RelayCommand(ContinueWithExistingTfpFile, () => ExistingTfpFileLocation != null); } public override void OnBeforeNavigatedTo() @@ -76,16 +68,8 @@ namespace Tango.FSE.Upgrade.ViewModels { UseExistingTfpFile = false; } - } - private async void SelectTfpFileLocation() - { - String fileName = $"firmware_package_v{SelectedVersion.FirmwareVersion}.tfp"; - var result = await StorageProvider.SaveFile("Select firmware package location", "Tango Firmware Package|*.tfp", fileName, ".tfp"); - if (result) - { - TfpFileLocation = result.SelectedItem; - } + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; } private async void SelectExistingTfpFileLocation() @@ -105,7 +89,7 @@ namespace Tango.FSE.Upgrade.ViewModels { try { - TangoVersions = (await Services.TangoVersionsService.GetAllTangoVersions()).Take(10).ToList(); + TangoVersions = (await Services.TangoVersionsService.GetAllTangoVersions()).DistinctBy(x => x.FirmwareVersion).Take(10).ToList(); SelectedVersion = TangoVersions.FirstOrDefault(); } catch (Exception ex) @@ -118,32 +102,40 @@ namespace Tango.FSE.Upgrade.ViewModels private async void GeneratePackage() { - if (UseExistingTfpFile) + try { - //Navigate to the firmware completion with the existing tfp file. + IsFree = false; + var tempTfpFile = TemporaryManager.CreateImaginaryFile(".tfp"); + Handler = await RemoteUpgradeManager.CreateTfpFile(SelectedVersion, tempTfpFile); + await Handler.WaitForCompletion(); + await ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeGeneratedView, new FirmwareUpgradeGeneratedViewVM.NavigationObject() + { + IsExistingTfpFile = false, + TfpFileLocation = tempTfpFile, + SelectedVersion = SelectedVersion, + }, false); } - else + catch (OperationCanceledException) { - try - { - IsFree = false; - Handler = await RemoteUpgradeManager.CreateTfpFile(SelectedVersion, TfpFileLocation); - await Handler.WaitForCompletion(); - } - catch (OperationCanceledException) - { - //Aborted... - } - catch (Exception ex) - { - LogManager.Log("Error generating remote firmware upgrade package."); - await NotificationProvider.ShowError($"Error occurred while trying to generate the firmware upgrade package.\n{ex.FlattenMessage()}"); - } - finally - { - IsFree = true; - } + //Aborted... + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating remote firmware upgrade package."); + } + finally + { + IsFree = true; } } + + private async void ContinueWithExistingTfpFile() + { + await ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeGeneratedView, new FirmwareUpgradeGeneratedViewVM.NavigationObject() + { + IsExistingTfpFile = true, + TfpFileLocation = ExistingTfpFileLocation, + }, false); + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/MainViewVM.cs index fb067f405..e41021b78 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/MainViewVM.cs @@ -6,15 +6,15 @@ using System.Text; using System.Threading.Tasks; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; +using Tango.FSE.Upgrade.Navigation; using Tango.FSE.Upgrade.Views; using Tango.SharedUI.Helpers; namespace Tango.FSE.Upgrade.ViewModels { - [NavigationContainer] - public class MainViewVM : FSEViewModel + public class MainViewVM : RemoteUpgradeViewModel { - public override void OnApplicationStarted() + public override void OnApplicationReady() { InvokeUI(() => { @@ -30,5 +30,18 @@ namespace Tango.FSE.Upgrade.ViewModels }); }); } + + public async override Task OnNavigateBackRequest() + { + if (ModularNavigationManager.CurrentView == RemoteUpgradeView.WelcomeView) + { + return await base.OnNavigateBackRequest(); + } + else + { + await ModularNavigationManager.NavigateBack(); + return false; + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs index eebe39707..f69257e45 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs @@ -11,7 +11,7 @@ using Tango.FSE.Upgrade.Views; namespace Tango.FSE.Upgrade.ViewModels { - public class WelcomeViewVM : FSEViewModel + public class WelcomeViewVM : RemoteUpgradeViewModel { private Machine _selectedMachine; /// @@ -54,40 +54,47 @@ namespace Tango.FSE.Upgrade.ViewModels public WelcomeViewVM() { IsApplicationUpdate = true; - IsUpdateConnectedMachine = false; + IsUpdateConnectedMachine = true; StartUpgradeCommand = new RelayCommand(StartUpgrade, () => !IsApplicationUpdate || IsUpdateConnectedMachine || SelectedMachine != null); } + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + MachineProvider.MachineConnected += (_, __) => { if (IsVisible) InvalidateIsUpdateConnectedMachine(); }; + MachineProvider.MachineDisconnected += (_, __) => { if (IsVisible) InvalidateIsUpdateConnectedMachine(); }; + } + + private void InvalidateIsUpdateConnectedMachine() + { + if (IsUpdateConnectedMachine) + { + IsUpdateConnectedMachine = MachineProvider.IsConnected && MachineProvider.ConnectionType.IsRemote(); + } + } + /// /// Called before the navigation system has navigated to this VM view. /// public override void OnBeforeNavigatedTo() { base.OnBeforeNavigatedTo(); - - if (IsUpdateConnectedMachine && !MachineProvider.IsConnected) - { - IsUpdateConnectedMachine = false; - } + InvalidateIsUpdateConnectedMachine(); } private async void StartUpgrade() { if (IsApplicationUpdate) { - await NavigationManager.NavigateWithObject< - UpgradeModule, - ApplicationUpgradeView, - ApplicationUpgradeViewVM.NavigationObject> - (new ApplicationUpgradeViewVM.NavigationObject() - { - ApplicationUpgradeMode = IsUpdateConnectedMachine ? ApplicationUpgradeViewVM.ApplicationUpgradeMode.ConnectedMachine : ApplicationUpgradeViewVM.ApplicationUpgradeMode.OtherMachine, - SelectedMachine = IsUpdateConnectedMachine ? MachineProvider.Machine : SelectedMachine - }); + await ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.ApplicationUpgradeView, new ApplicationUpgradeViewVM.NavigationObject() + { + ApplicationUpgradeMode = IsUpdateConnectedMachine ? ApplicationUpgradeViewVM.ApplicationUpgradeMode.ConnectedMachine : ApplicationUpgradeViewVM.ApplicationUpgradeMode.OtherMachine, + SelectedMachine = IsUpdateConnectedMachine ? MachineProvider.Machine : SelectedMachine + }); } else { - await NavigationManager.NavigateTo(nameof(FirmwareUpgradeView)); + await ModularNavigationManager.NavigateTo(Navigation.RemoteUpgradeView.FirmwareUpgradeView); } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml index d70b496e7..852bdced6 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeGeneratedView.xaml @@ -11,59 +11,75 @@ mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:ApplicationUpgradeGeneratedViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.ApplicationUpgradeGeneratedViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> - - Application Upgrade Ready! + + + Application Upgrade Ready! - + Your machine application and firmware upgrade is ready. - + - - - You have chosen to upgrade the currently connected machine. - press 'start upgrade' to start upgrading remotely. - That is not currently possible due to the following reason: + + + You have chosen to upgrade the currently connected machine. + press 'upgrade now' to start upgrading remotely. + That is not currently possible due to the following reason: + + + + + + + + + + I want to upgrade the currently connected machine right now. + + + + + + + I will upgrade later using a removable flash drive. + + - + + Select where to save the upgrade package (.tup file) + + + + + + - - - - - - + + + + + + - + - - - - - + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeView.xaml index 349fa45e4..216d9d85f 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/ApplicationUpgradeView.xaml @@ -42,59 +42,54 @@ In case you chose to upgrade the currently connected machine, you will be able to perform the upgrade remotely. - - Select the desired Tango system software version + + + Select the desired Tango system software version - - - - - + + + + + () - - - + + + Application: v - - + + Firmware: v - - - - - - - - - - Select where to save the upgrade package (.tup file) + + + + + + + - - - - + + + - - - - - - - - + + + - - + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml index 08bb74b6b..d3b151c27 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeGeneratedView.xaml @@ -10,7 +10,67 @@ xmlns:local="clr-namespace:Tango.FSE.Upgrade.Views" mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:FirmwareUpgradeGeneratedViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.FirmwareUpgradeGeneratedViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> - - + + + + Firmware Upgrade Ready! + + + Your machine firmware upgrade is ready. + + + + + + + + I want to upgrade the currently connected machine right now. + + + + + + + I will upgrade later using a removable flash drive. + + + + + Select where to save the firmware package (.tfp file) + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml index b899b4e04..527b70445 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml @@ -12,17 +12,6 @@ mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:FirmwareUpgradeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.FirmwareUpgradeViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> - - - - Firmware Upgrade @@ -49,34 +38,25 @@ - + Select the desired firmware version - - - - - + + + + + () - - - + + + Firmware: v - - - - - - - - - - Select where to save the firmware package (.tfp file) - - - - - + + + + + + @@ -96,46 +76,33 @@ + - - - - - - - - - - - - + + - - + + + + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml index efc9913ea..57363eed8 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml @@ -10,6 +10,17 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + + + + @@ -27,10 +38,10 @@ @@ -47,7 +58,7 @@ - + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml.cs index 867fb27c7..17442332b 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/MainView.xaml.cs @@ -20,8 +20,11 @@ namespace Tango.FSE.Upgrade.Views /// public partial class MainView : UserControl { + public static MainView Instance { get; set; } + public MainView() { + Instance = this; InitializeComponent(); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/WelcomeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/WelcomeView.xaml index 111d19b29..e82173419 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/WelcomeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/WelcomeView.xaml @@ -11,55 +11,47 @@ mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:WelcomeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.WelcomeViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> - + - Please select the desired upgrade operation and press 'continue'. + + Please select the desired upgrade operation and press 'continue'. - - - - - I want to upgrade a machine's application and firmware version. - - + + + + + I want to upgrade a machine's application and firmware versions. (recommended) + + - - Please specify the target machine for this upgrade. - Upgrade the currently connected machine. - Upgrade a different machine. - - - - + + Please specify the target machine for this upgrade. + Upgrade the currently connected machine. + Upgrade a different machine. + + + + - - - - I want to upgrade a machine's firmware version. - - + + + + I want to upgrade a machine's firmware version. + + + + - - - - - + + - - + - + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TangoVersionsService.cs b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TangoVersionsService.cs index ed0a2a356..89a0e14ec 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TangoVersionsService.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.BL/Services/TangoVersionsService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -95,5 +96,89 @@ namespace Tango.FSE.BL.Services }) .BuildExecuteAsync(); } + + public Task UploadCachedTupFile(TangoVersion version, String tupFilePath) + { + return Task.Factory.StartNew(() => + { + using (var cache = DiskCache.CreateContext()) + { + cache.FileStorage.Upload(CreateCachedTangoVersionFileName(version), tupFilePath); + } + }); + } + + public Task UploadCachedTfpFile(TangoVersion version, String tfpFilePath) + { + return Task.Factory.StartNew(() => + { + using (var cache = DiskCache.CreateContext()) + { + cache.FileStorage.Upload(CreateCachedFirmwareVersionFileName(version), tfpFilePath); + } + }); + } + + public Task DownloadCachedTupFile(TangoVersion version, String outputFilePath) + { + return Task.Factory.StartNew(() => + { + using (var cache = DiskCache.CreateContext()) + { + var file = cache.FileStorage.FindById(CreateCachedTangoVersionFileName(version)); + + if (file == null) + { + throw new KeyNotFoundException("The specified version cache could not be found."); + } + + file.SaveAs(outputFilePath, true); + } + }); + } + + public Task DownloadCachedTfpFile(TangoVersion version, String outputFilePath) + { + return Task.Factory.StartNew(() => + { + using (var cache = DiskCache.CreateContext()) + { + var file = cache.FileStorage.FindById(CreateCachedFirmwareVersionFileName(version)); + + if (file == null) + { + throw new KeyNotFoundException("The specified version cache could not be found."); + } + + file.SaveAs(outputFilePath, true); + } + }); + } + + public bool IsCachedTupFileExists(TangoVersion version) + { + using (var cache = DiskCache.CreateContext()) + { + return cache.FileStorage.FindById(CreateCachedTangoVersionFileName(version)) != null; + } + } + + public bool IsCachedTfpFileExists(TangoVersion version) + { + using (var cache = DiskCache.CreateContext()) + { + return cache.FileStorage.FindById(CreateCachedFirmwareVersionFileName(version)) != null; + } + } + + private String CreateCachedTangoVersionFileName(TangoVersion version) + { + return $"$/TangoVersions/application_package_v{version.Version}.tup"; + } + + private String CreateCachedFirmwareVersionFileName(TangoVersion version) + { + return $"$/TangoVersions/firmware_package_v{version.FirmwareVersion}.tfp"; + } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs index 6f3495a13..6f9d85fd5 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Connection/IMachineProvider.cs @@ -72,5 +72,14 @@ namespace Tango.FSE.Common.Connection /// /// Task DisconnectMachine(); + + /// + /// Disconnects the currently connected machine and displays a "waiting for reconnection dialog" with a timeout. + /// Useful when doing remote application restart. + /// + /// The amount of time to wait before starting reconnection attempts. + /// The timeout for when to drop the reconnection attempt. + /// + Task DisconnectAndWaitForReconnection(TimeSpan beginDelay, TimeSpan timeout); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/arrow_right.png b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/arrow_right.png new file mode 100644 index 000000000..cdcc0e7cd Binary files /dev/null and b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/arrow_right.png differ diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/IModularNavigationNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/IModularNavigationNavigationManager.cs new file mode 100644 index 000000000..4ef0f7024 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/IModularNavigationNavigationManager.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.Common.Navigation +{ + public interface IModularNavigationNavigationManager + { + T CurrentView { get; } + Task GetCurrentViewModel(); + bool CanNavigateBack { get; } + Task NavigateTo(T view, bool pushToHistory = true); + Task NavigateTo(T view, TPass objectToPass, bool pushToHistory = true); + Task NavigateBack(); + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationFSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationFSEViewModel.cs new file mode 100644 index 000000000..3bef447f1 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationFSEViewModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; + +namespace Tango.FSE.Common.Navigation +{ + public abstract class ModularNavigationFSEViewModel : FSEViewModel + { + [TangoInject(TangoInjectMode.WhenAvailable)] + protected IModularNavigationNavigationManager ModularNavigationManager { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationManager.cs new file mode 100644 index 000000000..33a1df304 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Navigation/ModularNavigationManager.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using Tango.Core; +using Tango.SharedUI.Controls; + +namespace Tango.FSE.Common.Navigation +{ + public abstract class ModularNavigationManager : ExtendedObject, IModularNavigationNavigationManager + { + private FrameworkElement _navigationControlParent; + private NavigationControl _navigationControl; + private Stack _history; + + private T _currentView; + public T CurrentView + { + get { return _currentView; } + protected set { _currentView = value; RaisePropertyChangedAuto(); } + } + + public bool CanNavigateBack + { + get { return _history.Count > 0; } + } + + public ModularNavigationManager(FrameworkElement navigationControlParent) + { + _history = new Stack(); + _navigationControlParent = navigationControlParent; + _navigationControlParent.RegisterForLoadedOrNow((_, __) => + { + _navigationControl = _navigationControlParent.FindChildOffline(); + _navigationControl.RegisterForLoadedOrNow((___, ____) => + { + var currentVM = (_navigationControl.GetElement(CurrentView.ToString()).DataContext as FSEViewModel); + currentVM.OnBeforeNavigatedTo(); + currentVM.OnNavigatedTo(); + }); + }); + } + + public Task NavigateTo(T view, bool pushToHistory = true) + { + return NavigateToInternal(view, null, pushToHistory); + } + + public Task NavigateTo(T view, TPass objectToPass, bool pushToHistory = true) + { + return NavigateToInternal(view, objectToPass, pushToHistory); + } + + private Task NavigateToInternal(T view, TPass objectToPass, bool pushToHistory) + { + TaskCompletionSource completion = new TaskCompletionSource(); + + var fromVM = _navigationControl.SelectedElement.DataContext as FSEViewModel; + var toVM = _navigationControl.GetElement(view.ToString()).DataContext as FSEViewModel; + + if (fromVM != toVM) + { + fromVM.OnBeforeNavigatedFrom(); + toVM.OnBeforeNavigatedTo(); + + if (toVM is INavigationObjectReceiver && objectToPass != null) + { + (toVM as INavigationObjectReceiver).OnNavigatedToWithObject(objectToPass); + } + + _navigationControl.NavigateTo(view.ToString(), () => + { + if (pushToHistory) + { + _history.Push(CurrentView); + DistinctHistory(); + RaisePropertyChanged(nameof(CanNavigateBack)); + } + + CurrentView = view; + + fromVM.OnNavigatedFrom(); + toVM.OnNavigatedTo(); + + completion.SetResult(true); + }); + } + else + { + completion.SetResult(true); + } + + return completion.Task; + } + + public async Task NavigateBack() + { + if (CanNavigateBack) + { + var toView = _history.Peek(); + + var fromVM = _navigationControl.GetElement(CurrentView.ToString()).DataContext as FSEViewModel; + + if (fromVM is INavigationBlocker) + { + if (!await (fromVM as INavigationBlocker).OnNavigateBackRequest()) + { + return false; + } + } + + _history.Pop(); + RaisePropertyChanged(nameof(CanNavigateBack)); + + await NavigateTo(toView); + + return true; + } + else + { + return false; + } + } + + private void DistinctHistory() + { + var list = _history.Distinct().ToList(); + list.Reverse(); + _history.Clear(); + + foreach (var item in list) + { + _history.Push(item); + } + + RaisePropertyChanged(nameof(CanNavigateBack)); + } + + public async Task GetCurrentViewModel() + { + if (_navigationControl == null) + { + await Task.Factory.StartNew(() => + { + while (_navigationControl == null) + { + Thread.Sleep(10); + } + }); + } + + return _navigationControl.GetElement(CurrentView.ToString()).DataContext as FSEViewModel; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs index 4d2389dc6..ec06b2e8f 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs @@ -41,5 +41,12 @@ namespace Tango.FSE.Common.RemoteUpgrade /// The .tup file. /// Task PerformRemoteApplicationUpgrade(String tupFile); + + /// + /// Performs a remote firmware upgrade using the specified .tfp file. + /// + /// The .tfp file. + /// + Task PerformRemoteFirmwareUpgrade(String tfpFile); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/RemoteUpgradeHandler.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/RemoteUpgradeHandler.cs index 8ba757edc..977a7a4cc 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/RemoteUpgradeHandler.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/RemoteUpgradeHandler.cs @@ -14,6 +14,10 @@ namespace Tango.FSE.Common.RemoteUpgrade public event EventHandler StatusChanged; + internal bool IsAborted { get; private set; } + + public bool CanAbort { get; internal set; } = true; + private double _progress; public double Progress { @@ -83,6 +87,7 @@ namespace Tango.FSE.Common.RemoteUpgrade public void Abort() { + IsAborted = true; _abortAction?.Invoke(); } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml index c0ce6434d..ef3cb683e 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Images.xaml @@ -11,5 +11,6 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml index 6aaffbd8a..ad59a5775 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Styles.xaml @@ -585,6 +585,26 @@ + + + + + + + + + + + + + + + + + + + + + +