aboutsummaryrefslogtreecommitdiff
path: root/Emby.Dlna/PlayTo/Device.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Dlna/PlayTo/Device.cs')
-rw-r--r--Emby.Dlna/PlayTo/Device.cs128
1 files changed, 46 insertions, 82 deletions
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs
index 9c476119d..bb9b8b0fd 100644
--- a/Emby.Dlna/PlayTo/Device.cs
+++ b/Emby.Dlna/PlayTo/Device.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
#pragma warning disable CS1591
using System;
@@ -25,7 +23,7 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger;
private readonly object _timerLock = new object();
- private Timer _timer;
+ private Timer? _timer;
private int _muteVol;
private int _volume;
private DateTime _lastVolumeRefresh;
@@ -40,13 +38,13 @@ namespace Emby.Dlna.PlayTo
_logger = logger;
}
- public event EventHandler<PlaybackStartEventArgs> PlaybackStart;
+ public event EventHandler<PlaybackStartEventArgs>? PlaybackStart;
- public event EventHandler<PlaybackProgressEventArgs> PlaybackProgress;
+ public event EventHandler<PlaybackProgressEventArgs>? PlaybackProgress;
- public event EventHandler<PlaybackStoppedEventArgs> PlaybackStopped;
+ public event EventHandler<PlaybackStoppedEventArgs>? PlaybackStopped;
- public event EventHandler<MediaChangedEventArgs> MediaChanged;
+ public event EventHandler<MediaChangedEventArgs>? MediaChanged;
public DeviceInfo Properties { get; set; }
@@ -75,13 +73,13 @@ namespace Emby.Dlna.PlayTo
public bool IsStopped => TransportState == TransportState.STOPPED;
- public Action OnDeviceUnavailable { get; set; }
+ public Action? OnDeviceUnavailable { get; set; }
- private TransportCommands AvCommands { get; set; }
+ private TransportCommands? AvCommands { get; set; }
- private TransportCommands RendererCommands { get; set; }
+ private TransportCommands? RendererCommands { get; set; }
- public UBaseObject CurrentMediaInfo { get; private set; }
+ public UBaseObject? CurrentMediaInfo { get; private set; }
public void Start()
{
@@ -131,7 +129,7 @@ namespace Emby.Dlna.PlayTo
_volumeRefreshActive = true;
var time = immediate ? 100 : 10000;
- _timer.Change(time, Timeout.Infinite);
+ _timer?.Change(time, Timeout.Infinite);
}
}
@@ -149,7 +147,7 @@ namespace Emby.Dlna.PlayTo
_volumeRefreshActive = false;
- _timer.Change(Timeout.Infinite, Timeout.Infinite);
+ _timer?.Change(Timeout.Infinite, Timeout.Infinite);
}
}
@@ -199,7 +197,7 @@ namespace Emby.Dlna.PlayTo
}
}
- private DeviceService GetServiceRenderingControl()
+ private DeviceService? GetServiceRenderingControl()
{
var services = Properties.Services;
@@ -207,7 +205,7 @@ namespace Emby.Dlna.PlayTo
services.FirstOrDefault(s => (s.ServiceType ?? string.Empty).StartsWith("urn:schemas-upnp-org:service:RenderingControl", StringComparison.OrdinalIgnoreCase));
}
- private DeviceService GetAvTransportService()
+ private DeviceService? GetAvTransportService()
{
var services = Properties.Services;
@@ -240,7 +238,7 @@ namespace Emby.Dlna.PlayTo
Properties.BaseUrl,
service,
command.Name,
- rendererCommands.BuildPost(command, service.ServiceType, value),
+ rendererCommands!.BuildPost(command, service.ServiceType, value), // null checked above
cancellationToken: cancellationToken)
.ConfigureAwait(false);
@@ -265,12 +263,7 @@ namespace Emby.Dlna.PlayTo
return;
}
- var service = GetServiceRenderingControl();
-
- if (service is null)
- {
- throw new InvalidOperationException("Unable to find service");
- }
+ var service = GetServiceRenderingControl() ?? throw new InvalidOperationException("Unable to find service");
// Set it early and assume it will succeed
// Remote control will perform better
@@ -281,7 +274,7 @@ namespace Emby.Dlna.PlayTo
Properties.BaseUrl,
service,
command.Name,
- rendererCommands.BuildPost(command, service.ServiceType, value),
+ rendererCommands!.BuildPost(command, service.ServiceType, value), // null checked above
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
@@ -296,26 +289,20 @@ namespace Emby.Dlna.PlayTo
return;
}
- var service = GetAvTransportService();
-
- if (service is null)
- {
- throw new InvalidOperationException("Unable to find service");
- }
-
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
await new DlnaHttpClient(_logger, _httpClientFactory)
.SendCommandAsync(
Properties.BaseUrl,
service,
command.Name,
- avCommands.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"),
+ avCommands!.BuildPost(command, service.ServiceType, string.Format(CultureInfo.InvariantCulture, "{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"), // null checked above
cancellationToken: cancellationToken)
.ConfigureAwait(false);
RestartTimer(true);
}
- public async Task SetAvTransport(string url, string header, string metaData, CancellationToken cancellationToken)
+ public async Task SetAvTransport(string url, string? header, string metaData, CancellationToken cancellationToken)
{
var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
@@ -335,14 +322,8 @@ namespace Emby.Dlna.PlayTo
{ "CurrentURIMetaData", CreateDidlMeta(metaData) }
};
- var service = GetAvTransportService();
-
- if (service is null)
- {
- throw new InvalidOperationException("Unable to find service");
- }
-
- var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary);
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
+ var post = avCommands!.BuildPost(command, service.ServiceType, url, dictionary); // null checked above
await new DlnaHttpClient(_logger, _httpClientFactory)
.SendCommandAsync(
Properties.BaseUrl,
@@ -372,7 +353,7 @@ namespace Emby.Dlna.PlayTo
* SetNextAvTransport is used to specify to the DLNA device what is the next track to play.
* Without that information, the next track command on the device does not work.
*/
- public async Task SetNextAvTransport(string url, string header, string metaData, CancellationToken cancellationToken = default)
+ public async Task SetNextAvTransport(string url, string? header, string metaData, CancellationToken cancellationToken = default)
{
var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
@@ -380,7 +361,7 @@ namespace Emby.Dlna.PlayTo
_logger.LogDebug("{PropertyName} - SetNextAvTransport Uri: {Url} DlnaHeaders: {Header}", Properties.Name, url, header);
- var command = avCommands.ServiceActions.FirstOrDefault(c => string.Equals(c.Name, "SetNextAVTransportURI", StringComparison.OrdinalIgnoreCase));
+ var command = avCommands?.ServiceActions.FirstOrDefault(c => string.Equals(c.Name, "SetNextAVTransportURI", StringComparison.OrdinalIgnoreCase));
if (command is null)
{
return;
@@ -392,14 +373,8 @@ namespace Emby.Dlna.PlayTo
{ "NextURIMetaData", CreateDidlMeta(metaData) }
};
- var service = GetAvTransportService();
-
- if (service is null)
- {
- throw new InvalidOperationException("Unable to find service");
- }
-
- var post = avCommands.BuildPost(command, service.ServiceType, url, dictionary);
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
+ var post = avCommands!.BuildPost(command, service.ServiceType, url, dictionary); // null checked above
await new DlnaHttpClient(_logger, _httpClientFactory)
.SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header, cancellationToken)
.ConfigureAwait(false);
@@ -423,12 +398,7 @@ namespace Emby.Dlna.PlayTo
return Task.CompletedTask;
}
- var service = GetAvTransportService();
- if (service is null)
- {
- throw new InvalidOperationException("Unable to find service");
- }
-
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
return new DlnaHttpClient(_logger, _httpClientFactory).SendCommandAsync(
Properties.BaseUrl,
service,
@@ -460,14 +430,13 @@ namespace Emby.Dlna.PlayTo
return;
}
- var service = GetAvTransportService();
-
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
await new DlnaHttpClient(_logger, _httpClientFactory)
.SendCommandAsync(
Properties.BaseUrl,
service,
command.Name,
- avCommands.BuildPost(command, service.ServiceType, 1),
+ avCommands!.BuildPost(command, service.ServiceType, 1), // null checked above
cancellationToken: cancellationToken)
.ConfigureAwait(false);
@@ -484,14 +453,13 @@ namespace Emby.Dlna.PlayTo
return;
}
- var service = GetAvTransportService();
-
+ var service = GetAvTransportService() ?? throw new InvalidOperationException("Unable to find service");
await new DlnaHttpClient(_logger, _httpClientFactory)
.SendCommandAsync(
Properties.BaseUrl,
service,
command.Name,
- avCommands.BuildPost(command, service.ServiceType, 1),
+ avCommands!.BuildPost(command, service.ServiceType, 1), // null checked above
cancellationToken: cancellationToken)
.ConfigureAwait(false);
@@ -500,7 +468,7 @@ namespace Emby.Dlna.PlayTo
RestartTimer(true);
}
- private async void TimerCallback(object sender)
+ private async void TimerCallback(object? sender)
{
if (_disposed)
{
@@ -623,7 +591,7 @@ namespace Emby.Dlna.PlayTo
Properties.BaseUrl,
service,
command.Name,
- rendererCommands.BuildPost(command, service.ServiceType),
+ rendererCommands!.BuildPost(command, service.ServiceType), // null checked above
cancellationToken: cancellationToken).ConfigureAwait(false);
if (result is null || result.Document is null)
@@ -673,7 +641,7 @@ namespace Emby.Dlna.PlayTo
Properties.BaseUrl,
service,
command.Name,
- rendererCommands.BuildPost(command, service.ServiceType),
+ rendererCommands!.BuildPost(command, service.ServiceType), // null checked above
cancellationToken: cancellationToken).ConfigureAwait(false);
if (result is null || result.Document is null)
@@ -728,7 +696,7 @@ namespace Emby.Dlna.PlayTo
return null;
}
- private async Task<UBaseObject> GetMediaInfo(TransportCommands avCommands, CancellationToken cancellationToken)
+ private async Task<UBaseObject?> GetMediaInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMediaInfo");
if (command is null)
@@ -798,7 +766,7 @@ namespace Emby.Dlna.PlayTo
return null;
}
- private async Task<(bool Success, UBaseObject Track)> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
+ private async Task<(bool Success, UBaseObject? Track)> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetPositionInfo");
if (command is null)
@@ -871,7 +839,7 @@ namespace Emby.Dlna.PlayTo
return (true, null);
}
- XElement uPnpResponse = null;
+ XElement? uPnpResponse = null;
try
{
@@ -895,7 +863,7 @@ namespace Emby.Dlna.PlayTo
return (true, uTrack);
}
- private XElement ParseResponse(string xml)
+ private XElement? ParseResponse(string xml)
{
// Handle different variations sent back by devices.
try
@@ -929,7 +897,7 @@ namespace Emby.Dlna.PlayTo
return null;
}
- private static UBaseObject CreateUBaseObject(XElement container, string trackUri)
+ private static UBaseObject CreateUBaseObject(XElement? container, string? trackUri)
{
ArgumentNullException.ThrowIfNull(container);
@@ -959,20 +927,17 @@ namespace Emby.Dlna.PlayTo
var resElement = container.Element(UPnpNamespaces.Res);
- if (resElement is not null)
- {
- var info = resElement.Attribute(UPnpNamespaces.ProtocolInfo);
+ var info = resElement?.Attribute(UPnpNamespaces.ProtocolInfo);
- if (info is not null && !string.IsNullOrWhiteSpace(info.Value))
- {
- return info.Value.Split(':');
- }
+ if (info is not null && !string.IsNullOrWhiteSpace(info.Value))
+ {
+ return info.Value.Split(':');
}
return new string[4];
}
- private async Task<TransportCommands> GetAVProtocolAsync(CancellationToken cancellationToken)
+ private async Task<TransportCommands?> GetAVProtocolAsync(CancellationToken cancellationToken)
{
if (AvCommands is not null)
{
@@ -1004,7 +969,7 @@ namespace Emby.Dlna.PlayTo
return AvCommands;
}
- private async Task<TransportCommands> GetRenderingProtocolAsync(CancellationToken cancellationToken)
+ private async Task<TransportCommands?> GetRenderingProtocolAsync(CancellationToken cancellationToken)
{
if (RendererCommands is not null)
{
@@ -1054,7 +1019,7 @@ namespace Emby.Dlna.PlayTo
return baseUrl + url;
}
- public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClientFactory httpClientFactory, ILogger logger, CancellationToken cancellationToken)
+ public static async Task<Device?> CreateuPnpDeviceAsync(Uri url, IHttpClientFactory httpClientFactory, ILogger logger, CancellationToken cancellationToken)
{
var ssdpHttpClient = new DlnaHttpClient(logger, httpClientFactory);
@@ -1171,7 +1136,6 @@ namespace Emby.Dlna.PlayTo
return new Device(deviceProperties, httpClientFactory, logger);
}
-#nullable enable
private static DeviceIcon CreateIcon(XElement element)
{
ArgumentNullException.ThrowIfNull(element);
@@ -1287,7 +1251,7 @@ namespace Emby.Dlna.PlayTo
}
_timer = null;
- Properties = null;
+ Properties = null!;
_disposed = true;
}