From 35d1fbf505d648e72199dd876ad1662468af3622 Mon Sep 17 00:00:00 2001 From: udit3333 Date: Tue, 18 Feb 2020 18:48:26 -0800 Subject: [PATCH] Add telemetry for Svg preview handler (#1314) * Added telemetry events for Svg Preview Handler * Added unit test in case preview handler throws * Updated the Error event name * Remove the not required return statement --- .../SvgPreviewHandler/Resource.Designer.cs | 9 +++ .../SvgPreviewHandler/Resource.resx | 3 + .../SvgPreviewHandler/SvgPreviewControl.cs | 50 ++++++++----- .../SvgPreviewHandler.csproj | 1 + .../SvgPreviewHandler/SvgTelemetry.cs | 70 +++++++++++++++++++ .../SvgPreviewControlTests.cs | 25 +++++++ 6 files changed, 140 insertions(+), 18 deletions(-) create mode 100644 src/modules/previewpane/SvgPreviewHandler/SvgTelemetry.cs diff --git a/src/modules/previewpane/SvgPreviewHandler/Resource.Designer.cs b/src/modules/previewpane/SvgPreviewHandler/Resource.Designer.cs index 300036aa4c1..5ab162c030d 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Resource.Designer.cs +++ b/src/modules/previewpane/SvgPreviewHandler/Resource.Designer.cs @@ -68,5 +68,14 @@ internal static string BlockedElementInfoText { return ResourceManager.GetString("BlockedElementInfoText", resourceCulture); } } + + /// + /// Looks up a localized string similar to The Svg could not be preview due to an internal error in Svg Preview Handler.. + /// + internal static string SvgNotPreviewedError { + get { + return ResourceManager.GetString("SvgNotPreviewedError", resourceCulture); + } + } } } diff --git a/src/modules/previewpane/SvgPreviewHandler/Resource.resx b/src/modules/previewpane/SvgPreviewHandler/Resource.resx index 201ff83be4a..e8d5827f1ba 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Resource.resx +++ b/src/modules/previewpane/SvgPreviewHandler/Resource.resx @@ -120,4 +120,7 @@ Some elements have been blocked to help prevent the sender from identifying your computer. Open this item to view all elements. + + The Svg could not be preview due to an internal error in Svg Preview Handler. + \ No newline at end of file diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs index 74c691492b8..58b8f53413c 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices.ComTypes; +using System.Runtime.Versioning; using System.Windows.Forms; using System.Xml; using System.Xml.Linq; @@ -33,9 +34,9 @@ public class SvgPreviewControl : FormHandlerControl private RichTextBox textBox; /// - /// Represent if any blocked element is found in the Svg. + /// Represent if an text box info bar is added for showing message. /// - private bool foundFilteredElements = false; + private bool infoBarAdded = false; /// /// Start the preview on the Control. @@ -45,25 +46,37 @@ public override void DoPreview(T dataSource) { this.InvokeOnControlThread(() => { - this.foundFilteredElements = false; - string svgData = null; - using (var stream = new StreamWrapper(dataSource as IStream)) + try { - using (var reader = new StreamReader(stream)) + this.infoBarAdded = false; + string svgData = null; + using (var stream = new StreamWrapper(dataSource as IStream)) { - svgData = reader.ReadToEnd(); + using (var reader = new StreamReader(stream)) + { + svgData = reader.ReadToEnd(); + } + } + + svgData = string.IsNullOrWhiteSpace(svgData) ? svgData : SvgPreviewHandlerHelper.RemoveElements(svgData, out this.infoBarAdded); + if (this.infoBarAdded) + { + this.AddTextBoxControl(Resource.BlockedElementInfoText); } - } - svgData = string.IsNullOrWhiteSpace(svgData) ? svgData : SvgPreviewHandlerHelper.RemoveElements(svgData, out this.foundFilteredElements); - if (this.foundFilteredElements) + this.AddBrowserControl(svgData); + this.Resize += this.FormResized; + base.DoPreview(dataSource); + SvgTelemetry.Log.SvgFilePreviewed(); + } + catch (Exception ex) { - this.AddTextBoxControl(); + SvgTelemetry.Log.SvgFilePreviewError(ex.Message); + this.Controls.Clear(); + this.infoBarAdded = true; + this.AddTextBoxControl(Resource.SvgNotPreviewedError); + base.DoPreview(dataSource); } - - this.AddBrowserControl(svgData); - this.Resize += this.FormResized; - base.DoPreview(dataSource); }); } @@ -85,7 +98,7 @@ private void RTBContentsResized(object sender, ContentsResizedEventArgs e) /// Provides data for the resize event. private void FormResized(object sender, EventArgs e) { - if (this.foundFilteredElements) + if (this.infoBarAdded) { this.textBox.Width = this.Width; } @@ -109,10 +122,11 @@ private void AddBrowserControl(string svgData) /// /// Adds a Text Box in Controls for showing information about blocked elements. /// - private void AddTextBoxControl() + /// Message to be displayed in textbox. + private void AddTextBoxControl(string message) { this.textBox = new RichTextBox(); - this.textBox.Text = Resource.BlockedElementInfoText; + this.textBox.Text = message; this.textBox.BackColor = Color.LightYellow; this.textBox.Multiline = true; this.textBox.Dock = DockStyle.Top; diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj index 7456a52b367..1b43ac7d3bb 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj @@ -67,6 +67,7 @@ + diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgTelemetry.cs b/src/modules/previewpane/SvgPreviewHandler/SvgTelemetry.cs new file mode 100644 index 00000000000..044077babd1 --- /dev/null +++ b/src/modules/previewpane/SvgPreviewHandler/SvgTelemetry.cs @@ -0,0 +1,70 @@ +// 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.Tracing; +using PreviewHandlerCommon.Telemetry; + +namespace SvgPreviewHandler +{ + /// + /// Telemetry helper class for Svg renderer. + /// + public class SvgTelemetry : TelemetryBase + { + /// + /// Name for ETW event. + /// + private const string EventSourceName = "Microsoft.PowerToys"; + + /// + /// ETW event name when Svg is previewed. + /// + private const string SvgFilePreviewedEventName = "PowerPreview_SVGRenderer_Previewed"; + + /// + /// ETW event name when error is thrown during Svg preview. + /// + private const string SvgFilePreviewErrorEventName = "PowerPreview_SVGRenderer_Error"; + + /// + /// Initializes a new instance of the class. + /// + public SvgTelemetry() + : base(EventSourceName) + { + } + + /// + /// Gets an instance of the class. + /// + public static SvgTelemetry Log { get; } = new SvgTelemetry(); + + /// + /// Publishes ETW event when svg is previewed successfully. + /// + public void SvgFilePreviewed() + { + this.Write(SvgFilePreviewedEventName, new EventSourceOptions() + { + Keywords = ProjectKeywordMeasure, + Tags = ProjectTelemetryTagProductAndServicePerformance, + }); + } + + /// + /// Publishes ETW event when svg could not be previewed. + /// + public void SvgFilePreviewError(string message) + { + this.Write( + SvgFilePreviewErrorEventName, + new EventSourceOptions() + { + Keywords = ProjectKeywordMeasure, + Tags = ProjectTelemetryTagProductAndServicePerformance, + }, + new { Message = message, }); + } + } +} diff --git a/src/modules/previewpane/UnitTests-SvgPreviewHandler/SvgPreviewControlTests.cs b/src/modules/previewpane/UnitTests-SvgPreviewHandler/SvgPreviewControlTests.cs index c5ec5a838cb..3699515e70b 100644 --- a/src/modules/previewpane/UnitTests-SvgPreviewHandler/SvgPreviewControlTests.cs +++ b/src/modules/previewpane/UnitTests-SvgPreviewHandler/SvgPreviewControlTests.cs @@ -162,6 +162,31 @@ public void SvgPreviewControl_RichTextBoxWidthShouldAdjust_IfParentControlWidthC Assert.AreEqual(finalParentWidth, textBox.Width); } + [TestMethod] + public void SvgPreviewControl_ShouldAddValidTextBox_IfSvgPreviewThrows() + { + // Arrange + var svgPreviewControl = new SvgPreviewControl(); + var mockStream = new Mock(); + mockStream + .Setup(x => x.Read(It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(new Exception()); + + // Act + svgPreviewControl.DoPreview(mockStream.Object); + var textBox = svgPreviewControl.Controls[0] as RichTextBox; + + // Assert + Assert.IsFalse(string.IsNullOrWhiteSpace(textBox.Text)); + Assert.AreEqual(svgPreviewControl.Controls.Count, 1); + Assert.AreEqual(textBox.Dock, DockStyle.Top); + Assert.AreEqual(textBox.BackColor, Color.LightYellow); + Assert.IsTrue(textBox.Multiline); + Assert.IsTrue(textBox.ReadOnly); + Assert.AreEqual(textBox.ScrollBars, RichTextBoxScrollBars.None); + Assert.AreEqual(textBox.BorderStyle, BorderStyle.None); + } + private IStream GetMockStream(string streamData) { var mockStream = new Mock();