diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 8518b13521..3253ea0267 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -101,7 +101,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Prometheus.DotNetRuntime;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
@@ -133,7 +132,7 @@ namespace Emby.Server.Implementations
/// All concrete types.
private Type[] _allConcreteTypes;
- private bool _disposed = false;
+ private bool _disposed;
///
/// Initializes a new instance of the class.
@@ -184,26 +183,16 @@ namespace Emby.Server.Implementations
public bool CoreStartupHasCompleted { get; private set; }
- public virtual bool CanLaunchWebBrowser => Environment.UserInteractive
- && !_startupOptions.IsService
- && (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
-
///
/// Gets the singleton instance.
///
public INetworkManager NetManager { get; private set; }
- ///
- /// Gets a value indicating whether this instance has changes that require the entire application to restart.
- ///
- /// true if this instance has pending application restart; otherwise, false.
- public bool HasPendingRestart { get; private set; }
-
///
- public bool IsShuttingDown { get; private set; }
+ public bool HasPendingRestart { get; private set; }
///
- public bool ShouldRestart { get; private set; }
+ public bool ShouldRestart { get; set; }
///
/// Gets the logger.
@@ -507,6 +496,8 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
+ serviceCollection.AddScoped();
+
serviceCollection.AddSingleton();
serviceCollection.AddSingleton(NetManager);
@@ -850,24 +841,6 @@ namespace Emby.Server.Implementations
}
}
- ///
- public void Restart()
- {
- ShouldRestart = true;
- Shutdown();
- }
-
- ///
- public void Shutdown()
- {
- Task.Run(async () =>
- {
- await Task.Delay(100).ConfigureAwait(false);
- IsShuttingDown = true;
- Resolve().StopApplication();
- });
- }
-
///
/// Gets the composable part assemblies.
///
@@ -923,49 +896,6 @@ namespace Emby.Server.Implementations
protected abstract IEnumerable GetAssembliesWithPartsInternal();
- ///
- /// Gets the system status.
- ///
- /// Where this request originated.
- /// SystemInfo.
- public SystemInfo GetSystemInfo(HttpRequest request)
- {
- return new SystemInfo
- {
- HasPendingRestart = HasPendingRestart,
- IsShuttingDown = IsShuttingDown,
- Version = ApplicationVersionString,
- WebSocketPortNumber = HttpPort,
- CompletedInstallations = Resolve().CompletedInstallations.ToArray(),
- Id = SystemId,
- ProgramDataPath = ApplicationPaths.ProgramDataPath,
- WebPath = ApplicationPaths.WebPath,
- LogPath = ApplicationPaths.LogDirectoryPath,
- ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
- InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
- CachePath = ApplicationPaths.CachePath,
- CanLaunchWebBrowser = CanLaunchWebBrowser,
- TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
- ServerName = FriendlyName,
- LocalAddress = GetSmartApiUrl(request),
- SupportsLibraryMonitor = true,
- PackageName = _startupOptions.PackageName
- };
- }
-
- public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
- {
- return new PublicSystemInfo
- {
- Version = ApplicationVersionString,
- ProductName = ApplicationProductName,
- Id = SystemId,
- ServerName = FriendlyName,
- LocalAddress = GetSmartApiUrl(request),
- StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted
- };
- }
-
///
public string GetSmartApiUrl(IPAddress remoteAddr)
{
diff --git a/Emby.Server.Implementations/SystemManager.cs b/Emby.Server.Implementations/SystemManager.cs
new file mode 100644
index 0000000000..5e9c424e9a
--- /dev/null
+++ b/Emby.Server.Implementations/SystemManager.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Updates;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.System;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Hosting;
+
+namespace Emby.Server.Implementations;
+
+///
+public class SystemManager : ISystemManager
+{
+ private readonly IHostApplicationLifetime _applicationLifetime;
+ private readonly IServerApplicationHost _applicationHost;
+ private readonly IServerApplicationPaths _applicationPaths;
+ private readonly IServerConfigurationManager _configurationManager;
+ private readonly IStartupOptions _startupOptions;
+ private readonly IInstallationManager _installationManager;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Instance of .
+ /// Instance of .
+ /// Instance of .
+ /// Instance of .
+ /// Instance of .
+ /// Instance of .
+ public SystemManager(
+ IHostApplicationLifetime applicationLifetime,
+ IServerApplicationHost applicationHost,
+ IServerApplicationPaths applicationPaths,
+ IServerConfigurationManager configurationManager,
+ IStartupOptions startupOptions,
+ IInstallationManager installationManager)
+ {
+ _applicationLifetime = applicationLifetime;
+ _applicationHost = applicationHost;
+ _applicationPaths = applicationPaths;
+ _configurationManager = configurationManager;
+ _startupOptions = startupOptions;
+ _installationManager = installationManager;
+ }
+
+ private bool CanLaunchWebBrowser => Environment.UserInteractive
+ && !_startupOptions.IsService
+ && (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
+
+ ///
+ public SystemInfo GetSystemInfo(HttpRequest request)
+ {
+ return new SystemInfo
+ {
+ HasPendingRestart = _applicationHost.HasPendingRestart,
+ IsShuttingDown = _applicationLifetime.ApplicationStopping.IsCancellationRequested,
+ Version = _applicationHost.ApplicationVersionString,
+ WebSocketPortNumber = _applicationHost.HttpPort,
+ CompletedInstallations = _installationManager.CompletedInstallations.ToArray(),
+ Id = _applicationHost.SystemId,
+ ProgramDataPath = _applicationPaths.ProgramDataPath,
+ WebPath = _applicationPaths.WebPath,
+ LogPath = _applicationPaths.LogDirectoryPath,
+ ItemsByNamePath = _applicationPaths.InternalMetadataPath,
+ InternalMetadataPath = _applicationPaths.InternalMetadataPath,
+ CachePath = _applicationPaths.CachePath,
+ CanLaunchWebBrowser = CanLaunchWebBrowser,
+ TranscodingTempPath = _configurationManager.GetTranscodePath(),
+ ServerName = _applicationHost.FriendlyName,
+ LocalAddress = _applicationHost.GetSmartApiUrl(request),
+ SupportsLibraryMonitor = true,
+ PackageName = _startupOptions.PackageName
+ };
+ }
+
+ ///
+ public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
+ {
+ return new PublicSystemInfo
+ {
+ Version = _applicationHost.ApplicationVersionString,
+ ProductName = _applicationHost.Name,
+ Id = _applicationHost.SystemId,
+ ServerName = _applicationHost.FriendlyName,
+ LocalAddress = _applicationHost.GetSmartApiUrl(request),
+ StartupWizardCompleted = _configurationManager.CommonConfiguration.IsStartupWizardCompleted
+ };
+ }
+
+ ///
+ public void Restart() => ShutdownInternal(true);
+
+ ///
+ public void Shutdown() => ShutdownInternal(false);
+
+ private void ShutdownInternal(bool restart)
+ {
+ Task.Run(async () =>
+ {
+ await Task.Delay(100).ConfigureAwait(false);
+ _applicationHost.ShouldRestart = restart;
+ _applicationLifetime.StopApplication();
+ });
+ }
+}
diff --git a/Jellyfin.Api/Controllers/SystemController.cs b/Jellyfin.Api/Controllers/SystemController.cs
index 42ac4a9b4b..11095a97f0 100644
--- a/Jellyfin.Api/Controllers/SystemController.cs
+++ b/Jellyfin.Api/Controllers/SystemController.cs
@@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
@@ -26,32 +25,36 @@ namespace Jellyfin.Api.Controllers;
///
public class SystemController : BaseJellyfinApiController
{
+ private readonly ILogger _logger;
private readonly IServerApplicationHost _appHost;
private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem;
- private readonly INetworkManager _network;
- private readonly ILogger _logger;
+ private readonly INetworkManager _networkManager;
+ private readonly ISystemManager _systemManager;
///
/// Initializes a new instance of the class.
///
- /// Instance of interface.
+ /// Instance of interface.
+ /// Instance of interface.
/// Instance of interface.
/// Instance of interface.
- /// Instance of interface.
- /// Instance of interface.
+ /// Instance of interface.
+ /// Instance of interface.
public SystemController(
- IServerConfigurationManager serverConfigurationManager,
+ ILogger logger,
IServerApplicationHost appHost,
+ IServerApplicationPaths appPaths,
IFileSystem fileSystem,
- INetworkManager network,
- ILogger logger)
+ INetworkManager networkManager,
+ ISystemManager systemManager)
{
- _appPaths = serverConfigurationManager.ApplicationPaths;
+ _logger = logger;
_appHost = appHost;
+ _appPaths = appPaths;
_fileSystem = fileSystem;
- _network = network;
- _logger = logger;
+ _networkManager = networkManager;
+ _systemManager = systemManager;
}
///
@@ -65,9 +68,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult GetSystemInfo()
- {
- return _appHost.GetSystemInfo(Request);
- }
+ => _systemManager.GetSystemInfo(Request);
///
/// Gets public information about the server.
@@ -77,9 +78,7 @@ public class SystemController : BaseJellyfinApiController
[HttpGet("Info/Public")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult GetPublicSystemInfo()
- {
- return _appHost.GetPublicSystemInfo(Request);
- }
+ => _systemManager.GetPublicSystemInfo(Request);
///
/// Pings the system.
@@ -90,9 +89,7 @@ public class SystemController : BaseJellyfinApiController
[HttpPost("Ping", Name = "PostPingSystem")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult PingSystem()
- {
- return _appHost.Name;
- }
+ => _appHost.Name;
///
/// Restarts the application.
@@ -106,7 +103,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult RestartApplication()
{
- _appHost.Restart();
+ _systemManager.Restart();
return NoContent();
}
@@ -122,7 +119,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult ShutdownApplication()
{
- _appHost.Shutdown();
+ _systemManager.Shutdown();
return NoContent();
}
@@ -180,7 +177,7 @@ public class SystemController : BaseJellyfinApiController
return new EndPointInfo
{
IsLocal = HttpContext.IsLocal(),
- IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP())
+ IsInNetwork = _networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP())
};
}
@@ -218,7 +215,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult> GetWakeOnLanInfo()
{
- var result = _network.GetMacAddresses()
+ var result = _networkManager.GetMacAddresses()
.Select(i => new WakeOnLanInfo(i));
return Ok(result);
}
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 5985d3dd82..23795c6be8 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -35,21 +35,15 @@ namespace MediaBrowser.Common
string SystemId { get; }
///
- /// Gets a value indicating whether this instance has pending kernel reload.
+ /// Gets a value indicating whether this instance has pending changes requiring a restart.
///
- /// true if this instance has pending kernel reload; otherwise, false.
+ /// true if this instance has a pending restart; otherwise, false.
bool HasPendingRestart { get; }
///
- /// Gets a value indicating whether this instance is currently shutting down.
+ /// Gets or sets a value indicating whether the application should restart.
///
- /// true if this instance is shutting down; otherwise, false.
- bool IsShuttingDown { get; }
-
- ///
- /// Gets a value indicating whether the application should restart.
- ///
- bool ShouldRestart { get; }
+ bool ShouldRestart { get; set; }
///
/// Gets the application version.
@@ -91,11 +85,6 @@ namespace MediaBrowser.Common
///
void NotifyPendingRestart();
- ///
- /// Restarts this instance.
- ///
- void Restart();
-
///
/// Gets the exports.
///
@@ -127,11 +116,6 @@ namespace MediaBrowser.Common
/// ``0.
T Resolve();
- ///
- /// Shuts down.
- ///
- void Shutdown();
-
///
/// Initializes this instance.
///
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 45ac5c3a85..e9c4d9e19a 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -4,7 +4,6 @@
using System.Net;
using MediaBrowser.Common;
-using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller
@@ -16,8 +15,6 @@ namespace MediaBrowser.Controller
{
bool CoreStartupHasCompleted { get; }
- bool CanLaunchWebBrowser { get; }
-
///
/// Gets the HTTP server port.
///
@@ -41,15 +38,6 @@ namespace MediaBrowser.Controller
/// The name of the friendly.
string FriendlyName { get; }
- ///
- /// Gets the system info.
- ///
- /// The HTTP request.
- /// SystemInfo.
- SystemInfo GetSystemInfo(HttpRequest request);
-
- PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
-
///
/// Gets a URL specific for the request.
///
diff --git a/MediaBrowser.Controller/ISystemManager.cs b/MediaBrowser.Controller/ISystemManager.cs
new file mode 100644
index 0000000000..ef3034d2f5
--- /dev/null
+++ b/MediaBrowser.Controller/ISystemManager.cs
@@ -0,0 +1,34 @@
+using MediaBrowser.Model.System;
+using Microsoft.AspNetCore.Http;
+
+namespace MediaBrowser.Controller;
+
+///
+/// A service for managing the application instance.
+///
+public interface ISystemManager
+{
+ ///
+ /// Gets the system info.
+ ///
+ /// The HTTP request.
+ /// The .
+ SystemInfo GetSystemInfo(HttpRequest request);
+
+ ///
+ /// Gets the public system info.
+ ///
+ /// The HTTP request.
+ /// The .
+ PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
+
+ ///
+ /// Starts the application restart process.
+ ///
+ void Restart();
+
+ ///
+ /// Starts the application shutdown process.
+ ///
+ void Shutdown();
+}