Skip to content

Inking: add usage, reliability and performance telemetry - #11880

Closed
Nitin Chaudhary (Nitin-100) wants to merge 1 commit into
microsoft:mainfrom
Nitin-100:user/nitinc/inking-telemetry
Closed

Nitin Chaudhary (Nitin-100) wants to merge 1 commit into
microsoft:mainfrom
Nitin-100:user/nitinc/inking-telemetry

Conversation

@Nitin-100

Copy link
Copy Markdown
Contributor

Problem

The WinUI 3 inking stack ships with no telemetry. We cannot answer basic questions about it: does an InkCanvas initialise successfully, how long does that take, how is it configured, and — the one that matters most right now — which composition engine are real users actually on?

There is no prior art to mirror. UWP and WinUI 2 shipped no ink telemetry; the UWP InkPresenter/InkToolbar live in the OS repo and are not instrumented. These signals are defined fresh, following the shape used by the Charts telemetry PR (usage / reliability / performance).

Five events

Question Event Records
Did the canvas initialise? InkCanvas_Initialization start, then success or failure with the stage reached and the HRESULT
How long did it take? InkCanvas_InitializationLatency elapsed ms for a successful attach
How is the canvas configured? InkCanvas_UsageSummary compositor engine, input device mask, high-contrast adjustment
Did the app take over drying? InkPresenter_CustomDryingActivation activation result, emitted from ActivateCustomDrying itself
How is the toolbar configured? InkToolbar_UsageSummary initial controls, orientation, active tool, attached target

Why CompositorEngine is on three of the five

InkCanvas forks on the composition engine: a system-backed process splices the ink visual under a lifted MUC visual, while a lifted process bridges it through ContentExternalOutputLink. The two paths differ materially in rendering and input behaviour, and the system path depends on OS support that is not yet broadly available.

We currently have no way to tell what share of users land on each path. That is the primary motivation for this change.

Design notes for review

Custom drying is an event, not a field. It is reported from ActivateCustomDrying rather than sampled onto the usage summary. ActivateCustomDrying must be called before the first stroke and its ordering against Loaded is not guaranteed, so a snapshot taken at attach time would under-report adoption. Reporting at the call site also captures the E_ILLEGAL_METHOD_CALL failure apps hit when they activate too late — a reliability signal that a state snapshot would have missed entirely.

Failures are captured without changing control flow. OnLoaded can throw from several check_hresult paths, so the attach sequence is bracketed with wil::scope_exit; a throw anywhere in it is still recorded as a failure with the stage reached.

Uses the existing provider. g_hTelemetryProvider with TelemetryPrivacyDataTag and MICROSOFT_KEYWORD_MEASURES, matching how WebView2 and NavigationView instrument, rather than defining a new provider. KEYWORD_INKTOOLBAR was already reserved and unused; KEYWORD_INKCANVAS is newly allocated.

No product API was added for telemetry. InkPresenter.h is untouched.

Privacy

No stroke data, coordinates, pressure, tilt, timestamps of user input, bitmap content or text of any kind. Every field is an enum, a flag or a duration. Instance ids are process-local counters used only to match a start to its outcome; they are not stable across runs and carry no user or device identity.

Performance events use PDT_ProductAndServicePerformance; usage events use PDT_ProductAndServiceUsage.

Docs

  • controls/dev/InkCanvas/docs/Telemetry.md — the signals, the measures they feed, and how to read the results
  • controls/dev/InkCanvas/docs/OpenQuestions.md — decisions needed before production collection

Please review whether each signal is necessary, and whether its boundary and population are right.

How verified — and what is NOT yet verified

Verified: the product builds clean with these changes. InkTelemetry.obj, InkCanvas.obj, InkPresenter.obj, InkToolbar.obj and Microsoft.UI.Xaml.Controls.dll were all produced after the final source edit, with zero errors.

Not yet verified: the events have not been observed firing. Runtime ETW capture is still outstanding. I could not build a host app against this branch locally — MUXControlsTestApp restore fails with 401 Unauthorized pulling Microsoft.NET.ILLink.Tasks from the WinUI-Dependencies feed.

I am calling this out rather than implying coverage I do not have. The design questions above stand on their own; I will attach a decoded capture (provider Microsoft.UI.Xaml.Controls, filtered on KEYWORD_INKCANVAS / KEYWORD_INKTOOLBAR, showing all five events and their fields) once the app can be built, and would not expect this to merge before then.

Adds five events for the inking stack. There was no prior art to mirror: UWP and
WinUI 2 shipped no ink telemetry (the UWP InkPresenter/InkToolbar live in the OS
repo and are not instrumented), so these signals are defined fresh.

  InkCanvas_Initialization             attach start, then success or failure with
                                       the stage reached and the HRESULT
  InkCanvas_InitializationLatency      elapsed time for a successful attach
  InkCanvas_UsageSummary               compositor engine, input device mask,
                                       high-contrast adjustment
  InkPresenter_CustomDryingActivation  activation result, emitted from
                                       ActivateCustomDrying itself
  InkToolbar_UsageSummary              initial controls, orientation, active tool,
                                       attached target

CompositorEngine appears on three of the five. InkCanvas forks between a system
splice and a lifted ContentExternalOutputLink bridge, the two paths behave
differently, and we currently have no way to tell what share of users are on
each. That is the signal this is primarily for.

Custom drying is reported as an event at its call site rather than as a field on
the usage summary: ActivateCustomDrying must be called before the first stroke
and its ordering against Loaded is not guaranteed, so a snapshot taken at attach
time would under-report it. Reporting at the call site also captures the
E_ILLEGAL_METHOD_CALL failure apps hit when they activate too late.

Uses the existing g_hTelemetryProvider rather than a new provider, matching how
WebView2 and NavigationView instrument. KEYWORD_INKTOOLBAR was already reserved
and unused; KEYWORD_INKCANVAS is newly allocated.

No stroke data, coordinates, pressure, tilt or text is collected - every field is
an enum, a flag or a duration. Instance ids are process-local counters used only
to match a start to its outcome.

docs/Telemetry.md states the signals and the measures they feed;
docs/OpenQuestions.md lists the decisions needed before production collection.
@microsoft-github-policy-service microsoft-github-policy-service Bot added the needs-triage Issue needs to be triaged by the area owners label Sep 14, 2026
@Nitin-100

Copy link
Copy Markdown
Contributor Author

Superseded by #11891. Same commit, but raised from a branch on this repo instead of a fork so the ADO WinUI-GitHub-PR (OneBranch) validation can authenticate - fork PRs fail PreBuild Validation with ADO auth token validation failed, which left this one BLOCKED. No code changes.

@Nitin-100
Nitin Chaudhary (Nitin-100) deleted the user/nitinc/inking-telemetry branch September 15, 2026 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-triage Issue needs to be triaged by the area owners

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant