using System.Collections.Generic; using System.Collections.ObjectModel; using UnityEngine; namespace AdjustSdk { public class AdjustUtils { public static string KeyAdid = "adid"; public static string KeyMessage = "message"; public static string KeyNetwork = "network"; public static string KeyAdgroup = "adgroup"; public static string KeyCampaign = "campaign"; public static string KeyCreative = "creative"; public static string KeyWillRetry = "willRetry"; public static string KeyTimestamp = "timestamp"; public static string KeyCallbackId = "callbackId"; public static string KeyEventToken = "eventToken"; public static string KeyClickLabel = "clickLabel"; public static string KeyTrackerName = "trackerName"; public static string KeyTrackerToken = "trackerToken"; public static string KeyJsonResponse = "jsonResponse"; public static string KeyCostType = "costType"; public static string KeyCostAmount = "costAmount"; public static string KeyCostCurrency = "costCurrency"; public static string KeyFbInstallReferrer = "fbInstallReferrer"; public static string KeySkanConversionValue = "fineValue"; public static string KeySkanCoarseValue = "coarseValue"; public static string KeySkanLockWindow = "lockWindow"; public static string KeyCode = "code"; public static string KeyVerificationStatus = "verificationStatus"; // For testing purposes. public static string KeyTestOptionsBaseUrl = "baseUrl"; public static string KeyTestOptionsGdprUrl = "gdprUrl"; public static string KeyTestOptionsSubscriptionUrl = "subscriptionUrl"; public static string KeyTestOptionsPurchaseVerificationUrl = "purchaseVerificationUrl"; public static string KeyTestOptionsOverwriteUrl = "urlOverwrite"; public static string KeyTestOptionsExtraPath = "extraPath"; public static string KeyTestOptionsBasePath = "basePath"; public static string KeyTestOptionsGdprPath = "gdprPath"; public static string KeyTestOptionsDeleteState = "deleteState"; public static string KeyTestOptionsUseTestConnectionOptions = "useTestConnectionOptions"; public static string KeyTestOptionsTimerIntervalInMilliseconds = "timerIntervalInMilliseconds"; public static string KeyTestOptionsTimerStartInMilliseconds = "timerStartInMilliseconds"; public static string KeyTestOptionsSessionIntervalInMilliseconds = "sessionIntervalInMilliseconds"; public static string KeyTestOptionsSubsessionIntervalInMilliseconds = "subsessionIntervalInMilliseconds"; public static string KeyTestOptionsTeardown = "teardown"; public static string KeyTestOptionsNoBackoffWait = "noBackoffWait"; public static string KeyTestOptionsAdServicesFrameworkEnabled = "adServicesFrameworkEnabled"; public static string KeyTestOptionsAttStatus = "attStatus"; public static string KeyTestOptionsIdfa = "idfa"; public static string KeyTestOptionsIgnoreSystemLifecycleBootstrap = "ignoreSystemLifecycleBootstrap"; public static int ConvertLogLevel(AdjustLogLevel? logLevel) { if (logLevel == null) { return -1; } return (int)logLevel; } public static int ConvertBool(bool? value) { if (value == null) { return -1; } if (value.Value) { return 1; } else { return 0; } } public static double ConvertDouble(double? value) { if (value == null) { return -1; } return (double)value; } public static int ConvertInt(int? value) { if (value == null) { return -1; } return (int)value; } public static long ConvertLong(long? value) { if (value == null) { return -1; } return (long)value; } public static string ConvertReadOnlyCollectionToJson(ReadOnlyCollection list) { if (list == null) { return null; } List processedList = new List(); for (int i = 0; i < list.Count; i += 1) { string item = list[i]; if (item == null) { continue; } processedList.Add(item); } // create JSON array var jsonArray = new JSONArray(); foreach (var listItem in processedList) { jsonArray.Add(new JSONData(listItem)); } return jsonArray.ToString(); } public static string ConvertReadOnlyCollectionOfPairsToJson(ReadOnlyCollection list) { if (list == null) { return null; } // list of callback / partner parameters must contain even number of elements if (list.Count % 2 != 0) { return null; } List processedList = new List(); for (int i = 0; i < list.Count; i += 2) { string key = list[i]; string value = list[i + 1]; if (key == null || value == null) { continue; } processedList.Add(key); processedList.Add(value); } // create JSON array var jsonArray = new JSONArray(); foreach (var listItem in processedList) { jsonArray.Add(new JSONData(listItem)); } return jsonArray.ToString(); } public static string ConvertReadOnlyCollectionOfTripletsToJson(ReadOnlyCollection list) { if (list == null) { return null; } // list of third party sharing parameters must contain number of elements divisible by 3 if (list.Count % 3 != 0) { return null; } List processedList = new List(); for (int i = 0; i < list.Count; i += 3) { string partnerName = list[i]; string key = list[i + 1]; string value = list[i + 2]; if (partnerName == null || key == null || value == null) { continue; } processedList.Add(partnerName); processedList.Add(key); processedList.Add(value); } // create JSON array var jsonArray = new JSONArray(); foreach (var listItem in processedList) { jsonArray.Add(new JSONData(listItem)); } return jsonArray.ToString(); } public static string GetJsonResponseCompact(Dictionary dictionary) { string logJsonResponse = ""; if (dictionary == null) { return logJsonResponse; } else { int preLoopCounter = 0; logJsonResponse += "{"; foreach (KeyValuePair pair in dictionary) { string valueString = pair.Value as string; if (valueString != null) { if (++preLoopCounter > 1) { logJsonResponse += ","; } // if the value is another JSON/complex-structure if (valueString.StartsWith("{") && valueString.EndsWith("}")) { logJsonResponse += "\"" + pair.Key + "\"" + ":" + valueString; } else { logJsonResponse += "\"" + pair.Key + "\"" + ":" + "\"" + valueString + "\""; } continue; } Dictionary valueDictionary = pair.Value as Dictionary; if (++preLoopCounter > 1) { logJsonResponse += ","; } logJsonResponse += "\"" + pair.Key + "\"" + ":"; logJsonResponse += GetJsonResponseCompact(valueDictionary); } logJsonResponse += "}"; } return logJsonResponse; } public static string GetJsonString(JSONNode node, string key) { if (node == null) { return null; } // Access value object and cast it to JSONData. var nodeValue = node[key] as JSONData; if (nodeValue == null) { return null; } // https://github.com/adjust/unity_sdk/issues/137 if (nodeValue == "") { return null; } return nodeValue.Value; } public static void WriteJsonResponseDictionary(JSONClass jsonObject, Dictionary output) { foreach (KeyValuePair pair in jsonObject) { // Try to cast value as a complex object. var subNode = pair.Value.AsObject; var key = pair.Key; // Value is not a complex object. if (subNode == null) { var value = pair.Value.Value; output.Add(key, value); continue; } // Create new dictionary for complex type. var newSubDictionary = new Dictionary(); // Save it in the current dictionary. output.Add(key, newSubDictionary); // Recursive call to fill new dictionary. WriteJsonResponseDictionary(subNode, newSubDictionary); } } public static string TryGetValue(Dictionary dictionary, string key) { string value; if (dictionary.TryGetValue(key, out value)) { // https://github.com/adjust/unity_sdk/issues/137 if (value == "") { return null; } return value; } return null; } public static Dictionary GetSkanUpdateDataDictionary(string skanUpdateData) { Dictionary skanUpdateDataDictionary = new Dictionary(); var skanUpdateDataNode = JSON.Parse(skanUpdateData); if (skanUpdateDataNode != null && skanUpdateDataNode.AsObject != null) { Dictionary temp = new Dictionary(); AdjustUtils.WriteJsonResponseDictionary(skanUpdateDataNode.AsObject, temp); foreach (KeyValuePair entry in temp) { skanUpdateDataDictionary.Add(entry.Key, entry.Value.ToString()); } } return skanUpdateDataDictionary; } public static Dictionary GetAttributionJsonResponse(string attributionJsonResponse) { Dictionary attributionJsonResponseDictionary = new Dictionary(); var attributionJsonResponseNode = JSON.Parse(attributionJsonResponse); if (attributionJsonResponseNode != null && attributionJsonResponseNode.AsObject != null) { Dictionary temp = new Dictionary(); AdjustUtils.WriteJsonResponseDictionary(attributionJsonResponseNode.AsObject, temp); foreach (KeyValuePair entry in temp) { attributionJsonResponseDictionary.Add(entry.Key, entry.Value); } } return attributionJsonResponseDictionary; } public static string GetValueOrEmptyToNull(string value) { return string.IsNullOrEmpty(value) ? null : value; } #if UNITY_ANDROID public static AndroidJavaObject TestOptionsMap2AndroidJavaObject(Dictionary testOptionsMap, AndroidJavaObject ajoCurrentActivity) { AndroidJavaObject ajoTestOptions = new AndroidJavaObject("com.adjust.sdk.AdjustTestOptions"); ajoTestOptions.Set("baseUrl", testOptionsMap[KeyTestOptionsBaseUrl]); ajoTestOptions.Set("gdprUrl", testOptionsMap[KeyTestOptionsGdprUrl]); ajoTestOptions.Set("subscriptionUrl", testOptionsMap[KeyTestOptionsSubscriptionUrl]); ajoTestOptions.Set("purchaseVerificationUrl", testOptionsMap[KeyTestOptionsPurchaseVerificationUrl]); if (testOptionsMap.ContainsKey(KeyTestOptionsExtraPath) && !string.IsNullOrEmpty(testOptionsMap[KeyTestOptionsExtraPath])) { ajoTestOptions.Set("basePath", testOptionsMap[KeyTestOptionsExtraPath]); ajoTestOptions.Set("gdprPath", testOptionsMap[KeyTestOptionsExtraPath]); ajoTestOptions.Set("subscriptionPath", testOptionsMap[KeyTestOptionsExtraPath]); ajoTestOptions.Set("purchaseVerificationPath", testOptionsMap[KeyTestOptionsExtraPath]); } if (testOptionsMap.ContainsKey(KeyTestOptionsDeleteState) && ajoCurrentActivity != null) { ajoTestOptions.Set("context", ajoCurrentActivity); } if (testOptionsMap.ContainsKey(KeyTestOptionsUseTestConnectionOptions)) { bool useTestConnectionOptions = testOptionsMap[KeyTestOptionsUseTestConnectionOptions].ToLower() == "true"; AndroidJavaObject ajoUseTestConnectionOptions = new AndroidJavaObject("java.lang.Boolean", useTestConnectionOptions); ajoTestOptions.Set("useTestConnectionOptions", ajoUseTestConnectionOptions); } if (testOptionsMap.ContainsKey(KeyTestOptionsTimerIntervalInMilliseconds)) { var timerIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsTimerIntervalInMilliseconds]); AndroidJavaObject ajoTimerIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", timerIntervalInMilliseconds); ajoTestOptions.Set("timerIntervalInMilliseconds", ajoTimerIntervalInMilliseconds); } if (testOptionsMap.ContainsKey(KeyTestOptionsTimerStartInMilliseconds)) { var timerStartInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsTimerStartInMilliseconds]); AndroidJavaObject ajoTimerStartInMilliseconds = new AndroidJavaObject("java.lang.Long", timerStartInMilliseconds); ajoTestOptions.Set("timerStartInMilliseconds", ajoTimerStartInMilliseconds); } if (testOptionsMap.ContainsKey(KeyTestOptionsSessionIntervalInMilliseconds)) { var sessionIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsSessionIntervalInMilliseconds]); AndroidJavaObject ajoSessionIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", sessionIntervalInMilliseconds); ajoTestOptions.Set("sessionIntervalInMilliseconds", ajoSessionIntervalInMilliseconds); } if (testOptionsMap.ContainsKey(KeyTestOptionsSubsessionIntervalInMilliseconds)) { var subsessionIntervalInMilliseconds = long.Parse(testOptionsMap[KeyTestOptionsSubsessionIntervalInMilliseconds]); AndroidJavaObject ajoSubsessionIntervalInMilliseconds = new AndroidJavaObject("java.lang.Long", subsessionIntervalInMilliseconds); ajoTestOptions.Set("subsessionIntervalInMilliseconds", ajoSubsessionIntervalInMilliseconds); } if (testOptionsMap.ContainsKey(KeyTestOptionsTeardown)) { bool teardown = testOptionsMap[KeyTestOptionsTeardown].ToLower() == "true"; AndroidJavaObject ajoTeardown = new AndroidJavaObject("java.lang.Boolean", teardown); ajoTestOptions.Set("teardown", ajoTeardown); } if (testOptionsMap.ContainsKey(KeyTestOptionsNoBackoffWait)) { bool noBackoffWait = testOptionsMap[KeyTestOptionsNoBackoffWait].ToLower() == "true"; AndroidJavaObject ajoNoBackoffWait = new AndroidJavaObject("java.lang.Boolean", noBackoffWait); ajoTestOptions.Set("noBackoffWait", ajoNoBackoffWait); } if (testOptionsMap.ContainsKey(KeyTestOptionsIgnoreSystemLifecycleBootstrap)) { // TODO: fix native logic not to have negation in naming throughout the chain of calls bool doNotIgnoreSystemLifecycleBootstrap = testOptionsMap[KeyTestOptionsIgnoreSystemLifecycleBootstrap].ToLower() == "true"; AndroidJavaObject ajoDoNotIgnoreSystemLifecycleBootstrap = new AndroidJavaObject("java.lang.Boolean", doNotIgnoreSystemLifecycleBootstrap); ajoTestOptions.Set("ignoreSystemLifecycleBootstrap", ajoDoNotIgnoreSystemLifecycleBootstrap); } return ajoTestOptions; } #endif } }