Public Access
Add meeting inactivity safeguards
PR and Push Build/Test / build-and-test (push) Failing after 14m53s
PR and Push Build/Test / build-and-test (push) Failing after 14m53s
This commit is contained in:
@@ -4,7 +4,7 @@ using CommunityToolkit.WinUI.Notifications;
|
||||
|
||||
namespace MeetingAssistant.Recording;
|
||||
|
||||
public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPromptService, IDisposable
|
||||
public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPromptService, IHostedService, IDisposable
|
||||
{
|
||||
private const string NotificationSource = "meeting-inactivity-safeguard";
|
||||
private const string NotificationGroup = "meeting-inactivity";
|
||||
@@ -39,6 +39,10 @@ public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPr
|
||||
EnsureRegistered();
|
||||
var promptId = Guid.NewGuid().ToString("N");
|
||||
pendingPrompts[promptId] = new PendingPrompt(handleResponseAsync);
|
||||
logger.LogInformation(
|
||||
"Registered native Windows inactivity notification {PromptId} response callback at threshold {Threshold}",
|
||||
promptId,
|
||||
request.Threshold);
|
||||
var notification = BuildNotification(promptId, request);
|
||||
notification.Show(toast =>
|
||||
{
|
||||
@@ -59,6 +63,23 @@ public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPr
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17763))
|
||||
{
|
||||
logger.LogWarning("Windows app notifications require Windows 10 version 1809 or later");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
EnsureRegistered();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!registered)
|
||||
@@ -69,11 +90,10 @@ public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPr
|
||||
try
|
||||
{
|
||||
ToastNotificationManagerCompat.OnActivated -= OnNotificationInvoked;
|
||||
ToastNotificationManagerCompat.Uninstall();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
logger.LogWarning(exception, "Failed to unregister native Windows toast notifications");
|
||||
logger.LogWarning(exception, "Failed to detach native Windows toast notification activation handler");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,12 +146,31 @@ public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPr
|
||||
|
||||
private void OnNotificationInvoked(ToastNotificationActivatedEventArgsCompat args)
|
||||
{
|
||||
var arguments = ParseArguments(args.Argument);
|
||||
logger.LogInformation(
|
||||
"Native Windows inactivity notification activation received with arguments {Arguments}",
|
||||
args.Argument);
|
||||
|
||||
var arguments = NotificationActivationArguments.Parse(args.Argument);
|
||||
if (!TryGetArgument(arguments, "source", out var source) ||
|
||||
!string.Equals(source, NotificationSource, StringComparison.OrdinalIgnoreCase) ||
|
||||
!TryGetArgument(arguments, "promptId", out var promptId) ||
|
||||
!pendingPrompts.TryRemove(promptId, out var pendingPrompt))
|
||||
!string.Equals(source, NotificationSource, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
logger.LogDebug(
|
||||
"Ignoring native Windows notification activation for unrelated source {Source}",
|
||||
source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGetArgument(arguments, "promptId", out var promptId))
|
||||
{
|
||||
logger.LogWarning("Ignoring native Windows inactivity notification activation without prompt id");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pendingPrompts.TryRemove(promptId, out var pendingPrompt))
|
||||
{
|
||||
logger.LogWarning(
|
||||
"Ignoring native Windows inactivity notification {PromptId} activation because no pending prompt callback exists",
|
||||
promptId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -159,31 +198,6 @@ public sealed class WindowsMeetingInactivityPromptService : IMeetingInactivityPr
|
||||
});
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, string> ParseArguments(string argumentText)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(argumentText))
|
||||
{
|
||||
return new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
var arguments = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var pair in argumentText.Split('&', StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var separatorIndex = pair.IndexOf('=');
|
||||
if (separatorIndex < 0)
|
||||
{
|
||||
arguments[Uri.UnescapeDataString(pair)] = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = Uri.UnescapeDataString(pair[..separatorIndex]);
|
||||
var value = Uri.UnescapeDataString(pair[(separatorIndex + 1)..]);
|
||||
arguments[key] = value;
|
||||
}
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
private static bool TryGetArgument(
|
||||
IReadOnlyDictionary<string, string> arguments,
|
||||
string key,
|
||||
|
||||
Reference in New Issue
Block a user