123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- #if (UNITY_EDITOR || DEVELOPMENT_BUILD) && UNITY_ANALYTICS
- #define ADAPTIVE_PERFORMANCE_ANALYTICS_LOGGING
- #endif
-
- using System;
- using System.Diagnostics;
- using System.Collections.Generic;
- using UnityEngine.Assertions;
-
- namespace UnityEngine.AdaptivePerformance
- {
- internal static class AdaptivePerformanceAnalytics
- {
- #if UNITY_ANALYTICS
- [Serializable]
- internal struct ProviderData
- {
- public bool enabled;
- public string id;
- public string version;
- public string customData;
- }
-
- [Serializable]
- internal struct FeatureData
- {
- public bool enabled;
- public string id;
- public string customData;
- }
-
- [Serializable]
- internal class AdaptivePerformanceAnalyticsEvent
- {
- // Is Adaptive Performance enable at all or only added as package and disabled
- public bool enabled;
- // Is Adaptive Performance active and has at least one provider initialized
- public bool initialized;
- // Name of the currently active provider
- public string activeProvider;
- public ProviderData[] providerData = new ProviderData[0];
- public string ctrlMode;
- public FeatureData[] featureData = new FeatureData[0];
-
- public AdaptivePerformanceAnalyticsEvent()
- {
- UpdateProviderData();
- UpdateFeatureData();
- }
-
- void UpdateProviderData()
- {
- List<Provider.AdaptivePerformanceSubsystemDescriptor> perfDescriptors = Provider.AdaptivePerformanceSubsystemRegistry.GetRegisteredDescriptors();
- if (perfDescriptors == null)
- return;
-
- if (perfDescriptors.Count == providerData.Length)
- return;
-
- Array.Resize<ProviderData>(ref providerData, perfDescriptors.Count);
- for (var i = 0; i < providerData.Length; ++i)
- {
- providerData[i].id = perfDescriptors[i].id;
- providerData[i].version = "0.0";
- providerData[i].enabled = false;
- providerData[i].customData = "";
- }
- }
-
- public void UpdateFeatureData()
- {
- if (s_Features.Count == featureData.Length)
- return;
-
- featureData = s_Features.ToArray();
- }
-
- public void UpdateGeneralEventData()
- {
- var ap = Holder.Instance;
- if (ap == null)
- return;
-
- enabled = ap.Active;
- if (ap.DevicePerformanceControl != null)
- {
- ctrlMode = ap.DevicePerformanceControl.PerformanceControlMode.ToString();
- }
- }
- }
-
- [Serializable]
- internal struct AdaptivePerformanceThermalAnalyticsEvent
- {
- public long numThrottlingEventSinceStartup;
- public long numThrottlingImminentEventSinceStartup;
- public long numNoWarningEventSinceStartup;
- public float currentTempTrend;
- public float currentTempLevel;
- }
-
- enum EventName
- {
- AdaptivePerformance,
- AdaptivePerformanceThermal
- }
-
- const string k_VendorKey = "unity.adaptiveperformance";
- const int k_MaxEventsPerHour = 100;
- const int k_MaxNumberOfElementsInStruct = 10;
-
- static AdaptivePerformanceAnalyticsEvent s_AdaptivePerformanceEvent;
- static AdaptivePerformanceThermalAnalyticsEvent s_AdaptivePerformanceThermalEvent;
- static List<FeatureData> s_Features = new List<FeatureData>();
- static WarningLevel s_LastWarningLevel = WarningLevel.NoWarning;
- static bool s_IsRegistered;
- #endif
-
- // A feature registers itself with a feature name and once a event is sent, the feature list of the event is updated with this new event
- [Conditional("UNITY_ANALYTICS")]
- public static void RegisterFeature(string feature, bool status)
- {
- #if UNITY_ANALYTICS
- Assert.IsFalse(feature.Equals(string.Empty));
-
- s_Features.Add(new FeatureData { id = feature, enabled = status, customData = "" });
- #endif
- }
-
- [Conditional("UNITY_ANALYTICS")]
- public static void SendAdaptiveStartupEvent(Provider.AdaptivePerformanceSubsystem subsystem)
- {
- #if UNITY_ANALYTICS
-
- if (s_AdaptivePerformanceEvent == null)
- s_AdaptivePerformanceEvent = new AdaptivePerformanceAnalyticsEvent();
-
- s_AdaptivePerformanceEvent.initialized = subsystem != null ? subsystem.initialized : false;
- s_AdaptivePerformanceEvent.activeProvider = subsystem != null ? subsystem.SubsystemDescriptor.id : "NoSubsystemLoaded";
-
- s_AdaptivePerformanceEvent.UpdateGeneralEventData();
- var providerData = s_AdaptivePerformanceEvent.providerData;
- if (subsystem != null)
- {
- for (var i = 0; i < providerData.Length; ++i)
- {
- if (providerData[i].id == subsystem.SubsystemDescriptor.id)
- {
- providerData[i].version = subsystem.Version.ToString();
- providerData[i].enabled = subsystem.initialized;
- }
- }
- }
- s_AdaptivePerformanceEvent.UpdateFeatureData();
-
- Send(EventName.AdaptivePerformance, s_AdaptivePerformanceEvent);
- #endif
- }
-
- // If the status of a feature changes it uses this method to update the AdaptivePerformanceEvent and sends the update. Features should not change often as it has performance implications using string comparison.
- [Conditional("UNITY_ANALYTICS")]
- public static void SendAdaptiveFeatureUpdateEvent(string feature, bool status)
- {
- #if UNITY_ANALYTICS
- // When features are initialized adaptivePerformanceEvent is not created yet but SendAdaptiveStartupEvent will send a status update for all events during creation of the event.
- if (s_AdaptivePerformanceEvent == null)
- return;
-
- s_AdaptivePerformanceEvent.UpdateGeneralEventData();
- s_AdaptivePerformanceEvent.UpdateFeatureData();
-
- for (var i = 0; i < s_AdaptivePerformanceEvent.featureData.Length; ++i)
- {
- if (s_AdaptivePerformanceEvent.featureData[i].id.Equals(feature))
- {
- if (s_AdaptivePerformanceEvent.featureData[i].enabled == status)
- return;
-
- s_AdaptivePerformanceEvent.featureData[i].enabled = status;
- }
- }
-
- Send(EventName.AdaptivePerformance, s_AdaptivePerformanceEvent);
- #endif
- }
-
- [Conditional("UNITY_ANALYTICS")]
- public static void SendAdaptivePerformanceThermalEvent(ThermalMetrics thermalMetrics)
- {
- #if UNITY_ANALYTICS
- // Temperature level and trend will call the method more often but we do not want to send events
- if (s_LastWarningLevel == thermalMetrics.WarningLevel)
- return;
-
- switch (thermalMetrics.WarningLevel)
- {
- case WarningLevel.Throttling:
- s_AdaptivePerformanceThermalEvent.numThrottlingEventSinceStartup++; break;
- case WarningLevel.ThrottlingImminent:
- s_AdaptivePerformanceThermalEvent.numThrottlingImminentEventSinceStartup++; break;
- case WarningLevel.NoWarning:
- s_AdaptivePerformanceThermalEvent.numNoWarningEventSinceStartup++; break;
- }
-
- s_AdaptivePerformanceThermalEvent.currentTempLevel = thermalMetrics.TemperatureLevel;
- s_AdaptivePerformanceThermalEvent.currentTempTrend = thermalMetrics.TemperatureTrend;
-
- s_LastWarningLevel = thermalMetrics.WarningLevel;
-
- Send(EventName.AdaptivePerformanceThermal, s_AdaptivePerformanceThermalEvent);
- #endif
- }
-
- #if UNITY_ANALYTICS
- static bool RegisterEvents()
- {
- if (s_IsRegistered)
- return true;
-
- var allEventNames = Enum.GetNames(typeof(EventName));
- for (var i = 0; i < allEventNames.Length; ++i)
- {
- if (!RegisterEvent(allEventNames[i]))
- return false;
- }
-
- s_IsRegistered = true;
- return s_IsRegistered;
- }
-
- static bool RegisterEvent(string eventName)
- {
- var result = Analytics.Analytics.RegisterEvent(eventName, k_MaxEventsPerHour, k_MaxNumberOfElementsInStruct, k_VendorKey);
- switch (result)
- {
- case Analytics.AnalyticsResult.Ok:
- AnalyticsLog.Debug("Registered event: {0}", eventName);
- return true;
- case Analytics.AnalyticsResult.TooManyRequests:
- // this is fine - event registration survives domain reload (native)
- return true;
- default:
- AnalyticsLog.Debug("Failed to register event {0}. Result: {1}", eventName, result);
- return false;
- }
- }
-
- static void Send(EventName eventName, object eventData)
- {
- if (!RegisterEvents())
- {
- AnalyticsLog.Debug("Disabled: event='{0}', time='{1}', payload={2}", eventName, DateTime.Now, JsonUtility.ToJson(eventData));
- return;
- }
-
- try
- {
- var result = Analytics.Analytics.SendEvent(eventName.ToString(), eventData);
- if (result == Analytics.AnalyticsResult.Ok)
- AnalyticsLog.Debug("Event sent: event='{0}', time='{1}', payload={2}", eventName, DateTime.Now, JsonUtility.ToJson(eventData));
- else
- AnalyticsLog.Debug("Failed to send event {0}. Result: {1}", eventName, result);
- }
- catch (Exception ex)
- {
- AnalyticsLog.Debug("Failed to send event {0}. Result: {1}", eventName, ex);
- }
- }
-
- #endif
- internal static class AnalyticsLog
- {
- [Conditional("ADAPTIVE_PERFORMANCE_ANALYTICS_LOGGING")]
- public static void Debug(string format, params object[] args)
- {
- IAdaptivePerformanceSettings settings = AdaptivePerformanceGeneralSettings.Instance?.Manager.ActiveLoaderAs<AdaptivePerformanceLoader>()?.GetSettings();
- if (settings != null && settings.logging)
- UnityEngine.Debug.Log(System.String.Format("[Analytics] " + format, args));
- }
- }
- }
- }
|