From 2af7c06f7b6a2f53b7555d3062616b327340f6cf Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 26 Feb 2025 12:19:42 +0100 Subject: [PATCH 1/7] feat: add JsonResponse to AdjustAttribution --- Assets/Adjust/Native/Editor/Dependencies.xml | 2 +- Assets/Adjust/Native/iOS/AdjustUnity.mm | 29 ++++++------------- .../Adjust/Native/iOS/AdjustUnityDelegate.mm | 8 +++++ Assets/Adjust/Scripts/AdjustAndroid.cs | 16 +++++++++- Assets/Adjust/Scripts/AdjustAttribution.cs | 9 ++++++ Assets/Adjust/Scripts/AdjustiOS.cs | 2 +- Assets/Adjust/package.json | 2 +- Assets/Test/Scripts/CommandExecutor.cs | 19 ++++++++++++ Assets/Test/TestApp/TestApp.cs | 4 +-- VERSION | 2 +- 10 files changed, 66 insertions(+), 27 deletions(-) diff --git a/Assets/Adjust/Native/Editor/Dependencies.xml b/Assets/Adjust/Native/Editor/Dependencies.xml index e810465d..4a585d05 100644 --- a/Assets/Adjust/Native/Editor/Dependencies.xml +++ b/Assets/Adjust/Native/Editor/Dependencies.xml @@ -7,7 +7,7 @@ - + diff --git a/Assets/Adjust/Native/iOS/AdjustUnity.mm b/Assets/Adjust/Native/iOS/AdjustUnity.mm index aebcaac7..d11eb5df 100644 --- a/Assets/Adjust/Native/iOS/AdjustUnity.mm +++ b/Assets/Adjust/Native/iOS/AdjustUnity.mm @@ -346,16 +346,7 @@ void _AdjustSetPushToken(const char* pushToken) { void _AdjustProcessDeeplink(const char* deeplink) { if (deeplink != NULL) { NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; - NSURL *urlDeeplink; - if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) { - urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]; - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - } -#pragma clang diagnostic pop - + NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; [Adjust processDeeplink:deeplink]; } @@ -381,6 +372,13 @@ void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback) { addValueOrEmpty(dictionary, @"costType", attribution.costType); addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount); addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency); + + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse + options:0 + error:nil]; + NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + addValueOrEmpty(dictionary, @"jsonResponse", strJsonResponse); + NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; @@ -719,16 +717,7 @@ void _AdjustVerifyAppStorePurchase(const char* transactionId, void _AdjustProcessAndResolveDeeplink(const char* deeplink, AdjustDelegateResolvedDeeplinkCallback callback) { if (deeplink != NULL) { NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; - NSURL *urlDeeplink; - if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) { - urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]; - } else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - } -#pragma clang diagnostic pop - + NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; [Adjust processAndResolveDeeplink:deeplink withCompletionHandler:^(NSString * _Nullable resolvedLink) { // TODO: nil checks diff --git a/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm b/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm index 9ffe284a..4de69a0f 100644 --- a/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm +++ b/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm @@ -124,6 +124,14 @@ - (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution { forKey:@"costCurrency" toDictionary:dictionary]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse + options:0 + error:nil]; + NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + [self addValueOrEmpty:strJsonResponse + forKey:@"jsonResponse" + toDictionary:dictionary]; + NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; diff --git a/Assets/Adjust/Scripts/AdjustAndroid.cs b/Assets/Adjust/Scripts/AdjustAndroid.cs index 8653bea2..4054028f 100644 --- a/Assets/Adjust/Scripts/AdjustAndroid.cs +++ b/Assets/Adjust/Scripts/AdjustAndroid.cs @@ -8,7 +8,7 @@ namespace AdjustSdk #if UNITY_ANDROID public class AdjustAndroid { - private const string sdkPrefix = "unity5.0.7"; + private const string sdkPrefix = "unity5.1.0"; private static bool isDeferredDeeplinkOpeningEnabled = true; private static AndroidJavaClass ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); private static AndroidJavaObject ajoCurrentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity"); @@ -774,6 +774,13 @@ public void onAttributionChanged(AndroidJavaObject ajoAttribution) adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency; string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer); adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer; + string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } this.callback(adjustAttribution); } @@ -1169,6 +1176,13 @@ public void onAttributionRead(AndroidJavaObject ajoAttribution) adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency; string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer); adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer; + string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } this.callback(adjustAttribution); } diff --git a/Assets/Adjust/Scripts/AdjustAttribution.cs b/Assets/Adjust/Scripts/AdjustAttribution.cs index dad2d92f..261f2ad9 100644 --- a/Assets/Adjust/Scripts/AdjustAttribution.cs +++ b/Assets/Adjust/Scripts/AdjustAttribution.cs @@ -15,6 +15,7 @@ public class AdjustAttribution public string CostType { get; set; } public double? CostAmount { get; set; } public string CostCurrency { get; set; } + public Dictionary JsonResponse { get; set; } // Android only public string FbInstallReferrer { get; set; } @@ -49,6 +50,14 @@ public AdjustAttribution(string jsonString) } this.CostCurrency = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostCurrency); this.FbInstallReferrer = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyFbInstallReferrer); + + string jsonResponseString = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, this.JsonResponse); + } } public AdjustAttribution(Dictionary dicAttributionData) diff --git a/Assets/Adjust/Scripts/AdjustiOS.cs b/Assets/Adjust/Scripts/AdjustiOS.cs index 05065b9a..5974ef6e 100644 --- a/Assets/Adjust/Scripts/AdjustiOS.cs +++ b/Assets/Adjust/Scripts/AdjustiOS.cs @@ -8,7 +8,7 @@ namespace AdjustSdk #if UNITY_IOS public class AdjustiOS { - private const string sdkPrefix = "unity5.0.7"; + private const string sdkPrefix = "unity5.1.0"; // app callbacks as method parameters private static List> appIsEnabledGetterCallbacks; diff --git a/Assets/Adjust/package.json b/Assets/Adjust/package.json index e5d96d98..a4fdff35 100644 --- a/Assets/Adjust/package.json +++ b/Assets/Adjust/package.json @@ -1,6 +1,6 @@ { "name": "com.adjust.sdk", - "version": "5.0.7", + "version": "5.1.0", "unity": "2019.4", "displayName": "Adjust", "license": "MIT", diff --git a/Assets/Test/Scripts/CommandExecutor.cs b/Assets/Test/Scripts/CommandExecutor.cs index a51dd732..308ec989 100644 --- a/Assets/Test/Scripts/CommandExecutor.cs +++ b/Assets/Test/Scripts/CommandExecutor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using Newtonsoft.Json; namespace AdjustSdk.Test { @@ -368,6 +369,15 @@ private void Config() _testLibrary.AddInfoToSend("cost_amount", attribution.CostAmount.ToString()); _testLibrary.AddInfoToSend("cost_currency", attribution.CostCurrency); _testLibrary.AddInfoToSend("fb_install_referrer", attribution.FbInstallReferrer); + var updatedJsonResponse = new Dictionary(attribution.JsonResponse); +#if UNITY_IOS + updatedJsonResponse.Remove("fb_install_referrer"); + if (updatedJsonResponse.TryGetValue("cost_amount", out var costAmount) && costAmount is IConvertible) + { + updatedJsonResponse["cost_amount"] = string.Format("{0:0.00}", System.Convert.ToDouble(costAmount)); + } +#endif + _testLibrary.AddInfoToSend("json_response", JsonConvert.SerializeObject(updatedJsonResponse)); _testLibrary.SendInfoToServer(localExtraPath); }); } @@ -959,6 +969,15 @@ private void AttributionGetter() _testLibrary.AddInfoToSend("cost_amount", attribution.CostAmount.ToString()); _testLibrary.AddInfoToSend("cost_currency", attribution.CostCurrency); _testLibrary.AddInfoToSend("fb_install_referrer", attribution.FbInstallReferrer); + var updatedJsonResponse = new Dictionary(attribution.JsonResponse); +#if UNITY_IOS + updatedJsonResponse.Remove("fb_install_referrer"); + if (updatedJsonResponse.TryGetValue("cost_amount", out var costAmount) && costAmount is IConvertible) + { + updatedJsonResponse["cost_amount"] = string.Format("{0:0.00}", System.Convert.ToDouble(costAmount)); + } +#endif + _testLibrary.AddInfoToSend("json_response", JsonConvert.SerializeObject(updatedJsonResponse)); _testLibrary.SendInfoToServer(localExtraPath); }); } diff --git a/Assets/Test/TestApp/TestApp.cs b/Assets/Test/TestApp/TestApp.cs index 38595621..d832c737 100644 --- a/Assets/Test/TestApp/TestApp.cs +++ b/Assets/Test/TestApp/TestApp.cs @@ -11,11 +11,11 @@ public class TestApp : MonoBehaviour #if UNITY_ANDROID private const string PORT = ":8443"; private const string PROTOCOL = "https://"; - private const string IP = "192.168.86.99"; + private const string IP = "192.168.8.207"; #elif UNITY_IOS private const string PORT = ":8080"; private const string PROTOCOL = "http://"; - private const string IP = "192.168.86.99"; + private const string IP = "192.168.8.207"; private TestLibraryiOS _testLibraryiOS; #else private const string PORT = ":8080"; diff --git a/VERSION b/VERSION index 00433367..831446cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.7 +5.1.0 From 54b839f948f3c1f927334b46c9d9c86d63cc4669 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 27 Feb 2025 13:55:37 +0100 Subject: [PATCH 2/7] refac: create separate intent-filter per scheme uri --- .../Editor/AdjustEditorPreprocessor.cs | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs index 7d39e3c2..c8c38028 100644 --- a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs +++ b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs @@ -11,11 +11,11 @@ namespace AdjustSdk { - #if UNITY_2018_1_OR_NEWER +#if UNITY_2018_1_OR_NEWER public class AdjustEditorPreprocessor : IPreprocessBuildWithReport - #else +#else public class AdjustEditorPreprocessor : IPreprocessBuild - #endif +#endif { public int callbackOrder { @@ -24,24 +24,24 @@ public int callbackOrder return 0; } } - #if UNITY_2018_1_OR_NEWER +#if UNITY_2018_1_OR_NEWER public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) { OnPreprocessBuild(report.summary.platform, string.Empty); } - #endif +#endif public void OnPreprocessBuild(BuildTarget target, string path) { if (target == BuildTarget.Android) { - #if UNITY_ANDROID +#if UNITY_ANDROID RunPostProcessTasksAndroid(); - #endif +#endif } } - #if UNITY_ANDROID +#if UNITY_ANDROID private static void RunPostProcessTasksAndroid() { var isAdjustManifestUsed = false; @@ -119,7 +119,6 @@ private static bool AddURISchemes(XmlDocument manifest) var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='com.unity3d.player.UnityPlayerActivity']", GetNamespaceManager(manifest)); var usedIntentFiltersChanged = false; - var usedIntentFilters = GetIntentFilter(manifest); foreach (var uriScheme in AdjustSettings.AndroidUriSchemes) { Uri uri; @@ -141,54 +140,46 @@ private static bool AddURISchemes(XmlDocument manifest) continue; } - if (!IsIntentFilterAlreadyExist(manifest, uri)) + if (!DoesIntentFilterAlreadyExist(manifest, uri)) { Debug.Log("[Adjust]: Adding new URI with scheme: " + uri.Scheme + ", and host: " + uri.Host); + var newIntentFilter = GetNewIntentFilter(manifest); var androidSchemeNode = manifest.CreateElement("data"); AddAndroidNamespaceAttribute(manifest, "scheme", uri.Scheme, androidSchemeNode); AddAndroidNamespaceAttribute(manifest, "host", uri.Host, androidSchemeNode); - usedIntentFilters.AppendChild(androidSchemeNode); - usedIntentFiltersChanged = true; - + newIntentFilter.AppendChild(androidSchemeNode); + intentRoot.AppendChild(newIntentFilter); Debug.Log(string.Format("[Adjust]: Android deeplink URI scheme \"{0}\" successfully added to your app's AndroidManifest.xml file.", uriScheme)); + usedIntentFiltersChanged = true; } } - if (usedIntentFiltersChanged && usedIntentFilters.ParentNode == null) - { - intentRoot.AppendChild(usedIntentFilters); - } - return usedIntentFiltersChanged; } - private static XmlElement GetIntentFilter(XmlDocument manifest) + private static XmlElement GetNewIntentFilter(XmlDocument manifest) { - var xpath = "/manifest/application/activity/intent-filter[data/@android:scheme and data/@android:host]"; - var intentFilter = manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) as XmlElement; - if (intentFilter == null) - { - const string androidName = "name"; - const string category = "category"; + const string androidName = "name"; + const string category = "category"; - intentFilter = manifest.CreateElement("intent-filter"); + var intentFilter = manifest.CreateElement("intent-filter"); - var actionElement = manifest.CreateElement("action"); - AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.action.VIEW", actionElement); - intentFilter.AppendChild(actionElement); + var actionElement = manifest.CreateElement("action"); + AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.action.VIEW", actionElement); + intentFilter.AppendChild(actionElement); - var defaultCategory = manifest.CreateElement(category); - AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.DEFAULT", defaultCategory); - intentFilter.AppendChild(defaultCategory); + var defaultCategory = manifest.CreateElement(category); + AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.DEFAULT", defaultCategory); + intentFilter.AppendChild(defaultCategory); + + var browsableCategory = manifest.CreateElement(category); + AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory); + intentFilter.AppendChild(browsableCategory); - var browsableCategory = manifest.CreateElement(category); - AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory); - intentFilter.AppendChild(browsableCategory); - } return intentFilter; } - private static bool IsIntentFilterAlreadyExist(XmlDocument manifest, Uri link) + private static bool DoesIntentFilterAlreadyExist(XmlDocument manifest, Uri link) { var xpath = string.Format("/manifest/application/activity/intent-filter/data[@android:scheme='{0}' and @android:host='{1}']", link.Scheme, link.Host); return manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null; @@ -363,6 +354,6 @@ private static XmlNamespaceManager GetNamespaceManager(XmlDocument manifest) namespaceManager.AddNamespace("android", "http://schemas.android.com/apk/res/android"); return namespaceManager; } - #endif -} +#endif + } } From ad4dc6845ba15e4889a83d5360a529b08eaf6579 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 27 Feb 2025 14:37:57 +0100 Subject: [PATCH 3/7] feat: add ability to specify custom android activity name --- .../Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs | 10 +++++++++- Assets/Adjust/Scripts/Editor/AdjustSettings.cs | 8 ++++++++ Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs | 11 +++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs index c8c38028..753630f4 100644 --- a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs +++ b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs @@ -117,7 +117,15 @@ private static bool AddURISchemes(XmlDocument manifest) } Debug.Log("[Adjust]: Start addition of URI schemes"); - var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='com.unity3d.player.UnityPlayerActivity']", GetNamespaceManager(manifest)); + // Check if user has defined a custom Android activity name. + string androidActivityName = "com.unity3d.player.UnityPlayerActivity"; + if (AdjustSettings.AndroidCustomActivityName.Length != 0) + { + androidActivityName = AdjustSettings.AndroidCustomActivityName; + } + + var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='" + + androidActivityName + "']", GetNamespaceManager(manifest)); var usedIntentFiltersChanged = false; foreach (var uriScheme in AdjustSettings.AndroidUriSchemes) { diff --git a/Assets/Adjust/Scripts/Editor/AdjustSettings.cs b/Assets/Adjust/Scripts/Editor/AdjustSettings.cs index 6953ce24..b4d620b7 100644 --- a/Assets/Adjust/Scripts/Editor/AdjustSettings.cs +++ b/Assets/Adjust/Scripts/Editor/AdjustSettings.cs @@ -38,6 +38,8 @@ public class AdjustSettings : ScriptableObject private string[] _iOSUniversalLinksDomains = new string[0]; [SerializeField] private string[] androidUriSchemes = new string[0]; + [SerializeField] + private string _androidCustomActivityName; public static AdjustSettings Instance { @@ -182,5 +184,11 @@ public static string[] AndroidUriSchemes get { return Instance.androidUriSchemes; } set { Instance.androidUriSchemes = value; } } + + public static string AndroidCustomActivityName + { + get { return Instance._androidCustomActivityName; } + set { Instance._androidCustomActivityName = value; } + } } } diff --git a/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs b/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs index bde2addd..0bafe024 100644 --- a/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs +++ b/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs @@ -20,6 +20,7 @@ public class AdjustSettingsEditor : Editor SerializedProperty iOSUrlSchemes; SerializedProperty iOSUniversalLinksDomains; SerializedProperty androidUriSchemes; + SerializedProperty androidCustomActivityName; void OnEnable() { @@ -36,6 +37,7 @@ void OnEnable() iOSUrlSchemes = serializedObject.FindProperty("_iOSUrlSchemes"); iOSUniversalLinksDomains = serializedObject.FindProperty("_iOSUniversalLinksDomains"); androidUriSchemes = serializedObject.FindProperty("androidUriSchemes"); + androidCustomActivityName = serializedObject.FindProperty("_androidCustomActivityName"); } public override void OnInspectorGUI() { @@ -92,6 +94,15 @@ public override void OnInspectorGUI() true); EditorGUI.indentLevel -= 1; EditorGUILayout.Space(); + EditorGUILayout.LabelField("ANDROID ACTIVITY NAME:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + EditorGUILayout.PropertyField(androidCustomActivityName, + new GUIContent("Custom Android Activity Name", + "In case you are using custom activity instead of the default Unity activity " + + "(com.unity3d.player.UnityPlayerActivity), please specify it's full name."), + true); + EditorGUI.indentLevel -= 1; + EditorGUILayout.Space(); EditorGUILayout.LabelField("DEEP LINKING:", darkerCyanTextFieldStyles); EditorGUI.indentLevel += 1; EditorGUILayout.PropertyField(iOSUrlIdentifier, From a765b04f037758f29066b06a20ce824c0adce635 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 27 Feb 2025 16:42:20 +0100 Subject: [PATCH 4/7] refac: fire callbacks behind native android ones inside of the main unity thread --- Assets/Adjust/Scripts/AdjustAndroid.cs | 510 ++++++++++-------- .../Adjust/Scripts/AdjustThreadDispatcher.cs | 46 ++ .../Scripts/AdjustThreadDispatcher.cs.meta | 11 + Assets/Adjust/Scripts/AdjustUtils.cs | 5 + 4 files changed, 333 insertions(+), 239 deletions(-) create mode 100644 Assets/Adjust/Scripts/AdjustThreadDispatcher.cs create mode 100644 Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta diff --git a/Assets/Adjust/Scripts/AdjustAndroid.cs b/Assets/Adjust/Scripts/AdjustAndroid.cs index 4054028f..434331e9 100644 --- a/Assets/Adjust/Scripts/AdjustAndroid.cs +++ b/Assets/Adjust/Scripts/AdjustAndroid.cs @@ -721,7 +721,8 @@ private class AttributionChangedListener : AndroidJavaProxy { private Action callback; - public AttributionChangedListener(Action pCallback) : base("com.adjust.sdk.OnAttributionChangedListener") + public AttributionChangedListener(Action pCallback) + : base("com.adjust.sdk.OnAttributionChangedListener") { this.callback = pCallback; } @@ -735,54 +736,50 @@ public void onAttributionChanged(AndroidJavaObject ajoAttribution) return; } - if (ajoAttribution == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustAttribution adjustAttribution = new AdjustAttribution(); - string trackerName = ajoAttribution.Get(AdjustUtils.KeyTrackerName); - adjustAttribution.TrackerName = trackerName == "" ? null : trackerName; - string trackerToken = ajoAttribution.Get(AdjustUtils.KeyTrackerToken); - adjustAttribution.TrackerToken = trackerToken == "" ? null : trackerToken; - string network = ajoAttribution.Get(AdjustUtils.KeyNetwork); - adjustAttribution.Network = network == "" ? null : network; - string campaign = ajoAttribution.Get(AdjustUtils.KeyCampaign); - adjustAttribution.Campaign = campaign == "" ? null : campaign; - string adgroup = ajoAttribution.Get(AdjustUtils.KeyAdgroup); - adjustAttribution.Adgroup = adgroup == "" ? null : adgroup; - string creative = ajoAttribution.Get(AdjustUtils.KeyCreative); - adjustAttribution.Creative = creative == "" ? null : creative; - string clickLabel = ajoAttribution.Get(AdjustUtils.KeyClickLabel); - adjustAttribution.ClickLabel = clickLabel == "" ? null : clickLabel; - string costType = ajoAttribution.Get(AdjustUtils.KeyCostType); - adjustAttribution.CostType = costType == "" ? null : costType; - using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount)) - { - if (ajoCostAmount == null) + try { - adjustAttribution.CostAmount = null; + if (ajoAttribution == null) + { + callback?.Invoke(null); + return; + } + + AdjustAttribution adjustAttribution = new AdjustAttribution + { + TrackerName = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerName)), + TrackerToken = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerToken)), + Network = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyNetwork)), + Campaign = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCampaign)), + Adgroup = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyAdgroup)), + Creative = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCreative)), + ClickLabel = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyClickLabel)), + CostType = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostType)), + CostCurrency = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostCurrency)), + FbInstallReferrer = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer)) + }; + + using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount)) + { + adjustAttribution.CostAmount = ajoCostAmount != null ? ajoCostAmount.Call("doubleValue") : (double?)null; + } + + string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } + + callback?.Invoke(adjustAttribution); } - else + catch (Exception) { - double costAmount = ajoCostAmount.Call("doubleValue"); - adjustAttribution.CostAmount = costAmount; + // JSON response reading failed. } - } - string costCurrency = ajoAttribution.Get(AdjustUtils.KeyCostCurrency); - adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency; - string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer); - adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer; - string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); - var jsonResponseNode = JSON.Parse(jsonResponse); - if (jsonResponseNode != null && jsonResponseNode.AsObject != null) - { - adjustAttribution.JsonResponse = new Dictionary(); - AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); - } - - this.callback(adjustAttribution); + }); } } @@ -790,7 +787,8 @@ private class DeferredDeeplinkListener : AndroidJavaProxy { private Action callback; - public DeferredDeeplinkListener(Action pCallback) : base("com.adjust.sdk.OnDeferredDeeplinkResponseListener") + public DeferredDeeplinkListener(Action pCallback) + : base("com.adjust.sdk.OnDeferredDeeplinkResponseListener") { this.callback = pCallback; } @@ -804,8 +802,12 @@ public bool launchReceivedDeeplink(AndroidJavaObject deeplink) return isDeferredDeeplinkOpeningEnabled; } - string strDeeplink = deeplink.Call("toString"); - callback(strDeeplink); + AdjustThreadDispatcher.RunOnMainThread(() => + { + string strDeeplink = deeplink != null ? deeplink.Call("toString") : null; + callback?.Invoke(strDeeplink); + }); + return isDeferredDeeplinkOpeningEnabled; } } @@ -828,39 +830,37 @@ public void onEventTrackingSucceeded(AndroidJavaObject eventSuccessData) return; } - if (eventSuccessData == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustEventSuccess adjustEventSuccess = new AdjustEventSuccess(); - string adid = eventSuccessData.Get(AdjustUtils.KeyAdid); - adjustEventSuccess.Adid = adid == "" ? null : adid; - string message = eventSuccessData.Get(AdjustUtils.KeyMessage); - adjustEventSuccess.Message = message == "" ? null : message; - string timestamp = eventSuccessData.Get(AdjustUtils.KeyTimestamp); - adjustEventSuccess.Timestamp = timestamp == "" ? null : timestamp; - string eventToken = eventSuccessData.Get(AdjustUtils.KeyEventToken); - adjustEventSuccess.EventToken = eventToken == "" ? null : eventToken; - string callbackId = eventSuccessData.Get(AdjustUtils.KeyCallbackId); - adjustEventSuccess.CallbackId = callbackId == "" ? null : callbackId; - try - { - using (AndroidJavaObject ajoJsonResponse = eventSuccessData.Get(AdjustUtils.KeyJsonResponse)) + try { - string jsonResponseString = ajoJsonResponse.Call("toString"); - adjustEventSuccess.BuildJsonResponseFromString(jsonResponseString); + AdjustEventSuccess adjustEventSuccess = new AdjustEventSuccess + { + Adid = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyAdid)), + Message = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyMessage)), + Timestamp = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyTimestamp)), + EventToken = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyEventToken)), + CallbackId = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyCallbackId)) + }; + + using (AndroidJavaObject ajoJsonResponse = eventSuccessData.Get(AdjustUtils.KeyJsonResponse)) + { + if (ajoJsonResponse != null) + { + string jsonResponseString = ajoJsonResponse.Call("toString"); + adjustEventSuccess.BuildJsonResponseFromString(jsonResponseString); + } + } + + callback?.Invoke(adjustEventSuccess); } - } - catch (Exception) - { - // JSON response reading failed. - // Native Android SDK should send empty JSON object if none available as of v4.12.5. - // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. - } - - this.callback(adjustEventSuccess); + catch (Exception) + { + // JSON response reading failed. + // Native Android SDK should send empty JSON object if none available as of v4.12.5. + // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. + } + }); } } @@ -882,40 +882,38 @@ public void onEventTrackingFailed(AndroidJavaObject eventFailureData) return; } - if (eventFailureData == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustEventFailure adjustEventFailure = new AdjustEventFailure(); - string adid = eventFailureData.Get(AdjustUtils.KeyAdid); - adjustEventFailure.Adid = adid == "" ? null : adid; - string message = eventFailureData.Get(AdjustUtils.KeyMessage); - adjustEventFailure.Message = message == "" ? null : message; - adjustEventFailure.WillRetry = eventFailureData.Get(AdjustUtils.KeyWillRetry); - string timestamp = eventFailureData.Get(AdjustUtils.KeyTimestamp); - adjustEventFailure.Timestamp = timestamp == "" ? null : timestamp; - string eventToken = eventFailureData.Get(AdjustUtils.KeyEventToken); - adjustEventFailure.EventToken = eventToken == "" ? null : eventToken; - string callbackId = eventFailureData.Get(AdjustUtils.KeyCallbackId); - adjustEventFailure.CallbackId = callbackId == "" ? null : callbackId; - try - { - using (AndroidJavaObject ajoJsonResponse = eventFailureData.Get(AdjustUtils.KeyJsonResponse)) + try { - string jsonResponseString = ajoJsonResponse.Call("toString"); - adjustEventFailure.BuildJsonResponseFromString(jsonResponseString); + AdjustEventFailure adjustEventFailure = new AdjustEventFailure + { + Adid = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyAdid)), + Message = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyMessage)), + Timestamp = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyTimestamp)), + EventToken = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyEventToken)), + CallbackId = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyCallbackId)), + WillRetry = eventFailureData.Get(AdjustUtils.KeyWillRetry) + }; + + using (AndroidJavaObject ajoJsonResponse = eventFailureData.Get(AdjustUtils.KeyJsonResponse)) + { + if (ajoJsonResponse != null) + { + string jsonResponseString = ajoJsonResponse.Call("toString"); + adjustEventFailure.BuildJsonResponseFromString(jsonResponseString); + } + } + + callback?.Invoke(adjustEventFailure); } - } - catch (Exception) - { - // JSON response reading failed. - // Native Android SDK should send empty JSON object if none available as of v4.12.5. - // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. - } - - this.callback(adjustEventFailure); + catch (Exception) + { + // JSON response reading failed. + // Native Android SDK should send empty JSON object if none available as of v4.12.5. + // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. + } + }); } } @@ -923,7 +921,8 @@ private class SessionTrackingSucceededListener : AndroidJavaProxy { private Action callback; - public SessionTrackingSucceededListener(Action pCallback) : base("com.adjust.sdk.OnSessionTrackingSucceededListener") + public SessionTrackingSucceededListener(Action pCallback) + : base("com.adjust.sdk.OnSessionTrackingSucceededListener") { this.callback = pCallback; } @@ -937,35 +936,35 @@ public void onSessionTrackingSucceeded(AndroidJavaObject sessionSuccessData) return; } - if (sessionSuccessData == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustSessionSuccess adjustSessionSuccess = new AdjustSessionSuccess(); - string adid = sessionSuccessData.Get(AdjustUtils.KeyAdid); - adjustSessionSuccess.Adid = adid == "" ? null : adid; - string message = sessionSuccessData.Get(AdjustUtils.KeyMessage); - adjustSessionSuccess.Message = message == "" ? null : message; - string timestamp = sessionSuccessData.Get(AdjustUtils.KeyTimestamp); - adjustSessionSuccess.Timestamp = timestamp == "" ? null : timestamp; - try - { - using (AndroidJavaObject ajoJsonResponse = sessionSuccessData.Get(AdjustUtils.KeyJsonResponse)) + try { - string jsonResponseString = ajoJsonResponse.Call("toString"); - adjustSessionSuccess.BuildJsonResponseFromString(jsonResponseString); + AdjustSessionSuccess adjustSessionSuccess = new AdjustSessionSuccess + { + Adid = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyAdid)), + Message = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyMessage)), + Timestamp = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyTimestamp)) + }; + + using (AndroidJavaObject ajoJsonResponse = sessionSuccessData.Get(AdjustUtils.KeyJsonResponse)) + { + if (ajoJsonResponse != null) + { + string jsonResponseString = ajoJsonResponse.Call("toString"); + adjustSessionSuccess.BuildJsonResponseFromString(jsonResponseString); + } + } + + callback?.Invoke(adjustSessionSuccess); } - } - catch (Exception) - { - // JSON response reading failed. - // Native Android SDK should send empty JSON object if none available as of v4.12.5. - // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. - } - - this.callback(adjustSessionSuccess); + catch (Exception) + { + // JSON response reading failed. + // Native Android SDK should send empty JSON object if none available as of v4.12.5. + // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. + } + }); } } @@ -973,7 +972,8 @@ private class SessionTrackingFailedListener : AndroidJavaProxy { private Action callback; - public SessionTrackingFailedListener(Action pCallback) : base("com.adjust.sdk.OnSessionTrackingFailedListener") + public SessionTrackingFailedListener(Action pCallback) + : base("com.adjust.sdk.OnSessionTrackingFailedListener") { this.callback = pCallback; } @@ -987,36 +987,36 @@ public void onSessionTrackingFailed(AndroidJavaObject sessionFailureData) return; } - if (sessionFailureData == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustSessionFailure adjustSessionFailure = new AdjustSessionFailure(); - string adid = sessionFailureData.Get(AdjustUtils.KeyAdid); - adjustSessionFailure.Adid = adid == "" ? null : adid; - string message = sessionFailureData.Get(AdjustUtils.KeyMessage); - adjustSessionFailure.Message = message == "" ? null : message; - adjustSessionFailure.WillRetry = sessionFailureData.Get(AdjustUtils.KeyWillRetry); - string timestamp = sessionFailureData.Get(AdjustUtils.KeyTimestamp); - adjustSessionFailure.Timestamp = timestamp == "" ? null : timestamp; - try - { - using (AndroidJavaObject ajoJsonResponse = sessionFailureData.Get(AdjustUtils.KeyJsonResponse)) + try { - string jsonResponseString = ajoJsonResponse.Call("toString"); - adjustSessionFailure.BuildJsonResponseFromString(jsonResponseString); + AdjustSessionFailure adjustSessionFailure = new AdjustSessionFailure + { + Adid = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyAdid)), + Message = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyMessage)), + Timestamp = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyTimestamp)), + WillRetry = sessionFailureData.Get(AdjustUtils.KeyWillRetry) + }; + + using (AndroidJavaObject ajoJsonResponse = sessionFailureData.Get(AdjustUtils.KeyJsonResponse)) + { + if (ajoJsonResponse != null) + { + string jsonResponseString = ajoJsonResponse.Call("toString"); + adjustSessionFailure.BuildJsonResponseFromString(jsonResponseString); + } + } + + callback?.Invoke(adjustSessionFailure); } - } - catch (Exception) - { - // JSON response reading failed. - // Native Android SDK should send empty JSON object if none available as of v4.12.5. - // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. - } - - this.callback(adjustSessionFailure); + catch (Exception) + { + // JSON response reading failed. + // Native Android SDK should send empty JSON object if none available as of v4.12.5. + // Native Android SDK added special logic to send Unity friendly values as of v4.15.0. + } + }); } } @@ -1024,7 +1024,8 @@ private class GoogleAdIdReadListener : AndroidJavaProxy { private Action callback; - public GoogleAdIdReadListener(Action pCallback) : base("com.adjust.sdk.OnGoogleAdIdReadListener") + public GoogleAdIdReadListener(Action pCallback) + : base("com.adjust.sdk.OnGoogleAdIdReadListener") { this.callback = pCallback; } @@ -1038,7 +1039,10 @@ public void onGoogleAdIdRead(string adid) return; } - this.callback(adid); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(adid); + }); } } @@ -1046,7 +1050,8 @@ private class VerificationResultListener : AndroidJavaProxy { private Action callback; - public VerificationResultListener(Action pCallback) : base("com.adjust.sdk.OnPurchaseVerificationFinishedListener") + public VerificationResultListener(Action pCallback) + : base("com.adjust.sdk.OnPurchaseVerificationFinishedListener") { this.callback = pCallback; } @@ -1060,18 +1065,30 @@ public void onVerificationFinished(AndroidJavaObject ajoVerificationInfo) return; } - if (ajoVerificationInfo == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustPurchaseVerificationResult purchaseVerificationResult = new AdjustPurchaseVerificationResult(); - purchaseVerificationResult.VerificationStatus = ajoVerificationInfo.Get(AdjustUtils.KeyVerificationStatus); - purchaseVerificationResult.Code = ajoVerificationInfo.Get(AdjustUtils.KeyCode); - purchaseVerificationResult.Message = ajoVerificationInfo.Get(AdjustUtils.KeyMessage); - - this.callback(purchaseVerificationResult); + try + { + if (ajoVerificationInfo == null) + { + callback?.Invoke(null); + return; + } + + AdjustPurchaseVerificationResult purchaseVerificationResult = new AdjustPurchaseVerificationResult + { + VerificationStatus = ajoVerificationInfo.Get(AdjustUtils.KeyVerificationStatus), + Code = ajoVerificationInfo.Get(AdjustUtils.KeyCode), + Message = AdjustUtils.GetValueOrEmptyToNull(ajoVerificationInfo.Get(AdjustUtils.KeyMessage)) + }; + + callback?.Invoke(purchaseVerificationResult); + } + catch (Exception) + { + // Handle potential errors during the verification process + } + }); } } @@ -1079,7 +1096,8 @@ private class DeeplinkResolutionListener : AndroidJavaProxy { private Action callback; - public DeeplinkResolutionListener(Action pCallback) : base("com.adjust.sdk.OnDeeplinkResolvedListener") + public DeeplinkResolutionListener(Action pCallback) + : base("com.adjust.sdk.OnDeeplinkResolvedListener") { this.callback = pCallback; } @@ -1093,7 +1111,10 @@ public void onDeeplinkResolved(string resolvedLink) return; } - this.callback(resolvedLink); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(resolvedLink); + }); } } @@ -1101,7 +1122,8 @@ private class AdidReadListener : AndroidJavaProxy { private Action callback; - public AdidReadListener(Action pCallback) : base("com.adjust.sdk.OnAdidReadListener") + public AdidReadListener(Action pCallback) + : base("com.adjust.sdk.OnAdidReadListener") { this.callback = pCallback; } @@ -1115,7 +1137,10 @@ public void onAdidRead(string adid) return; } - this.callback(adid); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(adid); + }); } } @@ -1123,7 +1148,8 @@ private class AttributionReadListener : AndroidJavaProxy { private Action callback; - public AttributionReadListener(Action pCallback) : base("com.adjust.sdk.OnAttributionReadListener") + public AttributionReadListener(Action pCallback) + : base("com.adjust.sdk.OnAttributionReadListener") { this.callback = pCallback; } @@ -1137,54 +1163,50 @@ public void onAttributionRead(AndroidJavaObject ajoAttribution) return; } - if (ajoAttribution == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - return; - } - - AdjustAttribution adjustAttribution = new AdjustAttribution(); - string trackerName = ajoAttribution.Get(AdjustUtils.KeyTrackerName); - adjustAttribution.TrackerName = trackerName == "" ? null : trackerName; - string trackerToken = ajoAttribution.Get(AdjustUtils.KeyTrackerToken); - adjustAttribution.TrackerToken = trackerToken == "" ? null : trackerToken; - string network = ajoAttribution.Get(AdjustUtils.KeyNetwork); - adjustAttribution.Network = network == "" ? null : network; - string campaign = ajoAttribution.Get(AdjustUtils.KeyCampaign); - adjustAttribution.Campaign = campaign == "" ? null : campaign; - string adgroup = ajoAttribution.Get(AdjustUtils.KeyAdgroup); - adjustAttribution.Adgroup = adgroup == "" ? null : adgroup; - string creative = ajoAttribution.Get(AdjustUtils.KeyCreative); - adjustAttribution.Creative = creative == "" ? null : creative; - string clickLabel = ajoAttribution.Get(AdjustUtils.KeyClickLabel); - adjustAttribution.ClickLabel = clickLabel == "" ? null : clickLabel; - string costType = ajoAttribution.Get(AdjustUtils.KeyCostType); - adjustAttribution.CostType = costType == "" ? null : costType; - using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount)) - { - if (ajoCostAmount == null) + try { - adjustAttribution.CostAmount = null; + if (ajoAttribution == null) + { + callback?.Invoke(null); + return; + } + + AdjustAttribution adjustAttribution = new AdjustAttribution + { + TrackerName = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerName)), + TrackerToken = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerToken)), + Network = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyNetwork)), + Campaign = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCampaign)), + Adgroup = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyAdgroup)), + Creative = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCreative)), + ClickLabel = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyClickLabel)), + CostType = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostType)), + CostCurrency = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostCurrency)), + FbInstallReferrer = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer)) + }; + + using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount)) + { + adjustAttribution.CostAmount = ajoCostAmount != null ? ajoCostAmount.Call("doubleValue") : (double?)null; + } + + string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } + + callback?.Invoke(adjustAttribution); } - else + catch (Exception) { - double costAmount = ajoCostAmount.Call("doubleValue"); - adjustAttribution.CostAmount = costAmount; + // JSON response reading failed. } - } - string costCurrency = ajoAttribution.Get(AdjustUtils.KeyCostCurrency); - adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency; - string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer); - adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer; - string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse); - var jsonResponseNode = JSON.Parse(jsonResponse); - if (jsonResponseNode != null && jsonResponseNode.AsObject != null) - { - adjustAttribution.JsonResponse = new Dictionary(); - AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); - } - - this.callback(adjustAttribution); + }); } } @@ -1192,7 +1214,8 @@ private class AmazonAdIdReadListener : AndroidJavaProxy { private Action callback; - public AmazonAdIdReadListener(Action pCallback) : base("com.adjust.sdk.OnAmazonAdIdReadListener") + public AmazonAdIdReadListener(Action pCallback) + : base("com.adjust.sdk.OnAmazonAdIdReadListener") { this.callback = pCallback; } @@ -1206,7 +1229,10 @@ public void onAmazonAdIdRead(string amazonAdId) return; } - this.callback(amazonAdId); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(amazonAdId); + }); } } @@ -1215,7 +1241,8 @@ private class SdkVersionReadListener : AndroidJavaProxy private Action callback; private string sdkPrefix; - public SdkVersionReadListener(Action pCallback, string sdkPrefix) : base("com.adjust.sdk.OnSdkVersionReadListener") + public SdkVersionReadListener(Action pCallback, string sdkPrefix) + : base("com.adjust.sdk.OnSdkVersionReadListener") { this.callback = pCallback; this.sdkPrefix = sdkPrefix; @@ -1230,7 +1257,10 @@ public void onSdkVersionRead(string sdkVersion) return; } - this.callback(this.sdkPrefix + "@" + sdkVersion); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(this.sdkPrefix + "@" + sdkVersion); + }); } } @@ -1238,7 +1268,8 @@ private class IsEnabledListener : AndroidJavaProxy { private Action callback; - public IsEnabledListener(Action pCallback) : base("com.adjust.sdk.OnIsEnabledListener") + public IsEnabledListener(Action pCallback) + : base("com.adjust.sdk.OnIsEnabledListener") { this.callback = pCallback; } @@ -1252,7 +1283,10 @@ public void onIsEnabledRead(bool isEnabled) return; } - this.callback(isEnabled); + AdjustThreadDispatcher.RunOnMainThread(() => + { + callback?.Invoke(isEnabled); + }); } } @@ -1260,7 +1294,8 @@ private class LastDeeplinkListener : AndroidJavaProxy { private Action callback; - public LastDeeplinkListener(Action pCallback) : base("com.adjust.sdk.OnLastDeeplinkReadListener") + public LastDeeplinkListener(Action pCallback) + : base("com.adjust.sdk.OnLastDeeplinkReadListener") { this.callback = pCallback; } @@ -1274,14 +1309,11 @@ public void onLastDeeplinkRead(AndroidJavaObject ajoLastDeeplink) return; } - if (ajoLastDeeplink == null) + AdjustThreadDispatcher.RunOnMainThread(() => { - this.callback(null); - } - else - { - this.callback(ajoLastDeeplink.Call("toString")); - } + string deeplink = ajoLastDeeplink != null ? ajoLastDeeplink.Call("toString") : null; + callback?.Invoke(deeplink); + }); } } } diff --git a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs new file mode 100644 index 00000000..1b1dd4bd --- /dev/null +++ b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class AdjustThreadDispatcher : MonoBehaviour +{ + private static readonly Queue executionQueue = new Queue(); + private static AdjustThreadDispatcher instance; + + public static void RunOnMainThread(Action action) + { + if (action == null) + { + return; + } + + lock (executionQueue) + { + executionQueue.Enqueue(action); + } + } + + private void Update() + { + while (executionQueue.Count > 0) + { + Action action; + lock (executionQueue) + { + action = executionQueue.Dequeue(); + } + action?.Invoke(); + } + } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] + private static void Initialize() + { + if (instance == null) + { + GameObject obj = new GameObject("AdjustThreadDispatcher"); + instance = obj.AddComponent(); + DontDestroyOnLoad(obj); + } + } +} \ No newline at end of file diff --git a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta new file mode 100644 index 00000000..fe68f179 --- /dev/null +++ b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 068759bba95d0411895637c9165b2f99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Adjust/Scripts/AdjustUtils.cs b/Assets/Adjust/Scripts/AdjustUtils.cs index 0925de4a..6793be98 100644 --- a/Assets/Adjust/Scripts/AdjustUtils.cs +++ b/Assets/Adjust/Scripts/AdjustUtils.cs @@ -350,6 +350,11 @@ public static Dictionary GetSkanUpdateDataDictionary(string skan return skanUpdateDataDictionary; } + public static string GetValueOrEmptyToNull(string value) + { + return string.IsNullOrEmpty(value) ? null : value; + } + #if UNITY_ANDROID public static AndroidJavaObject TestOptionsMap2AndroidJavaObject(Dictionary testOptionsMap, AndroidJavaObject ajoCurrentActivity) { From 9e8e6f6667f2499bc30a18ddf3716bea037185de Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 27 Feb 2025 17:10:42 +0100 Subject: [PATCH 5/7] refac: fire callbacks behind native ios ones inside of the main unity thread --- Assets/Adjust/Scripts/AdjustiOS.cs | 254 +++++++++++++++++++++-------- 1 file changed, 184 insertions(+), 70 deletions(-) diff --git a/Assets/Adjust/Scripts/AdjustiOS.cs b/Assets/Adjust/Scripts/AdjustiOS.cs index 5974ef6e..7c3a366e 100644 --- a/Assets/Adjust/Scripts/AdjustiOS.cs +++ b/Assets/Adjust/Scripts/AdjustiOS.cs @@ -694,192 +694,306 @@ public static void TrackSubsessionEnd(string testingArgument = null) // MonoPInvokeCallback methods as method parameters [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIsEnabledGetter))] - private static void IsEnabledGetterMonoPInvoke(bool isEnabled) { - if (appIsEnabledGetterCallbacks != null) + private static void IsEnabledGetterMonoPInvoke(bool isEnabled) + { + if (appIsEnabledGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appIsEnabledGetterCallbacks) { - callback(isEnabled); + callback?.Invoke(isEnabled); } appIsEnabledGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionGetter))] - private static void AttributionGetterMonoPInvoke(string attribution) { - if (appAttributionGetterCallbacks != null) + private static void AttributionGetterMonoPInvoke(string attribution) + { + if (appAttributionGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appAttributionGetterCallbacks) { - callback(new AdjustAttribution(attribution)); + callback?.Invoke(new AdjustAttribution(attribution)); } appAttributionGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAdidGetter))] - private static void AdidGetterMonoPInvoke(string adid) { - if (appAdidGetterCallbacks != null) + private static void AdidGetterMonoPInvoke(string adid) + { + if (appAdidGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appAdidGetterCallbacks) { - callback(adid); + callback?.Invoke(adid); } appAdidGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfaGetter))] - private static void IdfaGetterMonoPInvoke(string idfa) { - if (appIdfaGetterCallbacks != null) + private static void IdfaGetterMonoPInvoke(string idfa) + { + if (appIdfaGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appIdfaGetterCallbacks) { - callback(idfa); + callback?.Invoke(idfa); } appIdfaGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfvGetter))] - private static void IdfvGetterMonoPInvoke(string idfv) { - if (appIdfvGetterCallbacks != null) + private static void IdfvGetterMonoPInvoke(string idfv) + { + if (appIdfvGetterCallbacks == null) { - foreach (Action callback in appIdfaGetterCallbacks) + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appIdfvGetterCallbacks) { - callback(idfv); + callback?.Invoke(idfv); } appIdfvGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateLastDeeplinkGetter))] - private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink) { - if (appLastDeeplinkGetterCallbacks != null) + private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink) + { + if (appLastDeeplinkGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appLastDeeplinkGetterCallbacks) { - callback(lastDeeplink); + callback?.Invoke(lastDeeplink); } appLastDeeplinkGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSdkVersionGetter))] - private static void SdkVersionGetterMonoPInvoke(string sdkVersion) { - if (appSdkVersionGetterCallbacks != null) + private static void SdkVersionGetterMonoPInvoke(string sdkVersion) + { + if (appSdkVersionGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appSdkVersionGetterCallbacks) { - callback(sdkPrefix + "@" + sdkVersion); + callback?.Invoke(sdkPrefix + "@" + sdkVersion); } appSdkVersionGetterCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttCallback))] - private static void AttCallbackMonoPInvoke(int status) { - if (appAttCallbacks != null) + private static void AttCallbackMonoPInvoke(int status) + { + if (appAttCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => { foreach (Action callback in appAttCallbacks) { - callback(status); + callback?.Invoke(status); } appAttCallbacks.Clear(); - } + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegatePurchaseVerificationCallback))] - private static void PurchaseVerificationCallbackMonoPInvoke(string verificationResult) { - if (appPurchaseVerificationCallback != null) + private static void PurchaseVerificationCallbackMonoPInvoke(string verificationResult) + { + if (appPurchaseVerificationCallback == null) { - appPurchaseVerificationCallback(new AdjustPurchaseVerificationResult(verificationResult)); - appPurchaseVerificationCallback = null; + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appPurchaseVerificationCallback?.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + appPurchaseVerificationCallback = null; + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateVerifyAndTrackCallback))] - private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult) { - if (appVerifyAndTrackCallback != null) + private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult) + { + if (appVerifyAndTrackCallback == null) { - appVerifyAndTrackCallback(new AdjustPurchaseVerificationResult(verificationResult)); - appVerifyAndTrackCallback = null; + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appVerifyAndTrackCallback?.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + appVerifyAndTrackCallback = null; + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateResolvedDeeplinkCallback))] - private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink) { - if (appResolvedDeeplinkCallback != null) + private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink) + { + if (appResolvedDeeplinkCallback == null) { - appResolvedDeeplinkCallback(deeplink); - appResolvedDeeplinkCallback = null; + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appResolvedDeeplinkCallback?.Invoke(deeplink); + appResolvedDeeplinkCallback = null; + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanErrorCallback))] - private static void SkanErrorCallbackMonoPInvoke(string error) { - if (appSkanErrorCallback != null) + private static void SkanErrorCallbackMonoPInvoke(string error) + { + if (appSkanErrorCallback == null) { - appSkanErrorCallback(error); - appSkanErrorCallback = null; + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSkanErrorCallback?.Invoke(error); + appSkanErrorCallback = null; + }); } // MonoPInvokeCallback methods as subscriptions [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionCallback))] - private static void AttributionCallbackMonoPInvoke(string attribution) { - if (appAttributionCallback != null) + private static void AttributionCallbackMonoPInvoke(string attribution) + { + if (appAttributionCallback == null) { - appAttributionCallback(new AdjustAttribution(attribution)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appAttributionCallback(new AdjustAttribution(attribution)); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionSuccessCallback))] - private static void SessionSuccessCallbackMonoPInvoke(string sessionSuccess) { - if (appSessionSuccessCallback != null) + private static void SessionSuccessCallbackMonoPInvoke(string sessionSuccess) + { + if (appSessionSuccessCallback == null) { - appSessionSuccessCallback(new AdjustSessionSuccess(sessionSuccess)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSessionSuccessCallback(new AdjustSessionSuccess(sessionSuccess)); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionFailureCallback))] - private static void SessionFailureCallbackMonoPInvoke(string sessionFailure) { - if (appSessionFailureCallback != null) + private static void SessionFailureCallbackMonoPInvoke(string sessionFailure) + { + if (appSessionFailureCallback == null) { - appSessionFailureCallback(new AdjustSessionFailure(sessionFailure)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSessionFailureCallback(new AdjustSessionFailure(sessionFailure)); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventSuccessCallback))] - private static void EventSuccessCallbackMonoPInvoke(string eventSuccess) { - if (appEventSuccessCallback != null) + private static void EventSuccessCallbackMonoPInvoke(string eventSuccess) + { + if (appEventSuccessCallback == null) { - appEventSuccessCallback(new AdjustEventSuccess(eventSuccess)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appEventSuccessCallback(new AdjustEventSuccess(eventSuccess)); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventFailureCallback))] - private static void EventFailureCallbackMonoPInvoke(string eventFailure) { - if (appEventFailureCallback != null) + private static void EventFailureCallbackMonoPInvoke(string eventFailure) + { + if (appEventFailureCallback == null) { - appEventFailureCallback(new AdjustEventFailure(eventFailure)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appEventFailureCallback(new AdjustEventFailure(eventFailure)); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateDeferredDeeplinkCallback))] - private static void DeferredDeeplinkCallbackMonoPInvoke(string deeplink) { - if (appDeferredDeeplinkCallback != null) + private static void DeferredDeeplinkCallbackMonoPInvoke(string deeplink) + { + if (appDeferredDeeplinkCallback == null) { - appDeferredDeeplinkCallback(deeplink); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appDeferredDeeplinkCallback(deeplink); + }); } [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanUpdatedCallback))] - private static void SkanUpdatedCallbackMonoPInvoke(string skanData) { - if (appSkanUpdatedCallback != null) + private static void SkanUpdatedCallbackMonoPInvoke(string skanData) + { + if (appSkanUpdatedCallback == null) { - appSkanUpdatedCallback(AdjustUtils.GetSkanUpdateDataDictionary(skanData)); + return; } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSkanUpdatedCallback?.Invoke(AdjustUtils.GetSkanUpdateDataDictionary(skanData)); + }); } } #endif From e73b46e2684c0cab71f82e58085df35401986e1f Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 28 Feb 2025 11:01:12 +0100 Subject: [PATCH 6/7] docs: update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73e5c4ea..9672bd96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +### Version 5.1.0 (28th February 2025) +#### Added +- Added `JsonResponse` to `AdjustAttribution` where every key-value pair sent by the backend as part of the attribution response can be found. +- Added the ability to specify the name of custom Android activity which you might be using instead of the default `com.unity3d.player.UnityPlayerActivity` (https://github.com/adjust/unity_sdk/issues/273). + +#### Changed +- Switched to adding `` per specified Android URI scheme instead of adding them all as `` entries to the same intent filter (https://github.com/adjust/unity_sdk/issues/266). +- Moved execution of all the C# callbacks into the main Unity thread (https://github.com/adjust/unity_sdk/issues/277, https://github.com/adjust/unity_sdk/issues/310). + +#### Native SDKs +- [iOS@v5.1.1][ios_sdk_v5.1.1] +- [Android@v5.1.0][android_sdk_v5.1.0] + +--- + ### Version 5.0.7 (4th February 2025) #### Added - Added sending of the additional parameter to improve troubleshooting of `SKAdNetwork` related issues. @@ -1369,6 +1384,7 @@ Kudos to [Ivan](https://github.com/MatkovIvan) and [Evgeny](https://github.com/e [ios_sdk_v5.0.0]: https://github.com/adjust/ios_sdk/tree/v5.0.0 [ios_sdk_v5.0.1]: https://github.com/adjust/ios_sdk/tree/v5.0.1 [ios_sdk_v5.1.0]: https://github.com/adjust/ios_sdk/tree/v5.1.0 +[ios_sdk_v5.1.1]: https://github.com/adjust/ios_sdk/tree/v5.1.1 [android_sdk_v3.5.0]: https://github.com/adjust/android_sdk/tree/v3.5.0 [android_sdk_v4.1.0]: https://github.com/adjust/android_sdk/tree/v4.1.0 From e23710b7d1c7c6e04ac7fc9c12b94b4b9e9e15a7 Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 28 Feb 2025 12:11:49 +0100 Subject: [PATCH 7/7] refac: remove usage of null propagating operator --- Assets/Adjust/Scripts/AdjustAndroid.cs | 90 +++++++++++++++---- .../Adjust/Scripts/AdjustThreadDispatcher.cs | 5 +- Assets/Adjust/Scripts/AdjustiOS.cs | 73 +++++++++++---- 3 files changed, 132 insertions(+), 36 deletions(-) diff --git a/Assets/Adjust/Scripts/AdjustAndroid.cs b/Assets/Adjust/Scripts/AdjustAndroid.cs index 434331e9..b4d6d6cf 100644 --- a/Assets/Adjust/Scripts/AdjustAndroid.cs +++ b/Assets/Adjust/Scripts/AdjustAndroid.cs @@ -742,7 +742,10 @@ public void onAttributionChanged(AndroidJavaObject ajoAttribution) { if (ajoAttribution == null) { - callback?.Invoke(null); + if (callback != null) + { + callback.Invoke(null); + } return; } @@ -773,7 +776,10 @@ public void onAttributionChanged(AndroidJavaObject ajoAttribution) AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); } - callback?.Invoke(adjustAttribution); + if (callback != null) + { + callback.Invoke(adjustAttribution); + } } catch (Exception) { @@ -805,7 +811,10 @@ public bool launchReceivedDeeplink(AndroidJavaObject deeplink) AdjustThreadDispatcher.RunOnMainThread(() => { string strDeeplink = deeplink != null ? deeplink.Call("toString") : null; - callback?.Invoke(strDeeplink); + if (callback != null) + { + callback.Invoke(strDeeplink); + } }); return isDeferredDeeplinkOpeningEnabled; @@ -852,7 +861,10 @@ public void onEventTrackingSucceeded(AndroidJavaObject eventSuccessData) } } - callback?.Invoke(adjustEventSuccess); + if (callback != null) + { + callback.Invoke(adjustEventSuccess); + } } catch (Exception) { @@ -905,7 +917,10 @@ public void onEventTrackingFailed(AndroidJavaObject eventFailureData) } } - callback?.Invoke(adjustEventFailure); + if (callback != null) + { + callback.Invoke(adjustEventFailure); + } } catch (Exception) { @@ -956,7 +971,10 @@ public void onSessionTrackingSucceeded(AndroidJavaObject sessionSuccessData) } } - callback?.Invoke(adjustSessionSuccess); + if (callback != null) + { + callback.Invoke(adjustSessionSuccess); + } } catch (Exception) { @@ -1008,7 +1026,10 @@ public void onSessionTrackingFailed(AndroidJavaObject sessionFailureData) } } - callback?.Invoke(adjustSessionFailure); + if (callback != null) + { + callback.Invoke(adjustSessionFailure); + } } catch (Exception) { @@ -1041,7 +1062,10 @@ public void onGoogleAdIdRead(string adid) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(adid); + if (callback != null) + { + callback.Invoke(adid); + } }); } } @@ -1071,7 +1095,10 @@ public void onVerificationFinished(AndroidJavaObject ajoVerificationInfo) { if (ajoVerificationInfo == null) { - callback?.Invoke(null); + if (callback != null) + { + callback.Invoke(null); + } return; } @@ -1082,7 +1109,10 @@ public void onVerificationFinished(AndroidJavaObject ajoVerificationInfo) Message = AdjustUtils.GetValueOrEmptyToNull(ajoVerificationInfo.Get(AdjustUtils.KeyMessage)) }; - callback?.Invoke(purchaseVerificationResult); + if (callback != null) + { + callback.Invoke(purchaseVerificationResult); + } } catch (Exception) { @@ -1113,7 +1143,10 @@ public void onDeeplinkResolved(string resolvedLink) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(resolvedLink); + if (callback != null) + { + callback.Invoke(resolvedLink); + } }); } } @@ -1139,7 +1172,10 @@ public void onAdidRead(string adid) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(adid); + if (callback != null) + { + callback.Invoke(adid); + } }); } } @@ -1169,7 +1205,10 @@ public void onAttributionRead(AndroidJavaObject ajoAttribution) { if (ajoAttribution == null) { - callback?.Invoke(null); + if (callback != null) + { + callback.Invoke(null); + } return; } @@ -1200,7 +1239,10 @@ public void onAttributionRead(AndroidJavaObject ajoAttribution) AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); } - callback?.Invoke(adjustAttribution); + if (callback != null) + { + callback.Invoke(adjustAttribution); + } } catch (Exception) { @@ -1231,7 +1273,10 @@ public void onAmazonAdIdRead(string amazonAdId) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(amazonAdId); + if (callback != null) + { + callback.Invoke(amazonAdId); + } }); } } @@ -1259,7 +1304,10 @@ public void onSdkVersionRead(string sdkVersion) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(this.sdkPrefix + "@" + sdkVersion); + if (callback != null) + { + callback.Invoke(this.sdkPrefix + "@" + sdkVersion); + } }); } } @@ -1285,7 +1333,10 @@ public void onIsEnabledRead(bool isEnabled) AdjustThreadDispatcher.RunOnMainThread(() => { - callback?.Invoke(isEnabled); + if (callback != null) + { + callback.Invoke(isEnabled); + } }); } } @@ -1312,7 +1363,10 @@ public void onLastDeeplinkRead(AndroidJavaObject ajoLastDeeplink) AdjustThreadDispatcher.RunOnMainThread(() => { string deeplink = ajoLastDeeplink != null ? ajoLastDeeplink.Call("toString") : null; - callback?.Invoke(deeplink); + if (callback != null) + { + callback.Invoke(deeplink); + } }); } } diff --git a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs index 1b1dd4bd..26157f36 100644 --- a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs +++ b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs @@ -29,7 +29,10 @@ private void Update() { action = executionQueue.Dequeue(); } - action?.Invoke(); + if (action != null) + { + action.Invoke(); + } } } diff --git a/Assets/Adjust/Scripts/AdjustiOS.cs b/Assets/Adjust/Scripts/AdjustiOS.cs index 7c3a366e..1b4c398c 100644 --- a/Assets/Adjust/Scripts/AdjustiOS.cs +++ b/Assets/Adjust/Scripts/AdjustiOS.cs @@ -705,7 +705,10 @@ private static void IsEnabledGetterMonoPInvoke(bool isEnabled) { foreach (Action callback in appIsEnabledGetterCallbacks) { - callback?.Invoke(isEnabled); + if (callback != null) + { + callback.Invoke(isEnabled); + } } appIsEnabledGetterCallbacks.Clear(); }); @@ -723,7 +726,10 @@ private static void AttributionGetterMonoPInvoke(string attribution) { foreach (Action callback in appAttributionGetterCallbacks) { - callback?.Invoke(new AdjustAttribution(attribution)); + if (callback != null) + { + callback.Invoke(new AdjustAttribution(attribution)); + } } appAttributionGetterCallbacks.Clear(); }); @@ -741,7 +747,10 @@ private static void AdidGetterMonoPInvoke(string adid) { foreach (Action callback in appAdidGetterCallbacks) { - callback?.Invoke(adid); + if (callback != null) + { + callback.Invoke(adid); + } } appAdidGetterCallbacks.Clear(); }); @@ -759,7 +768,10 @@ private static void IdfaGetterMonoPInvoke(string idfa) { foreach (Action callback in appIdfaGetterCallbacks) { - callback?.Invoke(idfa); + if (callback != null) + { + callback.Invoke(idfa); + } } appIdfaGetterCallbacks.Clear(); }); @@ -777,7 +789,10 @@ private static void IdfvGetterMonoPInvoke(string idfv) { foreach (Action callback in appIdfvGetterCallbacks) { - callback?.Invoke(idfv); + if (callback != null) + { + callback.Invoke(idfv); + } } appIdfvGetterCallbacks.Clear(); }); @@ -795,7 +810,10 @@ private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink) { foreach (Action callback in appLastDeeplinkGetterCallbacks) { - callback?.Invoke(lastDeeplink); + if (callback != null) + { + callback.Invoke(lastDeeplink); + } } appLastDeeplinkGetterCallbacks.Clear(); }); @@ -813,7 +831,10 @@ private static void SdkVersionGetterMonoPInvoke(string sdkVersion) { foreach (Action callback in appSdkVersionGetterCallbacks) { - callback?.Invoke(sdkPrefix + "@" + sdkVersion); + if (callback != null) + { + callback.Invoke(sdkPrefix + "@" + sdkVersion); + } } appSdkVersionGetterCallbacks.Clear(); }); @@ -831,7 +852,10 @@ private static void AttCallbackMonoPInvoke(int status) { foreach (Action callback in appAttCallbacks) { - callback?.Invoke(status); + if (callback != null) + { + callback.Invoke(status); + } } appAttCallbacks.Clear(); }); @@ -847,8 +871,11 @@ private static void PurchaseVerificationCallbackMonoPInvoke(string verificationR AdjustThreadDispatcher.RunOnMainThread(() => { - appPurchaseVerificationCallback?.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); - appPurchaseVerificationCallback = null; + if (appPurchaseVerificationCallback != null) + { + appPurchaseVerificationCallback.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + appPurchaseVerificationCallback = null; + } }); } @@ -862,8 +889,11 @@ private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult) AdjustThreadDispatcher.RunOnMainThread(() => { - appVerifyAndTrackCallback?.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); - appVerifyAndTrackCallback = null; + if (appVerifyAndTrackCallback != null) + { + appVerifyAndTrackCallback.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + appVerifyAndTrackCallback = null; + } }); } @@ -877,8 +907,11 @@ private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink) AdjustThreadDispatcher.RunOnMainThread(() => { - appResolvedDeeplinkCallback?.Invoke(deeplink); - appResolvedDeeplinkCallback = null; + if (appResolvedDeeplinkCallback != null) + { + appResolvedDeeplinkCallback.Invoke(deeplink); + appResolvedDeeplinkCallback = null; + } }); } @@ -892,8 +925,11 @@ private static void SkanErrorCallbackMonoPInvoke(string error) AdjustThreadDispatcher.RunOnMainThread(() => { - appSkanErrorCallback?.Invoke(error); - appSkanErrorCallback = null; + if (appSkanErrorCallback != null) + { + appSkanErrorCallback.Invoke(error); + appSkanErrorCallback = null; + } }); } @@ -992,7 +1028,10 @@ private static void SkanUpdatedCallbackMonoPInvoke(string skanData) AdjustThreadDispatcher.RunOnMainThread(() => { - appSkanUpdatedCallback?.Invoke(AdjustUtils.GetSkanUpdateDataDictionary(skanData)); + if (appSkanUpdatedCallback != null) + { + appSkanUpdatedCallback.Invoke(AdjustUtils.GetSkanUpdateDataDictionary(skanData)); + } }); } }