diff --git a/Assets/Plugins/Android/AndroidManifest.xml b/Assets/Plugins/Android/AndroidManifest.xml new file mode 100644 index 0000000..83b372c --- /dev/null +++ b/Assets/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + diff --git a/Assets/Plugins/Android/AndroidManifest.xml.meta b/Assets/Plugins/Android/AndroidManifest.xml.meta new file mode 100644 index 0000000..1784b30 --- /dev/null +++ b/Assets/Plugins/Android/AndroidManifest.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 147d3bb1ca0da2b448667eec3a82bb26 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/GameScene.unity b/Assets/Scenes/GameScene.unity index cfdaf42..61d4ecb 100644 --- a/Assets/Scenes/GameScene.unity +++ b/Assets/Scenes/GameScene.unity @@ -833,6 +833,8 @@ GameObject: - component: {fileID: 2137923634} - component: {fileID: 2137923635} - component: {fileID: 2137923636} + - component: {fileID: 2137923637} + - component: {fileID: 2137923638} m_Layer: 0 m_Name: '[SDKManager]' m_TagString: Untagged @@ -880,6 +882,30 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: a550f9677d329f940876ee3d139f8289, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &2137923637 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137923633} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5019ae7cf0c6d3d4c89b8921e4beab15, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!114 &2137923638 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137923633} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f925ec84be5d37d4ba2ee62fc7ffb464, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1660057539 &9223372036854775807 SceneRoots: m_ObjectHideFlags: 0 diff --git a/Assets/Script/SDKManager/AdjustManager.meta b/Assets/Script/SDKManager/AdjustManager.meta new file mode 100644 index 0000000..1e6df9a --- /dev/null +++ b/Assets/Script/SDKManager/AdjustManager.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7612045c73134949a914f701ff109389 +timeCreated: 1756549078 \ No newline at end of file diff --git a/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs b/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs new file mode 100644 index 0000000..cab0086 --- /dev/null +++ b/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using AdjustSdk; +using Unity.VisualScripting; +using UnityEngine; + +public class AdjustManager : MonoBehaviour +{ + private string appToken = "你的App Token"; // 替换为你的实际App Token + private AdjustEnvironment environment = AdjustEnvironment.Sandbox; // 测试用Sandbox,发布用Production + + + + public void Awake() + { + AdjustConfig config = new AdjustConfig(appToken, environment); + + // 设置归因变更回调函数 + config.AttributionChangedDelegate = AttributionChangedDelegate; + + // (可选)设置其他配置,如日志级别 + config.LogLevel = AdjustLogLevel.Verbose; + + // 初始化Adjust SDK + Adjust.InitSdk(config); + } + + /// + /// 归因信息 + /// + /// + private void AttributionChangedDelegate(AdjustAttribution attribution) + { + Debug.Log("Attribution changed"); + AdjustNetwork.SetNetwork(attribution.Network); + } + + + +} diff --git a/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs.meta b/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs.meta new file mode 100644 index 0000000..6e69b71 --- /dev/null +++ b/Assets/Script/SDKManager/AdjustManager/AdjustManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f925ec84be5d37d4ba2ee62fc7ffb464 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs b/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs new file mode 100644 index 0000000..95a6707 --- /dev/null +++ b/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs @@ -0,0 +1,48 @@ +using UnityEngine; + +public static class AdjustNetwork +{ + private const string KEY_USER_NETWORK = "KEY_USER_NETWORK"; + + public static void SetNetwork(string network) + { + if (string.IsNullOrEmpty(network)) + { + return; + } + + if (network.ToLower().Replace(" ", "") == "Organic".ToLower().Replace(" ", "")) + { + return; + } + + string curNetwork = PlayerPrefs.GetString(KEY_USER_NETWORK, ""); + if (string.IsNullOrEmpty(curNetwork)) + { + PlayerPrefs.SetString(KEY_USER_NETWORK, network); + PlayerPrefs.Save(); + } + } + + /// + /// 是否是自然量用户 + /// 默认买量用户 + /// + /// + public static bool InOrganic() + { + string network = PlayerPrefs.GetString(KEY_USER_NETWORK, ""); + if (string.IsNullOrEmpty(network)) + { + return true; + } + + //去除大小写和空格之后再对比 + if (network.ToLower().Replace(" ", "") == "Untrusted Devices".ToLower().Replace(" ", "") || network.ToLower().Replace(" ", "") == "Google Organic Search".ToLower().Replace(" ", "")) + { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs.meta b/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs.meta new file mode 100644 index 0000000..c27c93a --- /dev/null +++ b/Assets/Script/SDKManager/AdjustManager/AdjustNetwork.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9292edbac2294418af38b6f95a185127 +timeCreated: 1756550070 \ No newline at end of file diff --git a/Assets/rd3/Adjust.meta b/Assets/rd3/Adjust.meta new file mode 100644 index 0000000..51f40ca --- /dev/null +++ b/Assets/rd3/Adjust.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b7941c48bfc3e44aea0300ced4d12b47 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native.meta b/Assets/rd3/Adjust/Native.meta new file mode 100644 index 0000000..de5dab9 --- /dev/null +++ b/Assets/rd3/Adjust/Native.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 48d8fb88fe43540d48dd33b18a151507 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/Android.meta b/Assets/rd3/Adjust/Native/Android.meta new file mode 100644 index 0000000..bc71354 --- /dev/null +++ b/Assets/rd3/Adjust/Native/Android.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 99903aebed26d46a2aa9f9aa2b17a339 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml b/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml new file mode 100644 index 0000000..d0471ae --- /dev/null +++ b/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml.meta b/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml.meta new file mode 100644 index 0000000..58af3b4 --- /dev/null +++ b/Assets/rd3/Adjust/Native/Android/AdjustAndroidManifest.xml.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: a13ef442648c346a79f9ff24875c037a +TextScriptImporter: + userData: diff --git a/Assets/rd3/Adjust/Native/Editor.meta b/Assets/rd3/Adjust/Native/Editor.meta new file mode 100644 index 0000000..c29b1d4 --- /dev/null +++ b/Assets/rd3/Adjust/Native/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c11a8a7fc7bfd4937bac95b31f1fb273 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/Editor/Dependencies.xml b/Assets/rd3/Adjust/Native/Editor/Dependencies.xml new file mode 100644 index 0000000..941e5b9 --- /dev/null +++ b/Assets/rd3/Adjust/Native/Editor/Dependencies.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Assets/rd3/Adjust/Native/Editor/Dependencies.xml.meta b/Assets/rd3/Adjust/Native/Editor/Dependencies.xml.meta new file mode 100644 index 0000000..1574ab1 --- /dev/null +++ b/Assets/rd3/Adjust/Native/Editor/Dependencies.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d4241857b233d46ee874c8f80bb65fdb +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS.meta b/Assets/rd3/Adjust/Native/iOS.meta new file mode 100644 index 0000000..9d5773a --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c8400ff077d6c4583b0f85a46cd1d50b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h new file mode 100644 index 0000000..d845be0 --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h @@ -0,0 +1,37 @@ +// +// AdjustUnity.h +// Adjust SDK +// +// Created by Pedro Silva (@nonelse) on 27th March 2014. +// Copyright © 2012-2018 Adjust GmbH. All rights reserved. +// + +/** + * @brief The main interface to Adjust Unity bridge. + */ +@interface AdjustUnity : NSObject + +// app callbacks as method parameters +typedef void (*AdjustDelegateIsEnabledGetter)(bool isEnabled); +typedef void (*AdjustDelegateAttributionGetter)(const char* attribution); +typedef void (*AdjustDelegateAdidGetter)(const char* adid); +typedef void (*AdjustDelegateIdfaGetter)(const char* idfa); +typedef void (*AdjustDelegateIdfvGetter)(const char* idfv); +typedef void (*AdjustDelegateLastDeeplinkGetter)(const char* lastDeeplink); +typedef void (*AdjustDelegateSdkVersionGetter)(const char* sdkVersion); +typedef void (*AdjustDelegateAttCallback)(int status); +typedef void (*AdjustDelegatePurchaseVerificationCallback)(const char* verificationResult, int callbackId); +typedef void (*AdjustDelegateVerifyAndTrackCallback)(const char* verificationResult, int callbackId); +typedef void (*AdjustDelegateResolvedDeeplinkCallback)(const char* deeplink); +typedef void (*AdjustDelegateSkanErrorCallback)(const char* error); + +// app callbacks as subscriptions +typedef void (*AdjustDelegateAttributionCallback)(const char* attribution); +typedef void (*AdjustDelegateSessionSuccessCallback)(const char* sessionSuccess); +typedef void (*AdjustDelegateSessionFailureCallback)(const char* sessionFailure); +typedef void (*AdjustDelegateEventSuccessCallback)(const char* eventSuccess); +typedef void (*AdjustDelegateEventFailureCallback)(const char* eventFailure); +typedef void (*AdjustDelegateDeferredDeeplinkCallback)(const char* deeplink); +typedef void (*AdjustDelegateSkanUpdatedCallback)(const char* skanData); + +@end diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h.meta new file mode 100644 index 0000000..0d8a566 --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.h.meta @@ -0,0 +1,110 @@ +fileFormatVersion: 2 +guid: 9ffff8839c6ab418b983add4c597fb87 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm new file mode 100644 index 0000000..841327a --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm @@ -0,0 +1,929 @@ +// +// AdjustUnity.mm +// Adjust SDK +// +// Created by Pedro Silva (@nonelse) on 27th March 2014. +// Copyright © 2012-2018 Adjust GmbH. All rights reserved. +// + +#import +#import "AdjustUnity.h" +#import "AdjustUnityDelegate.h" +#import "AdjustUnityAppDelegate.h" + +@implementation AdjustUnity + +#pragma mark - Object lifecycle methods + ++ (void)load { + // swizzle AppDelegate on the load + // it should be done as early as possible + [AdjustUnityAppDelegate swizzleAppDelegateCallbacks]; +} + +@end + +#pragma mark - Helper C methods + +// method for converting JSON stirng parameters into NSArray object +NSArray* convertArrayParameters(const char* cStringJsonArrayParameters) { + if (cStringJsonArrayParameters == NULL) { + return nil; + } + + NSError *error = nil; + NSArray *arrayParameters = nil; + NSString *stringJsonArrayParameters = [NSString stringWithUTF8String:cStringJsonArrayParameters]; + + if (stringJsonArrayParameters != nil) { + NSData *dataJson = [stringJsonArrayParameters dataUsingEncoding:NSUTF8StringEncoding]; + arrayParameters = [NSJSONSerialization JSONObjectWithData:dataJson options:0 error:&error]; + } + if (error != nil) { + NSString *errorMessage = @"Failed to parse json parameters!"; + NSLog(@"%@", errorMessage); + } + + return arrayParameters; +} + +BOOL isStringValid(const char* cString) { + if (cString == NULL) { + return false; + } + + NSString *objcString = [NSString stringWithUTF8String:cString]; + if (objcString == nil) { + return false; + } + if ([objcString isEqualToString:@"ADJ_INVALID"]) { + return false; + } + + return true; +} + +void addValueOrEmpty(NSMutableDictionary *dictionary, NSString *key, NSObject *value) { + if (nil != value) { + if ([value isKindOfClass:[NSString class]]) { + [dictionary setObject:[NSString stringWithFormat:@"%@", value] forKey:key]; + } else if ([value isKindOfClass:[NSNumber class]]) { + [dictionary setObject:[NSString stringWithFormat:@"%@", [((NSNumber *)value) stringValue]] forKey:key]; + } else { + [dictionary setObject:@"" forKey:key]; + } + } else { + [dictionary setObject:@"" forKey:key]; + } +} + +#pragma mark - Publicly available C methods + +extern "C" +{ + void _AdjustInitSdk( + const char* appToken, + const char* environment, + const char* sdkPrefix, + const char* defaultTracker, + const char* externalDeviceId, + const char* jsonUrlStrategyDomains, + const char* storeName, + const char* storeAppId, + int allowSuppressLogLevel, + int logLevel, + int attConsentWaitingInterval, + int eventDeduplicationIdsMaxSize, + int shouldUseSubdomains, + int isCoppaComplianceEnabled, + int isDataResidency, + int isSendingInBackgroundEnabled, + int isAdServicesEnabled, + int isIdfaReadingEnabled, + int isIdfvReadingEnabled, + int isSkanAttributionEnabled, + int isLinkMeEnabled, + int isCostDataInAttributionEnabled, + int isDeviceIdsReadingOnceEnabled, + int isAppTrackingTransparencyUsageEnabled, + int isFirstSessionDelayEnabled, + int isDeferredDeeplinkOpeningEnabled, + AdjustDelegateAttributionCallback attributionCallback, + AdjustDelegateEventSuccessCallback eventSuccessCallback, + AdjustDelegateEventFailureCallback eventFailureCallback, + AdjustDelegateSessionSuccessCallback sessionSuccessCallback, + AdjustDelegateSessionFailureCallback sessionFailureCallback, + AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback, + AdjustDelegateSkanUpdatedCallback skanUpdatedCallback) { + NSString *strAppToken = isStringValid(appToken) == true ? [NSString stringWithUTF8String:appToken] : nil; + NSString *strEnvironment = isStringValid(environment) == true ? [NSString stringWithUTF8String:environment] : nil; + NSString *strSdkPrefix = isStringValid(sdkPrefix) == true ? [NSString stringWithUTF8String:sdkPrefix] : nil; + NSString *strDefaultTracker = isStringValid(defaultTracker) == true ? [NSString stringWithUTF8String:defaultTracker] : nil; + NSString *strExternalDeviceId = isStringValid(externalDeviceId) == true ? [NSString stringWithUTF8String:externalDeviceId] : nil; + NSString *strStoreName = isStringValid(storeName) == true ? [NSString stringWithUTF8String:storeName] : nil; + NSString *strStoreAppId = isStringValid(storeAppId) == true ? [NSString stringWithUTF8String:storeAppId] : nil; + + ADJConfig *adjustConfig; + + if (allowSuppressLogLevel != -1) { + adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken + environment:strEnvironment + suppressLogLevel:(BOOL)allowSuppressLogLevel]; + } else { + adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken + environment:strEnvironment]; + } + + // set SDK prefix + [adjustConfig setSdkPrefix:strSdkPrefix]; + + // check if user has selected to implement any of the callbacks + if (attributionCallback != nil || + sessionSuccessCallback != nil || + sessionFailureCallback != nil || + eventSuccessCallback != nil || + eventFailureCallback != nil || + deferredDeeplinkCallback != nil || + skanUpdatedCallback != nil) { + [adjustConfig setDelegate: + [AdjustUnityDelegate getInstanceWithAttributionCallback:attributionCallback + eventSuccessCallback:eventSuccessCallback + eventFailureCallback:eventFailureCallback + sessionSuccessCallback:sessionSuccessCallback + sessionFailureCallback:sessionFailureCallback + deferredDeeplinkCallback:deferredDeeplinkCallback + skanUpdatedCallback:skanUpdatedCallback + shouldLaunchDeferredDeeplink:isDeferredDeeplinkOpeningEnabled]]; + } + + // log level + if (logLevel != -1) { + [adjustConfig setLogLevel:(ADJLogLevel)logLevel]; + } + + // COPPA compliance. + if (isCoppaComplianceEnabled != -1) { + if ((BOOL)isCoppaComplianceEnabled == YES) { + [adjustConfig enableCoppaCompliance]; + } + } + + // Send in background. + if (isSendingInBackgroundEnabled != -1) { + if ((BOOL)isSendingInBackgroundEnabled == YES) { + [adjustConfig enableSendingInBackground]; + } + } + + // AdServices.framework handling + if (isAdServicesEnabled != -1) { + if ((BOOL)isAdServicesEnabled == NO) { + [adjustConfig disableAdServices]; + } + } + + // SKAN attribution + if (isSkanAttributionEnabled != -1) { + if ((BOOL)isSkanAttributionEnabled == NO) { + [adjustConfig disableSkanAttribution]; + } + } + + // IDFA reading + if (isIdfaReadingEnabled != -1) { + if ((BOOL)isIdfaReadingEnabled == NO) { + [adjustConfig disableIdfaReading]; + } + } + + // IDFV reading + if (isIdfvReadingEnabled != -1) { + if ((BOOL)isIdfvReadingEnabled == NO) { + [adjustConfig disableIdfvReading]; + } + } + + // LinkMe + if (isLinkMeEnabled != -1) { + if ((BOOL)isLinkMeEnabled == YES) { + [adjustConfig enableLinkMe]; + } + } + + // ATT dialog delay + if (attConsentWaitingInterval != -1) { + [adjustConfig setAttConsentWaitingInterval:attConsentWaitingInterval]; + } + + // disable AppTrackingTransparency.framework interaction + if (isAppTrackingTransparencyUsageEnabled != -1) { + if ((BOOL)isAppTrackingTransparencyUsageEnabled == NO) { + [adjustConfig disableAppTrackingTransparencyUsage]; + } + } + + // first session delay + if (isFirstSessionDelayEnabled != -1) { + if ((BOOL)isFirstSessionDelayEnabled == YES) { + [adjustConfig enableFirstSessionDelay]; + } + } + + // deduplication IDs max number + if (eventDeduplicationIdsMaxSize != -1) { + [adjustConfig setEventDeduplicationIdsMaxSize:eventDeduplicationIdsMaxSize]; + } + + // cost data in attribution callback + if (isCostDataInAttributionEnabled != -1) { + if ((BOOL)isCostDataInAttributionEnabled == YES) { + [adjustConfig enableCostDataInAttribution]; + } + } + + // read device info only once + if (isDeviceIdsReadingOnceEnabled != -1) { + if ((BOOL)isDeviceIdsReadingOnceEnabled == YES) { + [adjustConfig enableDeviceIdsReadingOnce]; + } + } + + // default tracker + if (strDefaultTracker != nil) { + [adjustConfig setDefaultTracker:strDefaultTracker]; + } + + // external device identifier + if (strExternalDeviceId != nil) { + [adjustConfig setExternalDeviceId:strExternalDeviceId]; + } + + // URL strategy + if (shouldUseSubdomains != -1 && isDataResidency != -1) { + NSArray *urlStrategyDomains = convertArrayParameters(jsonUrlStrategyDomains); + if (urlStrategyDomains != nil) { + [adjustConfig setUrlStrategy:urlStrategyDomains + useSubdomains:(BOOL)shouldUseSubdomains + isDataResidency:(BOOL)isDataResidency]; + } + } + + // custom store + if (strStoreName != nil) { + ADJStoreInfo *storeInfo = [[ADJStoreInfo alloc] initWithStoreName:strStoreName]; + if (strStoreAppId != nil) { + [storeInfo setStoreAppId:strStoreAppId]; + } + [adjustConfig setStoreInfo:storeInfo]; + } + + // initialize the SDK + [Adjust initSdk:adjustConfig]; + } + + void _AdjustTrackEvent(const char* eventToken, + double revenue, + const char* currency, + const char* productId, + const char* transactionId, + const char* callbackId, + const char* deduplicationId, + const char* jsonCallbackParameters, + const char* jsonPartnerParameters) { + NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil; + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken]; + + // revenue and currency + if (revenue != -1 && currency != NULL) { + NSString *stringCurrency = [NSString stringWithUTF8String:currency]; + [event setRevenue:revenue currency:stringCurrency]; + } + + // callback parameters + NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); + if (arrayCallbackParameters != nil) { + NSUInteger count = [arrayCallbackParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayCallbackParameters[i++]; + NSString *value = arrayCallbackParameters[i++]; + [event addCallbackParameter:key value:value]; + } + } + + // partner parameters + NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); + if (arrayPartnerParameters != nil) { + NSUInteger count = [arrayPartnerParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayPartnerParameters[i++]; + NSString *value = arrayPartnerParameters[i++]; + [event addPartnerParameter:key value:value]; + } + } + + // transaction ID + if (transactionId != NULL) { + NSString *strTransactionId = [NSString stringWithUTF8String:transactionId]; + [event setTransactionId:strTransactionId]; + } + + // product ID + if (productId != NULL) { + NSString *strProductId = [NSString stringWithUTF8String:productId]; + [event setProductId:strProductId]; + } + + // callback ID + if (callbackId != NULL) { + NSString *strCallbackId = [NSString stringWithUTF8String:callbackId]; + [event setCallbackId:strCallbackId]; + } + + // deduplication ID + if (deduplicationId != NULL) { + NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId]; + [event setDeduplicationId:strDeduplicationId]; + } + + // track event + [Adjust trackEvent:event]; + } + + void _AdjustTrackSubsessionStart() { + [Adjust trackSubsessionStart]; + } + + void _AdjustTrackSubsessionEnd() { + [Adjust trackSubsessionEnd]; + } + + void _AdjustEnable() { + [Adjust enable]; + } + + void _AdjustDisable() { + [Adjust disable]; + } + + void _AdjustSwitchToOfflineMode() { + [Adjust switchToOfflineMode]; + } + + void _AdjustSwitchBackToOnlineMode() { + [Adjust switchBackToOnlineMode]; + } + + void _AdjustSetPushToken(const char* pushToken) { + if (pushToken != NULL) { + NSString *strPushToken = [NSString stringWithUTF8String:pushToken]; + [Adjust setPushTokenAsString:strPushToken]; + } + } + + void _AdjustProcessDeeplink(const char* deeplink, const char* referrer) { + if (deeplink != NULL) { + NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; + NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; + ADJDeeplink *adjustDeeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; + + if (referrer != NULL) { + NSString *strReferrer = [NSString stringWithUTF8String:referrer]; + NSURL *urlReferrer = [NSURL URLWithString:strReferrer]; + [adjustDeeplink setReferrer:urlReferrer]; + } + [Adjust processDeeplink:adjustDeeplink]; + } + } + + void _AdjustIsEnabled(AdjustDelegateIsEnabledGetter callback) { + [Adjust isEnabledWithCompletionHandler:^(BOOL isEnabled) { + callback(isEnabled); + }]; + } + + void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback) { + [Adjust attributionWithCompletionHandler:^(ADJAttribution * _Nullable attribution) { + // TODO: nil checks + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + addValueOrEmpty(dictionary, @"trackerToken", attribution.trackerToken); + addValueOrEmpty(dictionary, @"trackerName", attribution.trackerName); + addValueOrEmpty(dictionary, @"network", attribution.network); + addValueOrEmpty(dictionary, @"campaign", attribution.campaign); + addValueOrEmpty(dictionary, @"creative", attribution.creative); + addValueOrEmpty(dictionary, @"adgroup", attribution.adgroup); + addValueOrEmpty(dictionary, @"clickLabel", attribution.clickLabel); + addValueOrEmpty(dictionary, @"costType", attribution.costType); + addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount); + addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency); + if (attribution.jsonResponse != nil) { + 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]; + NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes] + length:[dataAttribution length] + encoding:NSUTF8StringEncoding]; + const char* attributionCString = [stringAttribution UTF8String]; + callback(attributionCString); + }]; + } + + void _AdjustGetAdid(AdjustDelegateAdidGetter callback) { + [Adjust adidWithCompletionHandler:^(NSString * _Nullable adid) { + // TODO: nil checks + callback([adid UTF8String]); + }]; + } + + void _AdjustGetIdfa(AdjustDelegateIdfaGetter callback) { + [Adjust idfaWithCompletionHandler:^(NSString * _Nullable idfa) { + // TODO: nil checks + callback([idfa UTF8String]); + }]; + } + + void _AdjustGetIdfv(AdjustDelegateIdfvGetter callback) { + [Adjust idfvWithCompletionHandler:^(NSString * _Nullable idfv) { + // TODO: nil checks + callback([idfv UTF8String]); + }]; + } + + void _AdjustGetLastDeeplink(AdjustDelegateLastDeeplinkGetter callback) { + [Adjust lastDeeplinkWithCompletionHandler:^(NSURL * _Nullable lastDeeplink) { + // TODO: nil checks + NSString *strLastDeeplink = [lastDeeplink absoluteString]; + callback([strLastDeeplink UTF8String]); + }]; + } + + void _AdjustGetSdkVersion(AdjustDelegateSdkVersionGetter callback) { + [Adjust sdkVersionWithCompletionHandler:^(NSString * _Nullable sdkVersion) { + // TODO: nil checks + callback([sdkVersion UTF8String]); + }]; + } + + void _AdjustGdprForgetMe() { + [Adjust gdprForgetMe]; + } + + void _AdjustAddGlobalPartnerParameter(const char* key, const char* value) { + if (key != NULL && value != NULL) { + NSString *strKey = [NSString stringWithUTF8String:key]; + NSString *strValue = [NSString stringWithUTF8String:value]; + [Adjust addGlobalPartnerParameter:strValue forKey:strKey]; + } + } + + void _AdjustAddGlobalCallbackParameter(const char* key, const char* value) { + if (key != NULL && value != NULL) { + NSString *strKey = [NSString stringWithUTF8String:key]; + NSString *strValue = [NSString stringWithUTF8String:value]; + [Adjust addGlobalCallbackParameter:strValue forKey:strKey]; + } + } + + void _AdjustRemoveGlobalPartnerParameter(const char* key) { + if (key != NULL) { + NSString *strKey = [NSString stringWithUTF8String:key]; + [Adjust removeGlobalPartnerParameterForKey:strKey]; + } + } + + void _AdjustRemoveGlobalCallbackParameter(const char* key) { + if (key != NULL) { + NSString *strKey = [NSString stringWithUTF8String:key]; + [Adjust removeGlobalCallbackParameterForKey:strKey]; + } + } + + void _AdjustRemoveGlobalPartnerParameters() { + [Adjust removeGlobalPartnerParameters]; + } + + void _AdjustRemoveGlobalCallbackParameters() { + [Adjust removeGlobalCallbackParameters]; + } + + void _AdjustTrackAdRevenue(const char* source, + double revenue, + const char* currency, + int adImpressionsCount, + const char* adRevenueNetwork, + const char* adRevenueUnit, + const char* adRevenuePlacement, + const char* jsonCallbackParameters, + const char* jsonPartnerParameters) { + NSString *stringSource = isStringValid(source) == true ? [NSString stringWithUTF8String:source] : nil; + ADJAdRevenue *adRevenue = [[ADJAdRevenue alloc] initWithSource:stringSource]; + + // revenue and currency + if (revenue != -1 && currency != NULL) { + NSString *stringCurrency = [NSString stringWithUTF8String:currency]; + [adRevenue setRevenue:revenue currency:stringCurrency]; + } + + // ad impressions count + if (adImpressionsCount != -1) { + [adRevenue setAdImpressionsCount:adImpressionsCount]; + } + + // ad revenue network + if (adRevenueNetwork != NULL) { + NSString *stringAdRevenueNetwork = [NSString stringWithUTF8String:adRevenueNetwork]; + [adRevenue setAdRevenueNetwork:stringAdRevenueNetwork]; + } + + // ad revenue unit + if (adRevenueUnit != NULL) { + NSString *stringAdRevenueUnit = [NSString stringWithUTF8String:adRevenueUnit]; + [adRevenue setAdRevenueUnit:stringAdRevenueUnit]; + } + + // ad revenue placement + if (adRevenuePlacement != NULL) { + NSString *stringAdRevenuePlacement = [NSString stringWithUTF8String:adRevenuePlacement]; + [adRevenue setAdRevenuePlacement:stringAdRevenuePlacement]; + } + + // callback parameters + NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); + if (arrayCallbackParameters != nil) { + NSUInteger count = [arrayCallbackParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayCallbackParameters[i++]; + NSString *value = arrayCallbackParameters[i++]; + [adRevenue addCallbackParameter:key value:value]; + } + } + + // partner parameters + NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); + if (arrayPartnerParameters != nil) { + NSUInteger count = [arrayPartnerParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayPartnerParameters[i++]; + NSString *value = arrayPartnerParameters[i++]; + [adRevenue addPartnerParameter:key value:value]; + } + } + + // track ad revenue + [Adjust trackAdRevenue:adRevenue]; + } + + // TODO: consider non-string types for some fields? + void _AdjustTrackAppStoreSubscription(const char* price, + const char* currency, + const char* transactionId, + const char* transactionDate, + const char* salesRegion, + const char* jsonCallbackParameters, + const char* jsonPartnerParameters) { + // mandatory fields + NSDecimalNumber *mPrice; + NSString *mCurrency; + NSString *mTransactionId; + + // price + if (price != NULL) { + mPrice = [NSDecimalNumber decimalNumberWithString:[NSString stringWithUTF8String:price]]; + } + + // currency + if (currency != NULL) { + mCurrency = [NSString stringWithUTF8String:currency]; + } + + // transaction ID + if (transactionId != NULL) { + mTransactionId = [NSString stringWithUTF8String:transactionId]; + } + + ADJAppStoreSubscription *subscription = + [[ADJAppStoreSubscription alloc] initWithPrice:mPrice + currency:mCurrency + transactionId:mTransactionId]; + + // optional fields below + + // transaction date + if (transactionDate != NULL) { + NSTimeInterval transactionDateInterval = [[NSString stringWithUTF8String:transactionDate] doubleValue] / 1000.0; + NSDate *oTransactionDate = [NSDate dateWithTimeIntervalSince1970:transactionDateInterval]; + [subscription setTransactionDate:oTransactionDate]; + } + + // sales region + if (salesRegion != NULL) { + NSString *oSalesRegion = [NSString stringWithUTF8String:salesRegion]; + [subscription setSalesRegion:oSalesRegion]; + } + + // callback parameters + NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); + if (arrayCallbackParameters != nil) { + NSUInteger count = [arrayCallbackParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayCallbackParameters[i++]; + NSString *value = arrayCallbackParameters[i++]; + [subscription addCallbackParameter:key value:value]; + } + } + + // partner parameters + NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); + if (arrayPartnerParameters != nil) { + NSUInteger count = [arrayPartnerParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayPartnerParameters[i++]; + NSString *value = arrayPartnerParameters[i++]; + [subscription addPartnerParameter:key value:value]; + } + } + + // track subscription + [Adjust trackAppStoreSubscription:subscription]; + } + + void _AdjustTrackThirdPartySharing(int enabled, const char* jsonGranularOptions, const char* jsonPartnerSharingSettings) { + NSNumber *nEnabled = enabled >= 0 ? [NSNumber numberWithInt:enabled] : nil; + ADJThirdPartySharing *adjustThirdPartySharing = [[ADJThirdPartySharing alloc] initWithIsEnabled:nEnabled]; + + NSArray *arrayGranularOptions = convertArrayParameters(jsonGranularOptions); + if (arrayGranularOptions != nil) { + for (int i = 0; i < [arrayGranularOptions count];) { + NSString *partnerName = arrayGranularOptions[i++]; + NSString *key = arrayGranularOptions[i++]; + NSString *value = arrayGranularOptions[i++]; + [adjustThirdPartySharing addGranularOption:partnerName + key:key + value:value]; + } + } + + NSArray *arrayPartnerSharingSettings = convertArrayParameters(jsonPartnerSharingSettings); + if (arrayPartnerSharingSettings != nil) { + for (int i = 0; i < [arrayPartnerSharingSettings count];) { + NSString *partnerName = arrayPartnerSharingSettings[i++]; + NSString *key = arrayPartnerSharingSettings[i++]; + NSString *value = arrayPartnerSharingSettings[i++]; + [adjustThirdPartySharing addPartnerSharingSetting:partnerName + key:key + value:[value boolValue]]; + } + } + + [Adjust trackThirdPartySharing:adjustThirdPartySharing]; + } + + void _AdjustTrackMeasurementConsent(int enabled) { + BOOL bEnabled = (BOOL)enabled; + [Adjust trackMeasurementConsent:bEnabled]; + } + + void _AdjustRequestAppTrackingAuthorization(AdjustDelegateAttCallback callback) { + [Adjust requestAppTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) { + callback((int)status); + }]; + } + + void _AdjustUpdateSkanConversionValue(int conversionValue, + const char* coarseValue, + int lockWindow, + AdjustDelegateSkanErrorCallback callback) { + if (coarseValue != NULL) { + NSString *strCoarseValue = [NSString stringWithUTF8String:coarseValue]; + BOOL bLockWindow = (BOOL)lockWindow; + [Adjust updateSkanConversionValue:conversionValue + coarseValue:strCoarseValue + lockWindow:[NSNumber numberWithBool:bLockWindow] + withCompletionHandler:^(NSError * _Nullable error) { + // TODO: nil checks + NSString *errorString = [error localizedDescription]; + const char* errorChar = [errorString UTF8String]; + callback(errorChar); + }]; + } + } + + int _AdjustGetAppTrackingAuthorizationStatus() { + return [Adjust appTrackingAuthorizationStatus]; + } + + void _AdjustVerifyAppStorePurchase(const char* transactionId, + const char* productId, + int callbackId, + AdjustDelegatePurchaseVerificationCallback callback) { + NSString *strTransactionId; + NSString *strProductId; + + // transaction ID + if (transactionId != NULL) { + strTransactionId = [NSString stringWithUTF8String:transactionId]; + } + + // product ID + if (productId != NULL) { + strProductId = [NSString stringWithUTF8String:productId]; + } + + // verify the purchase + ADJAppStorePurchase *purchase = + [[ADJAppStorePurchase alloc] initWithTransactionId:strTransactionId + productId:strProductId]; + + [Adjust verifyAppStorePurchase:purchase + withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) { + // TODO: nil checks + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus); + addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]); + addValueOrEmpty(dictionary, @"message", verificationResult.message); + + NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes] + length:[dataVerificationInfo length] + encoding:NSUTF8StringEncoding]; + const char* verificationInfoCString = [strVerificationInfo UTF8String]; + callback(verificationInfoCString, callbackId); + }]; + } + + void _AdjustProcessAndResolveDeeplink(const char* deeplink, AdjustDelegateResolvedDeeplinkCallback callback) { + if (deeplink != NULL) { + NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; + NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; + ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; + [Adjust processAndResolveDeeplink:deeplink withCompletionHandler:^(NSString * _Nullable resolvedLink) { + // TODO: nil checks + const char* resolvedLinkCString = [resolvedLink UTF8String]; + callback(resolvedLinkCString); + }]; + } + } + + void _AdjustVerifyAndTrackAppStorePurchase( + const char* eventToken, + double revenue, + const char* currency, + const char* productId, + const char* transactionId, + const char* callbackId, + const char* deduplicationId, + const char* jsonCallbackParameters, + const char* jsonPartnerParameters, + int verificationCallbackId, + AdjustDelegateVerifyAndTrackCallback callback) { + NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil; + ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken]; + + // revenue and currency + if (revenue != -1 && currency != NULL) { + NSString *stringCurrency = [NSString stringWithUTF8String:currency]; + [event setRevenue:revenue currency:stringCurrency]; + } + + // callback parameters + NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); + if (arrayCallbackParameters != nil) { + NSUInteger count = [arrayCallbackParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayCallbackParameters[i++]; + NSString *value = arrayCallbackParameters[i++]; + [event addCallbackParameter:key value:value]; + } + } + + // partner parameters + NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); + if (arrayPartnerParameters != nil) { + NSUInteger count = [arrayPartnerParameters count]; + for (int i = 0; i < count;) { + NSString *key = arrayPartnerParameters[i++]; + NSString *value = arrayPartnerParameters[i++]; + [event addPartnerParameter:key value:value]; + } + } + + // transaction ID + if (transactionId != NULL) { + NSString *strTransactionId = [NSString stringWithUTF8String:transactionId]; + [event setTransactionId:strTransactionId]; + } + + // product ID + if (productId != NULL) { + NSString *strProductId = [NSString stringWithUTF8String:productId]; + [event setProductId:strProductId]; + } + + // callback ID + if (callbackId != NULL) { + NSString *strCallbackId = [NSString stringWithUTF8String:callbackId]; + [event setCallbackId:strCallbackId]; + } + + // deduplication ID + if (deduplicationId != NULL) { + NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId]; + [event setDeduplicationId:strDeduplicationId]; + } + + [Adjust verifyAndTrackAppStorePurchase:event + withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) { + // TODO: nil checks + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus); + addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]); + addValueOrEmpty(dictionary, @"message", verificationResult.message); + + NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes] + length:[dataVerificationInfo length] + encoding:NSUTF8StringEncoding]; + const char* verificationInfoCString = [strVerificationInfo UTF8String]; + callback(verificationInfoCString, verificationCallbackId); + }]; + } + + void _AdjustEndFirstSessionDelay() { + [Adjust endFirstSessionDelay]; + } + + void _AdjustEnableCoppaComplianceInDelay() { + [Adjust enableCoppaComplianceInDelay]; + } + + void _AdjustDisableCoppaComplianceInDelay() { + [Adjust disableCoppaComplianceInDelay]; + } + + void _AdjustSetExternalDeviceIdInDelay(const char* externalDeviceId) { + if (externalDeviceId != NULL) { + NSString *strExternalDeviceId = [NSString stringWithUTF8String:externalDeviceId]; + [Adjust setExternalDeviceIdInDelay:strExternalDeviceId]; + } + } + + void _AdjustSetTestOptions(const char* overwriteUrl, + const char* extraPath, + long timerIntervalInMilliseconds, + long timerStartInMilliseconds, + long sessionIntervalInMilliseconds, + long subsessionIntervalInMilliseconds, + int teardown, + int deleteState, + int noBackoffWait, + int adServicesFrameworkEnabled, + int attStatus, + const char *idfa) { + NSMutableDictionary *testOptions = [NSMutableDictionary dictionary]; + + NSString *strOverwriteUrl = isStringValid(overwriteUrl) == true ? [NSString stringWithUTF8String:overwriteUrl] : nil; + if (strOverwriteUrl != nil) { + testOptions[@"testUrlOverwrite"] = strOverwriteUrl; + } + NSString *strExtraPath = isStringValid(extraPath) == true ? [NSString stringWithUTF8String:extraPath] : nil; + if (strExtraPath != nil && [strExtraPath length] > 0) { + testOptions[@"extraPath"] = strExtraPath; + } + NSString *strIdfa = isStringValid(idfa) == true ? [NSString stringWithUTF8String:idfa] : nil; + if (strIdfa != nil && [strIdfa length] > 0) { + testOptions[@"idfa"] = strIdfa; + } + + testOptions[@"timerIntervalInMilliseconds"] = [NSNumber numberWithLong:timerIntervalInMilliseconds]; + testOptions[@"timerStartInMilliseconds"] = [NSNumber numberWithLong:timerStartInMilliseconds]; + testOptions[@"sessionIntervalInMilliseconds"] = [NSNumber numberWithLong:sessionIntervalInMilliseconds]; + testOptions[@"subsessionIntervalInMilliseconds"] = [NSNumber numberWithLong:subsessionIntervalInMilliseconds]; + testOptions[@"attStatusInt"] = [NSNumber numberWithInt:attStatus]; + + if (teardown != -1) { + [AdjustUnityDelegate teardown]; + testOptions[@"teardown"] = [NSNumber numberWithInt:teardown]; + } + if (deleteState != -1) { + testOptions[@"deleteState"] = [NSNumber numberWithInt:deleteState]; + } + if (noBackoffWait != -1) { + testOptions[@"noBackoffWait"] = [NSNumber numberWithInt:noBackoffWait]; + } + if (adServicesFrameworkEnabled != -1) { + testOptions[@"adServicesFrameworkEnabled"] = [NSNumber numberWithInt:adServicesFrameworkEnabled]; + } + + [Adjust setTestOptions:testOptions]; + } +} diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm.meta new file mode 100644 index 0000000..4651ffe --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnity.mm.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: 3e17e20d987e4449489d9e3accbd8602 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXIntel: 1 + Exclude OSXIntel64: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + '': Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + OS: AnyOS + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXIntel + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXIntel64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h new file mode 100644 index 0000000..25d1c2a --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h @@ -0,0 +1,18 @@ +// +// AdjustUnityAppDelegate.h +// Adjust SDK +// +// Copyright © 2012-2021 Adjust GmbH. All rights reserved. +// + +/** + * @brief The interface to Adjust App Delegate. Used to do callback methods swizzling for deep linking. + */ +@interface AdjustUnityAppDelegate : NSObject + +/** + * @brief Swizzle AppDelegate deep linking callbacks. + */ ++ (void)swizzleAppDelegateCallbacks; + +@end diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h.meta new file mode 100644 index 0000000..e1c7c3c --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.h.meta @@ -0,0 +1,115 @@ +fileFormatVersion: 2 +guid: ac4b0b80967dd499b94e6bd430ac6662 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + WebGL: WebGL + second: + enabled: 0 + settings: {} + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m new file mode 100644 index 0000000..7ed977b --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m @@ -0,0 +1,75 @@ +// +// AdjustUnityAppDelegate.mm +// Adjust SDK +// +// Copyright © 2012-2021 Adjust GmbH. All rights reserved. +// + +#import +#import +#import "AdjustUnityAppDelegate.h" + +typedef BOOL (*openURL_t)(id, SEL, UIApplication *, NSURL *, NSDictionary *); +typedef BOOL (*continueUserActivity_t)(id, SEL, UIApplication *, NSUserActivity *, void (^)(NSArray *restorableObjects)); +static openURL_t original_openURL = NULL; +static continueUserActivity_t original_continueUserActivity = NULL; + +@implementation AdjustUnityAppDelegate + ++ (void)swizzleAppDelegateCallbacks { + NSLog(@"[Adjust] Swizzling AppDelegate callbacks..."); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + original_openURL = (openURL_t)[self swizzleOriginalSelector:@selector(application:openURL:options:) + withSelector:@selector(adjust_application:openURL:options:)]; + original_continueUserActivity = (continueUserActivity_t)[self swizzleOriginalSelector:@selector(application:continueUserActivity:restorationHandler:) + withSelector:@selector(adjust_application:continueUserActivity:restorationHandler:)]; + }); +} + ++ (IMP)swizzleOriginalSelector:(SEL)originalSelector + withSelector:(SEL)swizzledSelector { + // The Unity base app controller class name. + extern const char* AppControllerClassName; + Class originalClass = NSClassFromString([NSString stringWithUTF8String:AppControllerClassName]); + Class swizzledClass = [self class]; + IMP originalImp = NULL; + IMP swizzledImp = class_getMethodImplementation(swizzledClass, swizzledSelector); + + // Replace original implementation by the custom one. + Method originalMethod = class_getInstanceMethod(originalClass, originalSelector); + if (originalMethod) { + originalImp = method_setImplementation(originalMethod, swizzledImp); + } else if (![originalClass instancesRespondToSelector:originalSelector]) { + // Add the method to the original class if it doesn't implement the selector. + Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector); + BOOL methodAdded = class_addMethod(originalClass, originalSelector, swizzledImp, method_getTypeEncoding(swizzledMethod)); + if (!methodAdded) { + NSLog(@"[Adjust] Cannot swizzle selector '%@' of class '%@'.", NSStringFromSelector(originalSelector), originalClass); + return NULL; + } + } + NSLog(@"[Adjust] Selector '%@' of class '%@' is swizzled.", NSStringFromSelector(originalSelector), originalClass); + return originalImp; +} + +- (BOOL)adjust_application:(UIApplication *)application + openURL:(NSURL *)url + options:(NSDictionary *)options { + ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:url]; + [Adjust processDeeplink:deeplink]; + return original_openURL ? original_openURL(self, _cmd, application, url, options) : YES; +} + +- (BOOL)adjust_application:(UIApplication *)application + continueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler { + if ([[userActivity activityType] isEqualToString:NSUserActivityTypeBrowsingWeb]) { + NSURL *url = [userActivity webpageURL]; + ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:url]; + [Adjust processDeeplink:deeplink]; + } + return original_continueUserActivity ? original_continueUserActivity(self, _cmd, application, userActivity, restorationHandler) : YES; +} + +@end diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m.meta new file mode 100644 index 0000000..a15a43e --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityAppDelegate.m.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: ea1bc374f78b747f8a81fcc82cd77d96 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 0 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h new file mode 100644 index 0000000..7d3a861 --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h @@ -0,0 +1,60 @@ +// +// AdjustUnityDelegate.h +// Adjust SDK +// +// Created by Uglješa Erceg (@uerceg) on 5th December 2016. +// Copyright © 2012-Present Adjust GmbH. All rights reserved. +// + +#import +#import "AdjustUnity.h" + +/** + * @brief The main interface to Adjust Unity delegate. Used to do callback methods swizzling where needed. + */ +@interface AdjustUnityDelegate : NSObject + +/** + * @brief Boolean indicating whether deferred deep link should be launched by SDK or not. + */ +@property (nonatomic) BOOL shouldLaunchDeferredDeeplink; + +@property (nonatomic) AdjustDelegateAttributionCallback attributionCallback; +@property (nonatomic) AdjustDelegateEventSuccessCallback eventSuccessCallback; +@property (nonatomic) AdjustDelegateEventFailureCallback eventFailureCallback; +@property (nonatomic) AdjustDelegateSessionSuccessCallback sessionSuccessCallback; +@property (nonatomic) AdjustDelegateSessionFailureCallback sessionFailureCallback; +@property (nonatomic) AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback; +@property (nonatomic) AdjustDelegateSkanUpdatedCallback skanUpdatedCallback; + +/** + * @brief Get instance of the AdjustUnityDelegate with properly swizzled callback methods. + * + * @param swizzleAttributionCallback Indicator whether attribution callback should be swizzled or not. + * @param swizzleEventSuccessCallback Indicator whether event success callback should be swizzled or not. + * @param swizzleEventFailureCallback Indicator whether event failure callback should be swizzled or not. + * @param swizzleSessionSuccessCallback Indicator whether session success callback should be swizzled or not. + * @param swizzleSessionFailureCallback Indicator whether session failure callback should be swizzled or not. + * @param swizzleDeferredDeeplinkCallback Indicator whether deferred deep link callback should be swizzled or not. + * @param swizzleSkanUpdatedCallback Indicator whether SKAD conversion value update callback should be swizzled or not. + * @param shouldLaunchDeferredDeeplink Indicator whether SDK should launch deferred deep link by default or not. + * @param adjustUnityGameObjectName Name of the Unity game object that loads Adjust script. + * + * @return AdjustUnityDelegate object instance with properly swizzled callback methods. + */ ++ (id)getInstanceWithAttributionCallback:(AdjustDelegateAttributionCallback)attributionCallback + eventSuccessCallback:(AdjustDelegateEventSuccessCallback)eventSuccessCallback + eventFailureCallback:(AdjustDelegateEventFailureCallback)eventFailureCallback + sessionSuccessCallback:(AdjustDelegateSessionSuccessCallback)sessionSuccessCallback + sessionFailureCallback:(AdjustDelegateSessionFailureCallback)sessionFailureCallback + deferredDeeplinkCallback:(AdjustDelegateDeferredDeeplinkCallback)deferredDeeplinkCallback + skanUpdatedCallback:(AdjustDelegateSkanUpdatedCallback)skanUpdatedCallback + shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink; + +/** + * @brief Teardown method used to reset static AdjustUnityDelegate instance. + * Used for testing purposes only. + */ ++ (void)teardown; + +@end diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h.meta new file mode 100644 index 0000000..fd52fe4 --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.h.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: 5d2beef19c617f74fbca612cc97e3c60 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXIntel: 1 + Exclude OSXIntel64: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + '': Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + OS: AnyOS + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXIntel + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXIntel64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm new file mode 100644 index 0000000..c8427eb --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm @@ -0,0 +1,345 @@ +// +// AdjustUnityDelegate.mm +// Adjust SDK +// +// Created by Uglješa Erceg (@uerceg) on 5th December 2016. +// Copyright © 2012-2018 Adjust GmbH. All rights reserved. +// + +#import +#import "AdjustUnityDelegate.h" + +static dispatch_once_t onceToken; +static AdjustUnityDelegate *defaultInstance = nil; + +@implementation AdjustUnityDelegate + +#pragma mark - Object lifecycle methods + +- (id)init { + self = [super init]; + if (nil == self) { + return nil; + } + return self; +} + +#pragma mark - Public methods + ++ (id)getInstanceWithAttributionCallback:(AdjustDelegateAttributionCallback)attributionCallback + eventSuccessCallback:(AdjustDelegateEventSuccessCallback)eventSuccessCallback + eventFailureCallback:(AdjustDelegateEventFailureCallback)eventFailureCallback + sessionSuccessCallback:(AdjustDelegateSessionSuccessCallback)sessionSuccessCallback + sessionFailureCallback:(AdjustDelegateSessionFailureCallback)sessionFailureCallback + deferredDeeplinkCallback:(AdjustDelegateDeferredDeeplinkCallback)deferredDeeplinkCallback + skanUpdatedCallback:(AdjustDelegateSkanUpdatedCallback)skanUpdatedCallback + shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink { + dispatch_once(&onceToken, ^{ + defaultInstance = [[AdjustUnityDelegate alloc] init]; + + // Do the swizzling where and if needed. + if (attributionCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustAttributionChanged:) + withSelector:@selector(adjustAttributionChangedWannabe:)]; + } + if (eventSuccessCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingSucceeded:) + withSelector:@selector(adjustEventTrackingSucceededWannabe:)]; + } + if (eventFailureCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingFailed:) + withSelector:@selector(adjustEventTrackingFailedWannabe:)]; + } + if (sessionSuccessCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingSucceeded:) + withSelector:@selector(adjustSessionTrackingSucceededWannabe:)]; + } + if (sessionFailureCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingFailed:) + withSelector:@selector(adjustSessionTrackingFailedWannabe:)]; + } + if (deferredDeeplinkCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustDeferredDeeplinkReceived:) + withSelector:@selector(adjustDeferredDeeplinkReceivedWannabe:)]; + } + if (skanUpdatedCallback != nil) { + [defaultInstance swizzleOriginalSelector:@selector(adjustSkanUpdatedWithConversionData:) + withSelector:@selector(adjustSkanUpdatedWithConversionDataWannabe:)]; + } + + [defaultInstance setAttributionCallback:attributionCallback]; + [defaultInstance setEventSuccessCallback:eventSuccessCallback]; + [defaultInstance setEventFailureCallback:eventFailureCallback]; + [defaultInstance setSessionSuccessCallback:sessionSuccessCallback]; + [defaultInstance setSessionFailureCallback:sessionFailureCallback]; + [defaultInstance setDeferredDeeplinkCallback:deferredDeeplinkCallback]; + [defaultInstance setSkanUpdatedCallback:skanUpdatedCallback]; + [defaultInstance setShouldLaunchDeferredDeeplink:shouldLaunchDeferredDeeplink]; + }); + + return defaultInstance; +} + ++ (void)teardown { + defaultInstance = nil; + onceToken = 0; +} + +#pragma mark - Private & helper methods + +- (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution { + if (attribution == nil || _attributionCallback == nil) { + return; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self addValueOrEmpty:attribution.trackerToken + forKey:@"trackerToken" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.trackerName + forKey:@"trackerName" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.network + forKey:@"network" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.campaign + forKey:@"campaign" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.creative + forKey:@"creative" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.adgroup + forKey:@"adgroup" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.clickLabel + forKey:@"clickLabel" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.costType + forKey:@"costType" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.costAmount + forKey:@"costAmount" + toDictionary:dictionary]; + [self addValueOrEmpty:attribution.costCurrency + forKey:@"costCurrency" + toDictionary:dictionary]; + + if (attribution.jsonResponse != nil) { + 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]; + NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes] + length:[dataAttribution length] + encoding:NSUTF8StringEncoding]; + const char* charArrayAttribution = [stringAttribution UTF8String]; + _attributionCallback(charArrayAttribution); +} + +- (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessResponseData { + if (nil == eventSuccessResponseData || _eventSuccessCallback == nil) { + return; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self addValueOrEmpty:eventSuccessResponseData.message + forKey:@"message" + toDictionary:dictionary]; + [self addValueOrEmpty:eventSuccessResponseData.timestamp + forKey:@"timestamp" + toDictionary:dictionary]; + [self addValueOrEmpty:eventSuccessResponseData.adid + forKey:@"adid" + toDictionary:dictionary]; + [self addValueOrEmpty:eventSuccessResponseData.eventToken + forKey:@"eventToken" + toDictionary:dictionary]; + [self addValueOrEmpty:eventSuccessResponseData.callbackId + forKey:@"callbackId" + toDictionary:dictionary]; + if (eventSuccessResponseData.jsonResponse != nil) { + [dictionary setObject:eventSuccessResponseData.jsonResponse + forKey:@"jsonResponse"]; + } + + NSData *dataEventSuccess = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *stringEventSuccess = [[NSString alloc] initWithBytes:[dataEventSuccess bytes] + length:[dataEventSuccess length] + encoding:NSUTF8StringEncoding]; + const char* charArrayEventSuccess = [stringEventSuccess UTF8String]; + _eventSuccessCallback(charArrayEventSuccess); +} + +- (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponseData { + if (nil == eventFailureResponseData || _eventFailureCallback == nil) { + return; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self addValueOrEmpty:eventFailureResponseData.message + forKey:@"message" + toDictionary:dictionary]; + [self addValueOrEmpty:eventFailureResponseData.timestamp + forKey:@"timestamp" + toDictionary:dictionary]; + [self addValueOrEmpty:eventFailureResponseData.adid + forKey:@"adid" + toDictionary:dictionary]; + [self addValueOrEmpty:eventFailureResponseData.eventToken + forKey:@"eventToken" + toDictionary:dictionary]; + [self addValueOrEmpty:eventFailureResponseData.callbackId + forKey:@"callbackId" + toDictionary:dictionary]; + [dictionary setObject:(eventFailureResponseData.willRetry ? @"true" : @"false") + forKey:@"willRetry"]; + if (eventFailureResponseData.jsonResponse != nil) { + [dictionary setObject:eventFailureResponseData.jsonResponse + forKey:@"jsonResponse"]; + } + + NSData *dataEventFailure = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *stringEventFailure = [[NSString alloc] initWithBytes:[dataEventFailure bytes] + length:[dataEventFailure length] + encoding:NSUTF8StringEncoding]; + const char* charArrayEventFailure = [stringEventFailure UTF8String]; + _eventFailureCallback(charArrayEventFailure); +} + +- (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSuccessResponseData { + if (nil == sessionSuccessResponseData || _sessionSuccessCallback == nil) { + return; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self addValueOrEmpty:sessionSuccessResponseData.message + forKey:@"message" + toDictionary:dictionary]; + [self addValueOrEmpty:sessionSuccessResponseData.timestamp + forKey:@"timestamp" + toDictionary:dictionary]; + [self addValueOrEmpty:sessionSuccessResponseData.adid + forKey:@"adid" + toDictionary:dictionary]; + if (sessionSuccessResponseData.jsonResponse != nil) { + [dictionary setObject:sessionSuccessResponseData.jsonResponse + forKey:@"jsonResponse"]; + } + + NSData *dataSessionSuccess = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *stringSessionSuccess = [[NSString alloc] initWithBytes:[dataSessionSuccess bytes] + length:[dataSessionSuccess length] + encoding:NSUTF8StringEncoding]; + const char* charArraySessionSuccess = [stringSessionSuccess UTF8String]; + _sessionSuccessCallback(charArraySessionSuccess); +} + +- (void)adjustSessionTrackingFailedWannabe:(ADJSessionFailure *)sessionFailureResponseData { + if (nil == sessionFailureResponseData || _sessionFailureCallback == nil) { + return; + } + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self addValueOrEmpty:sessionFailureResponseData.message + forKey:@"message" + toDictionary:dictionary]; + [self addValueOrEmpty:sessionFailureResponseData.timestamp + forKey:@"timestamp" + toDictionary:dictionary]; + [self addValueOrEmpty:sessionFailureResponseData.adid + forKey:@"adid" + toDictionary:dictionary]; + [dictionary setObject:(sessionFailureResponseData.willRetry ? @"true" : @"false") + forKey:@"willRetry"]; + if (sessionFailureResponseData.jsonResponse != nil) { + [dictionary setObject:sessionFailureResponseData.jsonResponse + forKey:@"jsonResponse"]; + } + + NSData *dataSessionFailure = [NSJSONSerialization dataWithJSONObject:dictionary + options:0 + error:nil]; + NSString *stringSessionFailure = [[NSString alloc] initWithBytes:[dataSessionFailure bytes] + length:[dataSessionFailure length] + encoding:NSUTF8StringEncoding]; + const char* charArraySessionFailure = [stringSessionFailure UTF8String]; + _sessionFailureCallback(charArraySessionFailure); +} + +- (BOOL)adjustDeferredDeeplinkReceivedWannabe:(NSURL *)deeplink { + if (_deferredDeeplinkCallback != nil) { + NSString *stringDeeplink = [deeplink absoluteString]; + const char* charDeeplink = [stringDeeplink UTF8String]; + _deferredDeeplinkCallback(charDeeplink); + } + return _shouldLaunchDeferredDeeplink; +} + +- (void)adjustSkanUpdatedWithConversionDataWannabe:(NSDictionary *)data { + if (data == nil || _skanUpdatedCallback == nil) { + return; + } + + NSData *dataSkanUpdatedData = [NSJSONSerialization dataWithJSONObject:data + options:0 + error:nil]; + NSString *strSkanUpdatedData = [[NSString alloc] initWithBytes:[dataSkanUpdatedData bytes] + length:[dataSkanUpdatedData length] + encoding:NSUTF8StringEncoding]; + const char* charSkanUpdatedData = [strSkanUpdatedData UTF8String]; + _skanUpdatedCallback(charSkanUpdatedData); +} + +- (void)swizzleOriginalSelector:(SEL)originalSelector + withSelector:(SEL)swizzledSelector { + Class className = [self class]; + Method originalMethod = class_getInstanceMethod(className, originalSelector); + Method swizzledMethod = class_getInstanceMethod(className, swizzledSelector); + + BOOL didAddMethod = class_addMethod(className, + originalSelector, + method_getImplementation(swizzledMethod), + method_getTypeEncoding(swizzledMethod)); + if (didAddMethod) { + class_replaceMethod(className, + swizzledSelector, + method_getImplementation(originalMethod), + method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } +} + +- (void)addValueOrEmpty:(NSObject *)value + forKey:(NSString *)key + toDictionary:(NSMutableDictionary *)dictionary { + if (nil != value) { + if ([value isKindOfClass:[NSString class]]) { + [dictionary setObject:[NSString stringWithFormat:@"%@", value] + forKey:key]; + } else if ([value isKindOfClass:[NSNumber class]]) { + [dictionary setObject:[NSString stringWithFormat:@"%@", [((NSNumber *)value) stringValue]] + forKey:key]; + } else { + [dictionary setObject:@"" forKey:key]; + } + } else { + [dictionary setObject:@"" forKey:key]; + } +} + +@end diff --git a/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm.meta b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm.meta new file mode 100644 index 0000000..4d65f99 --- /dev/null +++ b/Assets/rd3/Adjust/Native/iOS/AdjustUnityDelegate.mm.meta @@ -0,0 +1,129 @@ +fileFormatVersion: 2 +guid: 81438eed05b2e4b489f13efc94d5476a +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXIntel: 1 + Exclude OSXIntel64: 1 + Exclude OSXUniversal: 1 + Exclude WebGL: 1 + Exclude Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + Exclude tvOS: 1 + - first: + '': Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + OS: AnyOS + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXIntel + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXIntel64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + - first: + iPhone: iOS + second: + enabled: 1 + settings: + CompileFlags: + FrameworkDependencies: + - first: + tvOS: tvOS + second: + enabled: 0 + settings: + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Prefab.meta b/Assets/rd3/Adjust/Prefab.meta new file mode 100644 index 0000000..6bc38d1 --- /dev/null +++ b/Assets/rd3/Adjust/Prefab.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0acdd227ad1b8d147ade044242671e15 +folderAsset: yes +timeCreated: 1578652549 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Prefab/Adjust.prefab b/Assets/rd3/Adjust/Prefab/Adjust.prefab new file mode 100644 index 0000000..394a83f --- /dev/null +++ b/Assets/rd3/Adjust/Prefab/Adjust.prefab @@ -0,0 +1,77 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &115478 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 415478} + - component: {fileID: 114179903453641630} + m_Layer: 0 + m_Name: Adjust + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &415478 +Transform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 115478} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1001 &100100000 +Prefab: + m_ObjectHideFlags: 1 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: [] + m_RemovedComponents: [] + m_ParentPrefab: {fileID: 0} + m_RootGameObject: {fileID: 115478} + m_IsPrefabParent: 1 +--- !u!114 &114179903453641630 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 115478} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 525ece82a472e4dea837e1ef938fd15d, type: 3} + m_Name: + m_EditorClassIdentifier: + startManually: 1 + appToken: + environment: 0 + logLevel: 3 + eventBuffering: 0 + sendInBackground: 0 + launchDeferredDeeplink: 1 + needsCost: 0 + coppaCompliant: 0 + linkMe: 0 + defaultTracker: + urlStrategy: 0 + startDelay: 0 + secretId: 0 + info1: 0 + info2: 0 + info3: 0 + info4: 0 + preinstallTracking: 0 + preinstallFilePath: + playStoreKidsApp: 0 + adServicesInfoReading: 1 + idfaInfoReading: 1 + skAdNetworkHandling: 1 diff --git a/Assets/rd3/Adjust/Prefab/Adjust.prefab.meta b/Assets/rd3/Adjust/Prefab/Adjust.prefab.meta new file mode 100644 index 0000000..ca66937 --- /dev/null +++ b/Assets/rd3/Adjust/Prefab/Adjust.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a3267720e82aa41c1a05ab29824902b4 +NativeFormatImporter: + mainObjectFileID: -1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Resources.meta b/Assets/rd3/Adjust/Resources.meta new file mode 100644 index 0000000..89ce266 --- /dev/null +++ b/Assets/rd3/Adjust/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e9688945324d3a44699534d71c3e55cb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Resources/AdjustSettings.asset b/Assets/rd3/Adjust/Resources/AdjustSettings.asset new file mode 100644 index 0000000..9b4f2a8 --- /dev/null +++ b/Assets/rd3/Adjust/Resources/AdjustSettings.asset @@ -0,0 +1,28 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ea4d495dc6d5ba64b90db7afda6a48a4, type: 3} + m_Name: AdjustSettings + m_EditorClassIdentifier: + _iOSFrameworkAdSupport: 1 + _iOSFrameworkAdServices: 0 + _iOSFrameworkAppTrackingTransparency: 0 + _iOSFrameworkStoreKit: 0 + _androidPermissionInternet: 1 + _androidPermissionInstallReferrerService: 1 + _androidPermissionAdId: 1 + _androidPermissionAccessNetworkState: 0 + _iOSUserTrackingUsageDescription: + _iOSUrlIdentifier: + _iOSUrlSchemes: [] + _iOSUniversalLinksDomains: [] + androidUriSchemes: [] + _androidCustomActivityName: diff --git a/Assets/rd3/Adjust/Resources/AdjustSettings.asset.meta b/Assets/rd3/Adjust/Resources/AdjustSettings.asset.meta new file mode 100644 index 0000000..905dd6b --- /dev/null +++ b/Assets/rd3/Adjust/Resources/AdjustSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 998d67a1c15bc8b4ea727ddd95230724 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts.meta b/Assets/rd3/Adjust/Scripts.meta new file mode 100644 index 0000000..dc956eb --- /dev/null +++ b/Assets/rd3/Adjust/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0e5ecfef4e691483199f0cdae3eebff2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Adjust.cs b/Assets/rd3/Adjust/Scripts/Adjust.cs new file mode 100644 index 0000000..77f4716 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Adjust.cs @@ -0,0 +1,839 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace AdjustSdk +{ + public class Adjust : MonoBehaviour + { + private const string errorMsgEditor = "[Adjust]: SDK can not be used in Editor."; + private const string errorMsgStart = "[Adjust]: SDK not started. Start it manually using the 'start' method."; + private const string errorMsgPlatform = "[Adjust]: SDK can only be used in Android and iOS apps."; + + // [Header("SDK SETTINGS:")] + // [Space(5)] + // [Tooltip("If selected, it is expected from you to initialize Adjust SDK from your app code. " + + // "Any SDK configuration settings from prefab will be ignored in that case.")] + [HideInInspector] + public bool startManually = true; + [HideInInspector] + public string appToken; + [HideInInspector] + public AdjustEnvironment environment = AdjustEnvironment.Sandbox; + [HideInInspector] + public AdjustLogLevel logLevel = AdjustLogLevel.Info; + [HideInInspector] + public bool coppaCompliance = false; + [HideInInspector] + public bool sendInBackground = false; + [HideInInspector] + public bool launchDeferredDeeplink = true; + [HideInInspector] + public bool costDataInAttribution = false; + [HideInInspector] + public bool linkMe = false; + [HideInInspector] + public string defaultTracker; + + // [Header("ANDROID SPECIFIC FEATURES:")] + // [Space(5)] + [HideInInspector] + public bool preinstallTracking = false; + [HideInInspector] + public string preinstallFilePath; + + // [Header("iOS SPECIFIC FEATURES:")] + // [Space(5)] + [HideInInspector] + public bool adServices = true; + [HideInInspector] + public bool idfaReading = true; + [HideInInspector] + public bool skanAttribution = true; + + void Awake() + { + if (IsEditor()) + { + return; + } + + DontDestroyOnLoad(transform.gameObject); + + // TODO: double-check the state of Unity on deep linking nowadays +#if UNITY_ANDROID && UNITY_2019_2_OR_NEWER + Application.deepLinkActivated += (deeplink) => + { + Adjust.ProcessDeeplink(new AdjustDeeplink(deeplink)); + }; + if (!string.IsNullOrEmpty(Application.absoluteURL)) + { + // cold start and Application.absoluteURL not null so process deep link + Adjust.ProcessDeeplink(new AdjustDeeplink(Application.absoluteURL)); + } +#endif + + if (!this.startManually) + { + AdjustConfig adjustConfig = new AdjustConfig( + this.appToken, + this.environment, + (this.logLevel == AdjustLogLevel.Suppress)); + adjustConfig.LogLevel = this.logLevel; + adjustConfig.IsSendingInBackgroundEnabled = this.sendInBackground; + adjustConfig.IsDeferredDeeplinkOpeningEnabled = this.launchDeferredDeeplink; + adjustConfig.DefaultTracker = this.defaultTracker; + // TODO: URL strategy + adjustConfig.IsCoppaComplianceEnabled = this.coppaCompliance; + adjustConfig.IsCostDataInAttributionEnabled = this.costDataInAttribution; + adjustConfig.IsPreinstallTrackingEnabled = this.preinstallTracking; + adjustConfig.PreinstallFilePath = this.preinstallFilePath; + adjustConfig.IsAdServicesEnabled = this.adServices; + adjustConfig.IsIdfaReadingEnabled = this.idfaReading; + adjustConfig.IsLinkMeEnabled = this.linkMe; + adjustConfig.IsSkanAttributionEnabled = this.skanAttribution; + Adjust.InitSdk(adjustConfig); + } + } + + public static void InitSdk(AdjustConfig adjustConfig) + { + if (IsEditor()) + { + return; + } + + if (adjustConfig == null) + { + Debug.Log("[Adjust]: Missing config to start."); + return; + } + +#if UNITY_IOS + AdjustiOS.InitSdk(adjustConfig); +#elif UNITY_ANDROID + AdjustAndroid.InitSdk(adjustConfig); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackEvent(AdjustEvent adjustEvent) + { + if (IsEditor()) + { + return; + } + + if (adjustEvent == null) + { + Debug.Log("[Adjust]: Missing event to track."); + return; + } +#if UNITY_IOS + AdjustiOS.TrackEvent(adjustEvent); +#elif UNITY_ANDROID + AdjustAndroid.TrackEvent(adjustEvent); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void Enable() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.Enable(); +#elif UNITY_ANDROID + AdjustAndroid.Enable(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void Disable() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.Disable(); +#elif UNITY_ANDROID + AdjustAndroid.Disable(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void IsEnabled(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.IsEnabled(callback); +#elif UNITY_ANDROID + AdjustAndroid.IsEnabled(callback); +#else + Debug.Log(errorMsgPlatform); + return; +#endif + } + + public static void SwitchToOfflineMode() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.SwitchToOfflineMode(); +#elif UNITY_ANDROID + AdjustAndroid.SwitchToOfflineMode(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void SwitchBackToOnlineMode() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.SwitchBackToOnlineMode(); +#elif UNITY_ANDROID + AdjustAndroid.SwitchBackToOnlineMode(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void SetPushToken(string pushToken) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.SetPushToken(pushToken); +#elif UNITY_ANDROID + AdjustAndroid.SetPushToken(pushToken); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GdprForgetMe() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GdprForgetMe(); +#elif UNITY_ANDROID + AdjustAndroid.GdprForgetMe(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void ProcessDeeplink(AdjustDeeplink deeplink) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.ProcessDeeplink(deeplink); +#elif UNITY_ANDROID + AdjustAndroid.ProcessDeeplink(deeplink); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void AddGlobalPartnerParameter(string key, string value) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.AddGlobalPartnerParameter(key, value); +#elif UNITY_ANDROID + AdjustAndroid.AddGlobalPartnerParameter(key, value); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void AddGlobalCallbackParameter(string key, string value) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.AddGlobalCallbackParameter(key, value); +#elif UNITY_ANDROID + AdjustAndroid.AddGlobalCallbackParameter(key, value); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void RemoveGlobalPartnerParameter(string key) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.RemoveGlobalPartnerParameter(key); +#elif UNITY_ANDROID + AdjustAndroid.RemoveGlobalPartnerParameter(key); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void RemoveGlobalCallbackParameter(string key) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.RemoveGlobalCallbackParameter(key); +#elif UNITY_ANDROID + AdjustAndroid.RemoveGlobalCallbackParameter(key); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void RemoveGlobalPartnerParameters() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.RemoveGlobalPartnerParameters(); +#elif UNITY_ANDROID + AdjustAndroid.RemoveGlobalPartnerParameters(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void RemoveGlobalCallbackParameters() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.RemoveGlobalCallbackParameters(); +#elif UNITY_ANDROID + AdjustAndroid.RemoveGlobalCallbackParameters(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackAdRevenue(AdjustAdRevenue adRevenue) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.TrackAdRevenue(adRevenue); +#elif UNITY_ANDROID + AdjustAndroid.TrackAdRevenue(adRevenue); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackAppStoreSubscription(AdjustAppStoreSubscription subscription) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.TrackAppStoreSubscription(subscription); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: App Store subscription tracking is only supported for iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackPlayStoreSubscription(AdjustPlayStoreSubscription subscription) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Play Store subscription tracking is only supported for Android platform."); +#elif UNITY_ANDROID + AdjustAndroid.TrackPlayStoreSubscription(subscription); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackThirdPartySharing(AdjustThirdPartySharing thirdPartySharing) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.TrackThirdPartySharing(thirdPartySharing); +#elif UNITY_ANDROID + AdjustAndroid.TrackThirdPartySharing(thirdPartySharing); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void TrackMeasurementConsent(bool measurementConsent) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.TrackMeasurementConsent(measurementConsent); +#elif UNITY_ANDROID + AdjustAndroid.TrackMeasurementConsent(measurementConsent); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void RequestAppTrackingAuthorization(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.RequestAppTrackingAuthorization(callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: Requesting tracking authorization is only supported for iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void UpdateSkanConversionValue( + int conversionValue, + string coarseValue, + bool lockWindow, + Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.UpdateSkanConversionValue(conversionValue, coarseValue, lockWindow, callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: Updating SKAdNetwork conversion value is only supported for iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static int GetAppTrackingAuthorizationStatus() + { + if (IsEditor()) + { + return -1; + } + +#if UNITY_IOS + return AdjustiOS.GetAppTrackingAuthorizationStatus(); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: Error! App tracking authorization status is only supported for iOS platform."); + return -1; +#else + Debug.Log(errorMsgPlatform); + return -1; +#endif + } + + public static void GetAdid(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetAdid(callback); +#elif UNITY_ANDROID + AdjustAndroid.GetAdid(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetAttribution(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetAttribution(callback); +#elif UNITY_ANDROID + AdjustAndroid.GetAttribution(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetIdfa(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetIdfa(callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: Error! IDFA is not available on Android platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetIdfv(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetIdfv(callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: Error! IDFV is not available on Android platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetGoogleAdId(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Error! Google Advertising ID is not available on iOS platform."); +#elif UNITY_ANDROID + AdjustAndroid.GetGoogleAdId(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetAmazonAdId(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Error! Amazon Fire Advertising ID is not available on iOS platform."); +#elif UNITY_ANDROID + AdjustAndroid.GetAmazonAdId(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetSdkVersion(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetSdkVersion(callback); +#elif UNITY_ANDROID + AdjustAndroid.GetSdkVersion(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void GetLastDeeplink(Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.GetLastDeeplink(callback); +#elif UNITY_ANDROID + AdjustAndroid.GetLastDeeplink(callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void VerifyAppStorePurchase( + AdjustAppStorePurchase purchase, + Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.VerifyAppStorePurchase(purchase, callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: App Store purchase verification is only supported for iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void VerifyPlayStorePurchase( + AdjustPlayStorePurchase purchase, + Action verificationResultCallback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Play Store purchase verification is only supported for Android platform."); +#elif UNITY_ANDROID + AdjustAndroid.VerifyPlayStorePurchase(purchase, verificationResultCallback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void ProcessAndResolveDeeplink(AdjustDeeplink deeplink, Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.ProcessAndResolveDeeplink(deeplink, callback); +#elif UNITY_ANDROID + AdjustAndroid.ProcessAndResolveDeeplink(deeplink, callback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void VerifyAndTrackAppStorePurchase( + AdjustEvent adjustEvent, + Action callback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.VerifyAndTrackAppStorePurchase(adjustEvent, callback); +#elif UNITY_ANDROID + Debug.Log("[Adjust]: App Store purchase verification is only supported for iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void VerifyAndTrackPlayStorePurchase( + AdjustEvent adjustEvent, + Action verificationResultCallback) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Play Store purchase verification is only supported for Android platform."); +#elif UNITY_ANDROID + AdjustAndroid.VerifyAndTrackPlayStorePurchase(adjustEvent, verificationResultCallback); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void EndFirstSessionDelay() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.EndFirstSessionDelay(); +#elif UNITY_ANDROID + AdjustAndroid.EndFirstSessionDelay(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void EnableCoppaComplianceInDelay() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.EnableCoppaComplianceInDelay(); +#elif UNITY_ANDROID + AdjustAndroid.EnableCoppaComplianceInDelay(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void DisableCoppaComplianceInDelay() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.DisableCoppaComplianceInDelay(); +#elif UNITY_ANDROID + AdjustAndroid.DisableCoppaComplianceInDelay(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void EnablePlayStoreKidsComplianceInDelay() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Play Store kids feature is only supported for Android platform."); +#elif UNITY_ANDROID + AdjustAndroid.EnablePlayStoreKidsComplianceInDelay(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void DisablePlayStoreKidsComplianceInDelay() + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Debug.Log("[Adjust]: Play Store kids feature is only supported for Android platform."); +#elif UNITY_ANDROID + AdjustAndroid.DisablePlayStoreKidsComplianceInDelay(); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + public static void SetExternalDeviceIdInDelay(string externalDeviceId) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.SetExternalDeviceIdInDelay(externalDeviceId); +#elif UNITY_ANDROID + AdjustAndroid.SetExternalDeviceIdInDelay(externalDeviceId); +#else + Debug.Log(errorMsgPlatform); +#endif + } + + private static bool IsEditor() + { +#if UNITY_EDITOR + Debug.Log(errorMsgEditor); + return true; +#else + return false; +#endif + } + + public static void SetTestOptions(Dictionary testOptions) + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + AdjustiOS.SetTestOptions(testOptions); +#elif UNITY_ANDROID + AdjustAndroid.SetTestOptions(testOptions); +#else + Debug.Log("[Adjust]: Cannot run integration tests. None of the supported platforms selected."); +#endif + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/Adjust.cs.meta b/Assets/rd3/Adjust/Scripts/Adjust.cs.meta new file mode 100644 index 0000000..08f7cad --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Adjust.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 525ece82a472e4dea837e1ef938fd15d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs b/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs new file mode 100644 index 0000000..7c13bd0 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace AdjustSdk +{ + public class AdjustAdRevenue + { + private List innerCallbackParameters; + private List innerPartnerParameters; + + public string Source { get; private set; } + public double? Revenue { get; private set; } + public string Currency { get; private set; } + public int? AdImpressionsCount { get; set; } + public string AdRevenueNetwork { get; set; } + public string AdRevenueUnit { get; set; } + public string AdRevenuePlacement { get; set; } + public ReadOnlyCollection CallbackParameters + { + get + { + if (innerCallbackParameters == null) + { + return null; + } + else + { + return innerCallbackParameters.AsReadOnly(); + } + } + } + public ReadOnlyCollection PartnerParameters + { + get + { + if (innerPartnerParameters == null) + { + return null; + } + else + { + return innerPartnerParameters.AsReadOnly(); + } + } + } + + public AdjustAdRevenue(string source) + { + this.Source = source; + } + + public void SetRevenue(double revenue, string currency) + { + this.Revenue = revenue; + this.Currency = currency; + } + + public void AddCallbackParameter(string key, string value) + { + if (this.innerCallbackParameters == null) + { + this.innerCallbackParameters = new List(); + } + this.innerCallbackParameters.Add(key); + this.innerCallbackParameters.Add(value); + } + + public void AddPartnerParameter(string key, string value) + { + if (this.innerPartnerParameters == null) + { + this.innerPartnerParameters = new List(); + } + this.innerPartnerParameters.Add(key); + this.innerPartnerParameters.Add(value); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs.meta new file mode 100644 index 0000000..bb3834f --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAdRevenue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 776a9d4b715bc44c68724248a5a75cb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs b/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs new file mode 100644 index 0000000..14a5e54 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs @@ -0,0 +1,1438 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace AdjustSdk +{ +#if UNITY_ANDROID + public class AdjustAndroid + { + private const string sdkPrefix = "unity5.4.2"; + 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"); + private static DeferredDeeplinkListener onDeferredDeeplinkListener; + private static AttributionChangedListener onAttributionChangedListener; + private static EventTrackingFailedListener onEventTrackingFailedListener; + private static EventTrackingSucceededListener onEventTrackingSucceededListener; + private static SessionTrackingFailedListener onSessionTrackingFailedListener; + private static SessionTrackingSucceededListener onSessionTrackingSucceededListener; + + private static DeeplinkResolutionListener onDeeplinkResolvedListener; + + public static void InitSdk(AdjustConfig adjustConfig) + { + // thank you, Unity 2019.2.0, for breaking this + // AndroidJavaObject ajoEnvironment = adjustConfig.environment == AdjustEnvironment.Sandbox ? + // new AndroidJavaClass("com.adjust.sdk.AdjustConfig").GetStatic("ENVIRONMENT_SANDBOX") : + // new AndroidJavaClass("com.adjust.sdk.AdjustConfig").GetStatic("ENVIRONMENT_PRODUCTION"); + + // get environment variable + string environment = adjustConfig.Environment == AdjustEnvironment.Production ? "production" : "sandbox"; + + using (AndroidJavaObject ajoAdjustConfig = adjustConfig.AllowSuppressLogLevel != null ? + new AndroidJavaObject("com.adjust.sdk.AdjustConfig", ajoCurrentActivity, adjustConfig.AppToken, environment, adjustConfig.AllowSuppressLogLevel) : + new AndroidJavaObject("com.adjust.sdk.AdjustConfig", ajoCurrentActivity, adjustConfig.AppToken, environment)) + { + // check if deferred deeplink should be launched by the SDK + if (adjustConfig.IsDeferredDeeplinkOpeningEnabled != null) + { + isDeferredDeeplinkOpeningEnabled = (bool)adjustConfig.IsDeferredDeeplinkOpeningEnabled; + } + + // check log level + if (adjustConfig.LogLevel != null) + { + AndroidJavaObject ajoLogLevel; + if (adjustConfig.LogLevel.Value.ToUppercaseString().Equals("SUPPRESS")) + { + ajoLogLevel = new AndroidJavaClass("com.adjust.sdk.LogLevel").GetStatic("SUPPRESS"); + } + else + { + ajoLogLevel = new AndroidJavaClass("com.adjust.sdk.LogLevel").GetStatic(adjustConfig.LogLevel.Value.ToUppercaseString()); + } + + if (ajoLogLevel != null) + { + ajoAdjustConfig.Call("setLogLevel", ajoLogLevel); + } + } + + // set Unity SDK prefix + ajoAdjustConfig.Call("setSdkPrefix", sdkPrefix); + + // check read device IDs only once + if (adjustConfig.IsDeviceIdsReadingOnceEnabled != null) + { + if (adjustConfig.IsDeviceIdsReadingOnceEnabled == true) + { + ajoAdjustConfig.Call("enableDeviceIdsReadingOnce"); + } + } + + // check if COPPA compliance is enabled + if (adjustConfig.IsCoppaComplianceEnabled != null) + { + if (adjustConfig.IsCoppaComplianceEnabled == true) + { + ajoAdjustConfig.Call("enableCoppaCompliance"); + } + } + + // check if Play Store Kids compliance is enabled + if (adjustConfig.IsPlayStoreKidsComplianceEnabled != null) + { + if (adjustConfig.IsPlayStoreKidsComplianceEnabled == true) + { + ajoAdjustConfig.Call("enablePlayStoreKidsCompliance"); + } + } + + // check if user enabled sening in the background + if (adjustConfig.IsSendingInBackgroundEnabled != null) + { + if (adjustConfig.IsSendingInBackgroundEnabled == true) + { + ajoAdjustConfig.Call("enableSendingInBackground"); + } + } + + // check if user wants to get cost data in attribution callback + if (adjustConfig.IsCostDataInAttributionEnabled != null) + { + if (adjustConfig.IsCostDataInAttributionEnabled == true) + { + ajoAdjustConfig.Call("enableCostDataInAttribution"); + } + } + + // check if user wants to run preinstall campaigns + if (adjustConfig.IsPreinstallTrackingEnabled != null) + { + if (adjustConfig.IsPreinstallTrackingEnabled == true) + { + ajoAdjustConfig.Call("enablePreinstallTracking"); + } + } + + // check if first session delay has been enabled + if (adjustConfig.IsFirstSessionDelayEnabled != null) + { + if (adjustConfig.IsFirstSessionDelayEnabled == true) + { + ajoAdjustConfig.Call("enableFirstSessionDelay"); + } + } + + // check if user has set custom preinstall file path + if (adjustConfig.PreinstallFilePath != null) + { + ajoAdjustConfig.Call("setPreinstallFilePath", adjustConfig.PreinstallFilePath); + } + + // check if FB app ID has been set + if (adjustConfig.FbAppId != null) + { + ajoAdjustConfig.Call("setFbAppId", adjustConfig.FbAppId); + } + + // check if user has set default tracker token + if (adjustConfig.DefaultTracker != null) + { + ajoAdjustConfig.Call("setDefaultTracker", adjustConfig.DefaultTracker); + } + + // check if user has set external device identifier + if (adjustConfig.ExternalDeviceId != null) + { + ajoAdjustConfig.Call("setExternalDeviceId", adjustConfig.ExternalDeviceId); + } + + // check if user has set max number of event deduplication IDs + if (adjustConfig.EventDeduplicationIdsMaxSize != null) + { + using (AndroidJavaObject ajoEventDeduplicationIdsMaxSize = new AndroidJavaObject("java.lang.Integer", adjustConfig.EventDeduplicationIdsMaxSize)) + { + ajoAdjustConfig.Call("setEventDeduplicationIdsMaxSize", ajoEventDeduplicationIdsMaxSize); + } + } + + // check if user has set custom URL strategy + if (adjustConfig.UrlStrategyDomains != null && + adjustConfig.ShouldUseSubdomains != null && + adjustConfig.IsDataResidency != null) + { + using (var ajoUrlStrategyDomains = new AndroidJavaObject("java.util.ArrayList")) + { + foreach (string domain in adjustConfig.UrlStrategyDomains) + { + ajoUrlStrategyDomains.Call("add", domain); + } + ajoAdjustConfig.Call("setUrlStrategy", + ajoUrlStrategyDomains, + adjustConfig.ShouldUseSubdomains, + adjustConfig.IsDataResidency); + } + } + + // check if custom store info has been set + if (adjustConfig.StoreInfo != null) + { + if (adjustConfig.StoreInfo.StoreName != null) + { + using (AndroidJavaObject ajoAdjustStoreInfo = + new AndroidJavaObject("com.adjust.sdk.AdjustStoreInfo", adjustConfig.StoreInfo.StoreName)) + { + if (adjustConfig.StoreInfo.StoreAppId != null) + { + ajoAdjustStoreInfo.Call("setStoreAppId", adjustConfig.StoreInfo.StoreAppId); + } + ajoAdjustConfig.Call("setStoreInfo", ajoAdjustStoreInfo); + } + } + } + + // check attribution changed delagate + if (adjustConfig.AttributionChangedDelegate != null) + { + onAttributionChangedListener = new AttributionChangedListener(adjustConfig.AttributionChangedDelegate); + ajoAdjustConfig.Call("setOnAttributionChangedListener", onAttributionChangedListener); + } + + // check event success delegate + if (adjustConfig.EventSuccessDelegate != null) + { + onEventTrackingSucceededListener = new EventTrackingSucceededListener(adjustConfig.EventSuccessDelegate); + ajoAdjustConfig.Call("setOnEventTrackingSucceededListener", onEventTrackingSucceededListener); + } + + // check event failure delagate + if (adjustConfig.EventFailureDelegate != null) + { + onEventTrackingFailedListener = new EventTrackingFailedListener(adjustConfig.EventFailureDelegate); + ajoAdjustConfig.Call("setOnEventTrackingFailedListener", onEventTrackingFailedListener); + } + + // check session success delegate + if (adjustConfig.SessionSuccessDelegate != null) + { + onSessionTrackingSucceededListener = new SessionTrackingSucceededListener(adjustConfig.SessionSuccessDelegate); + ajoAdjustConfig.Call("setOnSessionTrackingSucceededListener", onSessionTrackingSucceededListener); + } + + // check session failure delegate + if (adjustConfig.SessionFailureDelegate != null) + { + onSessionTrackingFailedListener = new SessionTrackingFailedListener(adjustConfig.SessionFailureDelegate); + ajoAdjustConfig.Call("setOnSessionTrackingFailedListener", onSessionTrackingFailedListener); + } + + // check deferred deeplink delegate + if (adjustConfig.DeferredDeeplinkDelegate != null) + { + onDeferredDeeplinkListener = new DeferredDeeplinkListener(adjustConfig.DeferredDeeplinkDelegate); + ajoAdjustConfig.Call("setOnDeferredDeeplinkResponseListener", onDeferredDeeplinkListener); + } + + // initialise and start the SDK + ajcAdjust.CallStatic("initSdk", ajoAdjustConfig); + } + } + + public static void TrackEvent(AdjustEvent adjustEvent) + { + using (AndroidJavaObject ajoAdjustEvent = + new AndroidJavaObject("com.adjust.sdk.AdjustEvent", adjustEvent.EventToken)) + { + // check if user has set revenue for the event + if (adjustEvent.Revenue != null) + { + ajoAdjustEvent.Call("setRevenue", (double)adjustEvent.Revenue, adjustEvent.Currency); + } + + // check if user has added any callback parameters to the event + if (adjustEvent.CallbackParameters != null) + { + for (int i = 0; i < adjustEvent.CallbackParameters.Count; i += 2) + { + string key = adjustEvent.CallbackParameters[i]; + string value = adjustEvent.CallbackParameters[i + 1]; + ajoAdjustEvent.Call("addCallbackParameter", key, value); + } + } + + // check if user has added any partner parameters to the event + if (adjustEvent.PartnerParameters != null) + { + for (int i = 0; i < adjustEvent.PartnerParameters.Count; i += 2) + { + string key = adjustEvent.PartnerParameters[i]; + string value = adjustEvent.PartnerParameters[i + 1]; + ajoAdjustEvent.Call("addPartnerParameter", key, value); + } + } + + // check if user has set deduplication ID for the event + if (adjustEvent.DeduplicationId != null) + { + ajoAdjustEvent.Call("setDeduplicationId", adjustEvent.DeduplicationId); + } + + // check if user has added callback ID to the event + if (adjustEvent.CallbackId != null) + { + ajoAdjustEvent.Call("setCallbackId", adjustEvent.CallbackId); + } + + // check if user has added product ID to the event + if (adjustEvent.ProductId != null) + { + ajoAdjustEvent.Call("setProductId", adjustEvent.ProductId); + } + + // check if user has added purchase token to the event + if (adjustEvent.PurchaseToken != null) + { + ajoAdjustEvent.Call("setPurchaseToken", adjustEvent.PurchaseToken); + } + + // track the event + ajcAdjust.CallStatic("trackEvent", ajoAdjustEvent); + } + } + + public static void Enable() + { + ajcAdjust.CallStatic("enable"); + } + + public static void Disable() + { + ajcAdjust.CallStatic("disable"); + } + + public static void SwitchToOfflineMode() + { + ajcAdjust.CallStatic("switchToOfflineMode"); + } + + public static void SwitchBackToOnlineMode() + { + ajcAdjust.CallStatic("switchBackToOnlineMode"); + } + + public static void EnableCoppaCompliance() + { + ajcAdjust.CallStatic("enableCoppaCompliance", ajoCurrentActivity); + } + + public static void DisableCoppaCompliance() + { + ajcAdjust.CallStatic("disableCoppaCompliance", ajoCurrentActivity); + } + + public static void EnablePlayStoreKidsApp() + { + ajcAdjust.CallStatic("enablePlayStoreKidsApp", ajoCurrentActivity); + } + + public static void DisablePlayStoreKidsApp() + { + ajcAdjust.CallStatic("disablePlayStoreKidsApp", ajoCurrentActivity); + } + + public static void SetPushToken(string pushToken) + { + ajcAdjust.CallStatic("setPushToken", pushToken, ajoCurrentActivity); + } + + public static void GdprForgetMe() + { + ajcAdjust.CallStatic("gdprForgetMe", ajoCurrentActivity); + } + + public static void AddGlobalPartnerParameter(string key, string value) + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("addGlobalPartnerParameter", key, value); + } + + public static void AddGlobalCallbackParameter(string key, string value) + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("addGlobalCallbackParameter", key, value); + } + + public static void RemoveGlobalPartnerParameter(string key) + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("removeGlobalPartnerParameter", key); + } + + public static void RemoveGlobalCallbackParameter(string key) + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("removeGlobalCallbackParameter", key); + } + + public static void RemoveGlobalPartnerParameters() + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("removeGlobalPartnerParameters"); + } + + public static void RemoveGlobalCallbackParameters() + { + if (ajcAdjust == null) + { + ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); + } + ajcAdjust.CallStatic("removeGlobalCallbackParameters"); + } + + public static void ProcessDeeplink(AdjustDeeplink deeplink) + { + using (AndroidJavaClass ajcUri = new AndroidJavaClass("android.net.Uri")) + using (AndroidJavaObject ajoUri = ajcUri.CallStatic("parse", deeplink.Deeplink)) + using (AndroidJavaObject ajoAdjustDeeplink = new AndroidJavaObject("com.adjust.sdk.AdjustDeeplink", ajoUri)) + { + if (deeplink.Referrer != null) + { + using (AndroidJavaObject ajoReferrer = ajcUri.CallStatic("parse", deeplink.Referrer)) + { + ajoAdjustDeeplink.Call("setReferrer", ajoReferrer); + } + } + + ajcAdjust.CallStatic("processDeeplink", ajoAdjustDeeplink, ajoCurrentActivity); + } + } + + public static void TrackAdRevenue(AdjustAdRevenue adRevenue) + { + using (AndroidJavaObject ajoAdjustAdRevenue = + new AndroidJavaObject("com.adjust.sdk.AdjustAdRevenue", adRevenue.Source)) + { + // check if user has set revenue + if (adRevenue.Revenue != null) + { + using (AndroidJavaObject ajoRevenue = new AndroidJavaObject("java.lang.Double", adRevenue.Revenue)) + { + ajoAdjustAdRevenue.Call("setRevenue", ajoRevenue, adRevenue.Currency); + } + } + + // check if user has set ad impressions count + if (adRevenue.AdImpressionsCount != null) + { + using (AndroidJavaObject ajoAdImpressionsCount = + new AndroidJavaObject("java.lang.Integer", adRevenue.AdImpressionsCount)) + { + ajoAdjustAdRevenue.Call("setAdImpressionsCount", ajoAdImpressionsCount); + } + } + + // check if user has set ad revenue network + if (adRevenue.AdRevenueNetwork != null) + { + ajoAdjustAdRevenue.Call("setAdRevenueNetwork", adRevenue.AdRevenueNetwork); + } + + // check if user has set ad revenue unit + if (adRevenue.AdRevenueUnit != null) + { + ajoAdjustAdRevenue.Call("setAdRevenueUnit", adRevenue.AdRevenueUnit); + } + + // check if user has set ad revenue placement + if (adRevenue.AdRevenuePlacement != null) + { + ajoAdjustAdRevenue.Call("setAdRevenuePlacement", adRevenue.AdRevenuePlacement); + } + + // check if user has added any callback parameters + if (adRevenue.CallbackParameters != null) + { + for (int i = 0; i < adRevenue.CallbackParameters.Count; i += 2) + { + string key = adRevenue.CallbackParameters[i]; + string value = adRevenue.CallbackParameters[i + 1]; + ajoAdjustAdRevenue.Call("addCallbackParameter", key, value); + } + } + + // check if user has added any partner parameters + if (adRevenue.PartnerParameters != null) + { + for (int i = 0; i < adRevenue.PartnerParameters.Count; i += 2) + { + string key = adRevenue.PartnerParameters[i]; + string value = adRevenue.PartnerParameters[i + 1]; + ajoAdjustAdRevenue.Call("addPartnerParameter", key, value); + } + } + + // track ad revenue + ajcAdjust.CallStatic("trackAdRevenue", ajoAdjustAdRevenue); + } + } + + public static void TrackPlayStoreSubscription(AdjustPlayStoreSubscription subscription) + { + using (AndroidJavaObject ajoSubscription = new AndroidJavaObject( + "com.adjust.sdk.AdjustPlayStoreSubscription", + Convert.ToInt64(subscription.Price), + subscription.Currency, + subscription.ProductId, + subscription.OrderId, + subscription.Signature, + subscription.PurchaseToken)) + { + // check if user has set purchase time for subscription + if (subscription.PurchaseTime != null) + { + ajoSubscription.Call("setPurchaseTime", Convert.ToInt64(subscription.PurchaseTime)); + } + + // check if user has added any callback parameters to the subscription + if (subscription.CallbackParameters != null) + { + for (int i = 0; i < subscription.CallbackParameters.Count; i += 2) + { + string key = subscription.CallbackParameters[i]; + string value = subscription.CallbackParameters[i + 1]; + ajoSubscription.Call("addCallbackParameter", key, value); + } + } + + // check if user has added any partner parameters to the subscription + if (subscription.PartnerParameters != null) + { + for (int i = 0; i < subscription.PartnerParameters.Count; i += 2) + { + string key = subscription.PartnerParameters[i]; + string value = subscription.PartnerParameters[i + 1]; + ajoSubscription.Call("addPartnerParameter", key, value); + } + } + + // track the subscription + ajcAdjust.CallStatic("trackPlayStoreSubscription", ajoSubscription); + } + } + + public static void TrackThirdPartySharing(AdjustThirdPartySharing thirdPartySharing) + { + using (var ajoAdjustThirdPartySharing = + thirdPartySharing.IsEnabled != null + ? new AndroidJavaObject("com.adjust.sdk.AdjustThirdPartySharing", + new AndroidJavaObject("java.lang.Boolean", thirdPartySharing.IsEnabled.Value)) + : new AndroidJavaObject("com.adjust.sdk.AdjustThirdPartySharing", (object)null)) + { + if (thirdPartySharing.GranularOptions != null) + { + for (int i = 0; i < thirdPartySharing.GranularOptions.Count;) + { + string partnerName = thirdPartySharing.GranularOptions[i++]; + string key = thirdPartySharing.GranularOptions[i++]; + string value = thirdPartySharing.GranularOptions[i++]; + ajoAdjustThirdPartySharing.Call("addGranularOption", partnerName, key, value); + } + } + + if (thirdPartySharing.PartnerSharingSettings != null) + { + for (int i = 0; i < thirdPartySharing.PartnerSharingSettings.Count;) + { + string partnerName = thirdPartySharing.PartnerSharingSettings[i++]; + string key = thirdPartySharing.PartnerSharingSettings[i++]; + string value = thirdPartySharing.PartnerSharingSettings[i++]; + ajoAdjustThirdPartySharing.Call("addPartnerSharingSetting", partnerName, key, bool.Parse(value)); + } + } + + ajcAdjust.CallStatic("trackThirdPartySharing", ajoAdjustThirdPartySharing); + } + } + + public static void TrackMeasurementConsent(bool measurementConsent) + { + ajcAdjust.CallStatic("trackMeasurementConsent", measurementConsent); + } + + public static void IsEnabled(Action onIsEnabled) + { + IsEnabledListener isEnabledProxy = new IsEnabledListener(onIsEnabled); + ajcAdjust.CallStatic("isEnabled", ajoCurrentActivity, isEnabledProxy); + } + + public static void GetAdid(Action onAdidRead) + { + AdidReadListener onAdidReadProxy = new AdidReadListener(onAdidRead); + ajcAdjust.CallStatic("getAdid", onAdidReadProxy); + } + + public static void GetAttribution(Action onAttributionRead) + { + AttributionReadListener onAttributionReadProxy = new AttributionReadListener(onAttributionRead); + ajcAdjust.CallStatic("getAttribution", onAttributionReadProxy); + } + + public static void GetSdkVersion(Action onSdkVersionRead) + { + SdkVersionReadListener onSdkVersionReadProxy = new SdkVersionReadListener(onSdkVersionRead, sdkPrefix); + ajcAdjust.CallStatic("getSdkVersion", onSdkVersionReadProxy); + } + + public static void GetLastDeeplink(Action onLastDeeplinkRead) + { + LastDeeplinkListener onLastDeeplinkReadProxy = new LastDeeplinkListener(onLastDeeplinkRead); + ajcAdjust.CallStatic("getLastDeeplink", ajoCurrentActivity, onLastDeeplinkReadProxy); + } + + public static void EndFirstSessionDelay() + { + ajcAdjust.CallStatic("endFirstSessionDelay"); + } + + public static void EnableCoppaComplianceInDelay() + { + ajcAdjust.CallStatic("enableCoppaComplianceInDelay"); + } + + public static void DisableCoppaComplianceInDelay() + { + ajcAdjust.CallStatic("disableCoppaComplianceInDelay"); + } + + public static void SetExternalDeviceIdInDelay(string externalDeviceId) + { + ajcAdjust.CallStatic("setExternalDeviceIdInDelay", externalDeviceId); + } + + // android specific methods + public static void GetGoogleAdId(Action onDeviceIdsRead) + { + GoogleAdIdReadListener onDeviceIdsReadProxy = new GoogleAdIdReadListener(onDeviceIdsRead); + ajcAdjust.CallStatic("getGoogleAdId", ajoCurrentActivity, onDeviceIdsReadProxy); + } + + public static void GetAmazonAdId(Action onAmazonAdIdRead) + { + AmazonAdIdReadListener onAmazonAdIdReadProxy = new AmazonAdIdReadListener(onAmazonAdIdRead); + ajcAdjust.CallStatic("getAmazonAdId", ajoCurrentActivity, onAmazonAdIdReadProxy); + } + + public static void VerifyPlayStorePurchase( + AdjustPlayStorePurchase purchase, + Action verificationInfoCallback) + { + VerificationResultListener verificationResultListener = new VerificationResultListener(verificationInfoCallback); + using (AndroidJavaObject ajoPurchase = new AndroidJavaObject("com.adjust.sdk.AdjustPlayStorePurchase", + purchase.ProductId, + purchase.PurchaseToken)) + { + ajcAdjust.CallStatic("verifyPlayStorePurchase", ajoPurchase, verificationResultListener); + } + } + + public static void ProcessAndResolveDeeplink(AdjustDeeplink deeplink, Action resolvedLinkCallback) + { + onDeeplinkResolvedListener = new DeeplinkResolutionListener(resolvedLinkCallback); + using (AndroidJavaClass ajcUri = new AndroidJavaClass("android.net.Uri")) + using (AndroidJavaObject ajoUri = ajcUri.CallStatic("parse", deeplink.Deeplink)) + using (AndroidJavaObject ajoAdjustDeeplink = new AndroidJavaObject("com.adjust.sdk.AdjustDeeplink", ajoUri)) + { + if (deeplink.Referrer != null) + { + using (AndroidJavaObject ajoReferrer = ajcUri.CallStatic("parse", deeplink.Referrer)) + { + ajoAdjustDeeplink.Call("setReferrer", ajoReferrer); + } + } + + ajcAdjust.CallStatic( + "processAndResolveDeeplink", + ajoAdjustDeeplink, + ajoCurrentActivity, + onDeeplinkResolvedListener); + } + } + + public static void VerifyAndTrackPlayStorePurchase( + AdjustEvent adjustEvent, + Action verificationInfoCallback) + { + VerificationResultListener verifyAndTrackListener = new VerificationResultListener(verificationInfoCallback); + using (AndroidJavaObject ajoAdjustEvent = + new AndroidJavaObject("com.adjust.sdk.AdjustEvent", adjustEvent.EventToken)) + { + // check if user has set revenue for the event + if (adjustEvent.Revenue != null) + { + ajoAdjustEvent.Call("setRevenue", (double)adjustEvent.Revenue, adjustEvent.Currency); + } + + // check if user has added any callback parameters to the event + if (adjustEvent.CallbackParameters != null) + { + for (int i = 0; i < adjustEvent.CallbackParameters.Count; i += 2) + { + string key = adjustEvent.CallbackParameters[i]; + string value = adjustEvent.CallbackParameters[i + 1]; + ajoAdjustEvent.Call("addCallbackParameter", key, value); + } + } + + // check if user has added any partner parameters to the event + if (adjustEvent.PartnerParameters != null) + { + for (int i = 0; i < adjustEvent.PartnerParameters.Count; i += 2) + { + string key = adjustEvent.PartnerParameters[i]; + string value = adjustEvent.PartnerParameters[i + 1]; + ajoAdjustEvent.Call("addPartnerParameter", key, value); + } + } + + // check if user has set deduplication ID for the event + if (adjustEvent.DeduplicationId != null) + { + ajoAdjustEvent.Call("setDeduplicationId", adjustEvent.DeduplicationId); + } + + // check if user has added callback ID to the event + if (adjustEvent.CallbackId != null) + { + ajoAdjustEvent.Call("setCallbackId", adjustEvent.CallbackId); + } + + // check if user has added product ID to the event + if (adjustEvent.ProductId != null) + { + ajoAdjustEvent.Call("setProductId", adjustEvent.ProductId); + } + + // check if user has added purchase token to the event + if (adjustEvent.PurchaseToken != null) + { + ajoAdjustEvent.Call("setPurchaseToken", adjustEvent.PurchaseToken); + } + + ajcAdjust.CallStatic("verifyAndTrackPlayStorePurchase", ajoAdjustEvent, verifyAndTrackListener); + } + } + + public static void EnablePlayStoreKidsComplianceInDelay() + { + ajcAdjust.CallStatic("enablePlayStoreKidsComplianceInDelay"); + } + + public static void DisablePlayStoreKidsComplianceInDelay() + { + ajcAdjust.CallStatic("disablePlayStoreKidsComplianceInDelay"); + } + + // used for testing only + public static void SetTestOptions(Dictionary testOptions) + { + using (AndroidJavaObject ajoTestOptions = AdjustUtils.TestOptionsMap2AndroidJavaObject(testOptions, ajoCurrentActivity)) + { + ajcAdjust.CallStatic("setTestOptions", ajoTestOptions); + } + } + + public static void OnResume(string testingArgument = null) + { + if (testingArgument == "test") + { + ajcAdjust.CallStatic("onResume"); + } + } + + public static void OnPause(string testingArgument = null) + { + if (testingArgument == "test") + { + ajcAdjust.CallStatic("onPause"); + } + } + + // private & helper classes + private class AttributionChangedListener : AndroidJavaProxy + { + private Action callback; + + public AttributionChangedListener(Action pCallback) + : base("com.adjust.sdk.OnAttributionChangedListener") + { + this.callback = pCallback; + } + + // native method: + // void onAttributionChanged(AdjustAttribution attribution); + public void onAttributionChanged(AndroidJavaObject ajoAttribution) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + if (ajoAttribution == null) + { + if (callback != 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); + if (jsonResponse != null) { + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } + } + + if (callback != null) + { + callback.Invoke(adjustAttribution); + } + } + catch (Exception) + { + // JSON response reading failed. + } + }); + } + } + + private class DeferredDeeplinkListener : AndroidJavaProxy + { + private Action callback; + + public DeferredDeeplinkListener(Action pCallback) + : base("com.adjust.sdk.OnDeferredDeeplinkResponseListener") + { + this.callback = pCallback; + } + + // native method: + // boolean launchReceivedDeeplink(Uri deeplink); + public bool launchReceivedDeeplink(AndroidJavaObject deeplink) + { + if (this.callback == null) + { + return isDeferredDeeplinkOpeningEnabled; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + string strDeeplink = deeplink != null ? deeplink.Call("toString") : null; + if (callback != null) + { + callback.Invoke(strDeeplink); + } + }); + + return isDeferredDeeplinkOpeningEnabled; + } + } + + private class EventTrackingSucceededListener : AndroidJavaProxy + { + private Action callback; + + public EventTrackingSucceededListener(Action pCallback) : base("com.adjust.sdk.OnEventTrackingSucceededListener") + { + this.callback = pCallback; + } + + // native method: + // void onEventTrackingSucceeded(AdjustEventSuccess eventSuccessResponseData); + public void onEventTrackingSucceeded(AndroidJavaObject eventSuccessData) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + 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); + } + } + + if (callback != null) + { + 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. + } + }); + } + } + + private class EventTrackingFailedListener : AndroidJavaProxy + { + private Action callback; + + public EventTrackingFailedListener(Action pCallback) : base("com.adjust.sdk.OnEventTrackingFailedListener") + { + this.callback = pCallback; + } + + // native method: + // void onEventTrackingFailed(AdjustEventFailure eventFailureResponseData); + public void onEventTrackingFailed(AndroidJavaObject eventFailureData) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + 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); + } + } + + if (callback != null) + { + 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. + } + }); + } + } + + private class SessionTrackingSucceededListener : AndroidJavaProxy + { + private Action callback; + + public SessionTrackingSucceededListener(Action pCallback) + : base("com.adjust.sdk.OnSessionTrackingSucceededListener") + { + this.callback = pCallback; + } + + // native method: + // void onSessionTrackingSucceeded(AdjustSessionSuccess sessionSuccessResponseData); + public void onSessionTrackingSucceeded(AndroidJavaObject sessionSuccessData) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + 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); + } + } + + if (callback != null) + { + 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. + } + }); + } + } + + private class SessionTrackingFailedListener : AndroidJavaProxy + { + private Action callback; + + public SessionTrackingFailedListener(Action pCallback) + : base("com.adjust.sdk.OnSessionTrackingFailedListener") + { + this.callback = pCallback; + } + + // native method: + // void onSessionTrackingFailed(AdjustSessionFailure failureResponseData); + public void onSessionTrackingFailed(AndroidJavaObject sessionFailureData) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + 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); + } + } + + if (callback != null) + { + 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. + } + }); + } + } + + private class GoogleAdIdReadListener : AndroidJavaProxy + { + private Action callback; + + public GoogleAdIdReadListener(Action pCallback) + : base("com.adjust.sdk.OnGoogleAdIdReadListener") + { + this.callback = pCallback; + } + + // native method: + // void onGoogleAdIdRead(String googleAdId); + public void onGoogleAdIdRead(string adid) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(adid); + } + }); + } + } + + private class VerificationResultListener : AndroidJavaProxy + { + private Action callback; + + public VerificationResultListener(Action pCallback) + : base("com.adjust.sdk.OnPurchaseVerificationFinishedListener") + { + this.callback = pCallback; + } + + // native method: + // void onVerificationFinished(AdjustPurchaseVerificationResult result); + public void onVerificationFinished(AndroidJavaObject ajoVerificationInfo) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + if (ajoVerificationInfo == null) + { + if (callback != 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)) + }; + + if (callback != null) + { + callback.Invoke(purchaseVerificationResult); + } + } + catch (Exception) + { + // Handle potential errors during the verification process + } + }); + } + } + + private class DeeplinkResolutionListener : AndroidJavaProxy + { + private Action callback; + + public DeeplinkResolutionListener(Action pCallback) + : base("com.adjust.sdk.OnDeeplinkResolvedListener") + { + this.callback = pCallback; + } + + // native method: + // void onDeeplinkResolved(String resolvedLink); + public void onDeeplinkResolved(string resolvedLink) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(resolvedLink); + } + }); + } + } + + private class AdidReadListener : AndroidJavaProxy + { + private Action callback; + + public AdidReadListener(Action pCallback) + : base("com.adjust.sdk.OnAdidReadListener") + { + this.callback = pCallback; + } + + // native method: + // void onAdidRead(String adid); + public void onAdidRead(string adid) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(adid); + } + }); + } + } + + private class AttributionReadListener : AndroidJavaProxy + { + private Action callback; + + public AttributionReadListener(Action pCallback) + : base("com.adjust.sdk.OnAttributionReadListener") + { + this.callback = pCallback; + } + + // native method: + // void onAttributionRead(AdjustAttribution attribution); + public void onAttributionRead(AndroidJavaObject ajoAttribution) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + try + { + if (ajoAttribution == null) + { + if (callback != 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); + if (jsonResponse != null) { + var jsonResponseNode = JSON.Parse(jsonResponse); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + adjustAttribution.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse); + } + } + + if (callback != null) + { + callback.Invoke(adjustAttribution); + } + } + catch (Exception) + { + // JSON response reading failed. + } + }); + } + } + + private class AmazonAdIdReadListener : AndroidJavaProxy + { + private Action callback; + + public AmazonAdIdReadListener(Action pCallback) + : base("com.adjust.sdk.OnAmazonAdIdReadListener") + { + this.callback = pCallback; + } + + // native method: + // void onAmazonAdIdRead(String amazonAdId); + public void onAmazonAdIdRead(string amazonAdId) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(amazonAdId); + } + }); + } + } + + private class SdkVersionReadListener : AndroidJavaProxy + { + private Action callback; + private string sdkPrefix; + + public SdkVersionReadListener(Action pCallback, string sdkPrefix) + : base("com.adjust.sdk.OnSdkVersionReadListener") + { + this.callback = pCallback; + this.sdkPrefix = sdkPrefix; + } + + // native method: + // void onSdkVersionRead(String sdkVersion); + public void onSdkVersionRead(string sdkVersion) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(this.sdkPrefix + "@" + sdkVersion); + } + }); + } + } + + private class IsEnabledListener : AndroidJavaProxy + { + private Action callback; + + public IsEnabledListener(Action pCallback) + : base("com.adjust.sdk.OnIsEnabledListener") + { + this.callback = pCallback; + } + + // native method: + // void onIsEnabledRead(boolean isEnabled); + public void onIsEnabledRead(bool isEnabled) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (callback != null) + { + callback.Invoke(isEnabled); + } + }); + } + } + + private class LastDeeplinkListener : AndroidJavaProxy + { + private Action callback; + + public LastDeeplinkListener(Action pCallback) + : base("com.adjust.sdk.OnLastDeeplinkReadListener") + { + this.callback = pCallback; + } + + // native method: + // void onLastDeeplinkRead(Uri deeplink); + public void onLastDeeplinkRead(AndroidJavaObject ajoLastDeeplink) + { + if (this.callback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + string deeplink = ajoLastDeeplink != null ? ajoLastDeeplink.Call("toString") : null; + if (callback != null) + { + callback.Invoke(deeplink); + } + }); + } + } + } +#endif +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs.meta new file mode 100644 index 0000000..5aa3741 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAndroid.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 04f57a99ef137445992d048a89c36788 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs b/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs new file mode 100644 index 0000000..ef345e1 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustAppStorePurchase + { + public string TransactionId { get; private set; } + public string ProductId { get; private set; } + + public AdjustAppStorePurchase(string transactionId, string productId) + { + this.TransactionId = transactionId; + this.ProductId = productId; + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs.meta new file mode 100644 index 0000000..dbd826d --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAppStorePurchase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 828a981c8c96741afa5d16ccb679e5af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs b/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs new file mode 100644 index 0000000..a7bdcc5 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace AdjustSdk +{ + public class AdjustAppStoreSubscription + { + private List innerCallbackParameters; + private List innerPartnerParameters; + + public string Price { get; private set; } + public string Currency { get; private set; } + public string TransactionId { get; private set; } + public string TransactionDate { get; set; } + public string SalesRegion { get; set; } + public ReadOnlyCollection CallbackParameters + { + get + { + if (innerCallbackParameters == null) + { + return null; + } + else + { + return innerCallbackParameters.AsReadOnly(); + } + } + } + public ReadOnlyCollection PartnerParameters + { + get + { + if (innerPartnerParameters == null) + { + return null; + } + else + { + return innerPartnerParameters.AsReadOnly(); + } + } + } + + public AdjustAppStoreSubscription(string price, string currency, string transactionId) + { + this.Price = price; + this.Currency = currency; + this.TransactionId = transactionId; + } + + public void AddCallbackParameter(string key, string value) + { + if (this.innerCallbackParameters == null) + { + this.innerCallbackParameters = new List(); + } + this.innerCallbackParameters.Add(key); + this.innerCallbackParameters.Add(value); + } + + public void AddPartnerParameter(string key, string value) + { + if (this.innerPartnerParameters == null) + { + this.innerPartnerParameters = new List(); + } + this.innerPartnerParameters.Add(key); + this.innerPartnerParameters.Add(value); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs.meta new file mode 100644 index 0000000..f5af330 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAppStoreSubscription.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7e2d69221b1124370a4c016edce5a95a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs b/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs new file mode 100644 index 0000000..661bc63 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustAttribution + { + public string TrackerToken { get; set; } + public string TrackerName { get; set; } + public string Network { get; set; } + public string Campaign { get; set; } + public string Adgroup { get; set; } + public string Creative { get; set; } + public string ClickLabel { get; set; } + 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; } + + public AdjustAttribution() {} + + public AdjustAttribution(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + this.TrackerName = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTrackerName); + this.TrackerToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTrackerToken); + this.Network = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyNetwork); + this.Campaign = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCampaign); + this.Adgroup = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdgroup); + this.Creative = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCreative); + this.ClickLabel = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyClickLabel); + this.CostType = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostType); + try + { + this.CostAmount = double.Parse( + AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostAmount), + System.Globalization.CultureInfo.InvariantCulture); + } + catch (Exception) + { + // attribution response doesn't contain cost amount attached + // value will default to null + } + this.CostCurrency = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostCurrency); + this.FbInstallReferrer = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyFbInstallReferrer); + + var jsonResponseValue = jsonNode[AdjustUtils.KeyJsonResponse]; + if (jsonResponseValue == null) + { + return; + } + this.JsonResponse = AdjustUtils.GetAttributionJsonResponse(jsonResponseValue); + } + + public AdjustAttribution(Dictionary dicAttributionData) + { + if (dicAttributionData == null) + { + return; + } + + this.TrackerName = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyTrackerName); + this.TrackerToken = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyTrackerToken); + this.Network = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyNetwork); + this.Campaign = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCampaign); + this.Adgroup = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyAdgroup); + this.Creative = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCreative); + this.ClickLabel = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyClickLabel); + this.CostType = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostType); + try + { + this.CostAmount = double.Parse( + AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostAmount), + System.Globalization.CultureInfo.InvariantCulture); + } + catch (Exception) + { + // attribution response doesn't contain cost amount attached + // value will default to null + } + this.CostCurrency = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyCostCurrency); + this.FbInstallReferrer = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyFbInstallReferrer); + + string jsonResponseString = AdjustUtils.TryGetValue(dicAttributionData, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, this.JsonResponse); + } + } + + public void BuildJsonResponseFromString(string jsonResponseString) + { + var jsonNode = JSON.Parse(jsonResponseString); + if (jsonNode == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse); + } + + public string GetJsonResponseAsString() + { + return AdjustUtils.GetJsonResponseCompact(JsonResponse); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs.meta new file mode 100644 index 0000000..37c4bbd --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustAttribution.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cc46748ad0e664f6d839a4f1a23d9f47 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustConfig.cs b/Assets/rd3/Adjust/Scripts/AdjustConfig.cs new file mode 100644 index 0000000..c13d75c --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustConfig.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustConfig + { + public string AppToken { get; private set; } + public string DefaultTracker { get; set; } + public string ExternalDeviceId { get; set; } + public bool? IsCoppaComplianceEnabled { get; set; } + public bool? IsSendingInBackgroundEnabled { get; set; } + public bool? IsCostDataInAttributionEnabled { get; set; } + public bool? IsDeviceIdsReadingOnceEnabled { get; set; } + public bool? IsDeferredDeeplinkOpeningEnabled { get; set; } + public bool? IsAppTrackingTransparencyUsageEnabled { get; set; } + public bool? IsFirstSessionDelayEnabled { get; set; } + public bool? AllowSuppressLogLevel { get; private set; } + public bool? IsDataResidency { get; private set; } + public bool? ShouldUseSubdomains { get; private set; } + public int? EventDeduplicationIdsMaxSize { get; set; } + public List UrlStrategyDomains { get; private set; } + public AdjustLogLevel? LogLevel { get; set; } + public AdjustEnvironment Environment { get; private set; } + public AdjustStoreInfo StoreInfo { get; set; } + public Action AttributionChangedDelegate { get; set; } + public Action EventSuccessDelegate { get; set; } + public Action EventFailureDelegate { get; set; } + public Action SessionSuccessDelegate { get; set; } + public Action SessionFailureDelegate { get; set; } + public Action DeferredDeeplinkDelegate { get; set; } + public Action> SkanUpdatedDelegate { get; set; } + + // iOS specific + public bool? IsAdServicesEnabled { get; set; } + public bool? IsIdfaReadingEnabled { get; set; } + public bool? IsIdfvReadingEnabled { get; set; } + public bool? IsSkanAttributionEnabled { get; set; } + public bool? IsLinkMeEnabled { get; set; } + public int? AttConsentWaitingInterval { get; set; } + + // Android specific + public bool? IsPlayStoreKidsComplianceEnabled { get; set; } + public bool? IsPreinstallTrackingEnabled { get; set; } + public string PreinstallFilePath { get; set; } + public string FbAppId { get; set; } + + public AdjustConfig(string appToken, AdjustEnvironment environment) + { + this.AppToken = appToken; + this.Environment = environment; + } + + public AdjustConfig(string appToken, AdjustEnvironment environment, bool allowSuppressLogLevel) + { + this.AppToken = appToken; + this.Environment = environment; + this.AllowSuppressLogLevel = allowSuppressLogLevel; + } + + public void SetUrlStrategy( + List urlStrategyDomains, + bool shouldUseSubdomains, + bool isDataResidency) + { + this.UrlStrategyDomains = urlStrategyDomains; + this.ShouldUseSubdomains = shouldUseSubdomains; + this.IsDataResidency = isDataResidency; + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustConfig.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustConfig.cs.meta new file mode 100644 index 0000000..d98ac07 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustConfig.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 02d4cad14fc094b17afde3b685897e5e +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs b/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs new file mode 100644 index 0000000..8ff852e --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs @@ -0,0 +1,15 @@ +using System; + +namespace AdjustSdk +{ + public class AdjustDeeplink + { + public string Deeplink { get; private set; } + public string Referrer { get; set; } + + public AdjustDeeplink(string deeplink) + { + this.Deeplink = deeplink; + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs.meta new file mode 100644 index 0000000..e4c1597 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustDeeplink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40e25efef61754d66a47cd3e62a7f6bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs b/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs new file mode 100644 index 0000000..f57f3bf --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs @@ -0,0 +1,25 @@ +namespace AdjustSdk +{ + [System.Serializable] + public enum AdjustEnvironment + { + Sandbox, + Production + } + + public static class AdjustEnvironmentExtension + { + public static string ToLowercaseString(this AdjustEnvironment adjustEnvironment) + { + switch (adjustEnvironment) + { + case AdjustEnvironment.Sandbox: + return "sandbox"; + case AdjustEnvironment.Production: + return "production"; + default: + return "unknown"; + } + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs.meta new file mode 100644 index 0000000..fb47242 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEnvironment.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 633f6fa279b2244fdb999db0441f9aac +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustEvent.cs b/Assets/rd3/Adjust/Scripts/AdjustEvent.cs new file mode 100644 index 0000000..0779e16 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEvent.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace AdjustSdk +{ + public class AdjustEvent + { + private List innerCallbackParameters; + private List innerPartnerParameters; + + public string EventToken { get; private set; } + public double? Revenue { get; private set; } + public string Currency { get; private set; } + public string CallbackId { get; set; } + public string DeduplicationId { get; set; } + public string ProductId { get; set; } + public ReadOnlyCollection CallbackParameters + { + get + { + if (innerCallbackParameters == null) + { + return null; + } + else + { + return innerCallbackParameters.AsReadOnly(); + } + } + } + public ReadOnlyCollection PartnerParameters + { + get + { + if (innerPartnerParameters == null) + { + return null; + } + else + { + return innerPartnerParameters.AsReadOnly(); + } + } + } + // ios specific + public string TransactionId { get; set; } + // android specific + public string PurchaseToken; + + public AdjustEvent(string eventToken) + { + this.EventToken = eventToken; + } + + public void SetRevenue(double amount, string currency) + { + this.Revenue = amount; + this.Currency = currency; + } + + public void AddCallbackParameter(string key, string value) + { + if (this.innerCallbackParameters == null) + { + this.innerCallbackParameters = new List(); + } + this.innerCallbackParameters.Add(key); + this.innerCallbackParameters.Add(value); + } + + public void AddPartnerParameter(string key, string value) + { + if (this.innerPartnerParameters == null) + { + this.innerPartnerParameters = new List(); + } + this.innerPartnerParameters.Add(key); + this.innerPartnerParameters.Add(value); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustEvent.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustEvent.cs.meta new file mode 100644 index 0000000..41ea634 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEvent.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cd89f7713977f497a862f1a1b6f60933 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs b/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs new file mode 100644 index 0000000..0320b8a --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustEventFailure + { + public string Adid { get; set; } + public string Message { get; set; } + public string Timestamp { get; set; } + public string EventToken { get; set; } + public string CallbackId { get; set; } + public bool WillRetry { get; set; } + public Dictionary JsonResponse { get; set; } + + public AdjustEventFailure() {} + + public AdjustEventFailure(Dictionary eventFailureDataMap) + { + if (eventFailureDataMap == null) + { + return; + } + + this.Adid = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyTimestamp); + this.EventToken = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyEventToken); + this.CallbackId = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyCallbackId); + + bool willRetry; + if (bool.TryParse(AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyWillRetry), out willRetry)) + { + this.WillRetry = willRetry; + } + + string jsonResponseString = AdjustUtils.TryGetValue(eventFailureDataMap, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + } + + public AdjustEventFailure(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp); + this.EventToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyEventToken); + this.CallbackId = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCallbackId); + this.WillRetry = Convert.ToBoolean(AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyWillRetry)); + + var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse]; + if (jsonResponseNode == null) + { + return; + } + if (jsonResponseNode.AsObject == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + + public void BuildJsonResponseFromString(string jsonResponseString) + { + var jsonNode = JSON.Parse(jsonResponseString); + if (jsonNode == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse); + } + + public string GetJsonResponseAsString() + { + return AdjustUtils.GetJsonResponseCompact(JsonResponse); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs.meta new file mode 100644 index 0000000..ee12da9 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEventFailure.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ea86cd4e1c6d0496397920902d0f0b5f +timeCreated: 1458128791 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs b/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs new file mode 100644 index 0000000..925ac49 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustEventSuccess + { + public string Adid { get; set; } + public string Message { get; set; } + public string Timestamp { get; set; } + public string EventToken { get; set; } + public string CallbackId { get; set; } + public Dictionary JsonResponse { get; set; } + + public AdjustEventSuccess() {} + + public AdjustEventSuccess(Dictionary eventSuccessDataMap) + { + if (eventSuccessDataMap == null) + { + return; + } + + this.Adid = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyTimestamp); + this.EventToken = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyEventToken); + this.CallbackId = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyCallbackId); + + string jsonResponseString = AdjustUtils.TryGetValue(eventSuccessDataMap, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + } + + public AdjustEventSuccess(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp); + this.EventToken = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyEventToken); + this.CallbackId = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCallbackId); + + var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse]; + if (jsonResponseNode == null) + { + return; + } + if (jsonResponseNode.AsObject == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + + public void BuildJsonResponseFromString(string jsonResponseString) + { + var jsonNode = JSON.Parse(jsonResponseString); + if (jsonNode == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse); + } + + public string GetJsonResponseAsString() + { + return AdjustUtils.GetJsonResponseCompact(JsonResponse); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs.meta new file mode 100644 index 0000000..a750f56 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustEventSuccess.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 1957a0e6e9aa14f0e8adefa2120f1e02 +timeCreated: 1458128791 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs b/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs new file mode 100644 index 0000000..63adf16 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs @@ -0,0 +1,63 @@ +namespace AdjustSdk +{ + [System.Serializable] + public enum AdjustLogLevel + { + Verbose = 1, + Debug, + Info, + Warn, + Error, + Assert, + Suppress + } + + public static class AdjustLogLevelExtension + { + public static string ToLowercaseString(this AdjustLogLevel AdjustLogLevel) + { + switch (AdjustLogLevel) + { + case AdjustLogLevel.Verbose: + return "verbose"; + case AdjustLogLevel.Debug: + return "debug"; + case AdjustLogLevel.Info: + return "info"; + case AdjustLogLevel.Warn: + return "warn"; + case AdjustLogLevel.Error: + return "error"; + case AdjustLogLevel.Assert: + return "assert"; + case AdjustLogLevel.Suppress: + return "suppress"; + default: + return "unknown"; + } + } + + public static string ToUppercaseString(this AdjustLogLevel AdjustLogLevel) + { + switch (AdjustLogLevel) + { + case AdjustLogLevel.Verbose: + return "VERBOSE"; + case AdjustLogLevel.Debug: + return "DEBUG"; + case AdjustLogLevel.Info: + return "INFO"; + case AdjustLogLevel.Warn: + return "WARN"; + case AdjustLogLevel.Error: + return "ERROR"; + case AdjustLogLevel.Assert: + return "ASSERT"; + case AdjustLogLevel.Suppress: + return "SUPPRESS"; + default: + return "UNKNOWN"; + } + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs.meta new file mode 100644 index 0000000..226164e --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustLogLevel.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 428ab44990df24973902248a9d2b43dd +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs b/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs new file mode 100644 index 0000000..2d2ddde --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustPlayStorePurchase + { + public string ProductId { get; private set; } + public string PurchaseToken { get; private set; } + + public AdjustPlayStorePurchase(string productId, string purchaseToken) + { + this.ProductId = productId; + this.PurchaseToken = purchaseToken; + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs.meta new file mode 100644 index 0000000..004849b --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPlayStorePurchase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d875a71a5aeb1496d93afac749ab17f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs b/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs new file mode 100644 index 0000000..a48d017 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace AdjustSdk +{ + public class AdjustPlayStoreSubscription + { + private List innerCallbackParameters; + private List innerPartnerParameters; + + public string Price { get; private set; } + public string Currency { get; private set; } + public string ProductId { get; private set; } + public string OrderId { get; private set; } + public string Signature { get; private set; } + public string PurchaseToken { get; private set; } + public string PurchaseTime { get; set; } + public ReadOnlyCollection CallbackParameters + { + get + { + if (innerCallbackParameters == null) + { + return null; + } + else + { + return innerCallbackParameters.AsReadOnly(); + } + } + } + public ReadOnlyCollection PartnerParameters + { + get + { + if (innerPartnerParameters == null) + { + return null; + } + else + { + return innerPartnerParameters.AsReadOnly(); + } + } + } + + public AdjustPlayStoreSubscription( + string price, + string currency, + string productId, + string orderId, + string signature, + string purchaseToken) + { + this.Price = price; + this.Currency = currency; + this.ProductId = productId; + this.OrderId = orderId; + this.Signature = signature; + this.PurchaseToken = purchaseToken; + } + + public void AddCallbackParameter(string key, string value) + { + if (this.innerCallbackParameters == null) + { + this.innerCallbackParameters = new List(); + } + this.innerCallbackParameters.Add(key); + this.innerCallbackParameters.Add(value); + } + + public void AddPartnerParameter(string key, string value) + { + if (this.innerPartnerParameters == null) + { + this.innerPartnerParameters = new List(); + } + this.innerPartnerParameters.Add(key); + this.innerPartnerParameters.Add(value); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs.meta new file mode 100644 index 0000000..8b82732 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPlayStoreSubscription.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69e7a4074abb44758b3f011d8352a57a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs b/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs new file mode 100644 index 0000000..6b5eb65 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustPurchaseVerificationResult + { + public int Code { get; set; } + public string Message { get; set; } + public string VerificationStatus { get; set; } + + public AdjustPurchaseVerificationResult() {} + + public AdjustPurchaseVerificationResult(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + string strCode = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCode); + this.Code = int.Parse(strCode); + this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage); + this.VerificationStatus = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyVerificationStatus); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs.meta new file mode 100644 index 0000000..83cbb24 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustPurchaseVerificationResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbd451b59ec374fa7b72f226b1cef0b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef b/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef new file mode 100644 index 0000000..93b41c2 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef @@ -0,0 +1,6 @@ +{ + "name": "AdjustSdk.Scripts", + "references": [], + "includePlatforms": [], + "excludePlatforms": [] +} \ No newline at end of file diff --git a/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef.meta b/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef.meta new file mode 100644 index 0000000..99f43a5 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSdk.Scripts.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7d8924c6e6beb44e18f19e8c0b5068cd +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs b/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs new file mode 100644 index 0000000..62c0ead --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustSessionFailure + { + public string Adid { get; set; } + public string Message { get; set; } + public string Timestamp { get; set; } + public bool WillRetry { get; set; } + public Dictionary JsonResponse { get; set; } + + public AdjustSessionFailure() {} + + public AdjustSessionFailure(Dictionary sessionFailureDataMap) + { + if (sessionFailureDataMap == null) + { + return; + } + + this.Adid = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyTimestamp); + + bool willRetry; + if (bool.TryParse(AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyWillRetry), out willRetry)) + { + this.WillRetry = willRetry; + } + + string jsonResponseString = AdjustUtils.TryGetValue(sessionFailureDataMap, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + } + + public AdjustSessionFailure(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp); + this.WillRetry = Convert.ToBoolean(AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyWillRetry)); + + var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse]; + if (jsonResponseNode == null) + { + return; + } + if (jsonResponseNode.AsObject == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + + public void BuildJsonResponseFromString(string jsonResponseString) + { + var jsonNode = JSON.Parse(jsonResponseString); + if (jsonNode == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse); + } + + public string GetJsonResponseAsString() + { + return AdjustUtils.GetJsonResponseCompact(JsonResponse); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs.meta new file mode 100644 index 0000000..4e905a4 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSessionFailure.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b4de268ab985448a594fb82264190742 +timeCreated: 1458128791 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs b/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs new file mode 100644 index 0000000..f556ee2 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; + +namespace AdjustSdk +{ + public class AdjustSessionSuccess + { + public string Adid { get; set; } + public string Message { get; set; } + public string Timestamp { get; set; } + public Dictionary JsonResponse { get; set; } + + public AdjustSessionSuccess() {} + + public AdjustSessionSuccess(Dictionary sessionSuccessDataMap) + { + if (sessionSuccessDataMap == null) + { + return; + } + + this.Adid = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyTimestamp); + + string jsonResponseString = AdjustUtils.TryGetValue(sessionSuccessDataMap, AdjustUtils.KeyJsonResponse); + var jsonResponseNode = JSON.Parse(jsonResponseString); + if (jsonResponseNode != null && jsonResponseNode.AsObject != null) + { + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + } + + public AdjustSessionSuccess(string jsonString) + { + var jsonNode = JSON.Parse(jsonString); + if (jsonNode == null) + { + return; + } + + this.Adid = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyAdid); + this.Message = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyMessage); + this.Timestamp = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyTimestamp); + + var jsonResponseNode = jsonNode[AdjustUtils.KeyJsonResponse]; + if (jsonResponseNode == null) + { + return; + } + if (jsonResponseNode.AsObject == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, JsonResponse); + } + + public void BuildJsonResponseFromString(string jsonResponseString) + { + var jsonNode = JSON.Parse(jsonResponseString); + if (jsonNode == null) + { + return; + } + + this.JsonResponse = new Dictionary(); + AdjustUtils.WriteJsonResponseDictionary(jsonNode.AsObject, JsonResponse); + } + + public string GetJsonResponseAsString() + { + return AdjustUtils.GetJsonResponseCompact(JsonResponse); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs.meta new file mode 100644 index 0000000..643c083 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustSessionSuccess.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c23847e7a1f464d7a8c7f9b35829af17 +timeCreated: 1458128791 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs b/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs new file mode 100644 index 0000000..0247d0f --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs @@ -0,0 +1,15 @@ +using System; + +namespace AdjustSdk +{ + public class AdjustStoreInfo + { + public string StoreName { get; private set; } + public string StoreAppId { get; set; } + + public AdjustStoreInfo(string storeName) + { + this.StoreName = storeName; + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs.meta new file mode 100644 index 0000000..4ea2ed0 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustStoreInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 09215b0ccf65143ae91e6fa6cdca34b9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs b/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs new file mode 100644 index 0000000..0243a83 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace AdjustSdk +{ + public class AdjustThirdPartySharing + { + private List innerGranularOptions; + private List innerPartnerSharingSettings; + + public bool? IsEnabled { get; private set; } + public ReadOnlyCollection GranularOptions + { + get + { + if (innerGranularOptions == null) + { + return null; + } + else + { + return innerGranularOptions.AsReadOnly(); + } + } + } + public ReadOnlyCollection PartnerSharingSettings + { + get + { + if (innerPartnerSharingSettings == null) + { + return null; + } + else + { + return innerPartnerSharingSettings.AsReadOnly(); + } + } + } + + public AdjustThirdPartySharing(bool? isEnabled) + { + this.IsEnabled = isEnabled; + } + + public void AddGranularOption(string partnerName, string key, string value) + { + if (this.innerGranularOptions == null) + { + this.innerGranularOptions = new List(); + } + this.innerGranularOptions.Add(partnerName); + this.innerGranularOptions.Add(key); + this.innerGranularOptions.Add(value); + } + + public void AddPartnerSharingSetting(string partnerName, string key, bool value) + { + if (this.innerPartnerSharingSettings == null) + { + this.innerPartnerSharingSettings = new List(); + } + this.innerPartnerSharingSettings.Add(partnerName); + this.innerPartnerSharingSettings.Add(key); + this.innerPartnerSharingSettings.Add(value.ToString()); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs.meta new file mode 100644 index 0000000..5270a0b --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustThirdPartySharing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcb2591dfab904327904b8879af699ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustThreadDispatcher.cs b/Assets/rd3/Adjust/Scripts/AdjustThreadDispatcher.cs new file mode 100644 index 0000000..26157f3 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustThreadDispatcher.cs @@ -0,0 +1,49 @@ +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(); + } + if (action != null) + { + 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/rd3/Adjust/Scripts/AdjustThreadDispatcher.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustThreadDispatcher.cs.meta new file mode 100644 index 0000000..fe68f17 --- /dev/null +++ b/Assets/rd3/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/rd3/Adjust/Scripts/AdjustUtils.cs b/Assets/rd3/Adjust/Scripts/AdjustUtils.cs new file mode 100644 index 0000000..ae21f5e --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustUtils.cs @@ -0,0 +1,448 @@ +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 + } +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustUtils.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustUtils.cs.meta new file mode 100644 index 0000000..5f6f1ad --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustUtils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 98e51a1481cc24ddebf93f61f6c1eb9d +timeCreated: 1458230617 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/AdjustiOS.cs b/Assets/rd3/Adjust/Scripts/AdjustiOS.cs new file mode 100644 index 0000000..308b720 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustiOS.cs @@ -0,0 +1,1121 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace AdjustSdk +{ +#if UNITY_IOS + public class AdjustiOS + { + private const string sdkPrefix = "unity5.4.2"; + + // app callbacks as method parameters + private static List> appIsEnabledGetterCallbacks; + private static List> appAttributionGetterCallbacks; + private static List> appAdidGetterCallbacks; + private static List> appIdfaGetterCallbacks; + private static List> appIdfvGetterCallbacks; + private static List> appLastDeeplinkGetterCallbacks; + private static List> appSdkVersionGetterCallbacks; + private static List> appAttCallbacks; + private static Dictionary> appPurchaseVerificationCallbacks; + private static Dictionary> appVerifyAndTrackCallbacks; + private static int nextPurchaseVerificationCallbackId = 0; + private static int nextVerifyAndTrackCallbackId = 0; + private static Action appResolvedDeeplinkCallback; + private static Action appSkanErrorCallback; + + // app callbacks as subscriptions + private static Action appAttributionCallback; + private static Action appSessionSuccessCallback; + private static Action appSessionFailureCallback; + private static Action appEventSuccessCallback; + private static Action appEventFailureCallback; + private static Action appDeferredDeeplinkCallback; + private static Action> appSkanUpdatedCallback; + + // extenral C methods + private delegate void AdjustDelegateAttributionCallback(string attribution); + private delegate void AdjustDelegateSessionSuccessCallback(string sessionSuccess); + private delegate void AdjustDelegateSessionFailureCallback(string sessionFailure); + private delegate void AdjustDelegateEventSuccessCallback(string eventSuccess); + private delegate void AdjustDelegateEventFailureCallback(string eventFailure); + private delegate void AdjustDelegateDeferredDeeplinkCallback(string callback); + private delegate void AdjustDelegateSkanUpdatedCallback(string callback); + [DllImport("__Internal")] + private static extern void _AdjustInitSdk( + string appToken, + string environment, + string sdkPrefix, + string defaultTracker, + string externalDeviceId, + string jsonUrlStrategyDomains, + string storeName, + string storeAppId, + int allowSuppressLogLevel, + int logLevel, + int attConsentWaitingInterval, + int eventDeduplicationIdsMaxSize, + int shouldUseSubdomains, + int isCoppaComplianceEnabled, + int isDataResidency, + int isSendingInBackgroundEnabled, + int isAdServicesEnabled, + int isIdfaReadingEnabled, + int isIdfvReadingEnabled, + int isSkanAttributionEnabled, + int isLinkMeEnabled, + int isCostDataInAttributionEnabled, + int isDeviceIdsReadingOnceEnabled, + int isAppTrackingTransparencyUsageEnabled, + int isFirstSessionDelayEnabled, + int isDeferredDeeplinkOpeningEnabled, + AdjustDelegateAttributionCallback attributionCallback, + AdjustDelegateEventSuccessCallback eventSuccessCallback, + AdjustDelegateEventFailureCallback eventFailureCallback, + AdjustDelegateSessionSuccessCallback sessionSuccessCallback, + AdjustDelegateSessionFailureCallback sessionFailureCallback, + AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback, + AdjustDelegateSkanUpdatedCallback skanUpdatedCallback); + + [DllImport("__Internal")] + private static extern void _AdjustTrackEvent( + string eventToken, + double revenue, + string currency, + string productId, + string transactionId, + string callbackId, + string deduplicationId, + string jsonCallbackParameters, + string jsonPartnerParameters); + + [DllImport("__Internal")] + private static extern void _AdjustEnable(); + + [DllImport("__Internal")] + private static extern void _AdjustDisable(); + + [DllImport("__Internal")] + private static extern void _AdjustSwitchToOfflineMode(); + + [DllImport("__Internal")] + private static extern void _AdjustSwitchBackToOnlineMode(); + + [DllImport("__Internal")] + private static extern void _AdjustSetPushToken(string pushToken); + + [DllImport("__Internal")] + private static extern void _AdjustProcessDeeplink(string deeplink, string referrer); + + private delegate void AdjustDelegateResolvedDeeplinkCallback(string deeplink); + [DllImport("__Internal")] + private static extern void _AdjustProcessAndResolveDeeplink( + string deeplink, + AdjustDelegateResolvedDeeplinkCallback callback); + + private delegate void AdjustDelegateIsEnabledGetter(bool isEnabed); + [DllImport("__Internal")] + private static extern void _AdjustIsEnabled(AdjustDelegateIsEnabledGetter callback); + + private delegate void AdjustDelegateAttributionGetter(string attribution); + [DllImport("__Internal")] + private static extern void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback); + + private delegate void AdjustDelegateAdidGetter(string adid); + [DllImport("__Internal")] + private static extern void _AdjustGetAdid(AdjustDelegateAdidGetter callback); + + private delegate void AdjustDelegateIdfaGetter(string idfa); + [DllImport("__Internal")] + private static extern void _AdjustGetIdfa(AdjustDelegateIdfaGetter callback); + + private delegate void AdjustDelegateIdfvGetter(string idfv); + [DllImport("__Internal")] + private static extern void _AdjustGetIdfv(AdjustDelegateIdfvGetter callback); + + private delegate void AdjustDelegateLastDeeplinkGetter(string lastDeeplink); + [DllImport("__Internal")] + private static extern void _AdjustGetLastDeeplink(AdjustDelegateLastDeeplinkGetter callback); + + private delegate void AdjustDelegateSdkVersionGetter(string sdkVersion); + [DllImport("__Internal")] + private static extern void _AdjustGetSdkVersion(AdjustDelegateSdkVersionGetter callback); + + [DllImport("__Internal")] + private static extern void _AdjustGdprForgetMe(); + + [DllImport("__Internal")] + private static extern void _AdjustAddGlobalPartnerParameter(string key, string value); + + [DllImport("__Internal")] + private static extern void _AdjustAddGlobalCallbackParameter(string key, string value); + + [DllImport("__Internal")] + private static extern void _AdjustRemoveGlobalPartnerParameter(string key); + + [DllImport("__Internal")] + private static extern void _AdjustRemoveGlobalCallbackParameter(string key); + + [DllImport("__Internal")] + private static extern void _AdjustRemoveGlobalPartnerParameters(); + + [DllImport("__Internal")] + private static extern void _AdjustRemoveGlobalCallbackParameters(); + + [DllImport("__Internal")] + private static extern void _AdjustTrackAdRevenue( + string source, + double revenue, + string currency, + int adImpressionsCount, + string adRevenueNetwork, + string adRevenueUnit, + string adRevenuePlacement, + string jsonCallbackParameters, + string jsonPartnerParameters); + + [DllImport("__Internal")] + private static extern void _AdjustTrackAppStoreSubscription( + string price, + string currency, + string transactionId, + string transactionDate, + string salesRegion, + string jsonCallbackParameters, + string jsonPartnerParameters); + + [DllImport("__Internal")] + private static extern void _AdjustTrackThirdPartySharing( + int enabled, + string jsonGranularOptions, + string jsonPartnerSharingSettings); + + [DllImport("__Internal")] + private static extern void _AdjustTrackMeasurementConsent(int enabled); + + [DllImport("__Internal")] + private static extern void _AdjustSetTestOptions( + string overwriteUrl, + string extraPath, + long timerIntervalInMilliseconds, + long timerStartInMilliseconds, + long sessionIntervalInMilliseconds, + long subsessionIntervalInMilliseconds, + int teardown, + int deleteState, + int noBackoffWait, + int adServicesFrameworkEnabled, + int attStatus, + string idfa); + + private delegate void AdjustDelegateAttCallback(int status); + [DllImport("__Internal")] + private static extern void _AdjustRequestAppTrackingAuthorization(AdjustDelegateAttCallback callback); + + private delegate void AdjustDelegateSkanErrorCallback(string error); + [DllImport("__Internal")] + private static extern void _AdjustUpdateSkanConversionValue( + int conversionValue, + string coarseValue, + int lockWindow, + AdjustDelegateSkanErrorCallback callback); + + [DllImport("__Internal")] + private static extern int _AdjustGetAppTrackingAuthorizationStatus(); + + [DllImport("__Internal")] + private static extern void _AdjustTrackSubsessionStart(); + + [DllImport("__Internal")] + private static extern void _AdjustTrackSubsessionEnd(); + + private delegate void AdjustDelegatePurchaseVerificationCallback(string verificationResult, int callbackId); + [DllImport("__Internal")] + private static extern void _AdjustVerifyAppStorePurchase( + string transactionId, + string productId, + int callbackId, + AdjustDelegatePurchaseVerificationCallback callback); + + private delegate void AdjustDelegateVerifyAndTrackCallback(string verificationResult, int callbackId); + [DllImport("__Internal")] + private static extern void _AdjustVerifyAndTrackAppStorePurchase( + string eventToken, + double revenue, + string currency, + string productId, + string transactionId, + string callbackId, + string deduplicationId, + string jsonCallbackParameters, + string jsonPartnerParameters, + int verificationCallbackId, + AdjustDelegateVerifyAndTrackCallback callback); + + [DllImport("__Internal")] + private static extern void _AdjustEndFirstSessionDelay(); + + [DllImport("__Internal")] + private static extern void _AdjustEnableCoppaComplianceInDelay(); + + [DllImport("__Internal")] + private static extern void _AdjustDisableCoppaComplianceInDelay(); + + [DllImport("__Internal")] + private static extern void _AdjustSetExternalDeviceIdInDelay(string externalDeviceId); + + // public API + public AdjustiOS() {} + + public static void InitSdk(AdjustConfig adjustConfig) + { + string appToken = adjustConfig.AppToken != null ? adjustConfig.AppToken : "ADJ_INVALID"; + string environment = adjustConfig.Environment.ToLowercaseString(); + string defaultTracker = adjustConfig.DefaultTracker != null ? adjustConfig.DefaultTracker : "ADJ_INVALID"; + string externalDeviceId = adjustConfig.ExternalDeviceId != null ? adjustConfig.ExternalDeviceId : "ADJ_INVALID"; + string stringJsonUrlStrategyDomains = AdjustUtils.ConvertReadOnlyCollectionToJson( + adjustConfig.UrlStrategyDomains != null ? adjustConfig.UrlStrategyDomains.AsReadOnly() : null); + string storeName = "ADJ_INVALID"; + string storeAppId = "ADJ_INVALID"; + if (adjustConfig.StoreInfo != null) + { + storeName = adjustConfig.StoreInfo.StoreName != null ? adjustConfig.StoreInfo.StoreName : "ADJ_INVALID"; + storeAppId = adjustConfig.StoreInfo.StoreAppId != null ? adjustConfig.StoreInfo.StoreAppId : "ADJ_INVALID"; + } + int attConsentWaitingInterval = AdjustUtils.ConvertInt(adjustConfig.AttConsentWaitingInterval); + int eventDeduplicationIdsMaxSize = AdjustUtils.ConvertInt(adjustConfig.EventDeduplicationIdsMaxSize); + int logLevel = AdjustUtils.ConvertLogLevel(adjustConfig.LogLevel); + int isCoppaComplianceEnabled = AdjustUtils.ConvertBool(adjustConfig.IsCoppaComplianceEnabled); + int isSendingInBackgroundEnabled = AdjustUtils.ConvertBool(adjustConfig.IsSendingInBackgroundEnabled); + int isAdServicesEnabled = AdjustUtils.ConvertBool(adjustConfig.IsAdServicesEnabled); + int isIdfaReadingEnabled = AdjustUtils.ConvertBool(adjustConfig.IsIdfaReadingEnabled); + int isIdfvReadingEnabled = AdjustUtils.ConvertBool(adjustConfig.IsIdfvReadingEnabled); + int allowSuppressLogLevel = AdjustUtils.ConvertBool(adjustConfig.AllowSuppressLogLevel); + int isDeferredDeeplinkOpeningEnabled = AdjustUtils.ConvertBool(adjustConfig.IsDeferredDeeplinkOpeningEnabled); + int isSkanAttributionEnabled = AdjustUtils.ConvertBool(adjustConfig.IsSkanAttributionEnabled); + int isLinkMeEnabled = AdjustUtils.ConvertBool(adjustConfig.IsLinkMeEnabled); + int isCostDataInAttributionEnabled = AdjustUtils.ConvertBool(adjustConfig.IsCostDataInAttributionEnabled); + int isDeviceIdsReadingOnceEnabled = AdjustUtils.ConvertBool(adjustConfig.IsDeviceIdsReadingOnceEnabled); + int isAppTrackingTransparencyUsageEnabled = AdjustUtils.ConvertBool(adjustConfig.IsAppTrackingTransparencyUsageEnabled); + int isFirstSessionDelayEnabled = AdjustUtils.ConvertBool(adjustConfig.IsFirstSessionDelayEnabled); + int shouldUseSubdomains = AdjustUtils.ConvertBool(adjustConfig.ShouldUseSubdomains); + int isDataResidency = AdjustUtils.ConvertBool(adjustConfig.IsDataResidency); + appAttributionCallback = adjustConfig.AttributionChangedDelegate; + appEventSuccessCallback = adjustConfig.EventSuccessDelegate; + appEventFailureCallback = adjustConfig.EventFailureDelegate; + appSessionSuccessCallback = adjustConfig.SessionSuccessDelegate; + appSessionFailureCallback = adjustConfig.SessionFailureDelegate; + appDeferredDeeplinkCallback = adjustConfig.DeferredDeeplinkDelegate; + appSkanUpdatedCallback = adjustConfig.SkanUpdatedDelegate; + + _AdjustInitSdk( + appToken, + environment, + sdkPrefix, + defaultTracker, + externalDeviceId, + stringJsonUrlStrategyDomains, + storeName, + storeAppId, + allowSuppressLogLevel, + logLevel, + attConsentWaitingInterval, + eventDeduplicationIdsMaxSize, + shouldUseSubdomains, + isCoppaComplianceEnabled, + isDataResidency, + isSendingInBackgroundEnabled, + isAdServicesEnabled, + isIdfaReadingEnabled, + isIdfvReadingEnabled, + isSkanAttributionEnabled, + isLinkMeEnabled, + isCostDataInAttributionEnabled, + isDeviceIdsReadingOnceEnabled, + isAppTrackingTransparencyUsageEnabled, + isFirstSessionDelayEnabled, + isDeferredDeeplinkOpeningEnabled, + AttributionCallbackMonoPInvoke, + EventSuccessCallbackMonoPInvoke, + EventFailureCallbackMonoPInvoke, + SessionSuccessCallbackMonoPInvoke, + SessionFailureCallbackMonoPInvoke, + DeferredDeeplinkCallbackMonoPInvoke, + SkanUpdatedCallbackMonoPInvoke); + } + + public static void TrackEvent(AdjustEvent adjustEvent) + { + double revenue = AdjustUtils.ConvertDouble(adjustEvent.Revenue); + string eventToken = adjustEvent.EventToken; + string currency = adjustEvent.Currency; + string productId = adjustEvent.ProductId; + string transactionId = adjustEvent.TransactionId; + string callbackId = adjustEvent.CallbackId; + string deduplicationId = adjustEvent.DeduplicationId; + string stringJsonCallbackParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adjustEvent.CallbackParameters); + string stringJsonPartnerParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adjustEvent.PartnerParameters); + + _AdjustTrackEvent( + eventToken, + revenue, + currency, + productId, + transactionId, + callbackId, + deduplicationId, + stringJsonCallbackParameters, + stringJsonPartnerParameters); + } + + public static void Enable() + { + _AdjustEnable(); + } + + public static void Disable() + { + _AdjustDisable(); + } + + public static void SwitchToOfflineMode() + { + _AdjustSwitchToOfflineMode(); + } + + public static void SwitchBackToOnlineMode() + { + _AdjustSwitchBackToOnlineMode(); + } + + public static void ProcessDeeplink(AdjustDeeplink adjustDeeplink) + { + _AdjustProcessDeeplink(adjustDeeplink.Deeplink, adjustDeeplink.Referrer); + } + + public static void AddGlobalPartnerParameter(string key, string value) + { + _AdjustAddGlobalPartnerParameter(key, value); + } + + public static void AddGlobalCallbackParameter(string key, string value) + { + _AdjustAddGlobalCallbackParameter(key, value); + } + + public static void RemoveGlobalPartnerParameter(string key) + { + _AdjustRemoveGlobalPartnerParameter(key); + } + + public static void RemoveGlobalCallbackParameter(string key) + { + _AdjustRemoveGlobalCallbackParameter(key); + } + + public static void RemoveGlobalPartnerParameters() + { + _AdjustRemoveGlobalPartnerParameters(); + } + + public static void RemoveGlobalCallbackParameters() + { + _AdjustRemoveGlobalCallbackParameters(); + } + + public static void TrackAdRevenue(AdjustAdRevenue adRevenue) + { + string source = adRevenue.Source; + double revenue = AdjustUtils.ConvertDouble(adRevenue.Revenue); + string currency = adRevenue.Currency; + int adImpressionsCount = AdjustUtils.ConvertInt(adRevenue.AdImpressionsCount); + string adRevenueNetwork = adRevenue.AdRevenueNetwork; + string adRevenueUnit = adRevenue.AdRevenueUnit; + string adRevenuePlacement = adRevenue.AdRevenuePlacement; + string stringJsonCallbackParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adRevenue.CallbackParameters); + string stringJsonPartnerParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adRevenue.PartnerParameters); + + _AdjustTrackAdRevenue( + source, + revenue, + currency, + adImpressionsCount, + adRevenueNetwork, + adRevenueUnit, + adRevenuePlacement, + stringJsonCallbackParameters, + stringJsonPartnerParameters); + } + + public static void TrackAppStoreSubscription(AdjustAppStoreSubscription subscription) + { + string price = subscription.Price; + string currency = subscription.Currency; + string transactionId = subscription.TransactionId; + string transactionDate = subscription.TransactionDate; + string salesRegion = subscription.SalesRegion; + string stringJsonCallbackParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(subscription.CallbackParameters); + string stringJsonPartnerParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(subscription.PartnerParameters); + + _AdjustTrackAppStoreSubscription( + price, + currency, + transactionId, + transactionDate, + salesRegion, + stringJsonCallbackParameters, + stringJsonPartnerParameters); + } + + public static void TrackThirdPartySharing(AdjustThirdPartySharing thirdPartySharing) + { + int enabled = AdjustUtils.ConvertBool(thirdPartySharing.IsEnabled); + string stringJsonGranularOptions = AdjustUtils.ConvertReadOnlyCollectionOfTripletsToJson(thirdPartySharing.GranularOptions); + string stringJsonPartnerSharingSettings = AdjustUtils.ConvertReadOnlyCollectionOfTripletsToJson(thirdPartySharing.PartnerSharingSettings); + + _AdjustTrackThirdPartySharing( + enabled, + stringJsonGranularOptions, + stringJsonPartnerSharingSettings); + } + + public static void TrackMeasurementConsent(bool enabled) + { + _AdjustTrackMeasurementConsent(AdjustUtils.ConvertBool(enabled)); + } + + public static void RequestAppTrackingAuthorization(Action callback) + { + if (appAttCallbacks == null) + { + appAttCallbacks = new List>(); + } + appAttCallbacks.Add(callback); + _AdjustRequestAppTrackingAuthorization(AttCallbackMonoPInvoke); + } + + public static void UpdateSkanConversionValue( + int conversionValue, + string coarseValue, + bool lockedWindow, + Action callback) + { + appSkanErrorCallback = callback; + _AdjustUpdateSkanConversionValue( + conversionValue, + coarseValue, + AdjustUtils.ConvertBool(lockedWindow), + SkanErrorCallbackMonoPInvoke); + } + + // TODO: consider making async + public static int GetAppTrackingAuthorizationStatus() + { + return _AdjustGetAppTrackingAuthorizationStatus(); + } + + public static void SetPushToken(string pushToken) + { + _AdjustSetPushToken(pushToken); + } + + public static void IsEnabled(Action callback) + { + if (appIsEnabledGetterCallbacks == null) + { + appIsEnabledGetterCallbacks = new List>(); + } + appIsEnabledGetterCallbacks.Add(callback); + _AdjustIsEnabled(IsEnabledGetterMonoPInvoke); + } + + public static void GetAttribution(Action callback) + { + if (appAttributionGetterCallbacks == null) + { + appAttributionGetterCallbacks = new List>(); + } + appAttributionGetterCallbacks.Add(callback); + _AdjustGetAttribution(AttributionGetterMonoPInvoke); + } + + public static void GetAdid(Action callback) + { + if (appAdidGetterCallbacks == null) + { + appAdidGetterCallbacks = new List>(); + } + appAdidGetterCallbacks.Add(callback); + _AdjustGetAdid(AdidGetterMonoPInvoke); + } + + public static void GetIdfa(Action callback) + { + if (appIdfaGetterCallbacks == null) + { + appIdfaGetterCallbacks = new List>(); + } + appIdfaGetterCallbacks.Add(callback); + _AdjustGetIdfa(IdfaGetterMonoPInvoke); + } + + public static void GetIdfv(Action callback) + { + if (appIdfvGetterCallbacks == null) + { + appIdfvGetterCallbacks = new List>(); + } + appIdfvGetterCallbacks.Add(callback); + _AdjustGetIdfv(IdfvGetterMonoPInvoke); + } + + public static void GetLastDeeplink(Action callback) + { + if (appLastDeeplinkGetterCallbacks == null) + { + appLastDeeplinkGetterCallbacks = new List>(); + } + appLastDeeplinkGetterCallbacks.Add(callback); + _AdjustGetLastDeeplink(LastDeeplinkGetterMonoPInvoke); + } + + public static void GetSdkVersion(Action callback) + { + if (appSdkVersionGetterCallbacks == null) + { + appSdkVersionGetterCallbacks = new List>(); + } + appSdkVersionGetterCallbacks.Add(callback); + _AdjustGetSdkVersion(SdkVersionGetterMonoPInvoke); + } + + public static void GdprForgetMe() + { + _AdjustGdprForgetMe(); + } + + public static void VerifyAppStorePurchase( + AdjustAppStorePurchase purchase, + Action callback) + { + string transactionId = purchase.TransactionId; + string productId = purchase.ProductId; + + if (appPurchaseVerificationCallbacks == null) + { + appPurchaseVerificationCallbacks = new Dictionary>(); + } + + int callbackId = ++nextPurchaseVerificationCallbackId; + appPurchaseVerificationCallbacks[callbackId] = callback; + + _AdjustVerifyAppStorePurchase( + transactionId, + productId, + callbackId, + PurchaseVerificationCallbackMonoPInvoke); + } + + public static void ProcessAndResolveDeeplink(AdjustDeeplink adjustDeeplink, Action callback) + { + appResolvedDeeplinkCallback = callback; + _AdjustProcessAndResolveDeeplink(adjustDeeplink.Deeplink, ResolvedDeeplinkCallbackMonoPInvoke); + } + + public static void VerifyAndTrackAppStorePurchase( + AdjustEvent adjustEvent, + Action callback) + { + double revenue = AdjustUtils.ConvertDouble(adjustEvent.Revenue); + string eventToken = adjustEvent.EventToken; + string currency = adjustEvent.Currency; + string productId = adjustEvent.ProductId; + string transactionId = adjustEvent.TransactionId; + string callbackId = adjustEvent.CallbackId; + string deduplicationId = adjustEvent.DeduplicationId; + string stringJsonCallbackParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adjustEvent.CallbackParameters); + string stringJsonPartnerParameters = AdjustUtils.ConvertReadOnlyCollectionOfPairsToJson(adjustEvent.PartnerParameters); + + if (appVerifyAndTrackCallbacks == null) + { + appVerifyAndTrackCallbacks = new Dictionary>(); + } + + int verificationCallbackId = ++nextVerifyAndTrackCallbackId; + appVerifyAndTrackCallbacks[verificationCallbackId] = callback; + + _AdjustVerifyAndTrackAppStorePurchase( + eventToken, + revenue, + currency, + productId, + transactionId, + callbackId, + deduplicationId, + stringJsonCallbackParameters, + stringJsonPartnerParameters, + verificationCallbackId, + VerifyAndTrackCallbackMonoPInvoke); + } + + public static void EndFirstSessionDelay() + { + _AdjustEndFirstSessionDelay(); + } + + public static void EnableCoppaComplianceInDelay() + { + _AdjustEnableCoppaComplianceInDelay(); + } + + public static void DisableCoppaComplianceInDelay() + { + _AdjustDisableCoppaComplianceInDelay(); + } + + public static void SetExternalDeviceIdInDelay(string externalDeviceId) + { + _AdjustSetExternalDeviceIdInDelay(externalDeviceId); + } + + // used for testing only (don't use this in your app) + public static void SetTestOptions(Dictionary testOptions) + { + string overwriteUrl = testOptions[AdjustUtils.KeyTestOptionsOverwriteUrl]; + string extraPath = testOptions.ContainsKey(AdjustUtils.KeyTestOptionsExtraPath) ? testOptions[AdjustUtils.KeyTestOptionsExtraPath] : null; + string idfa = testOptions.ContainsKey(AdjustUtils.KeyTestOptionsIdfa) ? testOptions[AdjustUtils.KeyTestOptionsIdfa] : null; + long timerIntervalMilis = -1; + long timerStartMilis = -1; + long sessionIntMilis = -1; + long subsessionIntMilis = -1; + bool teardown = false; + bool deleteState = false; + bool noBackoffWait = false; + bool adServicesFrameworkEnabled = false; + int attStatus = -1; + + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsTimerIntervalInMilliseconds)) + { + timerIntervalMilis = long.Parse(testOptions[AdjustUtils.KeyTestOptionsTimerIntervalInMilliseconds]); + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsTimerStartInMilliseconds)) + { + timerStartMilis = long.Parse(testOptions[AdjustUtils.KeyTestOptionsTimerStartInMilliseconds]); + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsSessionIntervalInMilliseconds)) + { + sessionIntMilis = long.Parse(testOptions[AdjustUtils.KeyTestOptionsSessionIntervalInMilliseconds]); + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsSubsessionIntervalInMilliseconds)) + { + subsessionIntMilis = long.Parse(testOptions[AdjustUtils.KeyTestOptionsSubsessionIntervalInMilliseconds]); + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsTeardown)) + { + teardown = testOptions[AdjustUtils.KeyTestOptionsTeardown].ToLower() == "true"; + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsDeleteState)) + { + deleteState = testOptions[AdjustUtils.KeyTestOptionsDeleteState].ToLower() == "true"; + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsNoBackoffWait)) + { + noBackoffWait = testOptions[AdjustUtils.KeyTestOptionsNoBackoffWait].ToLower() == "true"; + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsAdServicesFrameworkEnabled)) + { + adServicesFrameworkEnabled = testOptions[AdjustUtils.KeyTestOptionsAdServicesFrameworkEnabled].ToLower() == "true"; + } + if (testOptions.ContainsKey(AdjustUtils.KeyTestOptionsAttStatus)) + { + attStatus = int.Parse(testOptions[AdjustUtils.KeyTestOptionsAttStatus]); + } + + _AdjustSetTestOptions( + overwriteUrl, + extraPath, + timerIntervalMilis, + timerStartMilis, + sessionIntMilis, + subsessionIntMilis, + AdjustUtils.ConvertBool(teardown), + AdjustUtils.ConvertBool(deleteState), + AdjustUtils.ConvertBool(noBackoffWait), + AdjustUtils.ConvertBool(adServicesFrameworkEnabled), + attStatus, + idfa); + } + + public static void TrackSubsessionStart(string testingArgument = null) + { + if (testingArgument == "test") + { + _AdjustTrackSubsessionStart(); + } + } + + public static void TrackSubsessionEnd(string testingArgument = null) + { + if (testingArgument == "test") + { + _AdjustTrackSubsessionEnd(); + } + } + + // MonoPInvokeCallback methods as method parameters + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIsEnabledGetter))] + private static void IsEnabledGetterMonoPInvoke(bool isEnabled) + { + if (appIsEnabledGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appIsEnabledGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(isEnabled); + } + } + appIsEnabledGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionGetter))] + private static void AttributionGetterMonoPInvoke(string attribution) + { + if (appAttributionGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appAttributionGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(new AdjustAttribution(attribution)); + } + } + appAttributionGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAdidGetter))] + private static void AdidGetterMonoPInvoke(string adid) + { + if (appAdidGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appAdidGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(adid); + } + } + appAdidGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfaGetter))] + private static void IdfaGetterMonoPInvoke(string idfa) + { + if (appIdfaGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appIdfaGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(idfa); + } + } + appIdfaGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfvGetter))] + private static void IdfvGetterMonoPInvoke(string idfv) + { + if (appIdfvGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appIdfvGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(idfv); + } + } + appIdfvGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateLastDeeplinkGetter))] + private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink) + { + if (appLastDeeplinkGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appLastDeeplinkGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(lastDeeplink); + } + } + appLastDeeplinkGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSdkVersionGetter))] + private static void SdkVersionGetterMonoPInvoke(string sdkVersion) + { + if (appSdkVersionGetterCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appSdkVersionGetterCallbacks) + { + if (callback != null) + { + callback.Invoke(sdkPrefix + "@" + sdkVersion); + } + } + appSdkVersionGetterCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttCallback))] + private static void AttCallbackMonoPInvoke(int status) + { + if (appAttCallbacks == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + foreach (Action callback in appAttCallbacks) + { + if (callback != null) + { + callback.Invoke(status); + } + } + appAttCallbacks.Clear(); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegatePurchaseVerificationCallback))] + private static void PurchaseVerificationCallbackMonoPInvoke(string verificationResult, int callbackId) + { + if (appPurchaseVerificationCallbacks == null || !appPurchaseVerificationCallbacks.ContainsKey(callbackId)) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (appPurchaseVerificationCallbacks != null && appPurchaseVerificationCallbacks.ContainsKey(callbackId)) + { + Action callback = appPurchaseVerificationCallbacks[callbackId]; + appPurchaseVerificationCallbacks.Remove(callbackId); + + if (callback != null) + { + callback.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + } + } + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateVerifyAndTrackCallback))] + private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult, int callbackId) + { + if (appVerifyAndTrackCallbacks == null || !appVerifyAndTrackCallbacks.ContainsKey(callbackId)) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (appVerifyAndTrackCallbacks != null && appVerifyAndTrackCallbacks.ContainsKey(callbackId)) + { + Action callback = appVerifyAndTrackCallbacks[callbackId]; + appVerifyAndTrackCallbacks.Remove(callbackId); + + if (callback != null) + { + callback.Invoke(new AdjustPurchaseVerificationResult(verificationResult)); + } + } + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateResolvedDeeplinkCallback))] + private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink) + { + if (appResolvedDeeplinkCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (appResolvedDeeplinkCallback != null) + { + appResolvedDeeplinkCallback.Invoke(deeplink); + appResolvedDeeplinkCallback = null; + } + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanErrorCallback))] + private static void SkanErrorCallbackMonoPInvoke(string error) + { + if (appSkanErrorCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (appSkanErrorCallback != null) + { + appSkanErrorCallback.Invoke(error); + appSkanErrorCallback = null; + } + }); + } + + // MonoPInvokeCallback methods as subscriptions + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionCallback))] + private static void AttributionCallbackMonoPInvoke(string attribution) + { + if (appAttributionCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appAttributionCallback(new AdjustAttribution(attribution)); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionSuccessCallback))] + private static void SessionSuccessCallbackMonoPInvoke(string sessionSuccess) + { + if (appSessionSuccessCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSessionSuccessCallback(new AdjustSessionSuccess(sessionSuccess)); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionFailureCallback))] + private static void SessionFailureCallbackMonoPInvoke(string sessionFailure) + { + if (appSessionFailureCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appSessionFailureCallback(new AdjustSessionFailure(sessionFailure)); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventSuccessCallback))] + private static void EventSuccessCallbackMonoPInvoke(string eventSuccess) + { + if (appEventSuccessCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appEventSuccessCallback(new AdjustEventSuccess(eventSuccess)); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventFailureCallback))] + private static void EventFailureCallbackMonoPInvoke(string eventFailure) + { + if (appEventFailureCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appEventFailureCallback(new AdjustEventFailure(eventFailure)); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateDeferredDeeplinkCallback))] + private static void DeferredDeeplinkCallbackMonoPInvoke(string deeplink) + { + if (appDeferredDeeplinkCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + appDeferredDeeplinkCallback(deeplink); + }); + } + + [AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanUpdatedCallback))] + private static void SkanUpdatedCallbackMonoPInvoke(string skanData) + { + if (appSkanUpdatedCallback == null) + { + return; + } + + AdjustThreadDispatcher.RunOnMainThread(() => + { + if (appSkanUpdatedCallback != null) + { + appSkanUpdatedCallback.Invoke(AdjustUtils.GetSkanUpdateDataDictionary(skanData)); + } + }); + } + } +#endif +} diff --git a/Assets/rd3/Adjust/Scripts/AdjustiOS.cs.meta b/Assets/rd3/Adjust/Scripts/AdjustiOS.cs.meta new file mode 100644 index 0000000..f7369f2 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/AdjustiOS.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b9e944cddaba4b74b96cf2c01f5aee3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor.meta b/Assets/rd3/Adjust/Scripts/Editor.meta new file mode 100644 index 0000000..2868bb2 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fd79158f62f184079b58f414302dd242 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs b/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs new file mode 100644 index 0000000..193b05a --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor.SceneManagement; +using UnityEditor; + +namespace AdjustSdk +{ + [CustomEditor(typeof(Adjust))] + public class AdjustCustomEditor : Editor + { + private Editor settingsEditor; + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + var adjust = target as Adjust; + GUIStyle darkerCyanTextFieldStyles = new GUIStyle(EditorStyles.boldLabel); + darkerCyanTextFieldStyles.normal.textColor = new Color(0f/255f, 190f/255f, 190f/255f); + + // Not gonna ask: http://answers.unity.com/answers/1244650/view.html + EditorGUILayout.Space(); + var origFontStyle = EditorStyles.label.fontStyle; + EditorStyles.label.fontStyle = FontStyle.Bold; + adjust.startManually = EditorGUILayout.Toggle("START SDK MANUALLY", adjust.startManually, EditorStyles.toggle); + EditorStyles.label.fontStyle = origFontStyle; + + using (new EditorGUI.DisabledScope(adjust.startManually)) + { + EditorGUILayout.Space(); + EditorGUILayout.LabelField("MULTIPLATFORM SETTINGS:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + adjust.appToken = EditorGUILayout.TextField("App Token", adjust.appToken); + adjust.environment = (AdjustEnvironment)EditorGUILayout.EnumPopup("Environment", adjust.environment); + adjust.logLevel = (AdjustLogLevel)EditorGUILayout.EnumPopup("Log Level", adjust.logLevel); + // TODO: URL strategy missing + adjust.sendInBackground = EditorGUILayout.Toggle("Send In Background", adjust.sendInBackground); + adjust.launchDeferredDeeplink = EditorGUILayout.Toggle("Launch Deferred Deep Link", adjust.launchDeferredDeeplink); + adjust.costDataInAttribution = EditorGUILayout.Toggle("Cost Data In Attribution Callback", adjust.costDataInAttribution); + adjust.linkMe = EditorGUILayout.Toggle("LinkMe", adjust.linkMe); + adjust.defaultTracker = EditorGUILayout.TextField("Default Tracker", adjust.defaultTracker); + EditorGUI.indentLevel -= 1; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("ANDROID SETTINGS:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + adjust.preinstallTracking = EditorGUILayout.Toggle("Preinstall Tracking", adjust.preinstallTracking); + adjust.preinstallFilePath = EditorGUILayout.TextField("Preinstall File Path", adjust.preinstallFilePath); + EditorGUI.indentLevel -= 1; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("IOS SETTINGS:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + adjust.adServices = EditorGUILayout.Toggle("AdServices Info Reading", adjust.adServices); + adjust.idfaReading = EditorGUILayout.Toggle("IDFA Info Reading", adjust.idfaReading); + adjust.skanAttribution = EditorGUILayout.Toggle("SKAdNetwork Handling", adjust.skanAttribution); + EditorGUI.indentLevel -= 1; + } + + if (settingsEditor == null) + { + settingsEditor = CreateEditor(AdjustSettings.Instance); + } + + settingsEditor.OnInspectorGUI(); + + if (GUI.changed) + { + EditorUtility.SetDirty(adjust); + EditorSceneManager.MarkSceneDirty(adjust.gameObject.scene); + } + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs.meta new file mode 100644 index 0000000..8039909 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustCustomEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1772b9461c24c4df0ad55f51f81c7345 +timeCreated: 1617868100 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs new file mode 100644 index 0000000..eed421f --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs @@ -0,0 +1,343 @@ +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using UnityEngine; +using UnityEditor; +using UnityEditor.Callbacks; +#if UNITY_IOS +using UnityEditor.iOS.Xcode; +#if UNITY_2019_3_OR_NEWER +using UnityEditor.iOS.Xcode.Extensions; +#endif +#endif + +namespace AdjustSdk +{ + public class AdjustEditor : AssetPostprocessor + { + private const int AdjustEditorPostProcesssBuildPriority = 90; + private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do"; + private const string UseFrameworksPodfileLine = "use_frameworks!"; + private const string UseFrameworksDynamicPodfileLine = "use_frameworks! :linkage => :dynamic"; + private const string UseFrameworksStaticPodfileLine = "use_frameworks! :linkage => :static"; + + [PostProcessBuild(AdjustEditorPostProcesssBuildPriority)] + public static void OnPostprocessBuild(BuildTarget target, string projectPath) + { + RunPostBuildScript(target: target, projectPath: projectPath); + } + + private static void RunPostBuildScript(BuildTarget target, string projectPath = "") + { + if (target == BuildTarget.iOS) + { + #if UNITY_IOS + Debug.Log("[Adjust]: Starting to perform post build tasks for iOS platform."); + + string xcodeProjectPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj"; + + PBXProject xcodeProject = new PBXProject(); + xcodeProject.ReadFromFile(xcodeProjectPath); + + #if UNITY_2019_3_OR_NEWER + string xcodeTarget = xcodeProject.GetUnityMainTargetGuid(); + #else + string xcodeTarget = xcodeProject.TargetGuidByName("Unity-iPhone"); + #endif + HandlePlistIosChanges(projectPath); + + if (AdjustSettings.iOSUniversalLinksDomains.Length > 0) + { + AddUniversalLinkDomains(xcodeProject, xcodeProjectPath, xcodeTarget); + } + + // If enabled by the user, Adjust SDK will try to add following frameworks to your project: + // - AdSupport.framework (needed for access to IDFA value) + // - AdServices.framework (needed in case you are running ASA campaigns) + // - StoreKit.framework (needed for communication with SKAdNetwork framework) + // - AppTrackingTransparency.framework (needed for information about user's consent to be tracked) + // In case you don't need any of these, feel free to remove them from your app. + + if (AdjustSettings.iOSFrameworkAdSupport) + { + Debug.Log("[Adjust]: Adding AdSupport.framework to Xcode project."); + xcodeProject.AddFrameworkToProject(xcodeTarget, "AdSupport.framework", true); + Debug.Log("[Adjust]: AdSupport.framework added successfully."); + } + else + { + Debug.Log("[Adjust]: Skipping AdSupport.framework linking."); + } + if (AdjustSettings.iOSFrameworkAdServices) + { + Debug.Log("[Adjust]: Adding AdServices.framework to Xcode project."); + xcodeProject.AddFrameworkToProject(xcodeTarget, "AdServices.framework", true); + Debug.Log("[Adjust]: AdServices.framework added successfully."); + } + else + { + Debug.Log("[Adjust]: Skipping AdServices.framework linking."); + } + if (AdjustSettings.iOSFrameworkStoreKit) + { + Debug.Log("[Adjust]: Adding StoreKit.framework to Xcode project."); + xcodeProject.AddFrameworkToProject(xcodeTarget, "StoreKit.framework", true); + Debug.Log("[Adjust]: StoreKit.framework added successfully."); + } + else + { + Debug.Log("[Adjust]: Skipping StoreKit.framework linking."); + } + if (AdjustSettings.iOSFrameworkAppTrackingTransparency) + { + Debug.Log("[Adjust]: Adding AppTrackingTransparency.framework to Xcode project."); + xcodeProject.AddFrameworkToProject(xcodeTarget, "AppTrackingTransparency.framework", true); + Debug.Log("[Adjust]: AppTrackingTransparency.framework added successfully."); + } + else + { + Debug.Log("[Adjust]: Skipping AppTrackingTransparency.framework linking."); + } + + // The Adjust SDK needs to have Obj-C exceptions enabled. + // GCC_ENABLE_OBJC_EXCEPTIONS=YES + string xcodeTargetUnityFramework = xcodeProject.TargetGuidByName("UnityFramework"); + Debug.Log("[Adjust]: Enabling Obj-C exceptions by setting GCC_ENABLE_OBJC_EXCEPTIONS value to YES."); + xcodeProject.AddBuildProperty(xcodeTarget, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); + Debug.Log("[Adjust]: Obj-C exceptions enabled successfully."); + if (!string.IsNullOrEmpty(xcodeTargetUnityFramework)) + { + Debug.Log("[Adjust]: Enabling Obj-C exceptions by setting GCC_ENABLE_OBJC_EXCEPTIONS value to YES."); + xcodeProject.AddBuildProperty(xcodeTargetUnityFramework, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); + Debug.Log("[Adjust]: Obj-C exceptions enabled successfully."); + } + + // potential AdjustSigSdk.xcframework embedding + Debug.Log("[Adjust]: Checking whether AdjustSigSdk.xcframework needs to be embedded or not..."); + EmbedAdjustSignatureIfNeeded(projectPath, xcodeProject, xcodeTarget); + + // Save the changes to Xcode project file. + xcodeProject.WriteToFile(xcodeProjectPath); + #endif + } + } + + #if UNITY_IOS + // dynamic xcframework embedding logic adjusted and taken from: + // https://github.com/AppLovin/AppLovin-MAX-Unity-Plugin/blob/master/DemoApp/Assets/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs + private static void EmbedAdjustSignatureIfNeeded(string buildPath, PBXProject project, string targetGuid) + { + var podsDirectory = Path.Combine(buildPath, "Pods"); + + if (!Directory.Exists(podsDirectory) || !ShouldEmbedDynamicLibraries(buildPath)) + { + Debug.Log("[Adjust]: No need to embed AdjustSigSdk.xcframework."); + return; + } + + var dynamicLibraryPathToEmbed = GetAdjustSignaturePathToEmbed(podsDirectory, buildPath); + if (dynamicLibraryPathToEmbed == null) { + return; + } + + Debug.Log("[Adjust]: It needs to be embedded. Starting the embedding process..."); +#if UNITY_2019_3_OR_NEWER + var fileGuid = project.AddFile(dynamicLibraryPathToEmbed, dynamicLibraryPathToEmbed); + project.AddFileToEmbedFrameworks(targetGuid, fileGuid); +#else + string runpathSearchPaths; + runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); + runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; + + // check if runtime search paths already contains the required search paths for dynamic libraries + if (runpathSearchPaths.Contains("@executable_path/Frameworks")) { + return; + } + + runpathSearchPaths += "@executable_path/Frameworks"; + project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); +#endif + Debug.Log("[Adjust]: Embedding process completed."); + } + + private static bool ShouldEmbedDynamicLibraries(string buildPath) + { + var podfilePath = Path.Combine(buildPath, "Podfile"); + if (!File.Exists(podfilePath)) { + return false; + } + + // if the Podfile doesn't have a `Unity-iPhone` target, we should embed the dynamic libraries + var lines = File.ReadAllLines(podfilePath); + var containsUnityIphoneTarget = lines.Any(line => line.Contains(TargetUnityIphonePodfileLine)); + if (!containsUnityIphoneTarget) { + return true; + } + + // if the Podfile does not have a `use_frameworks! :linkage => static` line, we should not embed the dynamic libraries + var useFrameworksStaticLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksStaticPodfileLine)); + if (useFrameworksStaticLineIndex == -1) { + return false; + } + + // if more than one of the `use_frameworks!` lines are present, CocoaPods will use the last one + var useFrameworksLineIndex = Array.FindIndex(lines, line => line.Trim() == UseFrameworksPodfileLine); // check for exact line to avoid matching `use_frameworks! :linkage => static/dynamic` + var useFrameworksDynamicLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksDynamicPodfileLine)); + + // check if `use_frameworks! :linkage => :static` is the last line of the three + // if it is, we should embed the dynamic libraries + return useFrameworksLineIndex < useFrameworksStaticLineIndex && useFrameworksDynamicLineIndex < useFrameworksStaticLineIndex; + } + + private static string GetAdjustSignaturePathToEmbed(string podsDirectory, string buildPath) + { + var adjustSignatureFrameworkToEmbed = "AdjustSigSdk.xcframework"; + + // both .framework and .xcframework are directories, not files + var directories = Directory.GetDirectories(podsDirectory, adjustSignatureFrameworkToEmbed, SearchOption.AllDirectories); + if (directories.Length <= 0) { + return null; + } + + var dynamicLibraryAbsolutePath = directories[0]; + var relativePath = GetDynamicLibraryRelativePath(dynamicLibraryAbsolutePath); + return relativePath; + } + + private static string GetDynamicLibraryRelativePath(string dynamicLibraryAbsolutePath) + { + var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods", StringComparison.Ordinal); + return dynamicLibraryAbsolutePath.Substring(index); + } + + private static void HandlePlistIosChanges(string projectPath) + { + const string UserTrackingUsageDescriptionKey = "NSUserTrackingUsageDescription"; + + // Check if needs to do any info plist change. + bool hasUserTrackingDescription = + !string.IsNullOrEmpty(AdjustSettings.iOSUserTrackingUsageDescription); + bool hasUrlSchemesDeepLinksEnabled = AdjustSettings.iOSUrlSchemes.Length > 0; + + if (!hasUserTrackingDescription && !hasUrlSchemesDeepLinksEnabled) + { + return; + } + + // Get and read info plist. + var plistPath = Path.Combine(projectPath, "Info.plist"); + var plist = new PlistDocument(); + plist.ReadFromFile(plistPath); + var plistRoot = plist.root; + + // Do the info plist changes. + if (hasUserTrackingDescription) + { + if (plistRoot[UserTrackingUsageDescriptionKey] != null) + { + Debug.Log("[Adjust]: Overwritting User Tracking Usage Description."); + } + plistRoot.SetString(UserTrackingUsageDescriptionKey, + AdjustSettings.iOSUserTrackingUsageDescription); + } + + if (hasUrlSchemesDeepLinksEnabled) + { + AddUrlSchemesIOS(plistRoot, AdjustSettings.iOSUrlIdentifier, AdjustSettings.iOSUrlSchemes); + } + + // Write any info plist change. + File.WriteAllText(plistPath, plist.WriteToString()); + } + + private static void AddUrlSchemesIOS(PlistElementDict plistRoot, string urlIdentifier, string[] urlSchemes) + { + // Set Array for futher deeplink values. + var urlTypesArray = CreatePlistElementArray(plistRoot, "CFBundleURLTypes"); + + // Array will contain just one deeplink dictionary + var urlSchemesItems = CreatePlistElementDict(urlTypesArray); + urlSchemesItems.SetString("CFBundleURLName", urlIdentifier); + var urlSchemesArray = CreatePlistElementArray(urlSchemesItems, "CFBundleURLSchemes"); + + // Delete old deferred deeplinks URIs + Debug.Log("[Adjust]: Removing deeplinks that already exist in the array to avoid duplicates."); + foreach (var link in urlSchemes) + { + urlSchemesArray.values.RemoveAll( + element => element != null && element.AsString().Equals(link)); + } + + Debug.Log("[Adjust]: Adding new deep links."); + foreach (var link in urlSchemes.Distinct()) + { + urlSchemesArray.AddString(link); + } + } + + private static PlistElementArray CreatePlistElementArray(PlistElementDict root, string key) + { + if (!root.values.ContainsKey(key)) + { + Debug.Log(string.Format("[Adjust]: {0} not found in Info.plist. Creating a new one.", key)); + return root.CreateArray(key); + } + var result = root.values[key].AsArray(); + return result != null ? result : root.CreateArray(key); + } + + private static PlistElementDict CreatePlistElementDict(PlistElementArray rootArray) + { + if (rootArray.values.Count == 0) + { + Debug.Log("[Adjust]: Deeplinks array doesn't contain dictionary for deeplinks. Creating a new one."); + return rootArray.AddDict(); + } + + var urlSchemesItems = rootArray.values[0].AsDict(); + Debug.Log("[Adjust]: Reading deeplinks array"); + if (urlSchemesItems == null) + { + Debug.Log("[Adjust]: Deeplinks array doesn't contain dictionary for deeplinks. Creating a new one."); + urlSchemesItems = rootArray.AddDict(); + } + + return urlSchemesItems; + } + + private static void AddUniversalLinkDomains(PBXProject project, string xCodeProjectPath, string xCodeTarget) + { + string entitlementsFileName = project.GetBuildPropertyForAnyConfig(xCodeTarget, "CODE_SIGN_ENTITLEMENTS"); + if (entitlementsFileName == null) + { + entitlementsFileName = "Unity-iPhone.entitlements"; + } + + Debug.Log("[Adjust]: Adding associated domains to entitlements file."); + #if UNITY_2019_3_OR_NEWER + var projectCapabilityManager = new ProjectCapabilityManager(xCodeProjectPath, entitlementsFileName, null, project.GetUnityMainTargetGuid()); + #else + var projectCapabilityManager = new ProjectCapabilityManager(xCodeProjectPath, entitlementsFileName, PBXProject.GetUnityTargetName()); + #endif + var uniqueDomains = AdjustSettings.iOSUniversalLinksDomains.Distinct().ToArray(); + const string applinksPrefix = "applinks:"; + for (int i = 0; i < uniqueDomains.Length; i++) + { + if (!uniqueDomains[i].StartsWith(applinksPrefix)) + { + uniqueDomains[i] = applinksPrefix + uniqueDomains[i]; + } + } + + projectCapabilityManager.AddAssociatedDomains(uniqueDomains); + projectCapabilityManager.WriteToFile(); + + Debug.Log("[Adjust]: Enabling Associated Domains capability with created entitlements file."); + project.AddCapability(xCodeTarget, PBXCapabilityType.AssociatedDomains, entitlementsFileName); + } + #endif + } +} \ No newline at end of file diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs.meta new file mode 100644 index 0000000..13983a5 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc5962e0096e9495bbad76934c842619 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs new file mode 100644 index 0000000..753630f --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs @@ -0,0 +1,367 @@ +using System.IO; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor.Build; +using UnityEditor; +using System.Xml; +using System; +using System.Text.RegularExpressions; +using System.Linq; + +namespace AdjustSdk +{ +#if UNITY_2018_1_OR_NEWER + public class AdjustEditorPreprocessor : IPreprocessBuildWithReport +#else + public class AdjustEditorPreprocessor : IPreprocessBuild +#endif + { + public int callbackOrder + { + get + { + return 0; + } + } +#if UNITY_2018_1_OR_NEWER + public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) + { + OnPreprocessBuild(report.summary.platform, string.Empty); + } +#endif + + public void OnPreprocessBuild(BuildTarget target, string path) + { + if (target == BuildTarget.Android) + { +#if UNITY_ANDROID + RunPostProcessTasksAndroid(); +#endif + } + } + +#if UNITY_ANDROID + private static void RunPostProcessTasksAndroid() + { + var isAdjustManifestUsed = false; + var androidPluginsPath = Path.Combine(Application.dataPath, "Plugins/Android"); + var adjustManifestPath = Path.Combine(Application.dataPath, "Adjust/Native/Android/AdjustAndroidManifest.xml"); + var appManifestPath = Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"); + + // Check if user has already created AndroidManifest.xml file in its location. + // If not, use already predefined AdjustAndroidManifest.xml as default one. + if (!File.Exists(appManifestPath)) + { + if (!Directory.Exists(androidPluginsPath)) + { + Directory.CreateDirectory(androidPluginsPath); + } + + isAdjustManifestUsed = true; + File.Copy(adjustManifestPath, appManifestPath); + + Debug.Log("[Adjust]: User defined AndroidManifest.xml file not found in Plugins/Android folder."); + Debug.Log("[Adjust]: Creating default app's AndroidManifest.xml from AdjustAndroidManifest.xml file."); + } + else + { + Debug.Log("[Adjust]: User defined AndroidManifest.xml file located in Plugins/Android folder."); + } + + // Let's open the app's AndroidManifest.xml file. + var manifestFile = new XmlDocument(); + manifestFile.Load(appManifestPath); + + var manifestHasChanged = false; + + // If Adjust manifest is used, we have already set up everything in it so that + // our native Android SDK can be used properly. + if (!isAdjustManifestUsed) + { + // However, if you already had your own AndroidManifest.xml, we'll now run + // some checks on it and tweak it a bit if needed to add some stuff which + // our native Android SDK needs so that it can run properly. + + // Add needed permissions if they are missing. + manifestHasChanged |= AddPermissions(manifestFile); + + // Add intent filter to main activity if it is missing. + manifestHasChanged |= AddBroadcastReceiver(manifestFile); + } + + // Add intent filter to URL schemes for deeplinking + manifestHasChanged |= AddURISchemes(manifestFile); + + if (manifestHasChanged) + { + // Save the changes. + manifestFile.Save(appManifestPath); + + Debug.Log("[Adjust]: App's AndroidManifest.xml file check and potential modification completed."); + Debug.Log("[Adjust]: Please check if any error message was displayed during this process " + + "and make sure to fix all issues in order to properly use the Adjust SDK in your app."); + } + else + { + Debug.Log("[Adjust]: App's AndroidManifest.xml file check completed."); + Debug.Log("[Adjust]: No modifications performed due to app's AndroidManifest.xml file compatibility."); + } + } + + private static bool AddURISchemes(XmlDocument manifest) + { + if (AdjustSettings.AndroidUriSchemes.Length == 0) + { + return false; + } + Debug.Log("[Adjust]: Start addition of URI schemes"); + + // 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) + { + Uri uri; + try + { + // The first element is android:scheme and the second one is android:host. + uri = new Uri(uriScheme); + + // Uri class converts implicit file paths to explicit file paths with the file:// scheme. + if (!uriScheme.StartsWith(uri.Scheme)) + { + throw new UriFormatException(); + } + } + catch (UriFormatException) + { + Debug.LogError(string.Format("[Adjust]: Android deeplink URI scheme \"{0}\" is invalid and will be ignored.", uriScheme)); + Debug.LogWarning(string.Format("[Adjust]: Make sure that your URI scheme entry ends with ://")); + continue; + } + + 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); + 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; + } + } + + return usedIntentFiltersChanged; + } + + private static XmlElement GetNewIntentFilter(XmlDocument manifest) + { + const string androidName = "name"; + const string category = "category"; + + var intentFilter = manifest.CreateElement("intent-filter"); + + 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 browsableCategory = manifest.CreateElement(category); + AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory); + intentFilter.AppendChild(browsableCategory); + + return intentFilter; + } + + 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; + } + + private static bool AddPermissions(XmlDocument manifest) + { + // The Adjust SDK needs two permissions to be added to you app's manifest file: + // + // + // + // + + Debug.Log("[Adjust]: Checking if all permissions needed for the Adjust SDK are present in the app's AndroidManifest.xml file."); + + var manifestHasChanged = false; + + // If enabled by the user && android.permission.INTERNET permission is missing, add it. + if (AdjustSettings.androidPermissionInternet == true) + { + manifestHasChanged |= AddPermission(manifest, "android.permission.INTERNET"); + } + // If enabled by the user && com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE permission is missing, add it. + if (AdjustSettings.androidPermissionInstallReferrerService == true) + { + manifestHasChanged |= AddPermission(manifest, "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"); + } + // If enabled by the user && com.google.android.gms.permission.AD_ID permission is missing, add it. + if (AdjustSettings.androidPermissionAdId == true) + { + manifestHasChanged |= AddPermission(manifest, "com.google.android.gms.permission.AD_ID"); + } + // If enabled by the user && android.permission.ACCESS_NETWORK_STATE permission is missing, add it. + if (AdjustSettings.androidPermissionAccessNetworkState == true) + { + manifestHasChanged |= AddPermission(manifest, "android.permission.ACCESS_NETWORK_STATE"); + } + + return manifestHasChanged; + } + + private static bool AddPermission(XmlDocument manifest, string permissionValue) + { + if (DoesPermissionExist(manifest, permissionValue)) + { + Debug.Log(string.Format("[Adjust]: Your app's AndroidManifest.xml file already contains {0} permission.", permissionValue)); + return false; + } + + var element = manifest.CreateElement("uses-permission"); + AddAndroidNamespaceAttribute(manifest, "name", permissionValue, element); + manifest.DocumentElement.AppendChild(element); + Debug.Log(string.Format("[Adjust]: {0} permission successfully added to your app's AndroidManifest.xml file.", permissionValue)); + + return true; + } + + private static bool DoesPermissionExist(XmlDocument manifest, string permissionValue) + { + var xpath = string.Format("/manifest/uses-permission[@android:name='{0}']", permissionValue); + return manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null; + } + + private static bool AddBroadcastReceiver(XmlDocument manifest) + { + // We're looking for existence of broadcast receiver in the AndroidManifest.xml + // Check out the example below how that usually looks like: + + // > + // + // /> + // + // > + // + // + // + // + // + // + // + // + // + // + // + // > + // + // + + Debug.Log("[Adjust]: Checking if app's AndroidManifest.xml file contains receiver for INSTALL_REFERRER intent."); + + // Find the application node + var applicationNodeXpath = "/manifest/application"; + var applicationNode = manifest.DocumentElement.SelectSingleNode(applicationNodeXpath); + + // If there's no application node, something is really wrong with your AndroidManifest.xml. + if (applicationNode == null) + { + Debug.LogError("[Adjust]: Your app's AndroidManifest.xml file does not contain \"\" node."); + Debug.LogError("[Adjust]: Unable to add the Adjust broadcast receiver to AndroidManifest.xml."); + return false; + } + + // Okay, there's an application node in the AndroidManifest.xml file. + // Let's now check if user has already defined a receiver which is listening to INSTALL_REFERRER intent. + // If that is already defined, don't force the Adjust broadcast receiver to the manifest file. + // If not, add the Adjust broadcast receiver to the manifest file. + + var customBroadcastReceiversNodes = GetCustomRecieverNodes(manifest); + if (customBroadcastReceiversNodes.Count > 0) + { + if (DoesAdjustBroadcastReceiverExist(manifest)) + { + Debug.Log("[Adjust]: It seems like you are already using Adjust broadcast receiver. Yay."); + } + else + { + Debug.Log("[Adjust]: It seems like you are using your own broadcast receiver."); + Debug.Log("[Adjust]: Please, add the calls to the Adjust broadcast receiver like described in here: https://github.com/adjust/android_sdk/blob/master/doc/english/referrer.md"); + } + + return false; + } + + // Generate Adjust broadcast receiver entry and add it to the application node. + var receiverElement = manifest.CreateElement("receiver"); + AddAndroidNamespaceAttribute(manifest, "name", "com.adjust.sdk.AdjustReferrerReceiver", receiverElement); + AddAndroidNamespaceAttribute(manifest, "permission", "android.permission.INSTALL_PACKAGES", receiverElement); + AddAndroidNamespaceAttribute(manifest, "exported", "true", receiverElement); + + var intentFilterElement = manifest.CreateElement("intent-filter"); + var actionElement = manifest.CreateElement("action"); + AddAndroidNamespaceAttribute(manifest, "name", "com.android.vending.INSTALL_REFERRER", actionElement); + + intentFilterElement.AppendChild(actionElement); + receiverElement.AppendChild(intentFilterElement); + applicationNode.AppendChild(receiverElement); + + Debug.Log("[Adjust]: Adjust broadcast receiver successfully added to your app's AndroidManifest.xml file."); + + return true; + } + + private static bool DoesAdjustBroadcastReceiverExist(XmlDocument manifest) + { + var xpath = "/manifest/application/receiver[@android:name='com.adjust.sdk.AdjustReferrerReceiver']"; + return manifest.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null; + } + + private static List GetCustomRecieverNodes(XmlDocument manifest) + { + var xpath = "/manifest/application/receiver[intent-filter/action[@android:name='com.android.vending.INSTALL_REFERRER']]"; + return new List(manifest.DocumentElement.SelectNodes(xpath, GetNamespaceManager(manifest)).OfType()); + } + + private static void AddAndroidNamespaceAttribute(XmlDocument manifest, string key, string value, XmlElement node) + { + var androidSchemeAttribute = manifest.CreateAttribute("android", key, "http://schemas.android.com/apk/res/android"); + androidSchemeAttribute.InnerText = value; + node.SetAttributeNode(androidSchemeAttribute); + } + + private static XmlNamespaceManager GetNamespaceManager(XmlDocument manifest) + { + var namespaceManager = new XmlNamespaceManager(manifest.NameTable); + namespaceManager.AddNamespace("android", "http://schemas.android.com/apk/res/android"); + return namespaceManager; + } +#endif + } +} diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs.meta new file mode 100644 index 0000000..1aa966b --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c88a79442bb9342b6956c7d59705f982 +timeCreated: 1621599616 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef b/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef new file mode 100644 index 0000000..3017f9f --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef @@ -0,0 +1,10 @@ +{ + "name": "AdjustSdk.Editor", + "references": [ + "AdjustSdk.Scripts" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [] +} \ No newline at end of file diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef.meta new file mode 100644 index 0000000..818692a --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSdk.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: afc3483c5bcfe43c4a7a6b7f99b52a07 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustSettings.cs b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettings.cs new file mode 100644 index 0000000..b4d620b --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettings.cs @@ -0,0 +1,194 @@ +// Inspired by: https://github.com/facebook/facebook-sdk-for-unity/blob/master/Facebook.Unity.Settings/FacebookSettings.cs + +using System.Collections.Generic; +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace AdjustSdk +{ + public class AdjustSettings : ScriptableObject + { + private static AdjustSettings instance; + public const string AdjustSettingsExportPath = "Adjust/Resources/AdjustSettings.asset"; + + [SerializeField] + private bool _iOSFrameworkAdSupport = true; + [SerializeField] + private bool _iOSFrameworkAdServices = false; + [SerializeField] + private bool _iOSFrameworkAppTrackingTransparency = false; + [SerializeField] + private bool _iOSFrameworkStoreKit = false; + [SerializeField] + private bool _androidPermissionInternet = true; + [SerializeField] + private bool _androidPermissionInstallReferrerService = true; + [SerializeField] + private bool _androidPermissionAdId = true; + [SerializeField] + private bool _androidPermissionAccessNetworkState = false; + [SerializeField] + private string _iOSUserTrackingUsageDescription; + [SerializeField] + private string _iOSUrlIdentifier; + [SerializeField] + private string[] _iOSUrlSchemes = new string[0]; + [SerializeField] + private string[] _iOSUniversalLinksDomains = new string[0]; + [SerializeField] + private string[] androidUriSchemes = new string[0]; + [SerializeField] + private string _androidCustomActivityName; + + public static AdjustSettings Instance + { + get + { + instance = NullableInstance; + + if (instance == null) + { + // Create AdjustSettings.asset inside the folder in which AdjustSettings.cs reside. + instance = ScriptableObject.CreateInstance(); + var guids = AssetDatabase.FindAssets(string.Format("{0} t:script", "AdjustSettings")); + if (guids == null || guids.Length <= 0) + { + return instance; + } + + var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]).Replace("AdjustSettings.cs", "AdjustSettings.asset"); + // AdjustSettings.asset will be stored inside of the Adjust/Resources directory + if (assetPath.StartsWith("Assets")) + { + // plugin located in Assets directory + string rootDir = assetPath.Replace("/Adjust/Scripts/Editor/AdjustSettings.asset", ""); + string adjustResourcesPath = Path.Combine(rootDir, "Adjust/Resources"); + if (!Directory.Exists(adjustResourcesPath)) + { + Directory.CreateDirectory(adjustResourcesPath); + } + assetPath = Path.Combine(rootDir, AdjustSettingsExportPath); + } + else + { + // plugin located in Packages folder + string adjustResourcesPath = Path.Combine("Assets", "Adjust/Resources"); + if (!Directory.Exists(adjustResourcesPath)) + { + Directory.CreateDirectory(adjustResourcesPath); + } + assetPath = Path.Combine("Assets", AdjustSettingsExportPath); + } + + AssetDatabase.CreateAsset(instance, assetPath); + } + + return instance; + } + } + + public static AdjustSettings NullableInstance + { + get + { + if (instance == null) + { + var guids = AssetDatabase.FindAssets(string.Format("{0} t:ScriptableObject", "AdjustSettings")); + if (guids == null || guids.Length <= 0) + { + return instance; + } + var assetPath = AssetDatabase.GUIDToAssetPath(guids[0]); + instance = (AdjustSettings)AssetDatabase.LoadAssetAtPath(assetPath, typeof(AdjustSettings)); + } + + return instance; + } + } + + public static bool iOSFrameworkAdSupport + { + get { return Instance._iOSFrameworkAdSupport; } + set { Instance._iOSFrameworkAdSupport = value; } + } + + public static bool iOSFrameworkAdServices + { + get { return Instance._iOSFrameworkAdServices; } + set { Instance._iOSFrameworkAdServices = value; } + } + + public static bool iOSFrameworkAppTrackingTransparency + { + get { return Instance._iOSFrameworkAppTrackingTransparency; } + set { Instance._iOSFrameworkAppTrackingTransparency = value; } + } + + public static bool iOSFrameworkStoreKit + { + get { return Instance._iOSFrameworkStoreKit; } + set { Instance._iOSFrameworkStoreKit = value; } + } + + public static bool androidPermissionInternet + { + get { return Instance._androidPermissionInternet; } + set { Instance._androidPermissionInternet = value; } + } + + public static bool androidPermissionInstallReferrerService + { + get { return Instance._androidPermissionInstallReferrerService; } + set { Instance._androidPermissionInstallReferrerService = value; } + } + + public static bool androidPermissionAdId + { + get { return Instance._androidPermissionAdId; } + set { Instance._androidPermissionAdId = value; } + } + + public static bool androidPermissionAccessNetworkState + { + get { return Instance._androidPermissionAccessNetworkState; } + set { Instance._androidPermissionAccessNetworkState = value; } + } + + public static string iOSUserTrackingUsageDescription + { + get { return Instance._iOSUserTrackingUsageDescription; } + set { Instance._iOSUserTrackingUsageDescription = value; } + } + + public static string iOSUrlIdentifier + { + get { return Instance._iOSUrlIdentifier; } + set { Instance._iOSUrlIdentifier = value; } + } + + public static string[] iOSUrlSchemes + { + get { return Instance._iOSUrlSchemes; } + set { Instance._iOSUrlSchemes = value; } + } + + public static string[] iOSUniversalLinksDomains + { + get { return Instance._iOSUniversalLinksDomains; } + set { Instance._iOSUniversalLinksDomains = value; } + } + + 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/rd3/Adjust/Scripts/Editor/AdjustSettings.cs.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettings.cs.meta new file mode 100644 index 0000000..aefcdd0 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettings.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: ea4d495dc6d5ba64b90db7afda6a48a4 +timeCreated: 1601333126 +licenseType: Pro +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs new file mode 100644 index 0000000..0bafe02 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AdjustSdk +{ + [CustomEditor(typeof(AdjustSettings))] + public class AdjustSettingsEditor : Editor + { + SerializedProperty iOSFrameworkAdSupport; + SerializedProperty iOSFrameworkAdServices; + SerializedProperty iOSFrameworkAppTrackingTransparency; + SerializedProperty iOSFrameworkStoreKit; + SerializedProperty androidPermissionInternet; + SerializedProperty androidPermissionInstallReferrerService; + SerializedProperty androidPermissionAdId; + SerializedProperty androidPermissionAccessNetworkState; + SerializedProperty iOSUserTrackingUsageDescription; + SerializedProperty iOSUrlIdentifier; + SerializedProperty iOSUrlSchemes; + SerializedProperty iOSUniversalLinksDomains; + SerializedProperty androidUriSchemes; + SerializedProperty androidCustomActivityName; + + void OnEnable() + { + iOSFrameworkAdSupport = serializedObject.FindProperty("_iOSFrameworkAdSupport"); + iOSFrameworkAdServices = serializedObject.FindProperty("_iOSFrameworkAdServices"); + iOSFrameworkAppTrackingTransparency = serializedObject.FindProperty("_iOSFrameworkAppTrackingTransparency"); + iOSFrameworkStoreKit = serializedObject.FindProperty("_iOSFrameworkStoreKit"); + androidPermissionInternet = serializedObject.FindProperty("_androidPermissionInternet"); + androidPermissionInstallReferrerService = serializedObject.FindProperty("_androidPermissionInstallReferrerService"); + androidPermissionAdId = serializedObject.FindProperty("_androidPermissionAdId"); + androidPermissionAccessNetworkState = serializedObject.FindProperty("_androidPermissionAccessNetworkState"); + iOSUserTrackingUsageDescription = serializedObject.FindProperty("_iOSUserTrackingUsageDescription"); + iOSUrlIdentifier = serializedObject.FindProperty("_iOSUrlIdentifier"); + iOSUrlSchemes = serializedObject.FindProperty("_iOSUrlSchemes"); + iOSUniversalLinksDomains = serializedObject.FindProperty("_iOSUniversalLinksDomains"); + androidUriSchemes = serializedObject.FindProperty("androidUriSchemes"); + androidCustomActivityName = serializedObject.FindProperty("_androidCustomActivityName"); + } + public override void OnInspectorGUI() + { + GUIStyle darkerCyanTextFieldStyles = new GUIStyle(EditorStyles.boldLabel); + darkerCyanTextFieldStyles.normal.textColor = new Color(0f/255f, 190f/255f, 190f/255f); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("LINK IOS FRAMEWORKS:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + EditorGUILayout.PropertyField(iOSFrameworkAdSupport, + new GUIContent("AdSupport.framework", + "iOS framework needed to access IDFA value"), + true); + EditorGUILayout.PropertyField(iOSFrameworkAdServices, + new GUIContent("AdServices.framework", + "iOS framework needed to support AdServices based Apple Search Ads attribution"), + true); + EditorGUILayout.PropertyField(iOSFrameworkAppTrackingTransparency, + new GUIContent("AppTrackingTransparency.framework", + "iOS framework needed to display tracking consent dialog"), + true); + EditorGUILayout.PropertyField(iOSFrameworkStoreKit, + new GUIContent("StoreKit.framework", + "iOS framework needed to use SKAdNetwork capabilities"), + true); + EditorGUI.indentLevel -= 1; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("ADD ANDROID PERMISSIONS:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + EditorGUILayout.PropertyField(androidPermissionInternet, + new GUIContent("android.permission.INTERNET", + "Android permission needed to send data to Adjust backend"), + true); + EditorGUILayout.PropertyField(androidPermissionInstallReferrerService, + new GUIContent("com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE", + "Android permission needed to read install referrer"), + true); + EditorGUILayout.PropertyField(androidPermissionAdId, + new GUIContent("com.google.android.gms.permission.AD_ID", + "Android permission needed to read Google Advertising ID if you target API 33 or later"), + true); + EditorGUILayout.PropertyField(androidPermissionAccessNetworkState, + new GUIContent("android.permission.ACCESS_NETWORK_STATE", + "Android permission needed to determine type of network device is connected to"), + true); + EditorGUI.indentLevel -= 1; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("IOS PRIVACY:", darkerCyanTextFieldStyles); + EditorGUI.indentLevel += 1; + EditorGUILayout.PropertyField(iOSUserTrackingUsageDescription, + new GUIContent("User Tracking Description", + "String you would like to display to your users describing the reason " + + "behind asking for tracking permission."), + 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, + new GUIContent("iOS URL Identifier", + "Value of CFBundleURLName property of the root CFBundleURLTypes element. " + + "If not needed otherwise, value should be your bundle ID."), + true); + EditorGUILayout.PropertyField(iOSUrlSchemes, + new GUIContent("iOS URL Schemes", + "URL schemes handled by your app. " + + "Make sure to enter just the scheme name without :// part at the end."), + true); + EditorGUILayout.PropertyField(iOSUniversalLinksDomains, + new GUIContent("iOS Universal Links Domains", + "Associated domains handled by your app. State just the domain part without applinks: part in front."), + true); + EditorGUILayout.PropertyField(androidUriSchemes, + new GUIContent("Android URI Schemes", + "URI schemes handled by your app. " + + "Make sure to enter just the scheme name with :// part at the end."), + true); + EditorGUILayout.HelpBox( + "Please note that Adjust SDK doesn't remove existing URI Schemes, " + + "so if you need to clean previously added entries, " + + "you need to do it manually from \"Assets/Plugins/Android/AndroidManifest.xml\"", + MessageType.Info, + true); + EditorGUI.indentLevel -= 1; + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs.meta b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs.meta new file mode 100644 index 0000000..d667ac7 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/Editor/AdjustSettingsEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e957ffb3938e94bcaab247e46bd9804c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/ThirdParty.meta b/Assets/rd3/Adjust/Scripts/ThirdParty.meta new file mode 100644 index 0000000..660b2e8 --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/ThirdParty.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 638019d211e7141b7a78db997a91d582 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs b/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs new file mode 100644 index 0000000..b249d7a --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs @@ -0,0 +1,1037 @@ +//#define USE_SharpZipLib +#if !UNITY_WEBPLAYER +#define USE_FileIO +#endif + +/* * * * * + * A simple JSON Parser / builder + * ------------------------------ + * + * It mainly has been written as a simple JSON parser. It can build a JSON string + * from the node-tree, or generate a node tree from any valid JSON string. + * + * If you want to use compression when saving to file / stream / B64 you have to include + * SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) in your project and + * define "USE_SharpZipLib" at the top of the file + * + * Written by Bunny83 + * 2012-06-09 + * + * Features / attributes: + * - provides strongly typed node classes and lists / dictionaries + * - provides easy access to class members / array items / data values + * - the parser ignores data types. Each value is a string. + * - only double quotes (") are used for quoting strings. + * - values and names are not restricted to quoted strings. They simply add up and are trimmed. + * - There are only 3 types: arrays(JSONArray), objects(JSONClass) and values(JSONData) + * - provides "casting" properties to easily convert to / from those types: + * int / float / double / bool + * - provides a common interface for each node so no explicit casting is required. + * - the parser try to avoid errors, but if malformed JSON is parsed the result is undefined + * + * + * 2012-12-17 Update: + * - Added internal JSONLazyCreator class which simplifies the construction of a JSON tree + * Now you can simple reference any item that doesn't exist yet and it will return a JSONLazyCreator + * The class determines the required type by it's further use, creates the type and removes itself. + * - Added binary serialization / deserialization. + * - Added support for BZip2 zipped binary format. Requires the SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) + * The usage of the SharpZipLib library can be disabled by removing or commenting out the USE_SharpZipLib define at the top + * - The serializer uses different types when it comes to store the values. Since my data values + * are all of type string, the serializer will "try" which format fits best. The order is: int, float, double, bool, string. + * It's not the most efficient way but for a moderate amount of data it should work on all platforms. + * + * * * * */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace AdjustSdk +{ + public enum JSONBinaryTag + { + Array = 1, + Class = 2, + Value = 3, + IntValue = 4, + DoubleValue = 5, + BoolValue = 6, + FloatValue = 7, + } + + public class JSONNode + { + #region common interface + public virtual void Add(string aKey, JSONNode aItem){ } + public virtual JSONNode this[int aIndex] { get { return null; } set { } } + public virtual JSONNode this[string aKey] { get { return null; } set { } } + public virtual string Value { get { return ""; } set { } } + public virtual int Count { get { return 0; } } + + public virtual void Add(JSONNode aItem) + { + Add("", aItem); + } + + public virtual JSONNode Remove(string aKey) { return null; } + public virtual JSONNode Remove(int aIndex) { return null; } + public virtual JSONNode Remove(JSONNode aNode) { return aNode; } + + public virtual IEnumerable Childs { get { yield break;} } + public IEnumerable DeepChilds + { + get + { + foreach (var C in Childs) + foreach (var D in C.DeepChilds) + yield return D; + } + } + + public override string ToString() + { + return "JSONNode"; + } + public virtual string ToString(string aPrefix) + { + return "JSONNode"; + } + + #endregion common interface + + #region typecasting properties + public virtual int AsInt + { + get + { + int v = 0; + if (int.TryParse(Value,out v)) + return v; + return 0; + } + set + { + Value = value.ToString(); + } + } + public virtual float AsFloat + { + get + { + float v = 0.0f; + if (float.TryParse(Value,out v)) + return v; + return 0.0f; + } + set + { + Value = value.ToString(); + } + } + public virtual double AsDouble + { + get + { + double v = 0.0; + if (double.TryParse(Value,out v)) + return v; + return 0.0; + } + set + { + Value = value.ToString(); + } + } + public virtual bool AsBool + { + get + { + bool v = false; + if (bool.TryParse(Value,out v)) + return v; + return !string.IsNullOrEmpty(Value); + } + set + { + Value = (value)?"true":"false"; + } + } + public virtual JSONArray AsArray + { + get + { + return this as JSONArray; + } + } + public virtual JSONClass AsObject + { + get + { + return this as JSONClass; + } + } + + + #endregion typecasting properties + + #region operators + public static implicit operator JSONNode(string s) + { + return new JSONData(s); + } + public static implicit operator string(JSONNode d) + { + return (d == null)?null:d.Value; + } + public static bool operator ==(JSONNode a, object b) + { + if (b == null && a is JSONLazyCreator) + return true; + return System.Object.ReferenceEquals(a,b); + } + + public static bool operator !=(JSONNode a, object b) + { + return !(a == b); + } + public override bool Equals (object obj) + { + return System.Object.ReferenceEquals(this, obj); + } + public override int GetHashCode () + { + return base.GetHashCode(); + } + + + #endregion operators + + internal static string Escape(string aText) + { + string result = ""; + foreach(char c in aText) + { + switch(c) + { + case '\\' : result += "\\\\"; break; + case '\"' : result += "\\\""; break; + case '\n' : result += "\\n" ; break; + case '\r' : result += "\\r" ; break; + case '\t' : result += "\\t" ; break; + case '\b' : result += "\\b" ; break; + case '\f' : result += "\\f" ; break; + default : result += c ; break; + } + } + return result; + } + + public static JSONNode Parse(string aJSON) + { + Stack stack = new Stack(); + JSONNode ctx = null; + int i = 0; + string Token = ""; + string TokenName = ""; + bool QuoteMode = false; + while (i < aJSON.Length) + { + switch (aJSON[i]) + { + case '{': + if (QuoteMode) + { + Token += aJSON[i]; + break; + } + stack.Push(new JSONClass()); + if (ctx != null) + { + TokenName = TokenName.Trim(); + if (ctx is JSONArray) + ctx.Add(stack.Peek()); + else if (TokenName != "") + ctx.Add(TokenName,stack.Peek()); + } + TokenName = ""; + Token = ""; + ctx = stack.Peek(); + break; + + case '[': + if (QuoteMode) + { + Token += aJSON[i]; + break; + } + + stack.Push(new JSONArray()); + if (ctx != null) + { + TokenName = TokenName.Trim(); + if (ctx is JSONArray) + ctx.Add(stack.Peek()); + else if (TokenName != "") + ctx.Add(TokenName,stack.Peek()); + } + TokenName = ""; + Token = ""; + ctx = stack.Peek(); + break; + + case '}': + case ']': + if (QuoteMode) + { + Token += aJSON[i]; + break; + } + if (stack.Count == 0) + throw new Exception("JSON Parse: Too many closing brackets"); + + stack.Pop(); + if (Token != "") + { + TokenName = TokenName.Trim(); + if (ctx is JSONArray) + ctx.Add(Token); + else if (TokenName != "") + ctx.Add(TokenName,Token); + } + TokenName = ""; + Token = ""; + if (stack.Count>0) + ctx = stack.Peek(); + break; + + case ':': + if (QuoteMode) + { + Token += aJSON[i]; + break; + } + TokenName = Token; + Token = ""; + break; + + case '"': + QuoteMode ^= true; + break; + + case ',': + if (QuoteMode) + { + Token += aJSON[i]; + break; + } + if (Token != "") + { + if (ctx is JSONArray) + ctx.Add(Token); + else if (TokenName != "") + ctx.Add(TokenName, Token); + } + TokenName = ""; + Token = ""; + break; + + case '\r': + case '\n': + break; + + case ' ': + case '\t': + if (QuoteMode) + Token += aJSON[i]; + break; + + case '\\': + ++i; + if (QuoteMode) + { + char C = aJSON[i]; + switch (C) + { + case 't' : Token += '\t'; break; + case 'r' : Token += '\r'; break; + case 'n' : Token += '\n'; break; + case 'b' : Token += '\b'; break; + case 'f' : Token += '\f'; break; + case 'u': + { + string s = aJSON.Substring(i+1,4); + Token += (char)int.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier); + i += 4; + break; + } + default : Token += C; break; + } + } + break; + + default: + Token += aJSON[i]; + break; + } + ++i; + } + if (QuoteMode) + { + throw new Exception("JSON Parse: Quotation marks seems to be messed up."); + } + return ctx; + } + + public virtual void Serialize(System.IO.BinaryWriter aWriter) {} + + public void SaveToStream(System.IO.Stream aData) + { + var W = new System.IO.BinaryWriter(aData); + Serialize(W); + } + + #if USE_SharpZipLib + public void SaveToCompressedStream(System.IO.Stream aData) + { + using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData)) + { + gzipOut.IsStreamOwner = false; + SaveToStream(gzipOut); + gzipOut.Close(); + } + } + + public void SaveToCompressedFile(string aFileName) + { + #if USE_FileIO + System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName); + using(var F = System.IO.File.OpenWrite(aFileName)) + { + SaveToCompressedStream(F); + } + #else + throw new Exception("Can't use File IO stuff in webplayer"); + #endif + } + public string SaveToCompressedBase64() + { + using (var stream = new System.IO.MemoryStream()) + { + SaveToCompressedStream(stream); + stream.Position = 0; + return System.Convert.ToBase64String(stream.ToArray()); + } + } + + #else + public void SaveToCompressedStream(System.IO.Stream aData) + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + public void SaveToCompressedFile(string aFileName) + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + public string SaveToCompressedBase64() + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + #endif + + public static JSONNode Deserialize(System.IO.BinaryReader aReader) + { + JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte(); + switch(type) + { + case JSONBinaryTag.Array: + { + int count = aReader.ReadInt32(); + JSONArray tmp = new JSONArray(); + for(int i = 0; i < count; i++) + tmp.Add(Deserialize(aReader)); + return tmp; + } + case JSONBinaryTag.Class: + { + int count = aReader.ReadInt32(); + JSONClass tmp = new JSONClass(); + for(int i = 0; i < count; i++) + { + string key = aReader.ReadString(); + var val = Deserialize(aReader); + tmp.Add(key, val); + } + return tmp; + } + case JSONBinaryTag.Value: + { + return new JSONData(aReader.ReadString()); + } + case JSONBinaryTag.IntValue: + { + return new JSONData(aReader.ReadInt32()); + } + case JSONBinaryTag.DoubleValue: + { + return new JSONData(aReader.ReadDouble()); + } + case JSONBinaryTag.BoolValue: + { + return new JSONData(aReader.ReadBoolean()); + } + case JSONBinaryTag.FloatValue: + { + return new JSONData(aReader.ReadSingle()); + } + + default: + { + throw new Exception("Error deserializing JSON. Unknown tag: " + type); + } + } + } + + #if USE_SharpZipLib + public static JSONNode LoadFromCompressedStream(System.IO.Stream aData) + { + var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData); + return LoadFromStream(zin); + } + public static JSONNode LoadFromCompressedFile(string aFileName) + { + #if USE_FileIO + using(var F = System.IO.File.OpenRead(aFileName)) + { + return LoadFromCompressedStream(F); + } + #else + throw new Exception("Can't use File IO stuff in webplayer"); + #endif + } + public static JSONNode LoadFromCompressedBase64(string aBase64) + { + var tmp = System.Convert.FromBase64String(aBase64); + var stream = new System.IO.MemoryStream(tmp); + stream.Position = 0; + return LoadFromCompressedStream(stream); + } + #else + public static JSONNode LoadFromCompressedFile(string aFileName) + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + public static JSONNode LoadFromCompressedStream(System.IO.Stream aData) + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + public static JSONNode LoadFromCompressedBase64(string aBase64) + { + throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON"); + } + #endif + + public static JSONNode LoadFromStream(System.IO.Stream aData) + { + using(var R = new System.IO.BinaryReader(aData)) + { + return Deserialize(R); + } + } + public static JSONNode LoadFromBase64(string aBase64) + { + var tmp = System.Convert.FromBase64String(aBase64); + var stream = new System.IO.MemoryStream(tmp); + stream.Position = 0; + return LoadFromStream(stream); + } + } // End of JSONNode + + public class JSONArray : JSONNode, IEnumerable + { + private List m_List = new List(); + public override JSONNode this[int aIndex] + { + get + { + if (aIndex<0 || aIndex >= m_List.Count) + return new JSONLazyCreator(this); + return m_List[aIndex]; + } + set + { + if (aIndex<0 || aIndex >= m_List.Count) + m_List.Add(value); + else + m_List[aIndex] = value; + } + } + public override JSONNode this[string aKey] + { + get{ return new JSONLazyCreator(this);} + set{ m_List.Add(value); } + } + public override int Count + { + get { return m_List.Count; } + } + public override void Add(string aKey, JSONNode aItem) + { + m_List.Add(aItem); + } + public override JSONNode Remove(int aIndex) + { + if (aIndex < 0 || aIndex >= m_List.Count) + return null; + JSONNode tmp = m_List[aIndex]; + m_List.RemoveAt(aIndex); + return tmp; + } + public override JSONNode Remove(JSONNode aNode) + { + m_List.Remove(aNode); + return aNode; + } + public override IEnumerable Childs + { + get + { + foreach(JSONNode N in m_List) + yield return N; + } + } + public IEnumerator GetEnumerator() + { + foreach(JSONNode N in m_List) + yield return N; + } + public override string ToString() + { + string result = "[ "; + foreach (JSONNode N in m_List) + { + if (result.Length > 2) + result += ", "; + result += N.ToString(); + } + result += " ]"; + return result; + } + public override string ToString(string aPrefix) + { + string result = "[ "; + foreach (JSONNode N in m_List) + { + if (result.Length > 3) + result += ", "; + result += "\n" + aPrefix + " "; + result += N.ToString(aPrefix+" "); + } + result += "\n" + aPrefix + "]"; + return result; + } + public override void Serialize (System.IO.BinaryWriter aWriter) + { + aWriter.Write((byte)JSONBinaryTag.Array); + aWriter.Write(m_List.Count); + for(int i = 0; i < m_List.Count; i++) + { + m_List[i].Serialize(aWriter); + } + } + } // End of JSONArray + + public class JSONClass : JSONNode, IEnumerable + { + private Dictionary m_Dict = new Dictionary(); + public override JSONNode this[string aKey] + { + get + { + if (m_Dict.ContainsKey(aKey)) + return m_Dict[aKey]; + else + return new JSONLazyCreator(this, aKey); + } + set + { + if (m_Dict.ContainsKey(aKey)) + m_Dict[aKey] = value; + else + m_Dict.Add(aKey,value); + } + } + public override JSONNode this[int aIndex] + { + get + { + if (aIndex < 0 || aIndex >= m_Dict.Count) + return null; + return m_Dict.ElementAt(aIndex).Value; + } + set + { + if (aIndex < 0 || aIndex >= m_Dict.Count) + return; + string key = m_Dict.ElementAt(aIndex).Key; + m_Dict[key] = value; + } + } + public override int Count + { + get { return m_Dict.Count; } + } + + + public override void Add(string aKey, JSONNode aItem) + { + if (!string.IsNullOrEmpty(aKey)) + { + if (m_Dict.ContainsKey(aKey)) + m_Dict[aKey] = aItem; + else + m_Dict.Add(aKey, aItem); + } + else + m_Dict.Add(Guid.NewGuid().ToString(), aItem); + } + + public override JSONNode Remove(string aKey) + { + if (!m_Dict.ContainsKey(aKey)) + return null; + JSONNode tmp = m_Dict[aKey]; + m_Dict.Remove(aKey); + return tmp; + } + public override JSONNode Remove(int aIndex) + { + if (aIndex < 0 || aIndex >= m_Dict.Count) + return null; + var item = m_Dict.ElementAt(aIndex); + m_Dict.Remove(item.Key); + return item.Value; + } + public override JSONNode Remove(JSONNode aNode) + { + try + { + var item = m_Dict.Where(k => k.Value == aNode).First(); + m_Dict.Remove(item.Key); + return aNode; + } + catch + { + return null; + } + } + + public override IEnumerable Childs + { + get + { + foreach(KeyValuePair N in m_Dict) + yield return N.Value; + } + } + + public IEnumerator GetEnumerator() + { + foreach(KeyValuePair N in m_Dict) + yield return N; + } + public override string ToString() + { + string result = "{"; + foreach (KeyValuePair N in m_Dict) + { + if (result.Length > 2) + result += ", "; + result += "\"" + Escape(N.Key) + "\":" + N.Value.ToString(); + } + result += "}"; + return result; + } + public override string ToString(string aPrefix) + { + string result = "{ "; + foreach (KeyValuePair N in m_Dict) + { + if (result.Length > 3) + result += ", "; + result += "\n" + aPrefix + " "; + result += "\"" + Escape(N.Key) + "\" : " + N.Value.ToString(aPrefix+" "); + } + result += "\n" + aPrefix + "}"; + return result; + } + public override void Serialize (System.IO.BinaryWriter aWriter) + { + aWriter.Write((byte)JSONBinaryTag.Class); + aWriter.Write(m_Dict.Count); + foreach(string K in m_Dict.Keys) + { + aWriter.Write(K); + m_Dict[K].Serialize(aWriter); + } + } + } // End of JSONClass + + public class JSONData : JSONNode + { + private string m_Data; + public override string Value + { + get { return m_Data; } + set { m_Data = value; } + } + public JSONData(string aData) + { + m_Data = aData; + } + public JSONData(float aData) + { + AsFloat = aData; + } + public JSONData(double aData) + { + AsDouble = aData; + } + public JSONData(bool aData) + { + AsBool = aData; + } + public JSONData(int aData) + { + AsInt = aData; + } + + public override string ToString() + { + return "\"" + Escape(m_Data) + "\""; + } + public override string ToString(string aPrefix) + { + return "\"" + Escape(m_Data) + "\""; + } + public override void Serialize (System.IO.BinaryWriter aWriter) + { + var tmp = new JSONData(""); + + tmp.AsInt = AsInt; + if (tmp.m_Data == this.m_Data) + { + aWriter.Write((byte)JSONBinaryTag.IntValue); + aWriter.Write(AsInt); + return; + } + tmp.AsFloat = AsFloat; + if (tmp.m_Data == this.m_Data) + { + aWriter.Write((byte)JSONBinaryTag.FloatValue); + aWriter.Write(AsFloat); + return; + } + tmp.AsDouble = AsDouble; + if (tmp.m_Data == this.m_Data) + { + aWriter.Write((byte)JSONBinaryTag.DoubleValue); + aWriter.Write(AsDouble); + return; + } + + tmp.AsBool = AsBool; + if (tmp.m_Data == this.m_Data) + { + aWriter.Write((byte)JSONBinaryTag.BoolValue); + aWriter.Write(AsBool); + return; + } + aWriter.Write((byte)JSONBinaryTag.Value); + aWriter.Write(m_Data); + } + } // End of JSONData + + internal class JSONLazyCreator : JSONNode + { + private JSONNode m_Node = null; + private string m_Key = null; + + public JSONLazyCreator(JSONNode aNode) + { + m_Node = aNode; + m_Key = null; + } + public JSONLazyCreator(JSONNode aNode, string aKey) + { + m_Node = aNode; + m_Key = aKey; + } + + private void Set(JSONNode aVal) + { + if (m_Key == null) + { + m_Node.Add(aVal); + } + else + { + m_Node.Add(m_Key, aVal); + } + m_Node = null; // Be GC friendly. + } + + public override JSONNode this[int aIndex] + { + get + { + return new JSONLazyCreator(this); + } + set + { + var tmp = new JSONArray(); + tmp.Add(value); + Set(tmp); + } + } + + public override JSONNode this[string aKey] + { + get + { + return new JSONLazyCreator(this, aKey); + } + set + { + var tmp = new JSONClass(); + tmp.Add(aKey, value); + Set(tmp); + } + } + public override void Add (JSONNode aItem) + { + var tmp = new JSONArray(); + tmp.Add(aItem); + Set(tmp); + } + public override void Add (string aKey, JSONNode aItem) + { + var tmp = new JSONClass(); + tmp.Add(aKey, aItem); + Set(tmp); + } + public static bool operator ==(JSONLazyCreator a, object b) + { + if (b == null) + return true; + return System.Object.ReferenceEquals(a,b); + } + + public static bool operator !=(JSONLazyCreator a, object b) + { + return !(a == b); + } + public override bool Equals (object obj) + { + if (obj == null) + return true; + return System.Object.ReferenceEquals(this, obj); + } + public override int GetHashCode () + { + return base.GetHashCode(); + } + + public override string ToString() + { + return ""; + } + public override string ToString(string aPrefix) + { + return ""; + } + + public override int AsInt + { + get + { + JSONData tmp = new JSONData(0); + Set(tmp); + return 0; + } + set + { + JSONData tmp = new JSONData(value); + Set(tmp); + } + } + public override float AsFloat + { + get + { + JSONData tmp = new JSONData(0.0f); + Set(tmp); + return 0.0f; + } + set + { + JSONData tmp = new JSONData(value); + Set(tmp); + } + } + public override double AsDouble + { + get + { + JSONData tmp = new JSONData(0.0); + Set(tmp); + return 0.0; + } + set + { + JSONData tmp = new JSONData(value); + Set(tmp); + } + } + public override bool AsBool + { + get + { + JSONData tmp = new JSONData(false); + Set(tmp); + return false; + } + set + { + JSONData tmp = new JSONData(value); + Set(tmp); + } + } + public override JSONArray AsArray + { + get + { + JSONArray tmp = new JSONArray(); + Set(tmp); + return tmp; + } + } + public override JSONClass AsObject + { + get + { + JSONClass tmp = new JSONClass(); + Set(tmp); + return tmp; + } + } + } // End of JSONLazyCreator + + public static class JSON + { + public static JSONNode Parse(string aJSON) + { + return JSONNode.Parse(aJSON); + } + } +} \ No newline at end of file diff --git a/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs.meta b/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs.meta new file mode 100644 index 0000000..a28238d --- /dev/null +++ b/Assets/rd3/Adjust/Scripts/ThirdParty/SimpleJSON.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9c780c17852614618be5ffd9cc43a75f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/rd3/Adjust/package.json b/Assets/rd3/Adjust/package.json new file mode 100644 index 0000000..77f7337 --- /dev/null +++ b/Assets/rd3/Adjust/package.json @@ -0,0 +1,12 @@ +{ + "name": "com.adjust.sdk", + "version": "5.4.2", + "unity": "2019.4", + "displayName": "Adjust", + "license": "MIT", + "homepage": "https://www.adjust.com", + "author": { + "name": "Adjust", + "url": "https://github.com/adjust/unity_sdk" + } +} diff --git a/Assets/rd3/Adjust/package.json.meta b/Assets/rd3/Adjust/package.json.meta new file mode 100644 index 0000000..a5cc689 --- /dev/null +++ b/Assets/rd3/Adjust/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e70aaf9215a0244c1b2675cd72030bbe +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 2ddb3b9..5b0e59a 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -256,13 +256,13 @@ PlayerSettings: clonedFromGUID: 10ad67313f4034357812315f3c407484 templatePackageId: com.unity.template.2d@6.1.2 templateDefaultScene: Assets/Scenes/SampleScene.unity - useCustomMainManifest: 0 + useCustomMainManifest: 1 useCustomLauncherManifest: 0 - useCustomMainGradleTemplate: 0 + useCustomMainGradleTemplate: 1 useCustomLauncherGradleManifest: 0 useCustomBaseGradleTemplate: 0 - useCustomGradlePropertiesTemplate: 0 - useCustomGradleSettingsTemplate: 0 + useCustomGradlePropertiesTemplate: 1 + useCustomGradleSettingsTemplate: 1 useCustomProguardFile: 0 AndroidTargetArchitectures: 3 AndroidTargetDevices: 0