Info
Content

[Unity] 1. consentmanager SDK Integration

[Unity] 1. consentmanager SDK Integration

On this document, you'll find general information on how to integrate our SDK to your project. For further details, please refer to our API Reference documentation.

1. Installation

The consentmanager SDK for Android apps implements and provides functionality to inform the user about data protection and ask and collect consent from the user. It enables app-developers to easily integrate the consentmanager service into their app. As main features, we provide:

  • Support both iOS and Android platforms.
  • A bridge between Unity and native platform-specific CMP functionalities.
  • An easy way to initialize, manage user consent, and handle privacy-related data.

In terms of compatibility, we have:

  • Unity 20XX.X.X or later
  • iOS (via DllImport)
  • Android (via JNI)

Steps - High Level

    1. Integration and Configuration:

      • Integrate the SDK into your app.
      • Configure the SDK settings according to your needs.
    2. Creating an Instance:

      • On app startup, create an instance of the CMPConsentTool class. This instance will handle the consent process.
    3. SDK Initialization:
      • Once the instance is ready, the SDK automatically retrieves necessary information from the consentmanager servers to prepare for its operation.
    4. Displaying the Consent Screen:

      • The SDK will automatically display the consent screen if needed when the CMPConsentTool instance is created.
    5. Processing Personal Data:

      • Once consents are collected, info is stored and is available for querying through different properties and methods exposed by our SDK. You'll have information about rejected or accepted consents, vendors, purposes, etc.

    By following these steps, you ensure that your app is compliant with consent requirements and that user consent is properly managed and stored.

Consent Manager Provider SDK Sequence Diagram

To illustrate the steps above, let's check in the diagram below three possible SDK sequence flows. 

1. When creating an instance using the Initialize() function, there are two possible outcomes. The first is when the consentmanger API informs the SDK that the CMP will not open, which triggers the OnCmpNotOpenedCallback. The second outcome is when the consent layer opens, allowing the user to interact with it, and this triggers the OnOpenCallback. Once the user gives consent and the consent is processed, the OnCmpCloseCallback is called.

Please note that the OnErrorCallback is represented by the red dashed arrow lines to provide examples of when errors may occur during the process.

Initialize-Cmp-Sequence-Diagram.png

2. Creating an instance and calling the OpenConsentLayerOnCheck functions will lead to a similar process. The difference is that by decoupling the creation of the instance and the check for the consentmanger API, you gain the ability to add business logic and interact with the libraries API.

3. Creating an instance and calling the OpenConsentLayer function will open the layer without checking the consentmanager, if it's necessary. If there is already given consent, the options and settings will be shown to the user. The process flow will look like this:

openlayer-Cmp-Sequence-Diagram-.png

For further information about our SDK Version Overview & Changelog, please refer to this link.

    Importing the SDK package

    In just two steps you can have all set up.

      • Download the latest release of the plugin.
      • Import the package into your Unity project using Assets > Import Package > Custom Package.

    Config JSON

    In the CmpSdkConfig.json you can set the native SDK Version for iOS and Android which will be used for the build process: 

    Find the compatible native SDK Versions here

    {
      "displayName": "Consentmanager SDK",
      "name": "CmpSdk",
      "androidBasePath": "net.consentmanager.sdk",
      "version": "1.0.0",
      "androidLibraryVersion": "x.xx.x",
      "iosLibraryVersion": "x.xx.x",
      "description": "Unity plugin helps you to use native Consentmanager functionality on Android and iOS."
    }
    

    Build Settings

    To change the build settings go to Window -> CmpSdk 

    pluginwindow-unity.png

    iOS Build Settings

    • Enable iOS Build Script: Toggle this to enable or disable the build script responsible for integrating the iOS SDK into the Unity project.
    • xcFramework Path: Specify the path to the xcFramework directory. This path can be edited directly or browsed to using the accompanying button.
    • Include Version Tag: When enabled, appends the iOS SDK version to the xcFramework path, allowing for version-specific configurations.
    • Resulting Framework Path: Displays the fully resolved path to the xcFramework, including the SDK version if the version tag is included.
    • Enable App Tracking Transparency: Toggle this to enable the App Tracking Transparency feature for iOS, which is necessary for user consent under iOS privacy guidelines.
    • App Tracking Transparency Consent Message: A text field to input the custom message displayed to users when requesting consent for tracking. This message should be clear and concise, explaining why the consent is needed.

    Android Build Settings

    • Enable Android Build Script: Toggle to enable or disable the build script for integrating the Android SDK into the Unity project. 
    • Integrate Custom Layout: When enabled, this allows the use of a custom layout for the consent layer for the fragment UIView.

      If you are willing to use a custom layout with fragments, make sure that your Unity Project adds the appcompat dependency. Add a custom main Template: 
      Assets/Plugins/Android/mainTemplate.gradle
      and add the dependency:
      implementation 'androidx.appcompat:appcompat:1.x.x'

    2. Initializing the SDK

    Follow these steps to start using the plugin.

    Initializing the ConsentTool - Automatically

    Within the app-start (usually the regular override onCreate() function) , you must create an instance of class CMPConsentTool.  The initialize() function will automatically fetch the necessary data from our server and determine if the consent screen needs to be shown or not. If so, the SDK will automatically show the consent screen at this point, collect the data and provide the data to the app. The instance can then be used in order to get consent details from the SDK in order to use it in the app.

    Example of initialization, using the automatic behaviour of the Initialize() method.  

    public string codeId = "<YOUR-CONSENTMANAGER-APP-ID>", // example: b238acdf1a
    public string domain = "<YOUR-CONSENTMANAGER-APP-DOMAIN>", // example: delivery.consentmanager.net
    public string appName = "<YOUR-CONSENTMANAGER-APP-NAME>", // example: testApp
    public string language = "<YOUR-CONSENTMANAGER-APP-LANGUAGE>" // example: DE
    
    CmpManager.Instance.Initialize(domain, codeId, appName, language);                

    For domain use the Server-Domain found in your consentmanager account under Menu > CMPs > Get Codes for Apps. For codeID use the Code-ID found on the same page in your consentmanger account. The appName can be used in order to distinguish different apps in the consentmanager reporting. For the language, you can either use an empty string ("") for auto-detection or a 2-letter language code ("EN", "DE", "FR" and so on).

    Initializing the ConsentTool - Manually

    The SDK offers, for the sake of flexibility, a way to manually display the consent layer, as demonstrated below: 

    bool isConsentRequired = await _cmpManager.CheckConsentIsRequired();
    if (isConsentRequired)
    {
    	_cmpManager.OpenConsentLayer();
    }

    3. Using the SDK

    Check Consent: Check if the user has given consent:

    bool hasConsent = CmpManager.Instance.HasConsent();

    Callbacks: Set callback listeners for various events:

    CmpManager.Instance.AddEventListeners(OnOpen, OnClose, OnNotOpened, OnCmpButtonClicked, OnError);

    Purpose and Vendor Checks: Check for consent related to specific purposes and vendors:

    bool hasPurpose = CmpManager.Instance.HasPurpose(id);
    bool hasVendor = CmpManager.Instance.HasVendor(id);

    Export Data: Export CMP data:

    string cmpString = CmpManager.Instance.ExportCmpString();

    Event Listener

    Callback Event Description Parameters Passed
    OnOpen Triggered when the CMP consent tool is opened. None
    OnClose Triggered when the CMP consent tool is closed. None
    OnNotOpened Triggered if the CMP consent tool fails to open. None
    OnCmpButtonClicked Triggered when a button within the CMP consent tool is clicked. CmpButtonEvent buttonEvent
    OnError Triggered when an error occurs within the CMP consent tool. CmpErrorType errorType, string message
    OnGoogleConsentUpdated Triggered when the Google consent mode status is updated. CmpGoogleConsentModeStatus status
    OnCmpATTrackingStatusChanged (iOS only) Triggered when the App Tracking Transparency status changes. ATTrackingManagerAuthorizationStatus oldStatus, ATTrackingManagerAuthorizationStatus newStatus, double lastUpdated

     

    Custom Layout

    Unity supports different custom layouts: 

            public enum ScreenConfig
            {
                FullScreen,
                HalfScreenBottom,
                HalfScreenTop,
                CenterScreen,
                SmallCenterScreen,
                LargeTopScreen,
                LargeBottomScreen,
            }

    Example usage: 

                _cmpConfig = new CmpConfig(CodeId, Domain, AppName, Language)
                {
                    Debug = true,
                    Timeout = 8000
                };
    
                    _cmpConfig.UIConfig.screenConfig = (CmpUIConfig.ScreenConfig) Enum.Parse(typeof(CmpUIConfig.ScreenConfig), s);  
                    _cmpManager.SetUIConfig(_cmpConfig.UIConfig); 

    Reference documentation : Get started with Google Firebase for Unity

    Integration : Unity Setup

    To use the google consent mode the CMP Unity SDK supports an interface to set the google consent status: 

    // public class CmpSampleScript : MonoBehaviour, IOnCmpGoogleConsentUpdatedCallback { ... 
    // Make sure to implement the Interface IOnCmpGoogleConsentUpdatedCallback
    public void OnGoogleConsentUpdated(CmpGoogleConsentModeStatus status)
    {
    // Convert CmpGoogleConsentModeStatus to Firebase compatible dictionary
    var firebaseConsentDict = new Dictionary<ConsentType, ConsentStatus>();
    
    foreach (var consent in status.ConsentDictionary)
    {
    // Convert GoogleConsentType to Firebase ConsentType
    var firebaseConsentType = ConvertToFirebaseConsentType(consent.Key);
    
    // Convert GoogleConsentStatus to Firebase ConsentStatus
    var firebaseConsentStatus = ConvertToFirebaseConsentStatus(consent.Value);
    
    firebaseConsentDict[firebaseConsentType] = firebaseConsentStatus;
    }
    
    // Apply the consent settings to Firebase Analytics
    FirebaseAnalytics.SetConsent(firebaseConsentDict);
    AppendLog($"Google Consent Mode: {firebaseConsentDict}");
    }
    
    private static ConsentType ConvertToFirebaseConsentType(GoogleConsentType googleConsentType)
    {
    return googleConsentType switch
    {
    GoogleConsentType.AnalyticsStorage => ConsentType.AnalyticsStorage,
    GoogleConsentType.AdStorage => ConsentType.AdStorage,
    GoogleConsentType.AdUserData => ConsentType.AdUserData,
    GoogleConsentType.AdPersonalization => ConsentType.AdPersonalization,
    _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentType: {googleConsentType}")
    };
    }
    
    private static ConsentStatus ConvertToFirebaseConsentStatus(GoogleConsentStatus googleConsentStatus)
    {
    return googleConsentStatus switch
    {
    GoogleConsentStatus.Granted => ConsentStatus.Granted,
    GoogleConsentStatus.Denied => ConsentStatus.Denied,
    _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentStatus: {googleConsentStatus}")
    };
    }

    in this example the OnGoogleConsentUpdate callback is called when the user gives a consent. 

    FirebaseAnalytics.SetConsent(firebaseConsentDict);

    In this line the Consent Status is set to Firebase Analytics. The other two functions are mapping the CMP Consent Status to the Google Consent Types and Status.

    Example Script

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Threading;
      using CmpSdk.Callbacks;
      #if UNITY_IOS
      using CmpSdk.Delegates;
      #endif
      using CmpSdk.Models;
      using Firebase.Analytics;
      using Firebase.Extensions;
      using UnityEngine;
      using FirebaseApp = Firebase.FirebaseApp;
      
      namespace CmpSdk.Samples.Scripts
      {
          // V prefix for Vendor
          public static class Vendors
          {
              public const string GoogleAnalytics = "S26";
              public const string AmazonAD = "793";
              public const string Facebook = "S7";
              public const string S1 = "S1";
          }
      
          // P prefix for Purpose
          public static class Purposes
          {
              public const string P1 = "1";
              public const string Marketing = "C2";
              public const string Technical = "S2";
              public const string Security = "S1";
          }
      
      
          public class CmpSampleScript : MonoBehaviour, IOnOpenCallback, IOnCloseCallback, IOnCmpNotOpenedCallback,
              IOnCmpButtonClickedCallback, IOnErrorCallback, IOnCmpGoogleConsentUpdatedCallback
          {
              readonly List<string> _purposeList = new() { Purposes.P1, Purposes.Marketing, Purposes.Technical, Purposes.Security };
      
              readonly List<string> _vendorList = new() { Vendors.S1, Vendors.GoogleAnalytics, Vendors.AmazonAD, Vendors.Facebook };
      
              // UI elements
              private string _idPurposeOrVendorInputField;
              private string _importStringInputField;
              [SerializeField] private CmpUIManager uiManager;
      
              // CmpManager Instance
              private CmpConfig _cmpConfig;
              private CmpManager _cmpManager;
              private Thread _mainThread;
      
              // Configuration constants
              private const string CodeId = "TOOD Your CMP Code ID";
              private const string Domain = "delivery.consentmanager.net";
              private const string AppName = "UnityExample";
              private const string Language = "DE";
              private FirebaseApp _app; 
              
              private void Awake()
              {
                  if (!Application.isPlaying)
                  {
                      Debug.Log("Application is not playing.");
                      return;
                  }
                  
                  FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
                      var dependencyStatus = task.Result;
                      if (dependencyStatus == Firebase.DependencyStatus.Available) {
                          // Create and hold a reference to your FirebaseApp,
                          // where app is a Firebase.FirebaseApp property of your application class.
                          _app = FirebaseApp.DefaultInstance;
      
                          // Set a flag here to indicate whether Firebase is ready to use by your app.
                      } else {
                          Debug.LogError($"Could not resolve all Firebase dependencies: {dependencyStatus}");
                          // Firebase Unity SDK is not safe to use here.
                      }
                  });
                  _cmpManager = CmpManager.Instance;
              }
              
              private void Start()
              {
                  _cmpConfig = new CmpConfig(CodeId, Domain, AppName, Language)
                  {
                      Debug = true,
                      Timeout = 8000
                  };
      #if UNITY_ANDROID
                  _cmpConfig.UIConfig.isOutsideTouchable = true;
                  _cmpConfig.UIConfig.SetAndroidUiType(AndroidUiType.Dialog);
      #endif
                  // Initialize Consent Manager
                  InitializeCmpManager();
                  // Initialize UI buttons
                  InitializeUIButtons();
      
                  // Launch Consent Manager
                  _cmpManager.Launch();
              }
      
              private void InitializeUIButtons()
              {
                  uiManager.CreateButtons(
                      new ButtonData("Open", OnClickOpenConsentLayer),
                      new ButtonData("Check", OnClickOpenConsentLayerOnCheck),
                      new ButtonData("Check?", OnclickCheckConsentRequired),
                      new ButtonData("ATT?", OnClickRequestATTrackingStatus),
                      new ButtonData("Get Status", OnClickDebugConsentStatus),
                      new ButtonData("Initialize", OnClickInitialize),
                      new ButtonData("Accept All", OnClickAcceptAll),
                      new ButtonData("Reject All", OnClickRejectAll),
                      new ButtonData("Reset", OnClickResetConsentData),
                      new ButtonData("Import", OnClickImportCmpString),
                      new ButtonData("Export", OnClickExportCmpString)
                  );
                  uiManager.CreateDropdown("Screen Config", GetScreenConfigOptions(), s =>
                  {
                      AppendLog($"Set Screen ${s}");
                      _cmpConfig.UIConfig.screenConfig = (CmpUIConfig.ScreenConfig) Enum.Parse(typeof(CmpUIConfig.ScreenConfig), s);  
                      _cmpManager.SetUIConfig(_cmpConfig.UIConfig); 
                  });
                  uiManager.CreateDropdown("Purposes", _purposeList, s =>
                  {
                      _idPurposeOrVendorInputField = s;
                      CheckHasPurpose(s);
                  });
                  uiManager.CreateDropdown("Vendors", _vendorList, s =>
                  {
                      _idPurposeOrVendorInputField = s; 
                      CheckHasVendor(s);
                  }); 
              }
      
              private void InitializeCmpManager()
              {
                  _mainThread = Thread.CurrentThread;
                  AppendLog("Consentmanager SampleScene started");
      
      #if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
              _cmpManager.Initialize(_cmpConfig);
              _cmpManager.AddGoogleConsentModeListener(OnGoogleConsentUpdated);
              _cmpManager.AddEventListeners(OnOpen, OnClose, OnNotOpened, OnCmpButtonClicked, OnError);
      #endif
      
      #if UNITY_IOS
              CmpATTrackingManager.EnableAutomaticATTracking();
              CmpATTrackingManager.Instance.RegisterOnATTrackingStatusChangedListener(OnCmpATTrackingStatusChanged);
      #endif
              }
              
              #region Button Events
      
              private void OnClickInitialize()
              {
                  AppendLog("Initialize");
                  _cmpManager.Launch();
              }
      
              private async void OnClickRejectAll()
              {
                  AppendLog("Calling Reject All"); 
                  await _cmpManager.RejectAll();
                  AppendLog("Rejected All");
              }
      
              private async void OnClickAcceptAll()
              {
                  AppendLog("Calling Accept All");
                  await _cmpManager.AcceptAll();
                  AppendLog("Accepted All");
              }
      
              private void OnClickRequestATTrackingStatus()
              {
                  AppendLog("Request AT Tracking Status");
                  _ = _cmpManager.RequestATTrackingPermission();
              }
      
              private async void OnclickCheckConsentRequired()
              {
                  AppendLog("Calling Check Consent Required");
                  var isRequired = await _cmpManager.CheckConsentIsRequired();
                  AppendLog($"Is consent required: {isRequired}");
              }
      
              private void OnClickOpenConsentLayer()
              {
                  AppendLog("Open Consent Layer");
                  _cmpManager.OpenConsentLayer();
              }
      
              private void OnClickOpenConsentLayerOnCheck()
              {
                  AppendLog("Open Consent Layer on Check");
                  _cmpManager.OpenConsentLayerOnCheck();
              }
      
              private void OnClickImportCmpString()
              {
                  AppendLog("Click Import");
                  ImportCmpString();
              }
      
              private void OnClickResetConsentData()
              {
                  _cmpManager.Reset();
                  AppendLog("Reset");
              }
      
              private void OnClickDebugConsentStatus()
              {
                  DebugConsentStatus();
              }
      
              private void OnClickExportCmpString()
              {
                  var cmpString = _cmpManager.ExportCmpString();
                  AppendLog($"Exported CMP String: {cmpString}");
              }
      
              private void CheckHasPurpose(string purposeId)
              {
                  var hasPurpose = _cmpManager.HasPurpose(purposeId);
                  AppendLog($"Has Purpose ({purposeId}): {hasPurpose}");
              }
      
              private void CheckHasVendor(string vendorId)
              {
                  var hasVendor = _cmpManager.HasVendor(vendorId);
                  AppendLog($"Has Vendor ({vendorId}): {hasVendor}");
              }
      
              private async void ImportCmpString()
              {
                  var cmpString = _importStringInputField;
                  CmpImportResult result;
      
                  if (!string.IsNullOrEmpty(cmpString))
                  {
                      AppendLog($"Importing CMP String from input field: {cmpString}");
                      result = await _cmpManager.ImportCmpString(cmpString);
                  }
                  else
                  {
                      AppendLog($"Importing CMP String from sample string: {cmpString}");
                      result = await _cmpManager.ImportCmpString(cmpString);
                  }
      
                  AppendLog($"Unity import result: {result.IsSuccess} with message: {result.Message}");
              }
      
              #endregion
      
              #region Callbacks
      
              public void OnGoogleConsentUpdated(CmpGoogleConsentModeStatus status)
              {
                  // Convert CmpGoogleConsentModeStatus to Firebase compatible dictionary
                  var firebaseConsentDict = new Dictionary<ConsentType, ConsentStatus>();
      
                  foreach (var consent in status.ConsentDictionary)
                  {
                      // Convert GoogleConsentType to Firebase ConsentType
                      var firebaseConsentType = ConvertToFirebaseConsentType(consent.Key);
      
                      // Convert GoogleConsentStatus to Firebase ConsentStatus
                      var firebaseConsentStatus = ConvertToFirebaseConsentStatus(consent.Value);
      
                      firebaseConsentDict[firebaseConsentType] = firebaseConsentStatus;
                  }
                  
                  // Apply the consent settings to Firebase Analytics
                  FirebaseAnalytics.SetConsent(firebaseConsentDict);
                  AppendLog($"Google Consent Mode: {firebaseConsentDict}");
              }
      
              private static ConsentType ConvertToFirebaseConsentType(GoogleConsentType googleConsentType)
              {
                  return googleConsentType switch
                  {
                      GoogleConsentType.AnalyticsStorage => ConsentType.AnalyticsStorage,
                      GoogleConsentType.AdStorage => ConsentType.AdStorage,
                      GoogleConsentType.AdUserData => ConsentType.AdUserData,
                      GoogleConsentType.AdPersonalization => ConsentType.AdPersonalization,
                      _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentType: {googleConsentType}")
                  };
              }
      
              private static ConsentStatus ConvertToFirebaseConsentStatus(GoogleConsentStatus googleConsentStatus)
              {
                  return googleConsentStatus switch
                  {
                      GoogleConsentStatus.Granted => ConsentStatus.Granted,
                      GoogleConsentStatus.Denied => ConsentStatus.Denied,
                      _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentStatus: {googleConsentStatus}")
                  };
              }
      
              public void OnClose()
              {
                  LogThreadContext("OnClose");
                  AppendLog("CMPConsentTool closed");
              }
      
              public void OnCmpButtonClicked(CmpButtonEvent buttonEvent)
              {
                  LogThreadContext("OnCmpButtonClicked");
                  AppendLog($"CMPButton clicked. Event: {buttonEvent}");
              }
      
              public void OnNotOpened()
              {
                  LogThreadContext("OnNotOpened");
                  AppendLog("CMPConsentTool not opened");
              }
      
              public void OnError(CmpErrorType errorType, string message)
              {
                  LogThreadContext("OnError");
                  AppendLog($"Error: {errorType}, {message}");
              }
      
              public void OnOpen()
              {
                  LogThreadContext("OnOpen");
                  AppendLog("CMPConsentTool opened");
              }
      #if UNITY_IOS 
              private void OnCmpATTrackingStatusChanged(ATTrackingManagerAuthorizationStatus oldStatus,
                  ATTrackingManagerAuthorizationStatus newStatus, double lastUpdated)
              {
                  var unixTime = lastUpdated;
                  var dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                  dtDateTime = dtDateTime.AddSeconds(unixTime).ToLocalTime();
                  AppendLog("OnCmpATTrackingStatusChanged: " + newStatus + " lastUpdated: " + dtDateTime);
              }
      #endif
              
              #endregion
      
              private void DebugConsentStatus()
              {
                  var hasConsent = _cmpManager.HasConsent();
                  var allPurposes = _cmpManager.GetAllPurposes();
                  var disabledPurposes = _cmpManager.GetAllPurposes();
                  var enabledPurposes = _cmpManager.GetEnabledPurposes();
                  var allVendors = _cmpManager.GetAllVendors();
                  var disabledVendors = _cmpManager.GetDisabledVendors();
                  var enabledVendors = _cmpManager.GetEnabledVendors();
                  var exportCmp = _cmpManager.ExportCmpString();
                  
                  AppendLog("-----------------");
                  AppendLog($"Unity All Purposes: {string.Join(", ", allPurposes)}");
                  AppendLog($"Unity Disabled Purposes: {string.Join(", ", disabledPurposes)}");
                  AppendLog($"Unity Enabled Purposes: {string.Join(", ", enabledPurposes)}");
                  AppendLog($"Unity All Vendors: {string.Join(", ", allVendors)}");
                  AppendLog($"Unity Disabled Vendors: {string.Join(", ", disabledVendors)}");
                  AppendLog($"Unity Enabled Vendors: {string.Join(", ", enabledVendors)}");
                  AppendLog($"Unity Exported CMP String: {exportCmp}");
                  AppendLog($"Unity Has Consent: {hasConsent}");
                  AppendLog($"Unity US Privacy String: {_cmpManager.GetUsPrivacyString()}");
                  AppendLog($"Unity Google Ac String: {_cmpManager.GetGoogleAcString()}");
                  AppendLog($"Unity Has Purpose C1: {_cmpManager.HasPurpose("c1")}");
                  AppendLog($"Unity Has Vendor 10: {_cmpManager.HasVendor("628")}");
                  AppendLog($"Unity Google Consent Mode Status: {_cmpManager.GetGoogleConsentModeStatus()}");
                  AppendLog("-----------------");
              }
      
              #region Helper
      
              private void LogThreadContext(string callbackName)
              {
                  var onMainThread = IsMainThread();
                  var threadId = Thread.CurrentThread.ManagedThreadId;
                  AppendLog($"{callbackName} called. Is main thread: {onMainThread} ID: {threadId}");
              }
      
              private bool IsMainThread()
              {
                  return _mainThread.Equals(Thread.CurrentThread);
              }
      
              private void AppendLog(string message)
              {
                  Debug.Log(message); 
      
                  if (uiManager != null)
                  {
                      uiManager.AddLogText(message);
                  }
              }
                      
              private List<string> GetScreenConfigOptions()
              {
                  var options = new List<string>();
                  foreach (var config in Enum.GetValues(typeof(CmpUIConfig.ScreenConfig)))
                  {
                      options.Add(config.ToString());
                  }
      
                  return options;
              }
      
              #endregion
          }
      }

       

      Back to top