252 lines
6.7 KiB
C#
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}" : "1.0.0";
|
|
}
|
|
|
|
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; }
|
|
}
|
|
}
|