diff --git a/popcorn/Assets/Editor.meta b/popcorn/Assets/Editor.meta new file mode 100644 index 00000000..8b41c254 --- /dev/null +++ b/popcorn/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3403d0e00b8c843cba4ae3441274370f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Editor/BuildPostProcessor.cs b/popcorn/Assets/Editor/BuildPostProcessor.cs new file mode 100644 index 00000000..1f88e6ce --- /dev/null +++ b/popcorn/Assets/Editor/BuildPostProcessor.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEditor.iOS.Xcode; +using System.IO; +using System.Collections.Generic; + +public class BuildPostProcessor : MonoBehaviour +{ + [PostProcessBuild] + public static void OnPostprocessBuild(BuildTarget buildTarget, string path) + { + if (buildTarget == BuildTarget.iOS) + { + BuildiOS(path: path); + } + else if (buildTarget == BuildTarget.Android) + { + BuildAndroid(path: path); + } + } + + private static void BuildAndroid(string path = "") + { + Debug.Log("TenjinSDK: Starting Android Build"); + } + + private static void BuildiOS(string path = "") + { +#if UNITY_IOS + Debug.Log("TenjinSDK: Starting iOS Build"); + + string projectPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; + PBXProject project = new PBXProject(); + project.ReadFromFile(projectPath); + +#if UNITY_2019_3_OR_NEWER + string buildTarget = project.GetUnityFrameworkTargetGuid(); +#else + string buildTarget = project.TargetGuidByName("Unity-iPhone"); +#endif + + List frameworks = new List(); + + frameworks.Add("AdServices.framework"); + frameworks.Add("AdSupport.framework"); + frameworks.Add("AppTrackingTransparency.framework"); + frameworks.Add("iAd.framework"); + frameworks.Add("StoreKit.framework"); + + foreach (string framework in frameworks) + { + Debug.Log("TenjinSDK: Adding framework: " + framework); + project.AddFrameworkToProject(buildTarget, framework, true); + } + + Debug.Log("TenjinSDK: Adding -ObjC flag to other linker flags (OTHER_LDFLAGS)"); + project.AddBuildProperty(buildTarget, "OTHER_LDFLAGS", "-ObjC"); + + File.WriteAllText(projectPath, project.WriteToString()); +#endif + } +} diff --git a/popcorn/Assets/Editor/BuildPostProcessor.cs.meta b/popcorn/Assets/Editor/BuildPostProcessor.cs.meta new file mode 100644 index 00000000..e06d6db2 --- /dev/null +++ b/popcorn/Assets/Editor/BuildPostProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ebeefe713f9124897baf3451a11b0b28 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/MyGame/Scenes/Title/Title.unity b/popcorn/Assets/MyGame/Scenes/Title/Title.unity index 04833728..0b937b5f 100644 --- a/popcorn/Assets/MyGame/Scenes/Title/Title.unity +++ b/popcorn/Assets/MyGame/Scenes/Title/Title.unity @@ -1867,6 +1867,63 @@ Transform: type: 3} m_PrefabInstance: {fileID: 860729059} m_PrefabAsset: {fileID: 0} +--- !u!1001 &868273855 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 165288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_Name + value: GameAnalytics + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_RootOrder + value: 4 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 465288, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: a9d27d37bab3c447b8eb7a2a6756e952, type: 3} --- !u!1 &904702265 GameObject: m_ObjectHideFlags: 0 @@ -8882,6 +8939,49 @@ Transform: type: 3} m_PrefabInstance: {fileID: 1913405381} m_PrefabAsset: {fileID: 0} +--- !u!1 &1987905217 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1987905218} + - component: {fileID: 1987905219} + m_Layer: 0 + m_Name: AnalyticsInit + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1987905218 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987905217} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.5620365, y: -0.26919502, z: -7.2558317} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1987905219 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1987905217} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 92f829d05e001457d8dc5a62a7162e6e, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &2063870804 GameObject: m_ObjectHideFlags: 0 diff --git a/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs b/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs new file mode 100644 index 00000000..16bc69af --- /dev/null +++ b/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs @@ -0,0 +1,69 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using GameAnalyticsSDK; + + +public class AnalyticsInit : MonoBehaviour , IGameAnalyticsATTListener{ + + private bool _attDone = false; + + public static readonly string TENJIN_API_KEY = "VCRGBQMHMGYPM2B5ITDHLSVIFTS8JQSW"; + + private void Awake() { + + } + + void Start () { + if(Application.platform == RuntimePlatform.IPhonePlayer){ + GameAnalytics.RequestTrackingAuthorization(this); + }else{ + InitAnalytics(); + } + } + + void Update(){ + if(_attDone){ + _attDone = false; + InitAnalytics(); + } + + } + + void OnApplicationPause (bool pauseStatus){ + if(pauseStatus){ + //do nothing + }else{ + TenjinConnect(); + } + } + + private void InitAnalytics(){ + GameAnalytics.Initialize(); + TenjinConnect(); + } + + private void TenjinConnect(){ +#if !UNITY_EDITOR + BaseTenjin instance = Tenjin.getInstance(TENJIN_API_KEY); + instance.Connect(); +#endif + } + + //-- GameAnalytics --// + public void GameAnalyticsATTListenerNotDetermined(){ + _attDone = true; + } + public void GameAnalyticsATTListenerRestricted(){ + _attDone = true; + } + public void GameAnalyticsATTListenerDenied(){ + _attDone = true; + } + public void GameAnalyticsATTListenerAuthorized(){ + _attDone = true; + } + + + +} \ No newline at end of file diff --git a/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs.meta b/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs.meta new file mode 100644 index 00000000..67656639 --- /dev/null +++ b/popcorn/Assets/MyGame/Scripts/AnalyticsInit.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 92f829d05e001457d8dc5a62a7162e6e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/Android.meta b/popcorn/Assets/Plugins/Android.meta new file mode 100644 index 00000000..40b77833 --- /dev/null +++ b/popcorn/Assets/Plugins/Android.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 083742a6d8b6e4245b689eae7d7981a1 +folderAsset: yes +DefaultImporter: + userData: diff --git a/popcorn/Assets/Plugins/Android/AndroidManifest.xml b/popcorn/Assets/Plugins/Android/AndroidManifest.xml new file mode 100644 index 00000000..0e0ae4a8 --- /dev/null +++ b/popcorn/Assets/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + diff --git a/popcorn/Assets/Plugins/Android/AndroidManifest.xml.meta b/popcorn/Assets/Plugins/Android/AndroidManifest.xml.meta new file mode 100644 index 00000000..38afdc12 --- /dev/null +++ b/popcorn/Assets/Plugins/Android/AndroidManifest.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9ff5ce456e2794ddc8d114ee10373921 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar b/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar new file mode 100644 index 00000000..1ffc46aa Binary files /dev/null and b/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar differ diff --git a/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar.meta b/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar.meta new file mode 100644 index 00000000..ed9de2e0 --- /dev/null +++ b/popcorn/Assets/Plugins/Android/installreferrer-1.1.2.aar.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: a611a40881a114db9916f297d2255eac +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar b/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar new file mode 100644 index 00000000..e79b1266 Binary files /dev/null and b/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar differ diff --git a/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar.meta b/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar.meta new file mode 100644 index 00000000..89e45a8d --- /dev/null +++ b/popcorn/Assets/Plugins/Android/play-services-ads-identifier-17.0.0.aar.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 303faa6cfbcca422c88cec8d9e0ff22c +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar b/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar new file mode 100644 index 00000000..efa33e44 Binary files /dev/null and b/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar differ diff --git a/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar.meta b/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar.meta new file mode 100644 index 00000000..964b1100 --- /dev/null +++ b/popcorn/Assets/Plugins/Android/play-services-basement-17.4.0.aar.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 99fd02f5a1b324a52afb1c8578a1e570 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/Android/tenjin.aar b/popcorn/Assets/Plugins/Android/tenjin.aar new file mode 100644 index 00000000..43a36d9a Binary files /dev/null and b/popcorn/Assets/Plugins/Android/tenjin.aar differ diff --git a/popcorn/Assets/Plugins/Android/tenjin.aar.meta b/popcorn/Assets/Plugins/Android/tenjin.aar.meta new file mode 100644 index 00000000..84a6ce3f --- /dev/null +++ b/popcorn/Assets/Plugins/Android/tenjin.aar.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: ba8b0216d5dc542fa95dde93f8a75b0e +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Android: Android + second: + enabled: 1 + settings: {} + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/iOS.meta b/popcorn/Assets/Plugins/iOS.meta new file mode 100644 index 00000000..1da48043 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: bac35c308b1e840d3923c92e2d044a03 +folderAsset: yes +DefaultImporter: + userData: diff --git a/popcorn/Assets/Plugins/iOS/TenjinSDK.h b/popcorn/Assets/Plugins/iOS/TenjinSDK.h new file mode 100644 index 00000000..8b4800b0 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinSDK.h @@ -0,0 +1,189 @@ +// +// TenjinSDK.h +// TenjinSDK +// +// Version 1.12.7 + +// Copyright (c) 2016 Tenjin. All rights reserved. +// + +#import +#import + +@interface TenjinSDK : NSObject + +#pragma mark Initialization + +- (instancetype)init NS_UNAVAILABLE; + +// initialize the Tenjin SDK ++ (TenjinSDK *)init:(NSString *)apiToken __deprecated_msg("use `initialize`"); + +//initialize the Tenjin SDK with shared secret ++ (TenjinSDK *)init:(NSString *)apiToken + andSharedSecret:(NSString *)secret __deprecated_msg("use `initialize`"); + +//initialize the Tenjin SDK with app subversion ++ (TenjinSDK *)init:(NSString *)apiToken + andAppSubversion:(NSNumber *)subversion __deprecated_msg("use `initialize`"); + +//initialize the Tenjin SDK with shared secret and app subversion ++ (TenjinSDK *)init:(NSString *)apiToken + andSharedSecret:(NSString *)secret + andAppSubversion:(NSNumber *)subversion __deprecated_msg("use `initialize`"); + +// initialize the Tenjin SDK ++ (TenjinSDK *)initialize:(NSString *)apiToken; + +//initialize the Tenjin SDK with shared secret ++ (TenjinSDK *)initialize:(NSString *)apiToken + andSharedSecret:(NSString *)secret; + +//initialize the Tenjin SDK with app subversion ++ (TenjinSDK *)initialize:(NSString *)apiToken + andAppSubversion:(NSNumber *)subversion; + +//initialize the Tenjin SDK with shared secret and app subversion ++ (TenjinSDK *)initialize:(NSString *)apiToken + andSharedSecret:(NSString *)secret + andAppSubversion:(NSNumber *)subversion; + +- (id)initWithToken:(NSString *)apiToken + andSharedSecret:(NSString *)secret + andAppSubversion:(NSNumber *)subversion +andDeferredDeeplink:(NSURL *)url + ping:(BOOL)ping NS_DESIGNATED_INITIALIZER; + +#pragma mark Singleton access + +// initialize the Tenjin SDK ++ (TenjinSDK *)getInstance:(NSString *)apiToken; + +//initialize the Tenjin SDK with shared secret ++ (TenjinSDK *)getInstance:(NSString *)apiToken + andSharedSecret:(NSString *)secret; + +//initialize the Tenjin SDK with app subversion ++ (TenjinSDK *)getInstance:(NSString *)apiToken + andAppSubversion:(NSNumber *)subversion; + +//initialize the Tenjin SDK with shared secret and app subversion ++ (TenjinSDK *)getInstance:(NSString *)apiToken + andSharedSecret:(NSString *)secret + andAppSubversion:(NSNumber *)subversion; + +//initialize the Tenjin SDK + connect ++ (TenjinSDK *)sharedInstanceWithToken:(NSString *)apiToken __deprecated_msg("use `init` and `connect`"); + +//initialize the Tenjin SDK + connect with a third party deeplink ++ (TenjinSDK *)sharedInstanceWithToken:(NSString *)apiToken + andDeferredDeeplink:(NSURL *)url __deprecated_msg("use `init` and `connectWithDeferredDeeplink`"); + +//returns the shared Tenjin SDK instance ++ (TenjinSDK *)sharedInstance; + +#pragma mark - Functionality + +//use connect to send connect call. sharedInstanceWithToken automatically does a connect ++ (void)connect; + +//use connect to send connect call. sharedInstanceWithToken automatically does a connect ++ (void)connectWithDeferredDeeplink:(NSURL *)url; + +//use sendEventWithName for custom event names ++ (void)sendEventWithName:(NSString *)eventName; + +//This method checks to make sure integers are passed as values. ++ (void)sendEventWithName:(NSString *)eventName + andEventValue:(NSString *)eventValue; + +//This method is deprecated in favor of [transaction: andReceipt:], so Tenjin can verify your transactions ++ (void)transaction:(SKPaymentTransaction *)transaction __attribute__((deprecated)); + +//Use this method to submit a transaction to Tenjin, we will also attempt to verify it for our records ++ (void)transaction:(SKPaymentTransaction *)transaction + andReceipt:(NSData *)receipt; + +//use transactionWithProductName... when you don't use Apple's SKPaymentTransaction and need to pass revenue directly ++ (void)transactionWithProductName:(NSString *)productName + andCurrencyCode:(NSString *)currencyCode + andQuantity:(NSInteger)quantity + andUnitPrice:(NSDecimalNumber *)price; + +//use transactionWithProductName...when you don't use Apple's SKPaymentTransaction and need to pass revenue directly with a NSData binary receipt ++ (void)transactionWithProductName:(NSString *)productName + andCurrencyCode:(NSString *)currencyCode + andQuantity:(NSInteger)quantity + andUnitPrice:(NSDecimalNumber *)price + andTransactionId:(NSString *)transactionId + andReceipt:(NSData *)receipt; + +//use this method when you want to pass in a base64 receipt instead of a NSData receipt ++ (void)transactionWithProductName:(NSString *)productName + andCurrencyCode:(NSString *)currencyCode + andQuantity:(NSInteger)quantity + andUnitPrice:(NSDecimalNumber *)price + andTransactionId:(NSString *)transactionId + andBase64Receipt:(NSString *)receipt; + +//use this method to register the attribution callback +- (void)registerDeepLinkHandler:(void (^)(NSDictionary *params, NSError *error))deeplinkHandler; + +//notify Tenjin of a new subscription purchase +- (void)handleSubscriptionPurchase:(SKPaymentTransaction *)transaction; + +// GDPR opt-out ++ (void)optOut; + +// GDPR opt-in ++ (void)optIn; + +// GDPR opt-out of list of params ++ (void)optOutParams:(NSArray *)params; + +// GDPR opt-in with list of params ++ (void)optInParams:(NSArray *)params; + +// Appends app subversion to app version ++ (void)appendAppSubversion:(NSNumber *)subversion; + +// deprecated ++ (void)updateSkAdNetworkConversionValue:(int)conversionValue __deprecated_msg("use `updateConversionValue:`"); + +// Update conversion value ++ (void)updateConversionValue:(int)conversionValue; + +#pragma mark Util + ++ (void)verboseLogs; + ++ (void)debugLogs; + ++ (void)setLogHandler:(void (^)(NSString *))handler; + ++ (NSString *)sdkVersion; + ++ (void)setWrapperVersion:(NSString *)wrapperVersion; + ++ (void)setValue:(NSString *)value + forKey:(NSString *)key; + ++ (void)registerAppForAdNetworkAttribution; + ++ (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(NSUInteger status))completion; +@end +// +// Created by Tenjin on 2019-05-17. +// Copyright (c) 2019 Tenjin. All rights reserved. +// + +#import +#import "TenjinSDK.h" + + +@interface TenjinSDK (MoPubILRD) ++ (void)subscribeMoPubImpressions; + ++ (void)mopubImpressionFromJSON:(NSString *)jsonString; +@end + diff --git a/popcorn/Assets/Plugins/iOS/TenjinSDK.h.meta b/popcorn/Assets/Plugins/iOS/TenjinSDK.h.meta new file mode 100644 index 00000000..f6621a11 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinSDK.h.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 460520ebc89d6411cbf55a7bd8d2f698 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h new file mode 100755 index 00000000..a84eb32b --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h @@ -0,0 +1,56 @@ +// +// TenjinUnityInterface.h +// Unity-iOS bridge +// +// Copyright (c) 2018 Tenjin. All rights reserved. +// +// + +#ifndef __Unity_iPhone__TenjinUnityInterface__ +#define __Unity_iPhone__TenjinUnityInterface__ + +#include "TenjinSDK.h" + +extern "C" { + +typedef struct TenjinStringStringKeyValuePair { + const char* key; + const char* value; +} TenjinStringStringKeyValuePair; + +typedef void (*TenjinDeeplinkHandlerFunc)(TenjinStringStringKeyValuePair* deepLinkDataPairArray, int32_t deepLinkDataPairCount); + +void iosTenjinInit(const char* apiKey); +void iosTenjinInitWithSharedSecret(const char* apiKey, const char* sharedSecret); +void iosTenjinInitWithAppSubversion(const char* apiKey, int subversion); +void iosTenjinInitWithSharedSecretAppSubversion(const char* apiKey, const char* sharedSecret, int subversion); + +void iosTenjinInitialize(const char* apiKey); +void iosTenjinInitializeWithSharedSecret(const char* apiKey, const char* sharedSecret); +void iosTenjinInitializeWithAppSubversion(const char* apiKey, int subversion); +void iosTenjinInitializeWithSharedSecretAppSubversion(const char* apiKey, const char* sharedSecret, int subversion); + +void iosTenjinConnect(); +void iosTenjinConnectWithDeferredDeeplink(const char* deferredDeeplink); + +void iosTenjinSendEvent(const char* eventName); +void iosTenjinSendEventWithValue(const char* eventName, const char* eventValue); +void iosTenjinTransaction(const char* productId, const char* currencyCode, int quantity, double price); +void iosTenjinTransactionWithReceiptData(const char* productId, const char* currencyCode, int quantity, double price, const char* transactionId, const char* receipt); +void iosTenjinRegisterDeepLinkHandler(TenjinDeeplinkHandlerFunc deeplinkHandlerFunc); + +void iosTenjinOptIn(); +void iosTenjinOptOut(); +void iosTenjinOptInParams(char** params, int size); +void iosTenjinOptOutParams(char** params, int size); +void iosTenjinAppendAppSubversion(int subversion); +void iosTenjinUpdateConversionValue(int conversionValue); +void iosTenjinRequestTrackingAuthorizationWithCompletionHandler(); + +void iosTenjinSetDebugLogs(); + +void iosTenjinSubscribeMoPubImpressions(); +void iosTenjinMopubImpressionFromJSON(const char* jsonString); +} + +#endif diff --git a/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h.meta b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h.meta new file mode 100644 index 00000000..400c83b0 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.h.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: f9924cf43851d480ba52cf59448f4c51 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm new file mode 100644 index 00000000..f7335d5e --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm @@ -0,0 +1,239 @@ +// +// TenjinUnityInterface.mm +// Unity-iOS bridge +// +// Created by Christopher Farm. +// +// + +#include "TenjinUnityInterface.h" + +extern "C" { +#define MALLOC_ARRAY(count, type) (count == 0 ? NULL : (type*) malloc(count * sizeof(type))) +void iosTenjin_InternalFreeStringStringKeyValuePairs(TenjinStringStringKeyValuePair* pairs, int32_t pairCount); +bool iosTenjin_InternalConvertDictionaryToStringStringPairs(NSDictionary* dictionary, TenjinStringStringKeyValuePair** outPairArray, int* outPairCount); + +TenjinDeeplinkHandlerFunc registeredDeeplinkHandlerFunc; + +void iosTenjinInit(const char* apiKey){ + NSString *apiKeyStr = [NSString stringWithUTF8String:apiKey]; + + NSLog(@"Called Tenjin [TenjinSDK sharedInstanceWithToken:%@]", apiKeyStr); + [TenjinSDK initialize:apiKeyStr]; +} + +void iosTenjinInitWithSharedSecret(const char* apiKey, const char* sharedSecret){ + NSString *apiKeyStr = [NSString stringWithUTF8String:apiKey]; + NSString *sharedSecretStr = [NSString stringWithUTF8String:sharedSecret]; + + NSLog(@"Called Tenjin [TenjinSDK sharedInstanceWithToken:%@ andSharedSecret:*]", apiKeyStr); + [TenjinSDK initialize:apiKeyStr andSharedSecret:sharedSecretStr]; +} + +void iosTenjinInitWithAppSubversion(const char* apiKey, int subversion){ + NSString *apiKeyStr = [NSString stringWithUTF8String:apiKey]; + NSNumber *subVersion = [NSNumber numberWithInt:subversion]; + + NSLog(@"Called Tenjin [TenjinSDK sharedInstanceWithToken:%@ andAppSubversion:%@]", apiKeyStr, subVersion); + [TenjinSDK initialize:apiKeyStr andAppSubversion:subVersion]; +} + +void iosTenjinInitWithSharedSecretAppSubversion(const char* apiKey, const char* sharedSecret, int subversion){ + NSString *apiKeyStr = [NSString stringWithUTF8String:apiKey]; + NSString *sharedSecretStr = [NSString stringWithUTF8String:sharedSecret]; + NSNumber *subVersion = [NSNumber numberWithInt:subversion]; + + NSLog(@"Called Tenjin [TenjinSDK sharedInstanceWithToken:%@ andSharedSecret:* andAppSubversion:%@]", apiKeyStr, subVersion); + [TenjinSDK initialize:apiKeyStr andSharedSecret:sharedSecretStr andAppSubversion:subVersion]; +} + +void iosTenjinConnect(){ + [TenjinSDK connect]; +} + +void iosTenjinConnectWithDeferredDeeplink(const char* deferredDeeplink){ + NSString *deferredDeeplinkStr = [NSString stringWithUTF8String:deferredDeeplink]; + NSURL *deferredDeeplinkStrUri = [NSURL URLWithString:[deferredDeeplinkStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + NSLog(@"Called Tenjin [TenjinSDK connectWithDeferredDeeplink:%@]", deferredDeeplinkStr); + [TenjinSDK connectWithDeferredDeeplink:deferredDeeplinkStrUri]; +} + +void iosTenjinSendEvent(const char* eventName){ + NSString *eventNameStr = [NSString stringWithUTF8String:eventName]; + NSLog(@"Called Tenjin [TenjinSDK sendEventWithName:%@]", eventNameStr); + [TenjinSDK sendEventWithName:eventNameStr]; +} + +void iosTenjinSendEventWithValue(const char* eventName, const char* eventValue){ + NSString *eventNameStr = [NSString stringWithUTF8String:eventName]; + NSString *eventValueStr = [NSString stringWithUTF8String:eventValue]; + NSLog(@"Called Tenjin [TenjinSDK sendEventWithName:%@ andEventValue:%@]", eventNameStr, eventValueStr); + [TenjinSDK sendEventWithName:eventNameStr andEventValue:eventValueStr]; +} + +void iosTenjinTransaction(const char* productId, const char* currencyCode, int quantity, double price){ + NSString *prodId = [NSString stringWithUTF8String:productId]; + NSString *curCode = [NSString stringWithUTF8String:currencyCode]; + NSDecimalNumber* pr = [[NSDecimalNumber alloc] initWithDouble:price]; + NSLog(@"Called Tenjin [TenjinSDK transactionWithProductName:%@ andCurrencyCode:%@ andQuantity:%d andUnitPrice:%f]", prodId, curCode, quantity, price); + + //call manual method in tenjin sdk + [TenjinSDK transactionWithProductName:prodId andCurrencyCode:curCode andQuantity:quantity andUnitPrice:pr]; +} + +void iosTenjinTransactionWithReceiptData(const char* productId, const char* currencyCode, int quantity, double price, const char* transactionId, const char* receipt){ + NSString *prodId = [NSString stringWithUTF8String: productId]; + NSString *curCode = [NSString stringWithUTF8String: currencyCode]; + NSDecimalNumber *pr = [[NSDecimalNumber alloc] initWithDouble: price]; + NSString *tid = [NSString stringWithUTF8String: transactionId]; + NSString *rec = [NSString stringWithUTF8String: receipt]; + + //call manual tenjin call with receipt data + NSLog(@"Called Tenjin [TenjinSDK transactionWithProductName:%@ andCurrencyCode:%@ andQuantity:%d andUnitPrice:%f andTransactionId:%@ andBase64Receipt:%@]", prodId, curCode, quantity, price, tid, rec); + [TenjinSDK transactionWithProductName: prodId andCurrencyCode:curCode andQuantity:quantity andUnitPrice:pr andTransactionId:tid andBase64Receipt:rec]; +} + +void iosTenjinOptIn(){ + NSLog(@"Called Tenjin [TenjinSDK optIn]"); + [TenjinSDK optIn]; +} + +void iosTenjinOptOut(){ + NSLog(@"Called Tenjin [TenjinSDK optOut]"); + [TenjinSDK optOut]; +} + +void iosTenjinOptInParams(char** params, int size){ + NSMutableArray *paramsList = [[NSMutableArray alloc] init]; + for (int i = 0; i < size; ++i) { + NSString *str = [[NSString alloc] initWithCString:params[i] encoding:NSUTF8StringEncoding]; + NSLog(@"OptIn Param: %@", str); + [paramsList addObject:str]; + } + NSLog(@"Called Tenjin [TenjinSDK optInParams]"); + [TenjinSDK optInParams:paramsList]; +} + +void iosTenjinOptOutParams(char** params, int size){ + NSMutableArray *paramsList = [[NSMutableArray alloc] init]; + for (int i = 0; i < size; ++i) { + NSString *str = [[NSString alloc] initWithCString:params[i] encoding:NSUTF8StringEncoding]; + NSLog(@"OptOut Param: %@", str); + [paramsList addObject:str]; + } + NSLog(@"Called Tenjin [TenjinSDK optOutParams]"); + [TenjinSDK optOutParams:paramsList]; +} + +void iosTenjinAppendAppSubversion(int subversion){ + NSNumber *subVersion = [NSNumber numberWithInt:subversion]; + NSLog(@"Called Tenjin [TenjinSDK appendAppSubversion]"); + [TenjinSDK appendAppSubversion:subVersion]; +} + +void iosTenjinUpdateConversionValue(int conversionValue){ + NSLog(@"Called Tenjin [TenjinSDK updateConversionValue]"); + [TenjinSDK updateConversionValue:conversionValue]; +} + +void iosTenjinRegisterAppForAdNetworkAttribution(){ + NSLog(@"Called Tenjin [TenjinSDK registerAppForAdNetworkAttribution]"); + [TenjinSDK registerAppForAdNetworkAttribution]; +} + +void iosTenjinRequestTrackingAuthorizationWithCompletionHandler(){ + NSLog(@"Called Tenjin [TenjinSDK requestTrackingAuthorizationWithCompletionHandler]"); + [TenjinSDK requestTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) { + NSString *statusString = [NSString stringWithFormat:@"%tu", status]; + NSLog(@"ATTracking status: %@", statusString); + const char* charStatus = [statusString UTF8String]; + UnitySendMessage([@"Tenjin" UTF8String], "SetTrackingAuthorizationStatus", charStatus); + }]; +} + +void iosTenjinSubscribeMoPubImpressions(){ + [TenjinSDK subscribeMoPubImpressions]; +} + +void iosTenjinSetDebugLogs(){ + [TenjinSDK debugLogs]; +} + +void iosTenjinMopubImpressionFromJSON(const char* jsonString){ + NSString *jsonStr = [NSString stringWithUTF8String:jsonString]; + + [TenjinSDK mopubImpressionFromJSON:jsonStr]; +} + +void iosTenjinRegisterDeepLinkHandler(TenjinDeeplinkHandlerFunc deeplinkHandlerFunc) { + NSLog(@"Called iosTenjinRegisterDeepLinkHandler"); + registeredDeeplinkHandlerFunc = deeplinkHandlerFunc; + [[TenjinSDK sharedInstance] registerDeepLinkHandler:^(NSDictionary *params, NSError *error) { + NSLog(@"Entered deepLinkHandler"); + if (registeredDeeplinkHandlerFunc == NULL) + return; + + TenjinStringStringKeyValuePair* deepLinkDataPairArray; + int32_t deepLinkDataPairArrayCount; + iosTenjin_InternalConvertDictionaryToStringStringPairs(params, &deepLinkDataPairArray, &deepLinkDataPairArrayCount); + + registeredDeeplinkHandlerFunc(deepLinkDataPairArray, deepLinkDataPairArrayCount); + + iosTenjin_InternalFreeStringStringKeyValuePairs(deepLinkDataPairArray, deepLinkDataPairArrayCount); + }]; +} + +bool iosTenjin_InternalConvertDictionaryToStringStringPairs(NSDictionary* dictionary, TenjinStringStringKeyValuePair** outPairArray, int* outPairCount) { + *outPairArray = NULL; + *outPairCount = 0; + if (dictionary == nil) + return false; + + int pairCount = (int) dictionary.count; + TenjinStringStringKeyValuePair* pairArray = MALLOC_ARRAY(pairCount, TenjinStringStringKeyValuePair); + int counter = 0; + for (NSString* key in dictionary) { + NSObject* value = dictionary[key]; + TenjinStringStringKeyValuePair pair; + pair.key = strdup([key UTF8String]); + if ([value isKindOfClass:[NSNumber class]]) { + NSNumber* numberValue = (NSNumber*) value; + CFNumberType numberType = CFNumberGetType((CFNumberRef)numberValue); + if (numberType == kCFNumberCharType) { + pair.value = strdup([([numberValue boolValue] ? @"True" : @"False") UTF8String]); + } else { + pair.value = strdup([[numberValue stringValue] UTF8String]); + } + + } else if ([value isKindOfClass:[NSString class]]) { + pair.value = strdup([((NSString*) value) UTF8String]); + } else { + pair.value = strdup("Unknown data type"); + } + + pairArray[counter] = pair; + counter++; + } + + *outPairArray = pairArray; + *outPairCount = pairCount; + return true; +} + +void iosTenjin_InternalFreeStringStringKeyValuePairs(TenjinStringStringKeyValuePair* pairs, int32_t pairCount) { + for (int i = 0; i < pairCount; ++i) { + free((void*) pairs[i].key); + free((void*) pairs[i].value); + } + + free((void*) pairs); +} + +void iosTenjinSetWrapperVersion(const char* wrapperString){ + NSString *utfStr = [NSString stringWithUTF8String:wrapperString]; + + [TenjinSDK setWrapperVersion:utfStr]; +} + + +} //extern "C" diff --git a/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm.meta b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm.meta new file mode 100644 index 00000000..f4e3e03f --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/TenjinUnityInterface.mm.meta @@ -0,0 +1,99 @@ +fileFormatVersion: 2 +guid: f47a6cac8c2dd44de96c8c40c24f7ed3 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + 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 Win: 1 + Exclude Win64: 1 + Exclude iOS: 0 + - 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: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: x86 + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + CompileFlags: + FrameworkDependencies: + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/iOS/libTenjinSDK.a b/popcorn/Assets/Plugins/iOS/libTenjinSDK.a new file mode 100644 index 00000000..16dfa17c Binary files /dev/null and b/popcorn/Assets/Plugins/iOS/libTenjinSDK.a differ diff --git a/popcorn/Assets/Plugins/iOS/libTenjinSDK.a.meta b/popcorn/Assets/Plugins/iOS/libTenjinSDK.a.meta new file mode 100644 index 00000000..f3299d90 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/libTenjinSDK.a.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 107eef02a306b448b9bd52c2cf6f250b +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a b/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a new file mode 100644 index 00000000..3831590a Binary files /dev/null and b/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a differ diff --git a/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a.meta b/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a.meta new file mode 100644 index 00000000..71596cd2 --- /dev/null +++ b/popcorn/Assets/Plugins/iOS/libTenjinSDKUniversal.a.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 9469419f6f2784e119ca32cc6382fe6f +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: + AddToEmbeddedBinaries: false + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Resources/GameAnalytics/Settings.asset b/popcorn/Assets/Resources/GameAnalytics/Settings.asset index 2ecdbb95..5e4b735b 100644 --- a/popcorn/Assets/Resources/GameAnalytics/Settings.asset +++ b/popcorn/Assets/Resources/GameAnalytics/Settings.asset @@ -27,20 +27,26 @@ MonoBehaviour: CustomArea: gameKey: - c3c8c26af96bbd393d0423d5a9f99c11 + - ef08da6ddb1785f577d8327e78253c80 secretKey: - d078eab3b8d4a6b44ccfb7d9258a8e0bddad1337 + - 41e0f225a9f8751a3fc893cae6eb933df7d0214e Build: - 0.1 + - 0.1 SelectedPlatformOrganization: - usaya + - usaya SelectedPlatformStudio: - usaya + - usaya SelectedPlatformGame: - POPCORN - SelectedPlatformGameID: df9f0200 - SelectedOrganization: 03000000 - SelectedStudio: 01000000 - SelectedGame: 05000000 + - POPCORN_GP + SelectedPlatformGameID: df9f0200ff9f0200 + SelectedOrganization: 0300000003000000 + SelectedStudio: 0100000001000000 + SelectedGame: 0500000006000000 NewVersion: Changes: SignUpOpen: 1 @@ -63,7 +69,7 @@ MonoBehaviour: ResourceItemTypes: [] ResourceCurrencies: [] LastCreatedGamePlatform: 0 - Platforms: 08000000 + Platforms: 080000000b000000 CurrentInspectorState: 1 ClosedHints: DisplayHints: 0 @@ -91,7 +97,7 @@ MonoBehaviour: IncludeGooglePlay: 1 FpsCriticalThreshold: 20 FpsCirticalSubmitInterval: 1 - PlatformFoldOut: 01 + PlatformFoldOut: 0101 CustomDimensions01FoldOut: 0 CustomDimensions02FoldOut: 0 CustomDimensions03FoldOut: 0 diff --git a/popcorn/Assets/Tenjin.meta b/popcorn/Assets/Tenjin.meta new file mode 100644 index 00000000..2d8efb56 --- /dev/null +++ b/popcorn/Assets/Tenjin.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: db622e450792b49189c13039ece441be +folderAsset: yes +DefaultImporter: + userData: diff --git a/popcorn/Assets/Tenjin/Scripts.meta b/popcorn/Assets/Tenjin/Scripts.meta new file mode 100644 index 00000000..e428b847 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 0922ff8bfbb054078b63e8336b7c0a35 +folderAsset: yes +DefaultImporter: + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs b/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs new file mode 100644 index 00000000..66c20bdc --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs @@ -0,0 +1,400 @@ +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +public class AndroidTenjin : BaseTenjin { + + private const string AndroidJavaTenjinClass = "com.tenjin.android.TenjinSDK"; + private const string AndroidJavaTenjinAppStoreType = "com.tenjin.android.TenjinSDK$AppStoreType"; + +#if UNITY_ANDROID && !UNITY_EDITOR + private AndroidJavaObject tenjinJava = null; + private AndroidJavaObject activity = null; + + public override void Init(string apiKey){ + if (Debug.isDebugBuild) { + Debug.Log ("Android Initializing - v"+this.SdkVersion); + } + ApiKey = apiKey; + + SetUnityVersionInNativeSDK(); + + initActivity(); + AndroidJavaClass sdk = new AndroidJavaClass (AndroidJavaTenjinClass); + if (sdk == null){ + throw new MissingReferenceException( + string.Format("AndroidTenjin failed to load {0} class", AndroidJavaTenjinClass) + ); + } + tenjinJava = sdk.CallStatic ("getInstance", activity, apiKey); + } + + public override void InitWithSharedSecret(string apiKey, string sharedSecret){ + if (Debug.isDebugBuild) { + Debug.Log("Android Initializing with Shared Secret - v"+this.SdkVersion); + } + ApiKey = apiKey; + SharedSecret = sharedSecret; + + SetUnityVersionInNativeSDK(); + + initActivity(); + AndroidJavaClass sdk = new AndroidJavaClass (AndroidJavaTenjinClass); + if (sdk == null){ + throw new MissingReferenceException( + string.Format("AndroidTenjin failed to load {0} class", AndroidJavaTenjinClass) + ); + } + tenjinJava = sdk.CallStatic ("getInstanceWithSharedSecret", activity, apiKey, sharedSecret); + } + + public override void InitWithAppSubversion(string apiKey, int appSubversion){ + if (Debug.isDebugBuild) { + Debug.Log("Android Initializing with App Subversion: " + appSubversion + " v" +this.SdkVersion); + } + ApiKey = apiKey; + AppSubversion = appSubversion; + + SetUnityVersionInNativeSDK(); + + initActivity(); + AndroidJavaClass sdk = new AndroidJavaClass (AndroidJavaTenjinClass); + if (sdk == null){ + throw new MissingReferenceException( + string.Format("AndroidTenjin failed to load {0} class", AndroidJavaTenjinClass) + ); + } + tenjinJava = sdk.CallStatic ("getInstanceWithAppSubversion", activity, apiKey, appSubversion); + tenjinJava.Call ("appendAppSubversion", new object[]{appSubversion}); + } + + public override void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion){ + if (Debug.isDebugBuild) { + Debug.Log("Android Initializing with Shared Secret + App Subversion: " + appSubversion +" v" +this.SdkVersion); + } + ApiKey = apiKey; + SharedSecret = sharedSecret; + AppSubversion = appSubversion; + + SetUnityVersionInNativeSDK(); + + initActivity(); + AndroidJavaClass sdk = new AndroidJavaClass (AndroidJavaTenjinClass); + if (sdk == null){ + throw new MissingReferenceException( + string.Format("AndroidTenjin failed to load {0} class", AndroidJavaTenjinClass) + ); + } + tenjinJava = sdk.CallStatic ("getInstanceWithSharedSecretAppSubversion", activity, apiKey, sharedSecret, appSubversion); + tenjinJava.Call ("appendAppSubversion", new object[]{appSubversion}); + } + + private void SetUnityVersionInNativeSDK() { + var unitySdkVersion = this.SdkVersion + "u"; + + AndroidJavaClass sdk = new AndroidJavaClass (AndroidJavaTenjinClass); + if (sdk == null){ + throw new MissingReferenceException( + string.Format("AndroidTenjin failed to load {0} class", AndroidJavaTenjinClass) + ); + } + + sdk.CallStatic("setWrapperVersion", unitySdkVersion); + } + + private void initActivity(){ + AndroidJavaClass javaContext = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + activity = javaContext.GetStatic("currentActivity"); + } + + public override void Connect() { + string optInOut = null; + if (optIn) { + optInOut = "optin"; + } + else if (optOut) { + optInOut = "optout"; + } + object[] args = new object[]{null, optInOut}; + tenjinJava.Call ("connect", args); + } + + public override void Connect(string deferredDeeplink){ + string optInOut = null; + if (optIn) { + optInOut = "optin"; + } + else if (optOut) { + optInOut = "optout"; + } + object[] args = new object[]{deferredDeeplink, optInOut}; + tenjinJava.Call ("connect", args); + } + + //SendEvent accepts a single eventName as a String + public override void SendEvent (string eventName){ + object[] args = new object[]{eventName}; + tenjinJava.Call ("eventWithName", args); + } + + //SendEvent accepts eventName as a String and eventValue as a String + public override void SendEvent (string eventName, string eventValue){ + object[] args = new object[]{eventName, eventValue}; + tenjinJava.Call ("eventWithNameAndValue", args); + } + + public override void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature){ + + transactionId = null; + //if the receipt and signature have values then try to validate. if there are no values then manually log the transaction. + if(receipt != null && signature != null){ + object[] receiptArgs = new object[]{productId, currencyCode, quantity, unitPrice, receipt, signature}; + if (Debug.isDebugBuild) { + Debug.Log ("Android Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice + ", " + receipt + ", " + signature); + } + tenjinJava.Call ("transaction", receiptArgs); + } + else{ + object[] args = new object[]{productId, currencyCode, quantity, unitPrice}; + if (Debug.isDebugBuild) { + Debug.Log ("Android Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice); + } + tenjinJava.Call ("transaction", args); + } + } + + public override void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate) { + DeferredDeeplinkListener onDeferredDeeplinkListener = new DeferredDeeplinkListener(deferredDeeplinkDelegate); + tenjinJava.Call ("getDeeplink", onDeferredDeeplinkListener); + } + + private class DeferredDeeplinkListener : AndroidJavaProxy { + private Tenjin.DeferredDeeplinkDelegate callback; + + public DeferredDeeplinkListener(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkCallback) : base("com.tenjin.android.Callback") { + this.callback = deferredDeeplinkCallback; + } + + public void onSuccess(bool clickedTenjinLink, bool isFirstSession, AndroidJavaObject data) { + Dictionary deeplinkData = new Dictionary(); + string adNetwork = data.Call("get", "ad_network"); + string advertisingId = data.Call("get", "advertising_id"); + string campaignId = data.Call("get", "campaign_id"); + string campaignName = data.Call("get", "campaign_name"); + string deferredDeeplink = data.Call("get", "deferred_deeplink_url"); + string referrer = data.Call("get", "referrer"); + string siteId = data.Call("get", " site_id"); + + if (!string.IsNullOrEmpty(adNetwork)) { + deeplinkData["ad_network"] = adNetwork; + } + if (!string.IsNullOrEmpty(advertisingId)) { + deeplinkData["advertising_id"] = advertisingId; + } + if (!string.IsNullOrEmpty(campaignId)) { + deeplinkData["campaign_id"] = campaignId; + } + if (!string.IsNullOrEmpty(campaignName)) { + deeplinkData["campaign_name"] = campaignName; + } + if (!string.IsNullOrEmpty(deferredDeeplink)) { + deeplinkData["deferred_deeplink_url"] = deferredDeeplink; + } + if (!string.IsNullOrEmpty(referrer)) { + deeplinkData["referrer"] = referrer; + } + if (!string.IsNullOrEmpty(siteId)) { + deeplinkData["site_id"] = siteId; + } + + deeplinkData.Add("clicked_tenjin_link", Convert.ToString(clickedTenjinLink)); + deeplinkData.Add("is_first_session", Convert.ToString(isFirstSession)); + + callback(deeplinkData); + } + } + + public override void OptIn(){ + optIn = true; + tenjinJava.Call ("optIn"); + } + + public override void OptOut(){ + optOut = true; + tenjinJava.Call ("optOut"); + } + + public override void OptInParams(List parameters){ + tenjinJava.Call ("optInParams", new object[] {parameters.ToArray()}); + } + + public override void OptOutParams(List parameters){ + tenjinJava.Call ("optOutParams", new object[] {parameters.ToArray()}); + } + + public override void RegisterAppForAdNetworkAttribution(){ + } + + public override void UpdateConversionValue(int conversionValue){ + if (Debug.isDebugBuild) { + Debug.Log ("Android UpdateConversionValue"); + } + object[] args = new object[]{conversionValue}; + tenjinJava.Call ("updateConversionValue", args); + } + + public override void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback) { + } + + public override void AppendAppSubversion (int appSubversion){ + object[] args = new object[]{appSubversion}; + tenjinJava.Call ("appendAppSubversion", args); + } + + public static AndroidJavaObject CreateJavaMapFromDictainary(IDictionary parameters){ + AndroidJavaObject javaMap = new AndroidJavaObject("java.util.HashMap"); + IntPtr putMethod = AndroidJNIHelper.GetMethodID( + javaMap.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + + object[] args = new object[2]; + foreach (KeyValuePair kvp in parameters){ + using (AndroidJavaObject k = new AndroidJavaObject("java.lang.String", kvp.Key)){ + using (AndroidJavaObject v = new AndroidJavaObject("java.lang.String", kvp.Value)){ + args[0] = k; + args[1] = v; + AndroidJNI.CallObjectMethod(javaMap.GetRawObject(), + putMethod, AndroidJNIHelper.CreateJNIArgArray(args)); + } + } + } + return javaMap; + } + + public override void DebugLogs(){ + Debug.Log ("Debug logs not implemented on android"); + } + + public override void SubscribeMoPubImpressions() + { + Debug.Log("Subscribing to Mopub ILRD"); + TenjinMopubIntegration.ListenForImpressions(ImpressionHandler); + } + + private void ImpressionHandler(string json) + { + Debug.Log($"Got ILRD impression data {json}"); + var args = new object[] {json}; + tenjinJava.Call ("eventAdImpressionMoPub", args); + } + + public override void SetAppStoreType (AppStoreType appStoreType){ + object[] args = new object[]{appStoreType}; + AndroidJavaClass appStoreTypeClass = new AndroidJavaClass(AndroidJavaTenjinAppStoreType); + if (appStoreTypeClass != null){ + AndroidJavaObject tenjinAppStoreType = appStoreTypeClass.GetStatic(appStoreType.ToString()); + if (tenjinAppStoreType != null) { + tenjinJava.Call ("setAppStore", tenjinAppStoreType); + } + } + } +#else + public override void Init(string apiKey){ + Debug.Log ("Android Initializing - v"+this.SdkVersion); + ApiKey = apiKey; + } + + public override void InitWithSharedSecret(string apiKey, string sharedSecret) + { + Debug.Log("Android Initializing with Shared Secret - v"+this.SdkVersion); + ApiKey = apiKey; + SharedSecret = sharedSecret; + } + + public override void InitWithAppSubversion(string apiKey, int appSubversion) + { + Debug.Log("Android Initializing with App Subversion: " + appSubversion + " v" +this.SdkVersion); + ApiKey = apiKey; + AppSubversion = appSubversion; + } + + public override void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion) + { + Debug.Log("Android Initializing with Shared Secret + App Subversion: " + appSubversion +" v" +this.SdkVersion); + ApiKey = apiKey; + SharedSecret = sharedSecret; + AppSubversion = appSubversion; + } + + public override void Connect(){ + Debug.Log ("Android Connecting"); + } + + public override void Connect(string deferredDeeplink){ + Debug.Log ("Android Connecting with deferredDeeplink " + deferredDeeplink); + } + + public override void SendEvent (string eventName){ + Debug.Log ("Android Sending Event " + eventName); + } + + public override void SendEvent (string eventName, string eventValue){ + Debug.Log ("Android Sending Event " + eventName + " : " + eventValue); + } + + public override void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature){ + Debug.Log ("Android Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice + ", " + transactionId + ", " + receipt + ", " + signature); + } + + public override void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate) { + Debug.Log ("Sending AndroidTenjin::GetDeeplink"); + } + + public override void OptIn(){ + Debug.Log ("Sending AndroidTenjin::OptIn"); + } + + public override void OptOut(){ + Debug.Log ("Sending AndroidTenjin::OptOut"); + } + + public override void OptInParams(List parameters){ + Debug.Log ("Sending AndroidTenjin::OptInParams"); + } + + public override void OptOutParams(List parameters){ + Debug.Log ("Sending AndroidTenjin::OptOutParams"); + } + + public override void AppendAppSubversion(int subversion){ + Debug.Log("Sending AndroidTenjin::AppendAppSubversion :" + subversion); + } + + public override void SubscribeMoPubImpressions() + { + Debug.Log("Sending AndroidTenjin:: SubscribeMoPubImpressions " ); + } + public override void DebugLogs(){ + Debug.Log ("Setting debug logs "); + } + + public override void UpdateConversionValue(int conversionValue) + { + Debug.Log("Sending UpdateConversionValue: " + conversionValue); + } + + public override void RegisterAppForAdNetworkAttribution() + { + throw new NotImplementedException(); + } + + public override void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback) + { + throw new NotImplementedException(); + } + + public override void SetAppStoreType(AppStoreType appStoreType) { + Debug.Log("Setting AndroidTenjin::SetAppStoreType: " + appStoreType); + } +#endif +} diff --git a/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs.meta b/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs.meta new file mode 100644 index 00000000..10edbd4f --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/AndroidTenjin.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8bfcadc6d73354682b86bd6c20927ba1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs b/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs new file mode 100644 index 00000000..51f6d310 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs @@ -0,0 +1,23 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public enum AppStoreType +{ + unspecified, + + /** + * Google Play Store + */ + googleplay, + + /** + * Amazon Appstore + */ + amazon, + + /** + * Other App Stores + */ + other +} diff --git a/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs.meta b/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs.meta new file mode 100644 index 00000000..f80357d3 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/AppStoreType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7cd34d399a6e04db8b7cbbd8acfd39a8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs b/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs new file mode 100644 index 00000000..c8df947a --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs @@ -0,0 +1,64 @@ +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +public abstract class BaseTenjin : MonoBehaviour { + + protected string apiKey; + protected string sharedSecret; + protected bool optIn; + protected bool optOut; + protected int appSubversion; + + public string SdkVersion { get; } = "1.12.7"; + + public string ApiKey{ + get{ + return this.apiKey; + } + set{ + this.apiKey = value; + } + } + + public string SharedSecret{ + get{ + return this.sharedSecret; + } + set{ + this.sharedSecret = value; + } + } + + public int AppSubversion{ + get{ + return this.appSubversion; + } + set{ + this.appSubversion = value; + } + } + + public abstract void Init(string apiKey); + public abstract void InitWithSharedSecret(string apiKey, string sharedSecret); + public abstract void InitWithAppSubversion(string apiKey, int appSubversion); + public abstract void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion); + public abstract void Connect(); + public abstract void Connect(string deferredDeeplink); + public abstract void OptIn(); + public abstract void OptOut(); + public abstract void OptInParams(List parameters); + public abstract void OptOutParams(List parameters); + public abstract void AppendAppSubversion(int subversion); + public abstract void SendEvent (string eventName); + public abstract void SendEvent (string eventName, string eventValue); + public abstract void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature); + public abstract void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate); + public abstract void RegisterAppForAdNetworkAttribution(); + public abstract void UpdateConversionValue(int conversionValue); + public abstract void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback); + public abstract void DebugLogs(); + public abstract void SetAppStoreType(AppStoreType appStoreType); + public abstract void SubscribeMoPubImpressions(); +} diff --git a/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs.meta b/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs.meta new file mode 100644 index 00000000..9fac5243 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/BaseTenjin.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8dfaa70d264f14b9d951f10766771591 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs b/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs new file mode 100644 index 00000000..cad9a16e --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs @@ -0,0 +1,105 @@ +using UnityEngine; +using System; +using System.Collections.Generic; + +public class DebugTenjin : BaseTenjin { + + public override void Connect(){ + Debug.Log ("Connecting " + ApiKey); + } + + public override void Connect(string deferredDeeplink){ + Debug.Log ("Connecting with deferredDeeplink " + deferredDeeplink); + } + + public override void Init(string apiKey){ + Debug.Log ("Initializing - v"+this.SdkVersion); + } + + public override void InitWithSharedSecret(string apiKey, string sharedSecret) + { + Debug.Log("Initializing with Shared Secret - v"+this.SdkVersion); + } + + public override void InitWithAppSubversion(string apiKey, int appSubversion) + { + Debug.Log("Initializing with App Subversion: " + appSubversion + " v" +this.SdkVersion); + } + + public override void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion) + { + Debug.Log("Initializing with Shared Secret + App Subversion: " + appSubversion +" v" +this.SdkVersion); + } + + public override void SendEvent (string eventName){ + Debug.Log ("Sending Event " + eventName); + } + + public override void SendEvent (string eventName, string eventValue){ + Debug.Log ("Sending Event " + eventName + " : " + eventValue); + } + + public override void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature){ + Debug.Log ("Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice + ", " + transactionId + ", " + receipt + ", " + signature); + } + + public override void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate) { + Debug.Log ("Sending DebugTenjin::GetDeeplink"); + } + + public override void OptIn(){ + Debug.Log ("OptIn "); + } + + public override void OptOut(){ + Debug.Log ("OptOut "); + } + + public override void OptInParams(List parameters){ + Debug.Log ("OptInParams"); + } + + public override void OptOutParams(List parameters){ + Debug.Log ("OptOutParams" ); + } + + public override void DebugLogs(){ + Debug.Log ("Setting debug logs "); + } + + public override void AppendAppSubversion(int subversion) + { + Debug.Log("AppendAppSubversion: " + subversion); + } + + public override void SubscribeMoPubImpressions() + { + Debug.Log("Subscribing to mopub impressions"); + TenjinMopubIntegration.ListenForImpressions(ImpressionHandler); + } + + private void ImpressionHandler(string json) + { + Debug.Log($"Got impression data {json}"); + } + + public override void RegisterAppForAdNetworkAttribution() + { + Debug.Log("RegisterAppForAdNetworkAttribution"); + } + + public override void UpdateConversionValue(int conversionValue) + { + Debug.Log("UpdateConversionValue: " + conversionValue); + } + + public override void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback) + { + Debug.Log("RequestTrackingAuthorizationWithCompletionHandler"); + } + + public override void SetAppStoreType(AppStoreType appStoreType) + { + Debug.Log("SetAppStoreType"); + } +} diff --git a/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs.meta b/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs.meta new file mode 100644 index 00000000..8ea8a5c9 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/DebugTenjin.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1c77717d9c6514a9889ca237d680b3de +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/Editor.meta b/popcorn/Assets/Tenjin/Scripts/Editor.meta new file mode 100644 index 00000000..0f4316c2 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 506f6c9d83e0c4c2d93dd6aa21dd90f4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs new file mode 100644 index 00000000..e6af8a7f --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.IMGUI.Controls; +using UnityEngine; + +namespace Tenjin +{ + + class TenjinAssetTree : TreeView + { + public TenjinAssetTree(TreeViewState treeViewState) + : base(treeViewState) + { + Reload(); + } + + protected override TreeViewItem BuildRoot() + { + var selectedAssets = TenjinPackager.LoadManifest(); + var assets = AssetDatabase.FindAssets(null, new[] { "Assets" }).Select(x => AssetDatabase.GUIDToAssetPath(x)); + var root = new TenjinAssetViewItem { selected = false, id = 0, depth = -1, displayName = "Root" }; + + var allItems = assets.Select((a, index) => + { + return new TenjinAssetViewItem + { + selected = selectedAssets.Contains(a), + id = index, + depth = DepthFromPath(a), + displayName = a + } as TreeViewItem; + }).ToList(); + + SetupParentsAndChildrenFromDepths(root, allItems); + + return root; + } + + public int SelectedItemCount() + { + var root = rootItem as TenjinAssetViewItem; + return root.SelectedCount(); + } + + public IEnumerable SelectedItems() + { + return (rootItem as TenjinAssetViewItem).GetRecusivelySelectedItems(); + } + + protected override void RowGUI(RowGUIArgs args) + { + Event evt = Event.current; + extraSpaceBeforeIconAndLabel = 18f; + TenjinAssetViewItem avi = (TenjinAssetViewItem)args.item; + + Rect toggleRect = args.rowRect; + toggleRect.x += GetContentIndent(args.item); + toggleRect.width = 16f; + + //// Ensure row is selected before using the toggle (usability) + if (evt.type == EventType.MouseDown && toggleRect.Contains(evt.mousePosition)) + SelectionClick(args.item, false); + + EditorGUI.BeginChangeCheck(); + bool selected = EditorGUI.Toggle(toggleRect, avi.selected); + if (EditorGUI.EndChangeCheck()) + { + avi.selected = selected; + SetSelectedRecursively(avi.children, selected); + } + + // Text + base.RowGUI(args); + } + + private void SetSelectedRecursively(List c, bool value) + { + if (c == null) + return; + + var assetViewItems = c.Select(x => x as TenjinAssetViewItem); + foreach (var child in assetViewItems) + { + if (child == null) + continue; + + child.selected = value; + SetSelectedRecursively(child.children, value); + } + } + + private int DepthFromPath(string path) + { + return path.Split('/').Count(); + } + } + + class TenjinAssetViewItem : TreeViewItem + { + public bool selected { get; set; } + + public int SelectedCount() + { + int childrenCount = children == null ? 0 : children.Select(x => (x as TenjinAssetViewItem).SelectedCount()).Sum(); + return (selected ? 1 : 0) + childrenCount; + } + + public IEnumerable GetRecusivelySelectedItems() + { + if (children == null) + { + return selected ? new List() { this } : new List(); + } + + var selectedItems = children.Select((arg) => (arg as TenjinAssetViewItem).GetRecusivelySelectedItems()) + .SelectMany(x => x).ToList(); + + if (selected) + selectedItems.Add(this); + + return selectedItems; + } + } + + class TenjinAssetWindow : EditorWindow + { + [SerializeField] TreeViewState m_TreeViewState; + TenjinAssetTree m_SimpleTreeView; + + void OnEnable() + { + + if (m_TreeViewState == null) + m_TreeViewState = new TreeViewState(); + + m_SimpleTreeView = new TenjinAssetTree(m_TreeViewState); + } + + void OnGUI() + { + m_SimpleTreeView.OnGUI(new Rect(0, 0, position.width, position.height - 16)); + DoToolbar(bottomToolbarRect); + } + + IEnumerable SelectedAssets() + { + return m_SimpleTreeView.SelectedItems().Select(x => x.displayName); + } + void DoToolbar(Rect rect) + { + GUILayout.BeginArea(rect); + + using (new EditorGUILayout.HorizontalScope()) + { + var style = "miniButton"; + if (GUILayout.Button("Save Manifest", style)) + { + TenjinPackager.SaveManifestFile(SelectedAssets()); + } + + if (GUILayout.Button("Publish Unitypackage", style)) + { + TenjinPackager.PublishPackage(SelectedAssets()); + } + + GUILayout.FlexibleSpace(); + + var label = $"{m_SimpleTreeView.SelectedItemCount()} files in package"; + GUILayout.Label(label); + } + + GUILayout.EndArea(); + } + + Rect bottomToolbarRect + { + get { return new Rect(20f, position.height - 18f, position.width - 40f, 16f); } + } + + + [MenuItem("Tenjin/Select Assets")] + static void ShowWindow() + { + var window = GetWindow(); + window.titleContent = new GUIContent("Tenjin Unity SDK Files"); + window.Show(); + } + } +} \ No newline at end of file diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs.meta b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs.meta new file mode 100644 index 00000000..ec315d4a --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinAssetSelector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4311b33e0dc3c479bbe54dbb79765320 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs new file mode 100644 index 00000000..28f278f2 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs @@ -0,0 +1,150 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using System; +using System.IO; +using UnityEditor.Compilation; +using System.Linq; +using UnityEditor.Build.Content; +using UnityEditor.Callbacks; +using Assembly = System.Reflection.Assembly; + +#if UNITY_IOS +using UnityEditor.iOS.Xcode; +#endif + +namespace Tenjin +{ + class TenjinEditorPrefs : IPreprocessBuildWithReport + { + private static string tenjin_mopub = "tenjin_mopub_enabled"; + private static string tenjin_facebook = "tenjin_facebook_enabled"; + + public int callbackOrder => 0; + + public void OnPreprocessBuild(BuildReport report) + { + TenjinEditorPrefs.Update3rdPartyIntegrations(); + } + + [UnityEditor.Callbacks.DidReloadScripts] + private static void OnScriptsReloaded() + { + Update3rdPartyIntegrations(); + } + + private static void Update3rdPartyIntegrations() + { + UpdateMoPub(); + UpdateFacebook(); + } + + [PostProcessBuild(0)] + public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) + { + ProcessIosBuild(target, pathToBuiltProject); + } + + private static void ProcessIosBuild(BuildTarget target, string pathToBuiltProject) + { + if (target == BuildTarget.iOS) + { + if (PlayerSettings.iOS.sdkVersion == iOSSdkVersion.SimulatorSDK) + { + Debug.Log("Using simulator sdk - delete non universal tenjin lib from generated xcode project"); + RemoveFileFromXcodeProject("Libraries/Plugins/iOS/libTenjinSDK.a", pathToBuiltProject); + } + else + { + Debug.Log("Using device sdk - delete universal tenjin lib from generated xcode project"); + RemoveFileFromXcodeProject("Libraries/Plugins/iOS/libTenjinSDKUniversal.a", pathToBuiltProject); + } + } + } + + private static void RemoveFileFromXcodeProject(string filePath, string pathToBuiltProject) + { +#if UNITY_IOS + var projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj"; + + PBXProject pbxProject = new PBXProject (); + pbxProject.ReadFromFile (projectPath); + + var fileToRemove = pbxProject.FindFileGuidByProjectPath(filePath); + pbxProject.RemoveFile(fileToRemove); + + File.WriteAllText (projectPath, pbxProject.WriteToString ()); +#endif + } + + private static void UpdateDefines(string entry, bool enabled, BuildTargetGroup[] groups) + { + foreach (var group in groups) + { + var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group) + .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) + .Where(d => d != entry); + + if (enabled) + defines = defines.Concat(new[] { entry }); + PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.ToArray())); + } + } + + #region 3rd Party Lib Detection + + /// + /// Sets the scripting define symbol `tenjin_facebook_enabled` to true if Facebook classes are detected within the Unity project + /// + private static void UpdateFacebook() + { + var facebookTypes = new string[]{"Facebook", "FB"}; + if(TypeExists(facebookTypes)) + { + UpdateDefines(tenjin_facebook, true, new BuildTargetGroup[] { BuildTargetGroup.iOS, BuildTargetGroup.Android }); + } + else + { + UpdateDefines(tenjin_facebook, false, new BuildTargetGroup[] { BuildTargetGroup.iOS, BuildTargetGroup.Android }); + } + } + + + /// + /// Sets the scripting define symbol `tenjin_mopub_enabled` to true if MoPub classes are detected within the Unity project + /// + private static void UpdateMoPub() + { + var mopubTypes = new string[]{"MoPubBase", "MoPubManager"}; + if(TypeExists(mopubTypes)) + { + UpdateDefines(tenjin_mopub, true, new BuildTargetGroup[] { BuildTargetGroup.iOS, BuildTargetGroup.Android }); + } + else + { + UpdateDefines(tenjin_mopub, false, new BuildTargetGroup[] { BuildTargetGroup.iOS, BuildTargetGroup.Android }); + } + } + + private static bool TypeExists(params string[] types) + { + if (types == null || types.Length == 0) + return false; + + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + if (types.Any(type => assembly.GetType(type) != null)) + return true; + } + + return false; + } + + #endregion + } +} \ No newline at end of file diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs.meta b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs.meta new file mode 100644 index 00000000..e46374c2 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinEditorPrefs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4f09f5150b6494b85844e0fb75588115 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs new file mode 100644 index 00000000..baca023b --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + +namespace Tenjin +{ + //a simple wrapper class because Unity's json serializer can't deal with primitives.. + [Serializable] + internal class ManifestWrapper + { + public string[] files; + } + + public static class Exporter + { + static void Package() + { + var files = TenjinPackager.LoadManifest(); + TenjinPackager.PublishPackage(files); + } + + [MenuItem("Tenjin/Export Package")] + internal static void PackageInteractively() + { + var files = TenjinPackager.LoadManifest(); + TenjinPackager.PublishPackage(files,TenjinPackager.EXPORTED_PACKAGE_PATH, true); + } + } + + internal class TenjinPackager + { + const string MANIFEST_PATH = "Assets/tenjin.unitypackage.manifest"; + public const string EXPORTED_PACKAGE_PATH = "TenjinUnityPackage.unitypackage"; + + internal static void SaveManifestFile(IEnumerable assets) + { + if(File.Exists(MANIFEST_PATH)) + File.Delete(MANIFEST_PATH); + + var wtf = new ManifestWrapper() { files = assets.ToArray() }; + var json = JsonUtility.ToJson(wtf); + + var writer = new StreamWriter(MANIFEST_PATH, false); + + writer.WriteLine(json); + writer.Close(); + } + + internal static IEnumerable LoadManifest() + { + var reader = new StreamReader(MANIFEST_PATH); + var jsonString = reader.ReadToEnd(); + reader.Close(); + + var wrappedJson = JsonUtility.FromJson(jsonString); + + return wrappedJson.files; + } + + internal static void PublishPackage(IEnumerable enumerable, string path = EXPORTED_PACKAGE_PATH, bool interactive = false) + { + if (File.Exists(path)) + File.Delete(path); + + var options = ExportPackageOptions.IncludeDependencies; + if (interactive) + options = options | ExportPackageOptions.IncludeDependencies; + var filePaths = enumerable.ToArray(); + + Debug.Log("Exporting files :\n" + string.Join("\n", filePaths)); + + AssetDatabase.ExportPackage(filePaths, path, options); + } + + + } +} \ No newline at end of file diff --git a/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs.meta b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs.meta new file mode 100644 index 00000000..c9450bce --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Editor/TenjinPackager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 907680d75293f42129b14365df3d3dd1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs b/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs new file mode 100644 index 00000000..df7fbc93 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs @@ -0,0 +1,436 @@ +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using AOT; + +public class IosTenjin : BaseTenjin { + +#if UNITY_IPHONE && !UNITY_EDITOR + + [DllImport ("__Internal")] + private static extern void iosTenjinInit(string apiKey); + + [DllImport ("__Internal")] + private static extern void iosTenjinInitWithSharedSecret(string apiKey, string sharedSecret); + + [DllImport ("__Internal")] + private static extern void iosTenjinInitWithAppSubversion(string apiKey, int appSubversion); + + [DllImport ("__Internal")] + private static extern void iosTenjinInitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion); + + [DllImport ("__Internal")] + private static extern void iosTenjinConnect(); + + [DllImport ("__Internal")] + private static extern void iosTenjinConnectWithDeferredDeeplink(string deferredDeeplink); + + [DllImport ("__Internal")] + private static extern void iosTenjinOptIn(); + + [DllImport ("__Internal")] + private static extern void iosTenjinOptOut(); + + [DllImport ("__Internal")] + private static extern void iosTenjinOptInParams(String[] parameters, int size); + + [DllImport ("__Internal")] + private static extern void iosTenjinOptOutParams(String[] parameters, int size); + + [DllImport ("__Internal")] + private static extern void iosTenjinRegisterAppForAdNetworkAttribution(); + + [DllImport ("__Internal")] + private static extern void iosTenjinUpdateConversionValue(int conversionValue); + + [DllImport ("__Internal")] + private static extern void iosTenjinRequestTrackingAuthorizationWithCompletionHandler(); + + [DllImport ("__Internal")] + private static extern void iosTenjinAppendAppSubversion(int subversion); + + [DllImport ("__Internal")] + private static extern void iosTenjinSendEvent(string eventName); + + [DllImport ("__Internal")] + private static extern void iosTenjinSendEventWithValue(string eventName, string eventValue); + + [DllImport ("__Internal")] + private static extern void iosTenjinTransaction(string productId, string currencyCode, int quantity, double unitPrice); + + [DllImport ("__Internal")] + private static extern void iosTenjinTransactionWithReceiptData(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt); + + [DllImport ("__Internal")] + private static extern void iosTenjinRegisterDeepLinkHandler(DeepLinkHandlerNativeDelegate deepLinkHandlerNativeDelegate); + + [DllImport ("__Internal")] + private static extern void iosTenjinMopubImpressionFromJSON(string jsonString); + + [DllImport ("__Internal")] + private static extern void iosTenjinSetDebugLogs(); + + [DllImport ("__Internal")] + private static extern void iosTenjinSetWrapperVersion(string wrapperString); + + private delegate void DeepLinkHandlerNativeDelegate(IntPtr deepLinkDataPairArray, int deepLinkDataPairCount); + + private static readonly Stack> deferredDeeplinkEvents = new Stack>(); + private static Tenjin.DeferredDeeplinkDelegate registeredDeferredDeeplinkDelegate; + + public override void Init(string apiKey){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Initializing - v"+this.SdkVersion); + } + SetUnityVersionInNativeSDK(); + ApiKey = apiKey; + iosTenjinInit (ApiKey); + } + + public override void InitWithSharedSecret(string apiKey, string sharedSecret){ + if (Debug.isDebugBuild) { + Debug.Log("iOS Initializing with Shared Secret - v"+this.SdkVersion); + } + SetUnityVersionInNativeSDK(); + ApiKey = apiKey; + SharedSecret = sharedSecret; + iosTenjinInitWithSharedSecret (ApiKey, SharedSecret); + } + + public override void InitWithAppSubversion(string apiKey, int appSubversion){ + if (Debug.isDebugBuild) { + Debug.Log("iOS Initializing with App Subversion: " + appSubversion + " v" +this.SdkVersion); + } + SetUnityVersionInNativeSDK(); + ApiKey = apiKey; + AppSubversion = appSubversion; + iosTenjinInitWithAppSubversion (ApiKey, AppSubversion); + } + + public override void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion){ + if (Debug.isDebugBuild) { + Debug.Log("iOS Initializing with Shared Secret + App Subversion: " + appSubversion +" v" +this.SdkVersion); + } + SetUnityVersionInNativeSDK(); + ApiKey = apiKey; + SharedSecret = sharedSecret; + AppSubversion = appSubversion; + iosTenjinInitWithSharedSecretAppSubversion (ApiKey, SharedSecret, AppSubversion); + } + + private void SetUnityVersionInNativeSDK() { + var unitySdkVersion = this.SdkVersion + "u"; + + iosTenjinSetWrapperVersion(unitySdkVersion); + } + + public override void Connect(){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Connecting"); + } + iosTenjinConnect(); + } + + public override void Connect(string deferredDeeplink){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Connecting with deferredDeeplink " + deferredDeeplink); + } + iosTenjinConnectWithDeferredDeeplink (deferredDeeplink); + } + + public override void OptIn(){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS OptIn"); + } + iosTenjinOptIn (); + } + + public override void OptOut(){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS OptOut"); + } + iosTenjinOptOut (); + } + + public override void OptInParams(List parameters){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS OptInParams" + parameters.ToString()); + } + iosTenjinOptInParams (parameters.ToArray(), parameters.Count); + } + + public override void OptOutParams(List parameters){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS OptOutParams" + parameters.ToString()); + } + iosTenjinOptOutParams (parameters.ToArray(), parameters.Count); + } + + public override void RegisterAppForAdNetworkAttribution(){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS RegisterAppForAdNetworkAttribution"); + } + iosTenjinRegisterAppForAdNetworkAttribution (); + } + + public override void UpdateConversionValue(int conversionValue){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS UpdateConversionValue"); + } + iosTenjinUpdateConversionValue (conversionValue); + } + + public override void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS RequestTrackingAuthorizationWithCompletionHandler"); + } + Tenjin.authorizationStatusDelegate = trackingAuthorizationCallback; + iosTenjinRequestTrackingAuthorizationWithCompletionHandler(); + } + + private void SetTrackingAuthorizationStatus(string status){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS SetTrackingAuthorizationStatus " + status); + } + Tenjin.authorizationStatusDelegate(Int16.Parse(status)); + } + + public override void AppendAppSubversion(int appSubversion){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS AppendAppSubversion " + appSubversion); + } + iosTenjinAppendAppSubversion (appSubversion); + } + + public override void SendEvent(string eventName){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Sending Event " + eventName); + } + iosTenjinSendEvent(eventName); + } + + public override void SendEvent(string eventName, string eventValue){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Sending Event " + eventName + " : " + eventValue); + } + iosTenjinSendEventWithValue(eventName, eventValue); + } + + public override void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature){ + signature = null; + + //only if the receipt and transaction_id are not null, then try to validate the transaction. Otherwise manually record the transaction + if(receipt != null && transactionId != null){ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Transaction with receipt " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice + ", " + transactionId + ", " + receipt); + } + iosTenjinTransactionWithReceiptData(productId, currencyCode, quantity, unitPrice, transactionId, receipt); + } + else{ + if (Debug.isDebugBuild) { + Debug.Log ("iOS Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice); + } + iosTenjinTransaction(productId, currencyCode, quantity, unitPrice); + } + } + + public override void SetAppStoreType(AppStoreType appStoreType) { + } + + public override void SubscribeMoPubImpressions(){ + TenjinMopubIntegration.ListenForImpressions(ILARHandler); + } + + public void ILARHandler(string json){ + if(!string.IsNullOrEmpty(json)) + { + iosTenjinMopubImpressionFromJSON(json); + } + } + + public override void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate) { + if (Debug.isDebugBuild) { + Debug.Log ("Sending IosTenjin::GetDeeplink"); + } + registeredDeferredDeeplinkDelegate = deferredDeeplinkDelegate; + iosTenjinRegisterDeepLinkHandler(DeepLinkHandler); + } + + public override void DebugLogs() { + iosTenjinSetDebugLogs(); + } + + private void Update() { + lock (deferredDeeplinkEvents) { + while (deferredDeeplinkEvents.Count > 0) { + Dictionary deepLinkData = deferredDeeplinkEvents.Pop(); + if (registeredDeferredDeeplinkDelegate != null) { + registeredDeferredDeeplinkDelegate(deepLinkData); + } + } + } + } + + [MonoPInvokeCallback(typeof(DeepLinkHandlerNativeDelegate))] + private static void DeepLinkHandler(IntPtr deepLinkDataPairArray, int deepLinkDataPairCount) { + if (deepLinkDataPairArray == IntPtr.Zero) + return; + + Dictionary deepLinkData = + NativeUtility.MarshalStringStringDictionary(deepLinkDataPairArray, deepLinkDataPairCount); + + lock (deferredDeeplinkEvents) { + deferredDeeplinkEvents.Push(deepLinkData); + } + } + + private static class NativeUtility { + /// + /// Marshals a native linear array of structs to the managed array. + /// + public static T[] MarshalNativeStructArray(IntPtr nativeArrayPtr, int nativeArraySize) where T : struct { + if (nativeArrayPtr == IntPtr.Zero) + throw new ArgumentNullException("nativeArrayPtr"); + + if (nativeArraySize < 0) + throw new ArgumentOutOfRangeException("nativeArraySize"); + + T[] managedArray = new T[nativeArraySize]; + IntPtr currentNativeArrayPtr = nativeArrayPtr; + int structSize = Marshal.SizeOf(typeof(T)); + for (int i = 0; i < nativeArraySize; i++) { + T marshaledStruct = (T) Marshal.PtrToStructure(currentNativeArrayPtr, typeof(T)); + managedArray[i] = marshaledStruct; + currentNativeArrayPtr = (IntPtr) (currentNativeArrayPtr.ToInt64() + structSize); + } + + return managedArray; + } + + /// + /// Marshals the native representation to a IDictionary<string, string>. + /// + public static Dictionary MarshalStringStringDictionary(IntPtr nativePairArrayPtr, int nativePairArraySize) { + if (nativePairArrayPtr == IntPtr.Zero) + throw new ArgumentNullException("nativePairArrayPtr"); + + if (nativePairArraySize < 0) + throw new ArgumentOutOfRangeException("nativePairArraySize"); + + Dictionary dictionary = new Dictionary(nativePairArraySize); + StringStringKeyValuePair[] pairs = MarshalNativeStructArray(nativePairArrayPtr, nativePairArraySize); + foreach (StringStringKeyValuePair pair in pairs) { + dictionary.Add(pair.Key, pair.Value); + } + return dictionary; + } + + [StructLayout(LayoutKind.Sequential)] + public struct StringStringKeyValuePair { + public string Key; + public string Value; + } + } + +#else + public override void Init(string apiKey){ + Debug.Log ("iOS Initializing - v"+this.SdkVersion); + ApiKey = apiKey; + } + + public override void InitWithSharedSecret(string apiKey, string sharedSecret){ + Debug.Log("iOS Initializing with Shared Secret - v"+this.SdkVersion); + ApiKey = apiKey; + SharedSecret = sharedSecret; + } + + public override void InitWithAppSubversion(string apiKey, int appSubversion) + { + Debug.Log("iOS Initializing with App Subversion: " + appSubversion + " v" +this.SdkVersion); + ApiKey = apiKey; + AppSubversion = appSubversion; + } + + public override void InitWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion) + { + Debug.Log("iOS Initializing with Shared Secret + App Subversion: " + appSubversion +" v" +this.SdkVersion); + ApiKey = apiKey; + SharedSecret = sharedSecret; + AppSubversion = appSubversion; + } + + public override void Connect(){ + Debug.Log ("iOS Connecting"); + } + + public override void Connect(string deferredDeeplink){ + Debug.Log ("Connecting with deferredDeeplink " + deferredDeeplink); + } + + public override void SendEvent(string eventName){ + Debug.Log ("iOS Sending Event " + eventName); + } + + public override void SendEvent(string eventName, string eventValue){ + Debug.Log ("iOS Sending Event " + eventName + " : " + eventValue); + } + + public override void Transaction(string productId, string currencyCode, int quantity, double unitPrice, string transactionId, string receipt, string signature){ + Debug.Log ("iOS Transaction " + productId + ", " + currencyCode + ", " + quantity + ", " + unitPrice + ", " + transactionId + ", " + receipt + ", " + signature); + } + + public override void GetDeeplink(Tenjin.DeferredDeeplinkDelegate deferredDeeplinkDelegate) { + Debug.Log ("Sending IosTenjin::GetDeeplink"); + } + + public override void OptIn(){ + Debug.Log ("iOS OptIn"); + } + + public override void OptOut(){ + Debug.Log ("iOS OptOut"); + } + + public override void OptInParams(List parameters){ + Debug.Log ("iOS OptInParams"); + } + + public override void OptOutParams(List parameters){ + Debug.Log ("iOS OptOutParams"); + } + + public override void RegisterAppForAdNetworkAttribution() + { + Debug.Log("iOS RegisterAppForAdNetworkAttribution"); + } + + public override void UpdateConversionValue(int conversionValue) + { + Debug.Log("iOS UpdateConversionValue: " + conversionValue); + } + + public override void RequestTrackingAuthorizationWithCompletionHandler(Action trackingAuthorizationCallback) + { + Debug.Log("iOS RequestTrackingAuthorizationWithCompletionHandler"); + } + + public override void AppendAppSubversion(int subversion){ + Debug.Log("iOS AppendAppSubversion"); + } + + public override void DebugLogs(){ + Debug.Log ("Setting debug logs "); + } + + public override void SubscribeMoPubImpressions() + { + Debug.Log("iOS SubscribeMoPubImpressions"); + } + + public override void SetAppStoreType(AppStoreType appStoreType) { + Debug.Log("iOS SetAppStoreType"); + } +#endif +} diff --git a/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs.meta b/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs.meta new file mode 100644 index 00000000..b2ad3694 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/IosTenjin.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c2d7324a689314c77a9901f8e0a6721a +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/Tenjin.cs b/popcorn/Assets/Tenjin/Scripts/Tenjin.cs new file mode 100644 index 00000000..2f684cd5 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Tenjin.cs @@ -0,0 +1,79 @@ +using UnityEngine; +using System; +using System.Collections.Generic; + +public static class Tenjin { + + public delegate void DeferredDeeplinkDelegate(Dictionary deferredLinkData); + + //create dictionary of instances of tenjin with API keys + private static Dictionary _instances = new Dictionary(); + + // App Tracking Transparency callback + public static Action authorizationStatusDelegate = null; + + //return instance with specific api key + public static BaseTenjin getInstance(string apiKey){ + string instanceKey = apiKey; + if (!_instances.ContainsKey (apiKey)){ + _instances.Add(apiKey, createTenjin(apiKey, null, 0)); + } + return _instances[instanceKey]; + } + + public static BaseTenjin getInstanceWithSharedSecret(string apiKey, string sharedSecret){ + string instanceKey = apiKey + "." + sharedSecret; + if (!_instances.ContainsKey(instanceKey)){ + _instances.Add(instanceKey, createTenjin(apiKey, sharedSecret, 0)); + } + return _instances[instanceKey]; + } + + public static BaseTenjin getInstanceWithAppSubversion(string apiKey, int appSubversion){ + string instanceKey = apiKey + "." + appSubversion; + if (!_instances.ContainsKey(instanceKey)){ + _instances.Add(instanceKey, createTenjin(apiKey, null, appSubversion)); + } + return _instances[instanceKey]; + } + + public static BaseTenjin getInstanceWithSharedSecretAppSubversion(string apiKey, string sharedSecret, int appSubversion){ + string instanceKey = apiKey + "." + sharedSecret + "." + appSubversion; + if (!_instances.ContainsKey(instanceKey)){ + _instances.Add(instanceKey, createTenjin(apiKey, sharedSecret, appSubversion)); + } + return _instances[instanceKey]; + } + + private static BaseTenjin createTenjin(string apiKey, string sharedSecret, int appSubversion){ + GameObject tenjinGameObject = new GameObject("Tenjin"); + tenjinGameObject.hideFlags = HideFlags.HideAndDontSave; + UnityEngine.Object.DontDestroyOnLoad(tenjinGameObject); + +#if UNITY_ANDROID && !UNITY_EDITOR + BaseTenjin retTenjin = tenjinGameObject.AddComponent(); +#elif UNITY_IPHONE && !UNITY_EDITOR + BaseTenjin retTenjin = tenjinGameObject.AddComponent(); +#else + BaseTenjin retTenjin = tenjinGameObject.AddComponent(); +#endif + + if (!string.IsNullOrEmpty(sharedSecret) && appSubversion != 0) + { + retTenjin.InitWithSharedSecretAppSubversion(apiKey, sharedSecret, appSubversion); + } + else if (!string.IsNullOrEmpty(sharedSecret)) + { + retTenjin.InitWithSharedSecret(apiKey, sharedSecret); + } + else if (appSubversion != 0) + { + retTenjin.InitWithAppSubversion(apiKey, appSubversion); + } + else + { + retTenjin.Init(apiKey); + } + return retTenjin; + } +} diff --git a/popcorn/Assets/Tenjin/Scripts/Tenjin.cs.meta b/popcorn/Assets/Tenjin/Scripts/Tenjin.cs.meta new file mode 100644 index 00000000..28912068 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/Tenjin.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e577921dfc66746639e11ffbf5f18702 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs b/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs new file mode 100644 index 00000000..7c2ee329 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +public class TenjinMopubIntegration +{ + private static bool _subscribed = false; + public TenjinMopubIntegration() + { + } + + public static void ListenForImpressions(Action callback) + { +#if tenjin_mopub_enabled + if (_subscribed) + { + Debug.Log("Ignoring duplicate mopub subscription"); + return; + } + + MoPubManager.OnImpressionTrackedEvent += (arg1, arg2) => callback(arg2.JsonRepresentation); + _subscribed = true; +#endif + } + +} diff --git a/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs.meta b/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs.meta new file mode 100644 index 00000000..9abeb102 --- /dev/null +++ b/popcorn/Assets/Tenjin/Scripts/TenjinMopubIntegration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87ce33ab3417345b788b73a0d626090d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/popcorn/ProjectSettings/ProjectSettings.asset b/popcorn/ProjectSettings/ProjectSettings.asset index 3ae4f29c..75cc3ea6 100644 --- a/popcorn/ProjectSettings/ProjectSettings.asset +++ b/popcorn/ProjectSettings/ProjectSettings.asset @@ -624,6 +624,7 @@ PlayerSettings: daydreamIconForeground: {fileID: 0} daydreamIconBackground: {fileID: 0} cloudServicesEnabled: + Build: 1 UNet: 1 luminIcon: m_Name: