diff --git a/src/cascadia/TerminalSettingsEditor/AISettings.cpp b/src/cascadia/TerminalSettingsEditor/AISettings.cpp index 64e4cc4512..3b573a7fae 100644 --- a/src/cascadia/TerminalSettingsEditor/AISettings.cpp +++ b/src/cascadia/TerminalSettingsEditor/AISettings.cpp @@ -78,7 +78,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _ViewModel = e.Parameter().as(); TraceLoggingWrite( - g_hSettingsEditorProvider, + g_hTerminalSettingsEditorProvider, "AISettingsPageOpened", TraceLoggingDescription("Event emitted when the user navigates to the AI Settings page"), TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), @@ -102,7 +102,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation AzureOpenAIKeyInputBox().Password(winrt::hstring{}); TraceLoggingWrite( - g_hSettingsEditorProvider, + g_hTerminalSettingsEditorProvider, "AzureOpenAIEndpointAndKeySaved", TraceLoggingDescription("Event emitted when the user stores an Azure OpenAI key and endpoint"), TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), @@ -124,7 +124,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation OpenAIKeyInputBox().Password(winrt::hstring{}); TraceLoggingWrite( - g_hSettingsEditorProvider, + g_hTerminalSettingsEditorProvider, "OpenAIEndpointAndKeySaved", TraceLoggingDescription("Event emitted when the user stores an OpenAI key and endpoint"), TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), diff --git a/src/cascadia/TerminalSettingsEditor/AISettingsViewModel.cpp b/src/cascadia/TerminalSettingsEditor/AISettingsViewModel.cpp index 9a7df4b771..1757ab01ce 100644 --- a/src/cascadia/TerminalSettingsEditor/AISettingsViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/AISettingsViewModel.cpp @@ -181,7 +181,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _NotifyChanges(L"GithubCopilotAuthMessage"); GithubAuthRequested.raise(nullptr, nullptr); TraceLoggingWrite( - g_hSettingsEditorProvider, + g_hTerminalSettingsEditorProvider, "GithubAuthInitiated", TraceLoggingDescription("Event emitted when the user clicks the button to initiate the GitHub auth flow"), TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), diff --git a/src/cascadia/TerminalSettingsEditor/Actions.cpp b/src/cascadia/TerminalSettingsEditor/Actions.cpp index dafc7b51da..f27d89eb27 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.cpp +++ b/src/cascadia/TerminalSettingsEditor/Actions.cpp @@ -66,6 +66,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("actions", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Actions::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*eventArgs*/) diff --git a/src/cascadia/TerminalSettingsEditor/AddProfile.cpp b/src/cascadia/TerminalSettingsEditor/AddProfile.cpp index bb2156c646..03864e855e 100644 --- a/src/cascadia/TerminalSettingsEditor/AddProfile.cpp +++ b/src/cascadia/TerminalSettingsEditor/AddProfile.cpp @@ -29,11 +29,27 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void AddProfile::OnNavigatedTo(const NavigationEventArgs& e) { _State = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("addProfile", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void AddProfile::AddNewClick(const IInspectable& /*sender*/, const Windows::UI::Xaml::RoutedEventArgs& /*eventArgs*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "AddNewProfile", + TraceLoggingDescription("Event emitted when the user adds a new profile"), + TraceLoggingValue("EmptyProfile", "Type", "The type of the creation method (i.e. empty profile, duplicate)"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _State.RequestAddNew(); } @@ -42,7 +58,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { if (const auto selected = Profiles().SelectedItem()) { - _State.RequestDuplicate(selected.try_as().Guid()); + const auto selectedProfile = selected.as(); + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "AddNewProfile", + TraceLoggingDescription("Event emitted when the user adds a new profile"), + TraceLoggingValue("Duplicate", "Type", "The type of the creation method (i.e. empty profile, duplicate)"), + TraceLoggingValue(!selectedProfile.Source().empty(), "SourceProfileHasSource", "True, if the source profile has a source (i.e. dynamic profile generator namespace, fragment). Otherwise, False, indicating it's based on a custom profile."), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + + _State.RequestDuplicate(selectedProfile.Guid()); } } diff --git a/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp b/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp index be932d2b90..899cc5f826 100644 --- a/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp +++ b/src/cascadia/TerminalSettingsEditor/ColorSchemes.cpp @@ -44,6 +44,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation ColorSchemeListView().Focus(FocusState::Programmatic); }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("colorSchemes", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void ColorSchemes::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Compatibility.cpp b/src/cascadia/TerminalSettingsEditor/Compatibility.cpp index 9637992ae8..9fa7b81ecf 100644 --- a/src/cascadia/TerminalSettingsEditor/Compatibility.cpp +++ b/src/cascadia/TerminalSettingsEditor/Compatibility.cpp @@ -25,11 +25,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void CompatibilityViewModel::ResetApplicationState() { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "ResetApplicationState", + TraceLoggingDescription("Event emitted when the user resets their application state"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _settings.ResetApplicationState(); } void CompatibilityViewModel::ResetToDefaultSettings() { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "ResetToDefaultSettings", + TraceLoggingDescription("Event emitted when the user resets their settings to their default value"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _settings.ResetToDefaultSettings(); } @@ -41,6 +55,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Compatibility::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("compatibility", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Compatibility::ResetApplicationStateButton_Click(const Windows::Foundation::IInspectable& /*sender*/, const Windows::UI::Xaml::RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp b/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp index ce24a89e48..1c1d5f0c84 100644 --- a/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp +++ b/src/cascadia/TerminalSettingsEditor/EditColorScheme.cpp @@ -42,7 +42,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { _ViewModel = e.Parameter().as(); - NameBox().Text(_ViewModel.Name()); + const auto schemeName = _ViewModel.Name(); + NameBox().Text(schemeName); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("colorSchemes.editColorScheme", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(schemeName.data(), "SchemeName", "The name of the color scheme that's being edited"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void EditColorScheme::ColorPickerChanged(const IInspectable& sender, diff --git a/src/cascadia/TerminalSettingsEditor/Extensions.cpp b/src/cascadia/TerminalSettingsEditor/Extensions.cpp index a3aec0ad7c..ecf2cc26ad 100644 --- a/src/cascadia/TerminalSettingsEditor/Extensions.cpp +++ b/src/cascadia/TerminalSettingsEditor/Extensions.cpp @@ -20,8 +20,6 @@ using namespace winrt::Windows::UI::Xaml::Navigation; namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { - static constexpr std::wstring_view ExtensionPageId{ L"page.extensions" }; - Extensions::Extensions() { InitializeComponent(); @@ -41,6 +39,36 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation vmImpl->ExtensionPackageIdentifierTemplateSelector(_extensionPackageIdentifierTemplateSelector); vmImpl->LazyLoadExtensions(); vmImpl->MarkAsVisited(); + + if (vmImpl->IsExtensionView()) + { + const auto currentPkgVM = vmImpl->CurrentExtensionPackage(); + const auto currentPkg = currentPkgVM.Package(); + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("extensions.extensionView", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(currentPkg.Source().c_str(), "FragmentSource", "The source of the fragment included in this extension package"), + TraceLoggingValue(currentPkgVM.FragmentExtensions().Size(), "FragmentCount", "The number of fragments included in this extension package"), + TraceLoggingValue(currentPkgVM.Enabled(), "Enabled", "The enabled status of the extension"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + } + else + { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("extensions", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(vmImpl->ExtensionPackages().Size(), "ExtensionPackageCount", "The number of extension packages displayed"), + TraceLoggingValue(vmImpl->ProfilesModified().Size(), "ProfilesModifiedCount", "The number of profiles modified by enabled extensions"), + TraceLoggingValue(vmImpl->ProfilesAdded().Size(), "ProfilesAddedCount", "The number of profiles added by enabled extensions"), + TraceLoggingValue(vmImpl->ColorSchemesAdded().Size(), "ColorSchemesAddedCount", "The number of color schemes added by enabled extensions"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + } } void Extensions::ExtensionNavigator_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/) @@ -338,7 +366,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation bool ExtensionsViewModel::DisplayBadge() const noexcept { - return !Model::ApplicationState::SharedInstance().BadgeDismissed(ExtensionPageId); + return !Model::ApplicationState::SharedInstance().BadgeDismissed(L"page.extensions"); } // Returns true if the extension is enabled, false otherwise @@ -411,7 +439,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void ExtensionsViewModel::MarkAsVisited() { - Model::ApplicationState::SharedInstance().DismissBadge(ExtensionPageId); + Model::ApplicationState::SharedInstance().DismissBadge(L"page.extensions"); _NotifyChanges(L"DisplayBadge"); } diff --git a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp index acb0abcb34..2b220b2ddd 100644 --- a/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp +++ b/src/cascadia/TerminalSettingsEditor/GlobalAppearance.cpp @@ -25,5 +25,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void GlobalAppearance::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("globalAppearance", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Interaction.cpp b/src/cascadia/TerminalSettingsEditor/Interaction.cpp index 24199f0c1b..6015cbcea1 100644 --- a/src/cascadia/TerminalSettingsEditor/Interaction.cpp +++ b/src/cascadia/TerminalSettingsEditor/Interaction.cpp @@ -22,5 +22,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Interaction::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("interaction", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Launch.cpp b/src/cascadia/TerminalSettingsEditor/Launch.cpp index 286ed7c814..9c0a933961 100644 --- a/src/cascadia/TerminalSettingsEditor/Launch.cpp +++ b/src/cascadia/TerminalSettingsEditor/Launch.cpp @@ -43,5 +43,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _ViewModel = e.Parameter().as(); auto innerViewModel{ winrt::get_self(_ViewModel) }; /* coroutine dispatch */ innerViewModel->PrepareStartOnUserLoginSettings(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("startup", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp index 8401a46f70..5d3cb2bdcc 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp +++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp @@ -400,6 +400,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto altPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) || WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down); const auto target = altPressed ? SettingsTarget::DefaultsFile : SettingsTarget::SettingsFile; + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "OpenJson", + TraceLoggingDescription("Event emitted when the user clicks the Open JSON button in the settings UI"), + TraceLoggingValue(target == SettingsTarget::DefaultsFile ? "DefaultsFile" : "SettingsFile", "SettingsTarget", "The target settings file"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + OpenJson.raise(nullptr, target); return; } diff --git a/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp b/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp index 25b7f8ef77..1587740b68 100644 --- a/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp +++ b/src/cascadia/TerminalSettingsEditor/NewTabMenu.cpp @@ -44,6 +44,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void NewTabMenu::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue(_ViewModel.IsFolderView() ? "newTabMenu.folderView" : "newTabMenu", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void NewTabMenu::FolderPickerDialog_Opened(const IInspectable& /*sender*/, const Controls::ContentDialogOpenedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp index 29b9f89108..64bdecd1d4 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Advanced.cpp @@ -29,6 +29,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto args = e.Parameter().as(); _Profile = args.Profile(); _windowRoot = args.WindowRoot(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.advanced", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Advanced::OnNavigatedFrom(const NavigationEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp index bbdd0a5aae..af21f342c4 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Appearance.cpp @@ -44,6 +44,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // The Appearances object handles updating the values in the settings UI, but // we still need to listen to the changes here just to update the preview control _AppearanceViewModelChangedRevoker = _Profile.DefaultAppearance().PropertyChanged(winrt::auto_revoke, { this, &Profiles_Appearance::_onProfilePropertyChanged }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.appearance", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingValue(_Profile.DefaultAppearance().BackgroundImageSettingsVisible(), "HasBackgroundImage", "If the profile has a background image defined"), + TraceLoggingValue(_Profile.HasUnfocusedAppearance(), "HasUnfocusedAppearance", "If the profile has an unfocused appearance defined"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Appearance::OnNavigatedFrom(const NavigationEventArgs& /*e*/) @@ -54,6 +67,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Appearance::CreateUnfocusedAppearance_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "CreateUnfocusedAppearance", + TraceLoggingDescription("Event emitted when the user creates an unfocused appearance for a profile"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + _Profile.CreateUnfocusedAppearance(); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp index 88ba50e386..774ecbb34d 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.cpp @@ -55,6 +55,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _Profile.FocusDeleteButton(false); } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to. Set to {3ad42e7b-e073-5f3e-ac57-1c259ffa86a8} if the profiles.defaults object is being modified."), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Base::OnNavigatedFrom(const NavigationEventArgs& /*e*/) @@ -79,6 +90,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Base::DeleteConfirmation_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) { + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "DeleteProfile", + TraceLoggingDescription("Event emitted when the user deletes a profile"), + TraceLoggingValue(to_hstring(_Profile.Guid()).c_str(), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingValue(false, "Orphaned", "Tracks if the profile is orphaned"), + TraceLoggingValue(_Profile.Hidden(), "Hidden", "Tracks if the profile is hidden"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); + winrt::get_self(_Profile)->DeleteProfile(); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp index bc27cc4c2d..dc1de90cb0 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base_Orphaned.cpp @@ -41,6 +41,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _Profile.FocusDeleteButton(false); } }); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profileOrphaned", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Base_Orphaned::DeleteConfirmation_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp b/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp index 7d42d64d21..fd8899dff1 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Terminal.cpp @@ -22,6 +22,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Profiles_Terminal::OnNavigatedTo(const NavigationEventArgs& e) { _Profile = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("profile.terminal", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingValue(_Profile.IsBaseLayer(), "IsProfileDefaults", "If the modified profile is the profile.defaults object"), + TraceLoggingValue(static_cast(_Profile.Guid()), "ProfileGuid", "The guid of the profile that was navigated to"), + TraceLoggingValue(_Profile.Source().c_str(), "ProfileSource", "The source of the profile that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } void Profiles_Terminal::OnNavigatedFrom(const NavigationEventArgs& /*e*/) diff --git a/src/cascadia/TerminalSettingsEditor/Rendering.cpp b/src/cascadia/TerminalSettingsEditor/Rendering.cpp index 5ce0d1285e..836d63ca20 100644 --- a/src/cascadia/TerminalSettingsEditor/Rendering.cpp +++ b/src/cascadia/TerminalSettingsEditor/Rendering.cpp @@ -17,5 +17,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void Rendering::OnNavigatedTo(const NavigationEventArgs& e) { _ViewModel = e.Parameter().as(); + + TraceLoggingWrite( + g_hTerminalSettingsEditorProvider, + "NavigatedToPage", + TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"), + TraceLoggingValue("rendering", "PageId", "The identifier of the page that was navigated to"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), + TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage)); } } diff --git a/src/cascadia/TerminalSettingsEditor/Utils.cpp b/src/cascadia/TerminalSettingsEditor/Utils.cpp index 5fc2fea999..07fde8471f 100644 --- a/src/cascadia/TerminalSettingsEditor/Utils.cpp +++ b/src/cascadia/TerminalSettingsEditor/Utils.cpp @@ -13,8 +13,6 @@ using namespace winrt::Windows::System; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; -UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources"); - namespace winrt::Microsoft::Terminal::Settings { hstring GetSelectedItemTag(const winrt::Windows::Foundation::IInspectable& comboBoxAsInspectable) diff --git a/src/cascadia/TerminalSettingsEditor/init.cpp b/src/cascadia/TerminalSettingsEditor/init.cpp index c8c17dfafb..811920253c 100644 --- a/src/cascadia/TerminalSettingsEditor/init.cpp +++ b/src/cascadia/TerminalSettingsEditor/init.cpp @@ -8,7 +8,7 @@ // Note: Generate GUID using TlgGuid.exe tool #pragma warning(suppress : 26477) // One of the macros uses 0/NULL. We don't have control to make it nullptr. TRACELOGGING_DEFINE_PROVIDER( - g_hSettingsEditorProvider, + g_hTerminalSettingsEditorProvider, "Microsoft.Windows.Terminal.Settings.Editor", // {1b16317d-b594-51f8-c552-5d50572b5efc} (0x1b16317d, 0xb594, 0x51f8, 0xc5, 0x52, 0x5d, 0x50, 0x57, 0x2b, 0x5e, 0xfc), @@ -21,13 +21,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstDll); - TraceLoggingRegister(g_hSettingsEditorProvider); - Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hSettingsEditorProvider); + TraceLoggingRegister(g_hTerminalSettingsEditorProvider); + Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hTerminalSettingsEditorProvider); break; case DLL_PROCESS_DETACH: - if (g_hSettingsEditorProvider) + if (g_hTerminalSettingsEditorProvider) { - TraceLoggingUnregister(g_hSettingsEditorProvider); + TraceLoggingUnregister(g_hTerminalSettingsEditorProvider); } break; default: @@ -36,3 +36,5 @@ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/) return TRUE; } + +UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources"); diff --git a/src/cascadia/TerminalSettingsEditor/pch.h b/src/cascadia/TerminalSettingsEditor/pch.h index e0912e25cb..486510f7b2 100644 --- a/src/cascadia/TerminalSettingsEditor/pch.h +++ b/src/cascadia/TerminalSettingsEditor/pch.h @@ -20,10 +20,6 @@ #undef GetCurrentTime #endif -#include -TRACELOGGING_DECLARE_PROVIDER(g_hSettingsEditorProvider); -#include - #include #include #include @@ -61,6 +57,13 @@ TRACELOGGING_DECLARE_PROVIDER(g_hSettingsEditorProvider); #include #include +// Including TraceLogging essentials for the binary +#include +#include +TRACELOGGING_DECLARE_PROVIDER(g_hTerminalSettingsEditorProvider); +#include +#include + #include #include #include diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index 7b2a7f17c9..7d369a9828 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -839,7 +839,11 @@ void SettingsLoader::_parse(const OriginTag origin, const winrt::hstring& source settings.baseLayerProfile = Profile::FromJson(json.profileDefaults); // Remove the `guid` member from the default settings. // That will hyper-explode, so just don't let them do that. + // Also remove name, source, and commandline; those are not valid for the profiles defaults object. settings.baseLayerProfile->ClearGuid(); + settings.baseLayerProfile->ClearName(); + settings.baseLayerProfile->ClearSource(); + settings.baseLayerProfile->ClearCommandline(); settings.baseLayerProfile->Origin(OriginTag::ProfilesDefaults); } diff --git a/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp b/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp index 72c6b80256..c253a17493 100644 --- a/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/DeserializationTests.cpp @@ -1788,16 +1788,18 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { - "name": "PROFILE DEFAULTS" + "tabTitle": "PROFILE DEFAULTS TAB TITLE" }, "list": [ { "guid": "{61c54bbd-1111-5271-96e7-009a87ff44bf}", - "name": "CMD" + "name": "CMD", + "tabTitle": "CMD Tab Title" }, { "guid": "{61c54bbd-2222-5271-96e7-009a87ff44bf}", - "name": "PowerShell" + "name": "PowerShell", + "tabTitle": "PowerShell Tab Title" }, { "guid": "{61c54bbd-3333-5271-96e7-009a87ff44bf}" @@ -1816,25 +1818,30 @@ namespace SettingsModelUnitTests // test profiles VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Name(), copyImpl->AllProfiles().GetAt(0).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).TabTitle(), copyImpl->AllProfiles().GetAt(0).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).Name(), copyImpl->AllProfiles().GetAt(1).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).TabTitle(), copyImpl->AllProfiles().GetAt(1).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(2).Name(), copyImpl->AllProfiles().GetAt(2).Name()); - VERIFY_ARE_EQUAL(settings->ProfileDefaults().Name(), copyImpl->ProfileDefaults().Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(2).TabTitle(), copyImpl->AllProfiles().GetAt(2).TabTitle()); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().TabTitle(), copyImpl->ProfileDefaults().TabTitle()); // Modifying profile.defaults should... - VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasName(), copyImpl->ProfileDefaults().HasName()); - copyImpl->ProfileDefaults().Name(L"changed value"); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasTabTitle(), copyImpl->ProfileDefaults().HasTabTitle()); + copyImpl->ProfileDefaults().TabTitle(L"changed value"); - // ...keep the same name for the first two profiles + // ...keep the same name and tab title for the first two profiles VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Name(), copyImpl->AllProfiles().GetAt(0).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).TabTitle(), copyImpl->AllProfiles().GetAt(0).TabTitle()); VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).Name(), copyImpl->AllProfiles().GetAt(1).Name()); + VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(1).TabTitle(), copyImpl->AllProfiles().GetAt(1).TabTitle()); // ...but change the name for the one that inherited it from profile.defaults - VERIFY_ARE_NOT_EQUAL(settings->AllProfiles().GetAt(2).Name(), copyImpl->AllProfiles().GetAt(2).Name()); + VERIFY_ARE_NOT_EQUAL(settings->AllProfiles().GetAt(2).TabTitle(), copyImpl->AllProfiles().GetAt(2).TabTitle()); // profile.defaults should be different between the two graphs - VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasName(), copyImpl->ProfileDefaults().HasName()); - VERIFY_ARE_NOT_EQUAL(settings->ProfileDefaults().Name(), copyImpl->ProfileDefaults().Name()); + VERIFY_ARE_EQUAL(settings->ProfileDefaults().HasTabTitle(), copyImpl->ProfileDefaults().HasTabTitle()); + VERIFY_ARE_NOT_EQUAL(settings->ProfileDefaults().TabTitle(), copyImpl->ProfileDefaults().TabTitle()); Log::Comment(L"Test empty profiles.defaults"); static constexpr std::string_view emptyPDJson{ R"( diff --git a/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp b/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp index 16165dad8e..d10971906e 100644 --- a/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/MediaResourceTests.cpp @@ -103,8 +103,9 @@ namespace SettingsModelUnitTests TEST_METHOD(RealResolverSpecialKeywords); TEST_METHOD(RealResolverUrlCases); - static constexpr std::wstring_view defaultsCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk) + static constexpr std::wstring_view pingCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk) static constexpr std::wstring_view overrideCommandline{ LR"(C:\Windows\System32\cscript.exe)" }; + static constexpr std::wstring_view cmdCommandline{ LR"(C:\Windows\System32\cmd.exe)" }; // The default commandline for a profile static constexpr std::wstring_view fragmentBasePath1{ LR"(C:\Windows\Media)" }; private: @@ -809,7 +810,6 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", } } })"); @@ -818,7 +818,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"Base") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); // Profile with commandline always has an icon - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } // The invalid resource came from the profile itself, which has its own commandline. @@ -856,7 +856,7 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(overrideCommandline, icon.Resolved()); } - // The invalid resource came from the profile itself, which inherits a commandline from the parent (defaults, ping.exe) + // The invalid resource came from the profile itself, where the commandline is the default value (profile.commandline default value is CMD.exe) void MediaResourceTests::ProfileSpecifiesInvalidIconAndNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -871,8 +871,7 @@ namespace SettingsModelUnitTests "profiles": { "defaults": { "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", - }, + }, "list": [ { "guid": "{af9dec6c-1337-4278-897d-69ca04920b27}", @@ -887,10 +886,10 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileSpecifiesInvalidIconAndNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } - // The invalid resource came from the Defaults profile, which has the Defaults command line (PROFILE COMMANDLINE IGNORED) + // The invalid resource came from the Defaults profile, where the commandline falls back to the default value of CMD.exe (PROFILE COMMANDLINE IGNORED) void MediaResourceTests::ProfileInheritsInvalidIconAndHasCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -904,8 +903,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -921,10 +919,10 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileInheritsInvalidIconAndHasCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } - // The invalid resource came from the Defaults profile, which has the Defaults command line (PROFILE COMMANDLINE MISSING) + // The invalid resource came from the Defaults profile, which has the default command line of CMD.exe (PROFILE COMMANDLINE MISSING) void MediaResourceTests::ProfileInheritsInvalidIconAndHasNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -938,8 +936,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -954,7 +951,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileInheritsInvalidIconAndHasNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } // The invalid resource came from the profile itself, which has its own commandline. @@ -992,7 +989,7 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(overrideCommandline, icon.Resolved()); } - // The invalid resource came from the profile itself, which inherits a commandline from the parent (defaults, ping.exe) + // The invalid resource came from the profile itself, where the commandline falls back to the default value of CMD.exe void MediaResourceTests::ProfileSpecifiesNullIconAndHasNoCommandline() { WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{}; @@ -1006,8 +1003,7 @@ namespace SettingsModelUnitTests settings = createSettings(R"({ "profiles": { "defaults": { - "icon": "DoesNotMatter", - "commandline": "C:\\Windows\\System32\\ping.exe", + "icon": "DoesNotMatter" }, "list": [ { @@ -1023,7 +1019,7 @@ namespace SettingsModelUnitTests auto profile{ settings->GetProfileByName(L"ProfileSpecifiesNullIconAndHasNoCommandline") }; auto icon{ profile.Icon() }; VERIFY_IS_TRUE(icon.Ok()); // Profile with commandline always has an icon - VERIFY_ARE_EQUAL(defaultsCommandline, icon.Resolved()); + VERIFY_ARE_EQUAL(cmdCommandline, icon.Resolved()); } #pragma endregion diff --git a/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp b/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp index 56816de6e7..7697715b8f 100644 --- a/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/ProfileTests.cpp @@ -30,6 +30,7 @@ namespace SettingsModelUnitTests TEST_METHOD(DuplicateProfileTest); TEST_METHOD(TestGenGuidsForProfiles); TEST_METHOD(TestCorrectOldDefaultShellPaths); + TEST_METHOD(ProfileDefaultsProhibitedSettings); }; void ProfileTests::ProfileGeneratesGuid() @@ -470,4 +471,65 @@ namespace SettingsModelUnitTests VERIFY_ARE_EQUAL(L"%SystemRoot%\\System32\\cmd.exe", allProfiles.GetAt(2).Commandline()); VERIFY_ARE_EQUAL(L"cmd.exe", allProfiles.GetAt(3).Commandline()); } + + void ProfileTests::ProfileDefaultsProhibitedSettings() + { + static constexpr std::string_view userProfiles{ R"({ + "profiles": { + "defaults": + { + "guid": "{00000000-0000-0000-0000-000000000000}", + "name": "Default Profile Name", + "source": "Default Profile Source", + "commandline": "foo.exe" + }, + "list": + [ + { + "name" : "PowerShell", + "commandline": "powershell.exe", + "guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}" + }, + { + "name": "Profile with just a name" + }, + { + "guid": "{a0776706-1fa6-4439-b46c-287a65c084d5}", + } + ] + } + })" }; + + const auto settings = winrt::make_self(userProfiles); + + // Profile Defaults should not have a GUID, name, source, or commandline. + const auto profileDefaults = settings->ProfileDefaults(); + VERIFY_IS_FALSE(profileDefaults.HasGuid()); + VERIFY_IS_FALSE(profileDefaults.HasName()); + VERIFY_IS_FALSE(profileDefaults.HasSource()); + VERIFY_IS_FALSE(profileDefaults.HasCommandline()); + + const auto allProfiles = settings->AllProfiles(); + VERIFY_ARE_EQUAL(3u, allProfiles.Size()); + + // Profile settings should be set to the ones set at that layer + VERIFY_ARE_EQUAL(L"PowerShell", allProfiles.GetAt(0).Name()); + VERIFY_ARE_EQUAL(L"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", allProfiles.GetAt(0).Commandline()); + VERIFY_ARE_EQUAL(Utils::GuidFromString(L"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"), static_cast(allProfiles.GetAt(0).Guid())); + VERIFY_IS_FALSE(allProfiles.GetAt(0).HasSource()); + + // Profile should not inherit the values attempted to be set on the Profiles Defaults layer + // This profile only has a name set + VERIFY_ARE_EQUAL(L"Profile with just a name", allProfiles.GetAt(1).Name()); + VERIFY_ARE_NOT_EQUAL(Utils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}"), static_cast(allProfiles.GetAt(1).Guid())); + VERIFY_ARE_NOT_EQUAL(L"Default Profile Source", allProfiles.GetAt(1).Source()); + VERIFY_ARE_NOT_EQUAL(L"foo.exe", allProfiles.GetAt(1).Commandline()); + + // Profile should not inherit the values attempted to be set on the Profiles Defaults layer + // This profile only has a guid set + VERIFY_ARE_NOT_EQUAL(L"Default Profile Name", allProfiles.GetAt(2).Name()); + VERIFY_ARE_NOT_EQUAL(Utils::GuidFromString(L"{00000000-0000-0000-0000-000000000000}"), static_cast(allProfiles.GetAt(2).Guid())); + VERIFY_ARE_NOT_EQUAL(L"Default Profile Source", allProfiles.GetAt(2).Source()); + VERIFY_ARE_NOT_EQUAL(L"foo.exe", allProfiles.GetAt(2).Commandline()); + } }