internal SwitchModeViewModel(PhoneNotifierViewModel PhoneNotifier, PhoneInterfaces?TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, ModeSwitchErrorHandler ModeSwitchError, ModeSwitchSuccessHandler ModeSwitchSuccess, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null) : base() { if ((PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash)) { PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false); if (Info.BootManagerProtocolVersionMajor >= 2) { try { // The implementation of SwitchToFlashAppContext() is improved // SwitchToFlashAppContext() should only be used with BootMgr v2 // For switching from BootMgr to FlashApp, it will use NOKS // That will switch to a charging state, whereas a normal context switch will not start charging // The implementation of NOKS in BootMgr mode has changed in BootMgr v2 // It does not disconnect / reconnect anymore and the apptype is changed immediately // NOKS still doesnt return a status // BootMgr v1 uses normal NOKS and waits for arrival of FlashApp ((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext(); // But this was called as a real switch, so we will raise an arrival event. PhoneNotifier.CurrentInterface = PhoneInterfaces.Lumia_Flash; PhoneNotifier.NotifyArrival(); } catch { } } } if (PhoneNotifier.CurrentInterface == TargetMode) { ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface); } else { this.PhoneNotifier = PhoneNotifier; this.CurrentModel = (NokiaPhoneModel)PhoneNotifier.CurrentModel; this.CurrentMode = PhoneNotifier.CurrentInterface; this.TargetMode = TargetMode; if (ModeSwitchProgress != null) { this.ModeSwitchProgress += ModeSwitchProgress; } if (ModeSwitchError != null) { this.ModeSwitchError += ModeSwitchError; } if (ModeSwitchSuccess != null) { this.ModeSwitchSuccess += ModeSwitchSuccess; } if (SetWorkingStatus != null) { this.SetWorkingStatus = SetWorkingStatus; } if (UpdateWorkingStatus != null) { this.UpdateWorkingStatus = UpdateWorkingStatus; } if (this.CurrentMode == null) { LogFile.Log("Waiting for phone to connect...", LogType.FileAndConsole); PhoneNotifier.NewDeviceArrived += NewDeviceArrived; } else { // Make sure this ViewModel has its View loaded before we continue, // or else loading of Views can get mixed up. if (SynchronizationContext.Current == null) { StartSwitch(); } else { SynchronizationContext.Current.Post((s) => { ((SwitchModeViewModel)s).StartSwitch(); }, this); } } } }
internal async static Task <IDisposable> SwitchToWithProgress(PhoneNotifierViewModel Notifier, PhoneInterfaces?TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, string RequestedVolumeForMassStorage = "MainOS") { if (Notifier.CurrentInterface == TargetMode) { return(Notifier.CurrentModel); } IDisposable Result = null; string LocalErrorMessage = null; AsyncAutoResetEvent Event = new AsyncAutoResetEvent(false); SwitchModeViewModel Switch = new SwitchModeViewModel( Notifier, TargetMode, ModeSwitchProgress, (string ErrorMessage) => { LocalErrorMessage = ErrorMessage; Event.Set(); }, (IDisposable NewModel, PhoneInterfaces NewInterface) => { Result = NewModel; Event.Set(); } ); await Event.WaitAsync(Timeout.InfiniteTimeSpan); if (LocalErrorMessage != null) { throw new WPinternalsException(LocalErrorMessage); } return(Result); }