From a55b89e251c09e4d2b2ba10cdd3e32f6073d27dd Mon Sep 17 00:00:00 2001 From: Jaime Bernardo Date: Tue, 27 Feb 2024 16:24:34 +0000 Subject: [PATCH] [KBM]Send remappings configuration telemetry (#31563) * [KBM]Send remappings configuration telemetry * Add comments for the index comparisons --- .../KeyboardManager.cpp | 18 ++ .../KeyboardManagerEngineLibrary/trace.cpp | 176 ++++++++++++++++++ .../KeyboardManagerEngineLibrary/trace.h | 10 +- 3 files changed, 203 insertions(+), 1 deletion(-) diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManager.cpp b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManager.cpp index bb5b8a13e7..080a12ab05 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManager.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManager.cpp @@ -85,6 +85,24 @@ void KeyboardManager::LoadSettings() // retry once state.LoadSettings(); } + try + { + // Send telemetry about configured key/shortcut to key/shortcut mappings, OS an app specific level. + Trace::SendKeyAndShortcutRemapLoadedConfiguration(state); + } + catch (...) + { + try + { + Logger::error("Failed to send telemetry for the configured remappings."); + // Try not to crash the app sending telemetry. Everything inside a try. + Trace::ErrorSendingKeyAndShortcutRemapLoadedConfiguration(); + } + catch (...) + { + + } + } } LRESULT CALLBACK KeyboardManager::HookProc(int nCode, const WPARAM wParam, const LPARAM lParam) diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp index 5197d0afe2..1cf0c60e1f 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "trace.h" +#include TRACELOGGING_DEFINE_PROVIDER( g_hProvider, @@ -82,6 +83,181 @@ void Trace::ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) } } +// Function to return a human readable string for the shortcut +std::wstring GetShortcutHumanReadableString(Shortcut const & shortcut, LayoutMap& keyboardMap) +{ + std::wstring humanReadableShortcut = L""; + if (shortcut.winKey != ModifierKey::Disabled) + { + humanReadableShortcut += keyboardMap.GetKeyName(shortcut.GetWinKey(ModifierKey::Both)) + L" + "; + } + if (shortcut.ctrlKey != ModifierKey::Disabled) + { + humanReadableShortcut += keyboardMap.GetKeyName(shortcut.GetCtrlKey()) + L" + "; + } + if (shortcut.altKey != ModifierKey::Disabled) + { + humanReadableShortcut += keyboardMap.GetKeyName(shortcut.GetAltKey()) + L" + "; + } + if (shortcut.shiftKey != ModifierKey::Disabled) + { + humanReadableShortcut += keyboardMap.GetKeyName(shortcut.GetShiftKey()) + L" + "; + } + if (shortcut.actionKey != NULL) + { + humanReadableShortcut += keyboardMap.GetKeyName(shortcut.actionKey); + } + return humanReadableShortcut; +} + + +// Log the current remappings of key and shortcuts when keyboard manager engine loads the settings. +void Trace::SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexcept +{ + LayoutMap keyboardMap; + for (auto const& keyRemap : remappings.singleKeyReMap) + { + if (keyRemap.second.index() == 0) // 0 - Remapping to key + { + DWORD keyRemappedTo = std::get(keyRemap.second); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_KeyRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(keyRemap.first, "KeyRemapFrom"), + TraceLoggingInt64(keyRemappedTo, "KeyRemapTo"), + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemap.first).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo") + ); + } + else if (keyRemap.second.index() == 1) // 1 - Remapping to shortcut + { + Shortcut shortcutRemappedTo = std::get(keyRemap.second); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_KeyRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(keyRemap.first, "KeyRemapFrom"), + TraceLoggingInt64(shortcutRemappedTo.actionKey, "KeyRemapTo"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.winKey), "ModifierRemapToWin"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.ctrlKey), "ModifierRemapToCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.altKey), "ModifierRemapToAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemap.first).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo") + ); + } + } + + for (auto const& shortcutRemap : remappings.osLevelShortcutReMap) + { + Shortcut shortcutRemappedFrom = shortcutRemap.first; + if (shortcutRemap.second.targetShortcut.index() == 0) // 0 - Remapping to key + { + DWORD keyRemappedTo = std::get(shortcutRemap.second.targetShortcut); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_ShortcutRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(shortcutRemappedFrom.actionKey, "KeyRemapFrom"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.winKey), "ModifierRemapFromWin"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.ctrlKey), "ModifierRemapFromCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.altKey), "ModifierRemapFromAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.shiftKey), "ModifierRemapFromShift"), + TraceLoggingInt64(keyRemappedTo, "KeyRemapTo"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo")); + } + else if (shortcutRemap.second.targetShortcut.index() == 1) // 1 - Remapping to shortcut + { + Shortcut shortcutRemappedTo = std::get(shortcutRemap.second.targetShortcut); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_ShortcutRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(shortcutRemappedFrom.actionKey, "KeyRemapFrom"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.winKey), "ModifierRemapFromWin"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.ctrlKey), "ModifierRemapFromCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.altKey), "ModifierRemapFromAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.shiftKey), "ModifierRemapFromShift"), + TraceLoggingInt64(shortcutRemappedTo.actionKey, "KeyRemapTo"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.winKey), "ModifierRemapToWin"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.ctrlKey), "ModifierRemapToCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.altKey), "ModifierRemapToAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo") + ); + } + } + + for (auto const& appShortcutRemap : remappings.appSpecificShortcutReMap) + { + std::wstring appName = appShortcutRemap.first; + for (auto const& shortcutRemap : appShortcutRemap.second) + { + Shortcut shortcutRemappedFrom = shortcutRemap.first; + if (shortcutRemap.second.targetShortcut.index() == 0) // 0 - Remapping to key + { + DWORD keyRemappedTo = std::get(shortcutRemap.second.targetShortcut); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_AppSpecificShortcutRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(shortcutRemappedFrom.actionKey, "KeyRemapFrom"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.winKey), "ModifierRemapFromWin"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.ctrlKey), "ModifierRemapFromCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.altKey), "ModifierRemapFromAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.shiftKey), "ModifierRemapFromShift"), + TraceLoggingInt64(keyRemappedTo, "KeyRemapTo"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(keyboardMap.GetKeyName(keyRemappedTo).c_str(), "HumanRemapTo"), + TraceLoggingWideString(appName.c_str(), "TargetApp") + ); + } + else if (shortcutRemap.second.targetShortcut.index() == 1) // 1 - Remapping to shortcut + { + Shortcut shortcutRemappedTo = std::get(shortcutRemap.second.targetShortcut); + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_AppSpecificShortcutRemapConfigurationLoaded", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingInt64(shortcutRemappedFrom.actionKey, "KeyRemapFrom"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.winKey), "ModifierRemapFromWin"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.ctrlKey), "ModifierRemapFromCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.altKey), "ModifierRemapFromAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedFrom.shiftKey), "ModifierRemapFromShift"), + TraceLoggingInt64(shortcutRemappedTo.actionKey, "KeyRemapTo"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.winKey), "ModifierRemapToWin"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.ctrlKey), "ModifierRemapToCtrl"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.altKey), "ModifierRemapToAlt"), + TraceLoggingInt8(static_cast(shortcutRemappedTo.shiftKey), "ModifierRemapToShift"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedFrom, keyboardMap).c_str(), "HumanRemapFrom"), + TraceLoggingWideString(GetShortcutHumanReadableString(shortcutRemappedTo, keyboardMap).c_str(), "HumanRemapTo"), + TraceLoggingWideString(appName.c_str(), "TargetApp") + ); + } + } + } +} + +// Log an error while trying to send remappings telemetry. +void Trace::ErrorSendingKeyAndShortcutRemapLoadedConfiguration() noexcept +{ + TraceLoggingWrite( + g_hProvider, + "KeyboardManager_ErrorSendingKeyAndShortcutRemapLoadedConfiguration", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + + // Log if an error occurs in KBM void Trace::Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept { diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h index 48f0789e26..0281b59c81 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/trace.h @@ -1,5 +1,7 @@ #pragma once +#include "State.h" + class Trace { public: @@ -11,7 +13,13 @@ public: // Log if a shortcut remap has been invoked (not being used currently, due to being garrulous) static void ShortcutRemapInvoked(bool isShortcutToShortcut, bool isAppSpecific) noexcept; - + + // Log the current remappings of key and shortcuts when keyboard manager engine loads the settings. + static void SendKeyAndShortcutRemapLoadedConfiguration(State& remappings) noexcept; + + // Log an error while trying to send remappings telemetry. + static void ErrorSendingKeyAndShortcutRemapLoadedConfiguration() noexcept; + // Log if an error occurs in KBM static void Error(const DWORD errorCode, std::wstring errorMessage, std::wstring methodName) noexcept; };