Skip to content

Commit

Permalink
Improve suspend/resume on Windows
Browse files Browse the repository at this point in the history
not sure if that actually fixes it fully since debugging app lifecycle doesn't work at all
  • Loading branch information
Difegue committed Nov 26, 2022
1 parent 7afdf57 commit 0f5a5b8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 21 deletions.
6 changes: 5 additions & 1 deletion Sources/Stylophone.Common/Services/AlbumArtService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public void Initialize()
{
_queueCanceller?.Cancel();
_queueCanceller = new CancellationTokenSource();

var token = _queueCanceller.Token;

_albumArtQueue = new Stack<AlbumViewModel>();
Expand Down Expand Up @@ -81,6 +80,11 @@ public void Initialize()
}).ConfigureAwait(false);
}

public void Stop()
{
_queueCanceller?.Cancel();
}

/// <summary>
/// Check if this file's album art is already stored in the internal Album Art cache.
/// </summary>
Expand Down
48 changes: 30 additions & 18 deletions Sources/Stylophone.Common/Services/MPDConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,7 @@ public async Task InitializeAsync(bool withRetry = false)
IsConnecting = true;
CurrentStatus = BOGUS_STATUS; // Reset status

if (IsConnected)
{
IsConnected = false;
ConnectionChanged?.Invoke(this, new EventArgs());
}

ClearResources();
Disconnect();

var cancelToken = _cancelConnect.Token;

Expand All @@ -106,23 +100,31 @@ public async Task InitializeAsync(bool withRetry = false)
_connectionRetryAttempter.Start();
}
}

IsConnecting = false;
}

private void ClearResources()
public void Disconnect()
{
_idleConnection?.SendAsync(new NoIdleCommand());
_idleConnection?.DisconnectAsync();
_statusConnection?.DisconnectAsync();

if (IsConnected)
{
System.Diagnostics.Debug.WriteLine($"Terminating MPD connections");
IsConnected = false;
ConnectionChanged?.Invoke(this, new EventArgs());
}

// Stop the idle connection first
_cancelIdle?.Cancel();

_connectionRetryAttempter?.Stop();
_connectionRetryAttempter?.Dispose();

// Stop the status timer before killing the matching connection
_statusUpdater?.Stop();
_statusUpdater?.Dispose();
_statusConnection?.DisconnectAsync();

_cancelIdle?.Cancel();
_cancelIdle = new CancellationTokenSource();

_cancelConnect?.Cancel();
Expand Down Expand Up @@ -270,15 +272,25 @@ private void InitializeStatusUpdater(CancellationToken token = default)
try
{
// Run the idleConnection in a wrapper task since MpcNET isn't fully async and will block here
var idleChangesTask = Task.Run(async () => await _idleConnection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options update")));
// Wait for the idle command to finish or for the token to be cancelled
await Task.WhenAny(idleChangesTask, Task.Delay(-1, token));
if (token.IsCancellationRequested || _idleConnection == null || !_idleConnection.IsConnected)
{
//_idleConnection?.SendAsync(new NoIdleCommand());
_idleConnection?.DisconnectAsync();
break;
}
var message = idleChangesTask.Result;
var idleChanges = await _idleConnection.SendAsync(new IdleCommand("stored_playlist playlist player mixer output options update"));
if (idleChanges.IsResponseValid)
await HandleIdleResponseAsync(idleChanges.Response.Content);
if (message.IsResponseValid)
await HandleIdleResponseAsync(message.Response.Content);
else
throw new Exception(idleChanges.Response?.Content);
throw new Exception(message.Response?.Content);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ public PlaybackViewModelBase(INavigationService navigationService, INotification

_internalVolume = _mpdService.CurrentStatus.Volume;

// Bind timer methods and start it
// Bind timer methods
_updateInformationTimer = new System.Timers.Timer(500);
_updateInformationTimer.Elapsed += UpdateInformation;
_updateInformationTimer.Start();

// Update info to current track
_mpdService.ConnectionChanged += OnConnectionChanged;
Expand All @@ -82,6 +81,7 @@ private void OnConnectionChanged(object sender, EventArgs e)
else
{
IsTrackInfoAvailable = false;
_updateInformationTimer?.Stop();
}
}

Expand All @@ -90,6 +90,7 @@ private void Initialize()
OnTrackChange(this, new SongChangedEventArgs { NewSongId = -1 });
CurrentTimeValue = _mpdService.CurrentStatus.Elapsed.TotalSeconds;

_updateInformationTimer.Start();
OnStateChange(this, null);
}

Expand Down
15 changes: 15 additions & 0 deletions Sources/Stylophone/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.Toolkit.Uwp.Helpers;
using Windows.Foundation;
using Microsoft.Services.Store.Engagement;
using Windows.ApplicationModel;
#if DEBUG
#else
using System.Collections.Generic;
Expand All @@ -40,6 +41,8 @@ public App()

InitializeComponent();
UnhandledException += OnAppUnhandledException;
Suspending += OnAppSuspending;
Resuming += OnAppResuming;

// Deferred execution until used. Check https://msdn.microsoft.com/library/dd642331(v=vs.110).aspx for further info on Lazy<T> class.
_activationService = new Lazy<ActivationService>(CreateActivationService);
Expand Down Expand Up @@ -119,6 +122,18 @@ private void OnAppUnhandledException(object sender, Windows.UI.Xaml.UnhandledExc
e.Handled = true;
}

private async void OnAppResuming(object sender, object e)
{
await Ioc.Default.GetRequiredService<MPDConnectionService>().InitializeAsync(true);
Ioc.Default.GetRequiredService<AlbumArtService>().Initialize();
}

private void OnAppSuspending(object sender, SuspendingEventArgs e)
{
Ioc.Default.GetRequiredService<MPDConnectionService>().Disconnect();
Ioc.Default.GetRequiredService<AlbumArtService>().Stop();
}

private ActivationService CreateActivationService()
{
return new ActivationService(this, typeof(QueueViewModel), new Lazy<UIElement>(CreateShell));
Expand Down

0 comments on commit 0f5a5b8

Please sign in to comment.