Files
maui-linux/Services/VersionTrackingService.cs
logikonline c6a3f4acc4
All checks were successful
CI / Build (Linux) (push) Successful in 21s
Release / Build and Publish (push) Successful in 20s
chore(perf): bump version to 9.0.40 to match MAUI 9.0.40
Update version from 9.0.0 to 9.0.40 to align precisely with MAUI 9.0.40 release. Update CHANGELOG, package metadata, and templates. Fix thread safety issue in FontFallbackManager by changing _glyphCache from Dictionary to ConcurrentDictionary to prevent race conditions during concurrent glyph lookups.
2026-03-07 01:48:58 -05:00

252 lines
6.7 KiB
C#

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Reflection;
using System.Text.Json;
using Microsoft.Maui.ApplicationModel;
namespace Microsoft.Maui.Platform.Linux.Services;
/// <summary>
/// Linux version tracking implementation.
/// </summary>
public class VersionTrackingService : IVersionTracking
{
private const string VersionTrackingFile = ".maui-version-tracking.json";
private readonly string _trackingFilePath;
private VersionTrackingData _data;
private bool _isInitialized;
public VersionTrackingService()
{
_trackingFilePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
VersionTrackingFile);
_data = new VersionTrackingData();
}
private void EnsureInitialized()
{
if (_isInitialized) return;
_isInitialized = true;
LoadTrackingData();
UpdateTrackingData();
}
private void LoadTrackingData()
{
try
{
if (File.Exists(_trackingFilePath))
{
var json = File.ReadAllText(_trackingFilePath);
_data = JsonSerializer.Deserialize<VersionTrackingData>(json) ?? new VersionTrackingData();
}
}
catch
{
_data = new VersionTrackingData();
}
}
private void UpdateTrackingData()
{
var currentVersion = CurrentVersion;
var currentBuild = CurrentBuild;
// Check if this is a new version
if (_data.PreviousVersion != currentVersion || _data.PreviousBuild != currentBuild)
{
// Store previous version info
if (!string.IsNullOrEmpty(_data.CurrentVersion))
{
_data.PreviousVersion = _data.CurrentVersion;
_data.PreviousBuild = _data.CurrentBuild;
}
_data.CurrentVersion = currentVersion;
_data.CurrentBuild = currentBuild;
// Add to version history
if (!_data.VersionHistory.Contains(currentVersion))
{
_data.VersionHistory.Add(currentVersion);
}
// Add to build history
if (!_data.BuildHistory.Contains(currentBuild))
{
_data.BuildHistory.Add(currentBuild);
}
}
// Track first launch
if (_data.FirstInstalledVersion == null)
{
_data.FirstInstalledVersion = currentVersion;
_data.FirstInstalledBuild = currentBuild;
_data.IsFirstLaunchEver = true;
}
else
{
_data.IsFirstLaunchEver = false;
}
// Check if first launch for current version
_data.IsFirstLaunchForCurrentVersion = _data.PreviousVersion != currentVersion;
_data.IsFirstLaunchForCurrentBuild = _data.PreviousBuild != currentBuild;
SaveTrackingData();
}
private void SaveTrackingData()
{
try
{
var directory = Path.GetDirectoryName(_trackingFilePath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var json = JsonSerializer.Serialize(_data, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(_trackingFilePath, json);
}
catch
{
// Silently fail if we can't save
}
}
public bool IsFirstLaunchEver
{
get
{
EnsureInitialized();
return _data.IsFirstLaunchEver;
}
}
public bool IsFirstLaunchForCurrentVersion
{
get
{
EnsureInitialized();
return _data.IsFirstLaunchForCurrentVersion;
}
}
public bool IsFirstLaunchForCurrentBuild
{
get
{
EnsureInitialized();
return _data.IsFirstLaunchForCurrentBuild;
}
}
public string CurrentVersion => GetAssemblyVersion();
public string CurrentBuild => GetAssemblyBuild();
public string? PreviousVersion
{
get
{
EnsureInitialized();
return _data.PreviousVersion;
}
}
public string? PreviousBuild
{
get
{
EnsureInitialized();
return _data.PreviousBuild;
}
}
public string? FirstInstalledVersion
{
get
{
EnsureInitialized();
return _data.FirstInstalledVersion;
}
}
public string? FirstInstalledBuild
{
get
{
EnsureInitialized();
return _data.FirstInstalledBuild;
}
}
public IReadOnlyList<string> VersionHistory
{
get
{
EnsureInitialized();
return _data.VersionHistory.AsReadOnly();
}
}
public IReadOnlyList<string> BuildHistory
{
get
{
EnsureInitialized();
return _data.BuildHistory.AsReadOnly();
}
}
public bool IsFirstLaunchForVersion(string version)
{
EnsureInitialized();
return !_data.VersionHistory.Contains(version);
}
public bool IsFirstLaunchForBuild(string build)
{
EnsureInitialized();
return !_data.BuildHistory.Contains(build);
}
public void Track()
{
EnsureInitialized();
}
private static string GetAssemblyVersion()
{
var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();
var version = assembly.GetName().Version;
return version != null ? $"{version.Major}.{version.Minor}.{version.Build}" : "9.0.40";
}
private static string GetAssemblyBuild()
{
var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();
var version = assembly.GetName().Version;
return version?.Revision.ToString() ?? "0";
}
private class VersionTrackingData
{
public string? CurrentVersion { get; set; }
public string? CurrentBuild { get; set; }
public string? PreviousVersion { get; set; }
public string? PreviousBuild { get; set; }
public string? FirstInstalledVersion { get; set; }
public string? FirstInstalledBuild { get; set; }
public List<string> VersionHistory { get; set; } = new();
public List<string> BuildHistory { get; set; } = new();
public bool IsFirstLaunchEver { get; set; }
public bool IsFirstLaunchForCurrentVersion { get; set; }
public bool IsFirstLaunchForCurrentBuild { get; set; }
}
}