using System; using System.Reflection; namespace JustTrack { /// /// Utility class for reflection-based integrations with third-party SDKs. /// public class Reflection { /// /// Retrieves the AppsFlyer ID using reflection. /// /// The AppsFlyer ID, or an empty string if retrieval fails. internal static string GetAppsflyerId() { try { var assembly = GetAppsflyerAssembly(); if (assembly == null) { return string.Empty; } return assembly.GetAppsflyerId(); } catch (System.Exception) { return string.Empty; } } /// /// Checks if Facebook Audience Network Unity integration is available. /// /// true if Facebook Audience Network Unity is available; otherwise, false. public static bool HasFacebookAudienceNetworkUnity() { try { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var type = assembly.GetType("AudienceNetwork.AdSettings", false); if (type != null) { var method = type.GetMethod("SetAdvertiserTrackingEnabled", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Any, new Type[] { typeof(bool) }, null); return method != null; } } return false; } catch (System.Exception) { return false; } } /// /// Sets advertiser tracking enabled status for Facebook Audience Network on iOS. /// /// Whether advertiser tracking is authorized. internal static void SetAdvertiserTrackingEnabled(bool authorized) { #if UNITY_IOS // we only need to call this on iOS (the method also just exists on iOS), so we don't have to search for it on Android try { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var type = assembly.GetType("JustTrackInjected.FacebookAudienceNetworkAdapter", false); if (type != null) { var method = type.GetMethod("SetAdvertiserTrackingEnabled", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Any, new Type[] { typeof(bool) }, null); if (method != null) { method.Invoke(null, new object[] { authorized }); } return; } } } catch (System.Exception) { return; } #endif } /// /// Wrapper class for interacting with AppsFlyer SDK via reflection. /// public class AppsflyerAssembly { private readonly MethodInfo getAppsFlyerId; /// /// Initializes a new instance of the class. /// /// The method info for getting AppsFlyer ID. internal AppsflyerAssembly(MethodInfo getAppsFlyerId) { this.getAppsFlyerId = getAppsFlyerId; } /// /// Gets the AppsFlyer ID. /// /// The AppsFlyer ID. internal string GetAppsflyerId() { return (string)getAppsFlyerId.Invoke(null, null); } } private static AppsflyerAssembly? appsflyerAssembly = null; /// /// Gets the AppsFlyer assembly wrapper, creating it if necessary. /// /// The AppsFlyer assembly wrapper, or null if AppsFlyer is not available. public static AppsflyerAssembly? GetAppsflyerAssembly() { if (appsflyerAssembly != null) { return appsflyerAssembly; } try { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var type = assembly.GetType("AppsFlyerSDK.AppsFlyer", false); if (type == null) { continue; } var method = type.GetMethod("getAppsFlyerId", BindingFlags.Public | BindingFlags.Static); if (method == null) { continue; } appsflyerAssembly = new AppsflyerAssembly(method); return appsflyerAssembly; } return null; } catch (System.Exception) { return null; } } } }