Skip to content

Commit

Permalink
Add ADP opt-in ui under DebugMode (#10638)
Browse files Browse the repository at this point in the history
* add ADP UI consent + first step to  remove Instrumentation UI (under debug mode)
  • Loading branch information
pinzart authored May 18, 2020
1 parent 3136122 commit 6320bd8
Show file tree
Hide file tree
Showing 19 changed files with 485 additions and 83 deletions.
195 changes: 195 additions & 0 deletions doc/distrib/ADPAnalyticsConsent.rtf

Large diffs are not rendered by default.

Binary file modified extern/Analytics.NET/Analytics.NET.Core.dll
Binary file not shown.
Binary file modified extern/Analytics.NET/Analytics.NET.Google.dll
Binary file not shown.
Binary file modified extern/Analytics.NET/Analytics.Net.ADP.dll
Binary file not shown.
3 changes: 1 addition & 2 deletions src/DynamoCore/Configuration/DebugModes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ private static void RegisterDebugModes()
{
// Register app wide new debug modes here.
AddDebugMode("Python3DebugMode", "Enable/disable Python3 Engine.");
AddDebugMode("ADPAnalyticsTracker", "Enable/disable ADP analytics tracking. " +
"Consenting for Google analytics will opt-in to ADP as well. This debugMode should be enabled/disabled at startup.");
AddDebugMode("ADPAnalyticsTracker", "Enable/disable ADP analytics tracking.");
}

private static void LoadDebugModesStatusFromConfig(string configPath)
Expand Down
5 changes: 5 additions & 0 deletions src/DynamoCore/Configuration/IPreferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ public interface IPreferences
/// </summary>
bool IsAnalyticsReportingApproved { get; set; }

/// <summary>
/// Indicates whether ADP analytics reporting is approved or not.
/// </summary>
bool IsADPAnalyticsReportingApproved { get; set; }

/// <summary>
/// Indicates first run
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/DynamoCore/Configuration/PreferenceSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ public class PreferenceSettings : NotificationObject, IPreferences, IRenderPreci
/// Indicates whether analytics reporting is approved or not.
/// </summary>
public bool IsAnalyticsReportingApproved { get; set; }

/// <summary>
/// Indicates whether ADP analytics reporting is approved or not.
/// </summary>
[XmlIgnore]
public bool IsADPAnalyticsReportingApproved {
get { return Logging.AnalyticsService.IsADPOptedIn; }
set { Logging.AnalyticsService.IsADPOptedIn = value; }
}
#endregion

#region UI & Graphics settings
Expand Down
1 change: 1 addition & 0 deletions src/DynamoCore/DynamoCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ limitations under the License.
<Copy SourceFiles="$(SolutionDir)..\doc\distrib\TermsOfUse.rtf" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="$(SolutionDir)..\doc\distrib\GoogleAnalyticsConsent.rtf" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="$(SolutionDir)..\doc\distrib\InstrumentationConsent.rtf" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="$(SolutionDir)..\doc\distrib\ADPAnalyticsConsent.rtf" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="@(ExternProtoGeometry)" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="@(ExternProtoGeometryXml)" DestinationFolder="$(OutputPath)\$(UICulture)" />
<Copy SourceFiles="@(ExternProtoGeometryUICulture)" DestinationFolder="$(OutputPath)\$(UICulture)" />
Expand Down
19 changes: 19 additions & 0 deletions src/DynamoCore/Logging/AnalyticsService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Dynamo.Graph.Workspaces;
using Dynamo.Models;
using Analytics.NET.ADP;
using Autodesk.Analytics.Core;

namespace Dynamo.Logging
{
Expand All @@ -8,6 +10,8 @@ namespace Dynamo.Logging
/// </summary>
class AnalyticsService
{
private static IAnalyticsUI adpAnalyticsUI = new ADPAnalyticsUI();

/// <summary>
/// Starts the client when DynamoModel is created. This method initializes
/// the Analytics service and application life cycle start is tracked.
Expand All @@ -28,6 +32,21 @@ static void OnWorkspaceAdded(WorkspaceModel obj)
Analytics.TrackScreenView("Workspace");
}

/// <summary>
/// Indicates whether the user has opted-in to ADP analytics.
/// </summary>
internal static bool IsADPOptedIn
{
get
{
return adpAnalyticsUI.IsOptedIn();
}
set
{
adpAnalyticsUI.SetOptedIn(value);
}
}

/// <summary>
/// Shuts down the client. Application life cycle end is tracked.
/// </summary>
Expand Down
128 changes: 87 additions & 41 deletions src/DynamoCore/Logging/DynamoAnalyticsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,13 @@
using Dynamo.Models;
using Microsoft.Win32;


namespace Dynamo.Logging
{
class DynamoAnalyticsSession : IAnalyticsSession
{
private Heartbeat heartbeat;
private UsageLog logger;

#if DEBUG
private const string ANALYTICS_PROPERTY = "UA-78361914-2";
#else
private const string ANALYTICS_PROPERTY = "UA-52186525-1";
#endif

public DynamoAnalyticsSession()
{
UserId = GetUserID();
Expand All @@ -30,19 +23,6 @@ public DynamoAnalyticsSession()

public void Start(DynamoModel model)
{
//Whether enabled or not, we still record the startup.
var service = Service.Instance;

//Some clients such as Revit may allow start/close Dynamo multiple times
//in the same session so register only if the factory is not registered.
if(service.GetTrackerFactory(GATrackerFactory.Name) == null)
service.Register(new GATrackerFactory(ANALYTICS_PROPERTY));

if (Configuration.DebugModes.IsEnabled("ADPAnalyticsTracker") && service.GetTrackerFactory(ADPTrackerFactory.Name) == null)
{
service.Register(new ADPTrackerFactory());
}

StabilityCookie.Startup();

heartbeat = Heartbeat.GetInstance(model);
Expand All @@ -57,21 +37,6 @@ public void Dispose()
StabilityCookie.WriteCrashingShutdown();
else
StabilityCookie.WriteCleanShutdown();

// If the Analytics Client was initialized, shut it down.
// Otherwise skip this step because it would cause an exception.
if (Service.IsInitialized)
{
Service.ShutDown();
// Unregister the GATrackerFactory only after shutdown is recorded.
// Unregister is required, so that the host app can re-start Analytics service.
Service.Instance.Unregister(GATrackerFactory.Name);

if (Configuration.DebugModes.IsEnabled("ADPAnalyticsTracker"))
{
Service.Instance.Unregister(ADPTrackerFactory.Name);
}
}

if (null != heartbeat)
Heartbeat.DestroyInstance();
Expand Down Expand Up @@ -132,6 +97,12 @@ class Dummy : IDisposable
public void Dispose() { }
}

#if DEBUG
private const string ANALYTICS_PROPERTY = "UA-78361914-2";
#else
private const string ANALYTICS_PROPERTY = "UA-52186525-1";
#endif

private IPreferences preferences = null;

public static IDisposable Disposable { get { return new Dummy(); } }
Expand All @@ -141,18 +112,41 @@ public void Dispose() { }
public virtual IAnalyticsSession Session { get; private set; }

/// <summary>
/// Return if Analytics Client is allowed to send analytics info
/// Return if Analytics Client is allowed to send any analytics information (Google, ADP etc.)
/// </summary>
public bool ReportingAnalytics
{
get
{
return preferences != null
return Service.IsInitialized && (ReportingGoogleAnalytics || ReportingADPAnalytics);
}
}

/// <summary>
/// Return if Google Analytics Client is allowed to send analytics info
/// </summary>
private bool ReportingGoogleAnalytics
{
get
{
return preferences != null
&& Service.IsInitialized
&& preferences.IsAnalyticsReportingApproved;
}
}

/// <summary>
/// Return if ADP Analytics Client is allowed to send analytics info
/// </summary>
private bool ReportingADPAnalytics
{
get {
if (!Configuration.DebugModes.IsEnabled("ADPAnalyticsTracker")) { return false; }
return Service.IsInitialized && AnalyticsService.IsADPOptedIn;
}
set { AnalyticsService.IsADPOptedIn = value; }
}

/// <summary>
/// Return if Analytics Client is allowed to send instrumentation info
/// </summary>
Expand Down Expand Up @@ -191,18 +185,61 @@ public DynamoAnalyticsClient(DynamoModel dynamoModel)
product = new ProductInfo() { Id = "DYN", Name = "Dynamo", VersionString = appversion, AppVersion = appversion, BuildId = buildId, ReleaseId = releaseId };
}

private void RegisterGATracker(Service service)
{
//Some clients such as Revit may allow start/close Dynamo multiple times
//in the same session so register only if the factory is not registered.
if (service.GetTrackerFactory(GATrackerFactory.Name) == null)
service.Register(new GATrackerFactory(ANALYTICS_PROPERTY));

Service.Instance.AddTrackerFactoryFilter(GATrackerFactory.Name, () => ReportingGoogleAnalytics);
}

private void RegisterADPTracker(Service service)
{
//Some clients such as Revit may allow start/close Dynamo multiple times
//in the same session so register only if the factory is not registered.
if (service.GetTrackerFactory(ADPTrackerFactory.Name) == null)
service.Register(new ADPTrackerFactory());

Service.Instance.AddTrackerFactoryFilter(ADPTrackerFactory.Name, () => ReportingADPAnalytics);
}

/// <summary>
/// Starts the client when DynamoModel is created. This method initializes
/// the Analytics service and application life cycle start is tracked.
/// </summary>
public void Start()
{
if (preferences!= null && preferences.IsAnalyticsReportingApproved)
if (preferences != null &&
(preferences.IsAnalyticsReportingApproved || preferences.IsADPAnalyticsReportingApproved))
{
//Register trackers
var service = Service.Instance;

// Use separate functions to avoid loading the tracker dlls if they are not opted in (as an extra safety measure).
// ADP will be loaded because opt-in/opt-out is handled/serialized exclusively by the ADP module.

// Register Google Tracker only if the user is opted in.
if (preferences.IsAnalyticsReportingApproved)
RegisterGATracker(service);

// Register ADP Tracker only if the user is opted in.
if (preferences.IsADPAnalyticsReportingApproved)
RegisterADPTracker(service);

//If not ReportingAnalytics, then set the idle time as infinite so idle state is not recorded.
Service.StartUp(product, new UserInfo(Session.UserId), preferences.IsAnalyticsReportingApproved ? TimeSpan.FromMinutes(30) : TimeSpan.MaxValue);
Service.StartUp(product, new UserInfo(Session.UserId), TimeSpan.FromMinutes(30));
TrackPreferenceInternal("ReportingAnalytics", "", ReportingAnalytics ? 1 : 0);
TrackPreferenceInternal("ReportingUsage", "", ReportingUsage ? 1 : 0);

if (Configuration.DebugModes.IsEnabled("ADPAnalyticsTracker"))
{
TrackPreferenceInternal("ReportingADPAnalytics", "", ReportingADPAnalytics ? 1 : 0);
}
else
{
TrackPreferenceInternal("ReportingUsage", "", ReportingUsage ? 1 : 0);
}
}
}

Expand All @@ -221,7 +258,9 @@ public void TrackEvent(Actions action, Categories category, string description,

public void TrackPreference(string name, string stringValue, int? metricValue)
{
if (ReportingAnalytics) TrackPreferenceInternal(name, stringValue, metricValue);
if (!ReportingAnalytics) return;

TrackPreferenceInternal(name, stringValue, metricValue);
}

private void TrackPreferenceInternal(string name, string stringValue, int? metricValue)
Expand Down Expand Up @@ -253,6 +292,8 @@ public void TrackScreenView(string viewName)

public void TrackException(Exception ex, bool isFatal)
{
if (!ReportingAnalytics) return;

//Continue recording exception in all scenarios.
Service.TrackException(ex, isFatal);
}
Expand Down Expand Up @@ -334,6 +375,11 @@ public void LogPiiInfo(string tag, string data)

public void Dispose()
{
// If the Analytics Client was initialized, shut it down.
// Otherwise skip this step because it would cause an exception.
if (Service.IsInitialized)
Service.ShutDown();

if (Session != null)
{
Session.Dispose();
Expand Down
24 changes: 22 additions & 2 deletions src/DynamoCore/Models/DynamoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -594,8 +595,27 @@ protected DynamoModel(IStartConfiguration config)
PreferenceSettings = settings;
PreferenceSettings.PropertyChanged += PreferenceSettings_PropertyChanged;
}
// If user does not agree to GA terms, do not try to launch the client at all
if (PreferenceSettings.IsAnalyticsReportingApproved)

bool areAnalyticsDisabledFromConfig = false;
try
{
// Dynamo, behind a proxy server, has been known to have issues loading the Analytics binaries.
// Using the "DisableAnalytics" configuration setting, a user can skip loading analytics binaries altoghether.
var assemblyConfig = ConfigurationManager.OpenExeConfiguration(GetType().Assembly.Location);
if (assemblyConfig != null)
{
var disableAnalyticsValue = assemblyConfig.AppSettings.Settings["DisableAnalytics"];
bool.TryParse(disableAnalyticsValue.Value, out areAnalyticsDisabledFromConfig);
}
} catch(Exception)
{}

if (areAnalyticsDisabledFromConfig)
{
// If user skipped analytics from assembly configuration, do not try to launch the client at all
// Skip call to instrumentation logger initialization.
}
else
{
InitializeInstrumentationLogger();
}
Expand Down
11 changes: 10 additions & 1 deletion src/DynamoCoreWpf/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion src/DynamoCoreWpf/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,14 @@
<value>Compact</value>
</data>
<data name="ConsentFormGoogleAnalyticsCheckBoxContent" xml:space="preserve">
<value>Yes, I would like to contribute to this program (Google Analytics).</value>
<value>I agree to contribute to the Google Analytics program.</value>
</data>
<data name="ConsentFormInstrumentationCheckBoxContent" xml:space="preserve">
<value>I give my consent for Autodesk to collect information, using a tool called Instrumentation, on how I use {0}</value>
</data>
<data name="ConsentFormADPAnalyticsCheckBoxContent" xml:space="preserve">
<value>I agree to data collection in desktop products for Autodesk analytics programs.</value>
</data>
<data name="ContextAddGroupFromSelection" xml:space="preserve">
<value>Add To Group</value>
<comment>Context menu item</comment>
Expand Down
5 changes: 4 additions & 1 deletion src/DynamoCoreWpf/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1730,11 +1730,14 @@ Do you want to install the latest Dynamo update?</value>
<value>Autodesk A360</value>
</data>
<data name="ConsentFormGoogleAnalyticsCheckBoxContent" xml:space="preserve">
<value>Yes, I would like to contribute to this program (Google Analytics).</value>
<value>I agree to contribute to the Google Analytics program.</value>
</data>
<data name="ConsentFormInstrumentationCheckBoxContent" xml:space="preserve">
<value>I give my consent for Autodesk to collect information, using a tool called Instrumentation, on how I use {0}</value>
</data>
<data name="ConsentFormADPAnalyticsCheckBoxContent" xml:space="preserve">
<value>I agree to data collection in desktop products for Autodesk analytics programs.</value>
</data>
<data name="GroupContextMenuDeleteGroup" xml:space="preserve">
<value>Delete Group</value>
</data>
Expand Down
Loading

0 comments on commit 6320bd8

Please sign in to comment.