diff --git a/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs b/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs new file mode 100644 index 00000000000..b67680d7672 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs @@ -0,0 +1,136 @@ +using System.Text; +using System.Reflection; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Analytics; +using UnityEngine.Rendering.HighDefinition; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; + +namespace UnityEditor.Rendering.HighDefinition +{ + class HDAnalytics : IPostprocessBuildWithReport + { + const int k_MaxEventsPerHour = 10; + const int k_MaxNumberOfElements = 1000; + const string k_VendorKey = "unity.hdrp"; + const string k_EventName = "uHDRPUsage"; + + public int callbackOrder { get; } + + struct EventData + { + // Naming convention for analytics data + public string[] changed_settings; + + public EventData(Dictionary diff) + { + changed_settings = new string[diff.Count]; + + int i = 0; + foreach (var d in diff) + changed_settings[i++] = $@"{{""{d.Key}"":""{d.Value}""}}"; + } + } + + public void OnPostprocessBuild(BuildReport report) + { + SendEvent(); + } + + public static void SendEvent() + { + if (!EditorAnalytics.enabled) + return; + + var hdrpAsset = HDRenderPipeline.currentAsset; + if (hdrpAsset == null) + return; + + if (EditorAnalytics.RegisterEventWithLimit(k_EventName, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey) != AnalyticsResult.Ok) + return; + + RenderPipelineSettings settings = hdrpAsset.currentPlatformRenderPipelineSettings; + RenderPipelineSettings defaults = RenderPipelineSettings.NewDefault(); + + var data = new EventData(DiffSettings(settings, defaults)); + + EditorAnalytics.SendEventWithLimit(k_EventName, data); + } + + + // Helpers to get changed settings as JSON + static Dictionary DiffSettings(object a, object b) + { + var diff = new Dictionary(); + var fields = a.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); + foreach (var field in fields) + { + var va = field.GetValue(a); + var vb = field.GetValue(b); + + var t = field.FieldType; + if (t == typeof(string)) + continue; + if (t.IsPrimitive || t.IsEnum) + { + if (!va.Equals(vb)) + diff[field.Name] = va.ToString(); + } + else if (t.IsArray) + { + if (DiffArray(va, vb)) + diff[field.Name] = ArrayToJson(va); + } + else + { + if (t == typeof(IntScalableSetting) || t == typeof(FloatScalableSetting)) + { + var values = t.BaseType.GetField("m_Values", BindingFlags.NonPublic | BindingFlags.Instance); + va = values.GetValue(va); + vb = values.GetValue(vb); + if (DiffArray(va, vb)) + diff[field.Name] = ArrayToJson(va); + } + else if (t.IsClass || t.IsValueType) + { + var subdiff = DiffSettings(va, vb); + foreach (var d in subdiff) + { + diff[field.Name + "." + d.Key] = d.Value; + } + } + } + } + + return diff; + } + + static bool DiffArray(object a, object b) + { + var va = (System.Collections.IList)a; + var vb = (System.Collections.IList)b; + + if (va.Count != vb.Count) + return true; + for (int i = 0; i < va.Count; i++) + { + if (!va[i].Equals(vb[i])) + return true; + } + return false; + } + + static string ArrayToJson(object array) + { + var a = (System.Collections.IList)array; + StringBuilder sb = new StringBuilder("["); + for (int i = 0; i < a.Count; i++) + { + sb.Append(a[i].ToString()); + sb.Append(i == a.Count - 1 ? "]" : ","); + } + return sb.ToString(); + } + } +} diff --git a/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs.meta b/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs.meta new file mode 100644 index 00000000000..782e5c11e87 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/HDAnalytics.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1aa69ae4addf47479e3369d9c91d5d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: