< Summary - Jellyfin

Information
Class: Emby.Server.Implementations.Devices.DeviceId
Assembly: Emby.Server.Implementations
File(s): /srv/git/jellyfin/Emby.Server.Implementations/Devices/DeviceId.cs
Line coverage
70%
Covered lines: 26
Uncovered lines: 11
Coverable lines: 37
Total lines: 107
Line coverage: 70.2%
Branch coverage
75%
Covered branches: 6
Total branches: 8
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/16/2026 - 12:15:55 AM Line coverage: 62.1% (23/37) Branch coverage: 62.5% (5/8) Total lines: 985/20/2026 - 12:15:44 AM Line coverage: 62.1% (23/37) Branch coverage: 50% (4/8) Total lines: 987/18/2026 - 12:15:19 AM Line coverage: 62.1% (23/37) Branch coverage: 50% (4/8) Total lines: 10710/29/2026 - 12:17:11 AM Line coverage: 70.2% (26/37) Branch coverage: 75% (6/8) Total lines: 107 5/16/2026 - 12:15:55 AM Line coverage: 62.1% (23/37) Branch coverage: 62.5% (5/8) Total lines: 985/20/2026 - 12:15:44 AM Line coverage: 62.1% (23/37) Branch coverage: 50% (4/8) Total lines: 987/18/2026 - 12:15:19 AM Line coverage: 62.1% (23/37) Branch coverage: 50% (4/8) Total lines: 10710/29/2026 - 12:17:11 AM Line coverage: 70.2% (26/37) Branch coverage: 75% (6/8) Total lines: 107

Coverage delta

Coverage delta 25 -25

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Value()100%22100%
get_CachePath()100%11100%
GetCachedId()50%3250%
SaveId(...)50%2266.66%
GetNewId()100%11100%
GetDeviceId()100%22100%

File(s)

/srv/git/jellyfin/Emby.Server.Implementations/Devices/DeviceId.cs

#LineLine coverage
 1using System;
 2using System.Globalization;
 3using System.IO;
 4using System.Text;
 5using System.Threading;
 6using MediaBrowser.Common.Configuration;
 7using Microsoft.Extensions.Logging;
 8
 9namespace Emby.Server.Implementations.Devices
 10{
 11    /// <summary>
 12    /// Provides the persistent unique identifier of this server installation.
 13    /// </summary>
 14    public class DeviceId
 15    {
 16        private readonly IApplicationPaths _appPaths;
 17        private readonly ILogger<DeviceId> _logger;
 2818        private readonly Lock _syncLock = new();
 19
 20        private string? _id;
 21
 22        /// <summary>
 23        /// Initializes a new instance of the <see cref="DeviceId"/> class.
 24        /// </summary>
 25        /// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
 26        /// <param name="logger">Instance of the <see cref="ILogger{DeviceId}"/> interface.</param>
 27        public DeviceId(IApplicationPaths appPaths, ILogger<DeviceId> logger)
 28        {
 2829            _appPaths = appPaths;
 2830            _logger = logger;
 2831        }
 32
 33        /// <summary>
 34        /// Gets the device id, loading it from disk or generating and persisting a new one if none exists.
 35        /// </summary>
 13236        public string Value => _id ??= GetDeviceId();
 37
 5338        private string CachePath => Path.Combine(_appPaths.DataPath, "device.txt");
 39
 40        private string? GetCachedId()
 41        {
 42            try
 2743            {
 44                lock (_syncLock)
 45                {
 2746                    var value = File.ReadAllText(CachePath, Encoding.UTF8);
 47
 148                    if (Guid.TryParse(value, out _))
 49                    {
 150                        return value;
 51                    }
 52
 053                    _logger.LogError("Invalid value found in device id file");
 054                }
 055            }
 056            catch (DirectoryNotFoundException)
 57            {
 058            }
 2659            catch (FileNotFoundException)
 60            {
 2661            }
 062            catch (Exception ex)
 63            {
 064                _logger.LogError(ex, "Error reading file");
 065            }
 66
 2667            return null;
 168        }
 69
 70        private void SaveId(string id)
 71        {
 72            try
 73            {
 2674                var path = CachePath;
 75
 2676                Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new InvalidOperationException("Path can't
 77
 78                lock (_syncLock)
 79                {
 2680                    File.WriteAllText(path, id, Encoding.UTF8);
 2681                }
 2682            }
 083            catch (Exception ex)
 84            {
 085                _logger.LogError(ex, "Error writing to file");
 086            }
 2687        }
 88
 89        private static string GetNewId()
 90        {
 2691            return Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
 92        }
 93
 94        private string GetDeviceId()
 95        {
 2796            var id = GetCachedId();
 97
 2798            if (string.IsNullOrWhiteSpace(id))
 99            {
 26100                id = GetNewId();
 26101                SaveId(id);
 102            }
 103
 27104            return id;
 105        }
 106    }
 107}