Skip to content

Commit

Permalink
chore: Improve Suspending event deferral support
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Mar 10, 2022
1 parent b9d8e04 commit 712fe9a
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 40 deletions.
6 changes: 2 additions & 4 deletions src/Uno.UI/UI/Xaml/Application.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ partial void OnResumingPartial()
Resuming?.Invoke(null, null);
}

partial void OnSuspendingPartial()
{
Suspending?.Invoke(this, new Windows.ApplicationModel.SuspendingEventArgs(new Windows.ApplicationModel.SuspendingOperation(DateTime.Now.AddSeconds(30))));
}
private SuspendingOperation CreateSuspendingOperation() =>
new SuspendingOperation(DateTimeOffset.Now.AddSeconds(30), null);

public void Exit()
{
Expand Down
22 changes: 19 additions & 3 deletions src/Uno.UI/UI/Xaml/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,29 @@ internal void OnResuming()

internal void OnSuspending()
{
var suspendingEventArgs = new SuspendingEventArgs(new SuspendingOperation(DateTime.Now.AddSeconds(30)));
var suspendingOperation = CreateSuspendingOperation();
var suspendingEventArgs = new SuspendingEventArgs(suspendingOperation);

CoreApplication.RaiseSuspending(suspendingEventArgs);
Suspending?.Invoke(this, suspendingEventArgs);

var completedSynchronously = suspendingOperation.DeferralManager.EventRaiseCompleted();

OnSuspendingPartial();
#if !__IOS__ && !__ANDROID__ && !__MACOS__
// Asynchronous suspension is not supported on all targets, warn the user
if (!completedSynchronously && this.Log().IsEnabled(LogLevel.Warning))
{
this.Log().LogWarning(
"This platform does not support asynchronous Suspending deferral. " +
"Code executed after the of the method called by Suspending may not get executed.");
}
#endif
}

partial void OnSuspendingPartial();
#if !__IOS__ && !__ANDROID__ && !__MACOS__
private SuspendinOperation CreateSuspendingOperation() =>
new SuspendingOperation(DateTimeOffset.Now.AddSeconds(0), null);
#endif

protected virtual void OnWindowCreated(global::Windows.UI.Xaml.WindowCreatedEventArgs args)
{
Expand Down
10 changes: 2 additions & 8 deletions src/Uno.UI/UI/Xaml/Application.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,8 @@ public override void PerformActionForShortcutItem(
_preventSecondaryActivationHandling = false;
}

partial void OnSuspendingPartial()
{
var operation = new SuspendingOperation(DateTime.Now.AddSeconds(10));

Suspending?.Invoke(this, new SuspendingEventArgs(operation));

_suspended = true;
}
private SuspendinOperation CreateSuspendingOperation() =>
new SuspendingOperation(DateTimeOffset.Now.AddSeconds(10), () => _suspended = true);

public override void WillEnterForeground(UIApplication application)
=> OnResuming();
Expand Down
10 changes: 2 additions & 8 deletions src/Uno.UI/UI/Xaml/Application.macOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,13 @@ public override void DidFinishLaunching(NSNotification notification)
}
}

partial void OnSuspendingPartial()
{
var operation = new SuspendingOperation(DateTime.Now.AddSeconds(30), () =>
private SuspendinOperation CreateSuspendingOperation() =>
new SuspendingOperation(DateTimeOffset.Now.AddSeconds(30), () =>
{
Suspended = true;
NSApplication.SharedApplication.KeyWindow.PerformClose(null);
});

Suspending?.Invoke(this, new SuspendingEventArgs(operation));

operation.EventRaiseCompleted();
}

/// <summary>
/// This method enables UI Tests to get the output path
/// of the current application, in the context of the simulator.
Expand Down
14 changes: 0 additions & 14 deletions src/Uno.UI/UI/Xaml/Application.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,6 @@ internal static void DispatchSuspending()
Current?.OnSuspending();
}

partial void OnSuspendingPartial()
{
var completed = false;
var operation = new SuspendingOperation(DateTime.Now.AddSeconds(0), () => completed = true);

Suspending?.Invoke(this, new SuspendingEventArgs(operation));
operation.EventRaiseCompleted();

if (!completed && this.Log().IsEnabled(LogLevel.Warning))
{
this.Log().LogWarning($"This platform does not support asynchronous Suspending deferral. Code executed after the of the method called by Suspending may not get executed.");
}
}

private void ObserveApplicationVisibility()
{
WebAssemblyRuntime.InvokeJS("Windows.UI.Xaml.Application.observeVisibility()");
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UWP/ApplicationModel/SuspendingOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Windows.ApplicationModel;
/// </summary>
public sealed partial class SuspendingOperation : ISuspendingOperation
{
internal SuspendingOperation(DateTimeOffset offset, Action? onComplete = null)
internal SuspendingOperation(DateTimeOffset offset, Action? onComplete)
{
Deadline = offset;
DeferralManager = new DeferralManager<SuspendingDeferral>(h => new SuspendingDeferral(h));
Expand Down
8 changes: 6 additions & 2 deletions src/Uno.UWP/Helpers/DeferralManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,21 @@ void OnDeferralCompleted()
/// In case the operation is not deferred, it will also synchronously raise
/// the Completed event.
/// </summary>
internal void EventRaiseCompleted() => DeferralCompleted();
/// <returns>A value indicating whether the deferral completed synchronously.</returns>
internal bool EventRaiseCompleted() => DeferralCompleted();

internal Task WhenAllCompletedAsync() => _allDeferralsCompletedCompletionSource.Task;

private void DeferralCompleted()
private bool DeferralCompleted()
{
_deferralsCount--;
if (_deferralsCount <= 0)
{
Completed?.Invoke(this, EventArgs.Empty);
_allDeferralsCompletedCompletionSource.TrySetResult(null);
return true;
}

return false;
}
}

0 comments on commit 712fe9a

Please sign in to comment.