Skip to content

Commit

Permalink
Track packaged apps via AUMID vs install path
Browse files Browse the repository at this point in the history
  • Loading branch information
riverar committed Apr 11, 2024
1 parent edcfb76 commit a3a0587
Show file tree
Hide file tree
Showing 17 changed files with 44 additions and 8 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Changelog

## x.x.x.x
- Fixed an issue where EarTrumpet tooltips were not updating in some scenarios (thanks @Tester798!)
- Fixed an issue with EarTrumpet tooltips not updating in some scenarios (thanks @Tester798!)
- Fixed an issue with EarTrumpet Actions getting disconnected with updated packaged applications
- Added setting to show the full mixer window on startup
- Added support for adjusting volumes by 10% in one step from the flyout when the `Ctrl` key is pressed in combination with `Right`/`Left` or `+`/`-` (thanks @ryanspain)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private static IAudioDeviceSession FindForegroundApp(ObservableCollection<IAudio

foreach(var group in groups)
{
if (group.AppId == appInfo.PackageInstallPath)
if (group.AppId == appInfo.PackageInstallPath || group.AppId == appInfo.AppId)
{
Trace.WriteLine($"ActionProcessor FindForegroundApp: {group.DisplayName}");
return group;
Expand Down
14 changes: 12 additions & 2 deletions EarTrumpet/Addons/EarTrumpet.Actions/ViewModel/AppListViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public AppListViewModel(IPartWithApp part, AppKind flags)
}
}

public void OnInvoked(object sender, IAppItemViewModel vivewModel)
public void OnInvoked(object sender, IAppItemViewModel viewModel)
{
_part.App = new AppRef { Id = vivewModel.Id };
_part.App = new AppRef { Id = viewModel.Id };
RaisePropertyChanged(""); // Signal change so ToString will be called.

var popup = ((DependencyObject)sender).FindVisualParent<Popup>();
Expand All @@ -51,6 +51,16 @@ public void OnInvoked(object sender, IAppItemViewModel vivewModel)
public override string ToString()
{
var existing = All.FirstOrDefault(d => d.Id == _part.App?.Id);

// Fallback to checking against package full path, for compatibility with older actions
// that predate changes to how we track packaged applications.
// https://github.com/File-New-Project/EarTrumpet/issues/1524

if (existing == null)
{
existing = All.FirstOrDefault(d => d.PackageInstallPath == _part.App?.Id);
}

if (existing != null)
{
return existing.DisplayName;
Expand Down
1 change: 1 addition & 0 deletions EarTrumpet/DataModel/AppInformation/IAppInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace EarTrumpet.DataModel.AppInformation
public interface IAppInfo
{
event Action<IAppInfo> Stopped;
string AppId { get; }
string DisplayName { get; }
string ExeName { get; }
string PackageInstallPath { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class DesktopAppInfo : IAppInfo
public string ExeName { get; }
public string DisplayName { get; }
public string PackageInstallPath { get; }
public string AppId => PackageInstallPath;
public string SmallLogoPath { get; }
public bool IsDesktopApp => true;

Expand Down
2 changes: 2 additions & 0 deletions EarTrumpet/DataModel/AppInformation/Internal/ModernAppInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class ModernAppInfo : IAppInfo
{
public event Action<IAppInfo> Stopped;

public string AppId { get; }
public string ExeName { get; }
public string DisplayName { get; }
public string PackageInstallPath { get; }
Expand All @@ -28,6 +29,7 @@ public ModernAppInfo(int processId, bool trackProcess)
{
var shellItem = Shell32.SHCreateItemInKnownFolder(FolderIds.AppsFolder, Shell32.KF_FLAG_DONT_VERIFY, appUserModelId, typeof(IShellItem2).GUID);
PackageInstallPath = shellItem.GetString(ref PropertyKeys.PKEY_AppUserModel_PackageInstallPath);
AppId = shellItem.GetString(ref PropertyKeys.PKEY_AppUserModel_ID);
DisplayName = shellItem.GetString(ref PropertyKeys.PKEY_ItemNameDisplay);
ExeName = PackageInstallPath;
SmallLogoPath = appUserModelId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public event Action<IAppInfo> Stopped { add { } remove { } }
public string PackageInstallPath => "System.SystemSoundsSession";
public bool IsDesktopApp => true;
public string SmallLogoPath { get; set; }
public string AppId => PackageInstallPath;

public SystemSoundsAppInfo()
{
Expand Down
1 change: 1 addition & 0 deletions EarTrumpet/DataModel/Audio/IAudioDeviceSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface IAudioDeviceSession : IStreamWithVolumeControl
bool IsSystemSoundsSession { get; }
int ProcessId { get; }
string AppId { get; }
string PackageInstallPath { get; }
SessionState State { get; }
ObservableCollection<IAudioDeviceSession> Children { get; }
}
Expand Down
5 changes: 4 additions & 1 deletion EarTrumpet/DataModel/Audio/Mocks/AudioDeviceSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,17 @@ public float Volume

public Guid GroupingParam => Guid.Empty;

public AudioDeviceSession(IAudioDevice parent, string id, string displayName, string appId, string iconPath)
public string PackageInstallPath { get; }

public AudioDeviceSession(IAudioDevice parent, string id, string displayName, string appId, string iconPath, string packageInstallPath)
{
DisplayName = displayName;
Id = id;
AppId = appId;
IconPath = iconPath;
Parent = parent;
IsDesktopApp = true;
PackageInstallPath = packageInstallPath;
}

public void Hide()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public bool IsMuted
public float PeakValue1 { get; private set; }
public float PeakValue2 { get; private set; }
public bool IsDesktopApp => _appInfo.IsDesktopApp;
public string AppId => _appInfo.PackageInstallPath;
public string AppId => _appInfo.AppId;

public SessionState State
{
Expand Down Expand Up @@ -125,6 +125,7 @@ public SessionState State

public ObservableCollection<IAudioDeviceSession> Children { get; private set; }
public IEnumerable<IAudioDeviceSessionChannel> Channels => _channels.Channels;
public string PackageInstallPath { get; private set; }

private readonly string _id;
private readonly IAudioSessionControl _session;
Expand Down Expand Up @@ -159,6 +160,7 @@ public AudioDeviceSession(IAudioDevice parent, IAudioSessionControl session, Dis

_appInfo = AppInformationFactory.CreateForProcess(ProcessId, trackProcess: true);
_appInfo.Stopped += _ => DisconnectSession();
PackageInstallPath = _appInfo.PackageInstallPath;

// NOTE: Ensure that the callbacks won't touch state that isn't initialized yet (i.e. _appInfo must be valid before the first callback)
_session.RegisterAudioSessionNotification(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public float Volume

public ObservableCollection<IAudioDeviceSession> Children => _sessions;

public string PackageInstallPath => _sessions.FirstOrDefault()?.PackageInstallPath;

public void Hide()
{
foreach (var session in _sessions.ToArray())
Expand Down
3 changes: 2 additions & 1 deletion EarTrumpet/DebugHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ private static DataModel.Audio.Mocks.AudioDeviceSession MakeMockApp(IAudioDevice
Guid.NewGuid().ToString(),
displayName,
appId,
Environment.ExpandEnvironmentVariables(iconPath));
Environment.ExpandEnvironmentVariables(iconPath),
appId);
}

private static void DebugAddMockDevice()
Expand Down
6 changes: 6 additions & 0 deletions EarTrumpet/Interop/PropertyKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ namespace EarTrumpet.Interop
{
public static class PropertyKeys
{
public static PROPERTYKEY PKEY_AppUserModel_ID = new PROPERTYKEY
{
fmtid = new Guid("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3"),
pid = new UIntPtr(5)
};

public static PROPERTYKEY PKEY_ItemNameDisplay = new PROPERTYKEY
{
fmtid = new Guid("{B725F130-47EF-101A-A5F1-02608C9EEBAC}"),
Expand Down
2 changes: 2 additions & 0 deletions EarTrumpet/UI/ViewModels/AppItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public IDeviceViewModel Parent
}
}

public string PackageInstallPath => _session.PackageInstallPath;

private readonly IAudioDeviceSession _session;
private readonly WeakReference<DeviceViewModel> _parent;

Expand Down
1 change: 1 addition & 0 deletions EarTrumpet/UI/ViewModels/IAppItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface IAppItemViewModel : IAppIconSource, INotifyPropertyChanged
string DisplayName { get; }
string ExeName { get; }
string AppId { get; }
string PackageInstallPath { get; }
char IconText { get; }
bool IsExpanded { get; }
bool IsMovable { get; }
Expand Down
3 changes: 2 additions & 1 deletion EarTrumpet/UI/ViewModels/SettingsAppItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ public int Volume
public string PersistedOutputDevice => throw new NotImplementedException();
public int ProcessId => throw new NotImplementedException();
public IDeviceViewModel Parent => throw new NotImplementedException();

public ICommand Remove { get; set; }
public string PackageInstallPath { get; set; }

public SettingsAppItemViewModel(IAudioDeviceSession session)
{
AppId = session.AppId;
PackageInstallPath = session.PackageInstallPath;
DisplayName = session.DisplayName;
IsDesktopApp = session.IsDesktopApp;
IconPath = session.IconPath;
Expand Down
1 change: 1 addition & 0 deletions EarTrumpet/UI/ViewModels/TemporaryAppItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public int Volume
public string PersistedOutputDevice => ((IAudioDeviceManagerWindowsAudio)_deviceManager).GetDefaultEndPoint(ProcessId);
public int ProcessId { get; }
public IDeviceViewModel Parent { get; }
public string PackageInstallPath { get; }

private readonly IAudioDeviceManager _deviceManager;
private readonly WeakReference<DeviceCollectionViewModel> _parent;
Expand Down

0 comments on commit a3a0587

Please sign in to comment.