Adding telemetry events for Light Switch

This commit is contained in:
Jaylyn Barbee
2025-12-12 10:21:47 -05:00
parent f822826cf1
commit c077cc46f1
9 changed files with 245 additions and 0 deletions

View File

@@ -681,6 +681,30 @@ _If you want to find diagnostic data events in the source code, these two links
</tr>
</table>
### Light Switch
<table style="width:100%">
<tr>
<th>Event Name</th>
<th>Description</th>
</tr>
<tr>
<td>Microsoft.PowerToys.LightSwitch_EnableLightSwitch</td>
<td>Triggered when Light Switch is enabled or disabled.</td>
</tr>
<tr>
<td>Microsoft.PowerToys.LightSwitch_ShortcutInvoked</td>
<td>Occurs when the shortcut for Light Switch is invoked.</td>
</tr>
<tr>
<td>Microsoft.PowerToys.LightSwitch_ScheduleModeToggled</td>
<td>Occurs when a new schedule mode is selected for Light Switch.</td>
</tr>
<tr>
<td>Microsoft.PowerToys.LightSwitch_ThemeTargetChanged</td>
<td>Occurs when a the options for targeting the system or apps is updated.</td>
</tr>
</table>
### Mouse Highlighter
<table style="width:100%">
<tr>

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
/// <summary>
/// Tracks which actions the users are using to apply theme changes
/// Purpose: Identify which parts of the OS it is important for users to control.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class LightSwitchActionsUpdated : EventBase, IEvent
{
/// <summary>
/// Gets or sets whether the user is changing their app theme.
/// </summary>
public bool ChangeApps { get; set; }
/// <summary>
/// Gets or sets whether the user is changing their system theme.
/// </summary>
public bool ChangeSystem { get; set; }
public LightSwitchActionsUpdated(bool, ChangeApps, bool ChangeSystem)
{
EventName = "LightSwitch_ModeUpdated";
ChangeApps = changeApps;
ChangeSystem = changeSystem
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}

30
LightSwitchModeUpdated.cs Normal file
View File

@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
/// <summary>
/// Tracks which mode users are using to schedule theme changes
/// Purpose: Identify which modes users are using the most.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class LightSwitchModeUpdated : EventBase, IEvent
{
/// <summary>
/// Gets or sets the mode the user is using.
/// </summary>
public string Mode { get; set; }
public LightSwitchModeUpdated(bool mode)
{
EventName = "LightSwitch_ModeUpdated";
Mode = mode;
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
/// <summary>
/// Tracks if users are using the schedule to control their themeing.
/// Purpose: Identify how users are using Light Switch to control their theme.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class LightSwitchScheduleToggled : EventBase, IEvent
{
/// <summary>
/// Gets or sets whether the schedule is on or off.
/// </summary>
public bool OnOrOff { get; set; }
public LightSwitchScheduleToggled(bool onOrOff)
{
EventName = "LightSwitch_ScheduleToggled";
OnOrOff = onOrOff;
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
/// <summary>
/// Tracks shortcut usage and which mode are we toggling from and to.
/// Purpose: Identify how users are using the shortcut in their workflows.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class LightSwitchShortcutInvoked : EventBase, IEvent
{
/// <summary>
/// Gets or sets the target the mode the user is switching to
/// </summary>
public string TargetMode { get; set; }
/// <summary>
/// Gets or sets the time of day the user is using this command
/// </summary>
public int MinuteOfDay { get; set; }
public LightSwitchShortcutInvoked(string targetMode, int minuteOfDay)
{
EventName = "LightSwitch_ShortcutInvoked";
TargetMode = targetMode;
MinuteOfDay = minuteOfDay;
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}

View File

@@ -8,6 +8,7 @@
#include <codecvt>
#include <common/utils/logger_helper.h>
#include "ThemeHelper.h"
#include <LightSwitch/LightSwitchService/trace.h>
extern "C" IMAGE_DOS_HEADER __ImageBase;
@@ -394,6 +395,7 @@ public:
{
m_enabled = true;
Logger::info(L"Enabling Light Switch module...");
Trace::LightSwitch::Enable(true);
unsigned long powertoys_pid = GetCurrentProcessId();
std::wstring args = L"--pid " + std::to_wstring(powertoys_pid);
@@ -469,6 +471,7 @@ public:
CloseHandle(m_process);
m_process = nullptr;
}
Trace::LightSwitch::Enable(false);
}
// Returns if the powertoys is enabled
@@ -524,6 +527,8 @@ public:
if (m_enabled)
{
Logger::trace(L"Light Switch hotkey pressed");
Trace::LightSwitch::ShortcutInvoked();
if (!is_process_running())
{
enable();
@@ -541,6 +546,7 @@ public:
SetAppsTheme(!GetCurrentAppsTheme());
}
if (!m_manual_override_event_handle)
{
m_manual_override_event_handle = OpenEventW(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"POWERTOYS_LIGHTSWITCH_MANUAL_OVERRIDE");

View File

@@ -5,6 +5,7 @@
#include <filesystem>
#include <fstream>
#include <logger.h>
#include <LightSwitchService/trace.h>
using namespace std;
@@ -151,6 +152,7 @@ void LightSwitchSettings::LoadSettings()
if (m_settings.scheduleMode != newMode)
{
m_settings.scheduleMode = newMode;
Trace::LightSwitch::ScheduleModeToggled(val);
NotifyObservers(SettingId::ScheduleMode);
}
}
@@ -220,6 +222,8 @@ void LightSwitchSettings::LoadSettings()
}
}
bool themeTargetChanged = false;
// ChangeSystem
if (const auto jsonVal = values.get_bool_value(L"changeSystem"))
{
@@ -227,6 +231,7 @@ void LightSwitchSettings::LoadSettings()
if (m_settings.changeSystem != val)
{
m_settings.changeSystem = val;
themeTargetChanged = true;
NotifyObservers(SettingId::ChangeSystem);
}
}
@@ -238,9 +243,16 @@ void LightSwitchSettings::LoadSettings()
if (m_settings.changeApps != val)
{
m_settings.changeApps = val;
themeTargetChanged = true;
NotifyObservers(SettingId::ChangeApps);
}
}
// For ChangeSystem/ChangeApps changes, log telemetry
if (themeTargetChanged)
{
Trace::LightSwitch::ThemeTargetChanged(m_settings.changeApps, m_settings.changeSystem);
}
}
catch (...)
{

View File

@@ -0,0 +1,54 @@
#include "pch.h"
#include "trace.h"
#include <common/Telemetry/TraceBase.h>
// Telemetry strings should not be localized.
#define LoggingProviderKey "Microsoft.PowerToys"
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
LoggingProviderKey,
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::LightSwitch::Enable(bool enabled) noexcept
{
TraceLoggingWriteWrapper(
g_hProvider,
"LightSwitch_EnableLightSwitch",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(enabled, "Enabled"));
}
void Trace::LightSwitch::ShortcutInvoked() noexcept
{
TraceLoggingWriteWrapper(
g_hProvider,
"LightSwitch_ShortcutInvoked",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::LightSwitch::ScheduleModeToggled(const std::wstring& newMode) noexcept
{
TraceLoggingWriteWrapper(
g_hProvider,
"LightSwitch_ScheduleModeToggled",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingWideString(newMode.c_str(), "NewMode"));
}
void Trace::LightSwitch::ThemeTargetChanged(bool changeApps, bool changeSystem) noexcept
{
TraceLoggingWriteWrapper(
g_hProvider,
"LightSwitch_ThemeTargetChanged",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(changeApps, "ChangeApps"),
TraceLoggingBoolean(changeSystem, "ChangeSystem"));
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include <common/Telemetry/TraceBase.h>
#include <modules/interface/powertoy_module_interface.h>
class Trace
{
public:
class LightSwitch : public telemetry::TraceBase
{
public:
static void Enable(bool enabled) noexcept;
static void ShortcutInvoked() noexcept;
static void ScheduleModeToggled(const std::wstring& newMode) noexcept;
static void ThemeTargetChanged(bool changeApps, bool changeSystem) noexcept;
};
};