diff --git a/MaxSdk/AppLovin/Editor/Dependencies.xml b/MaxSdk/AppLovin/Editor/Dependencies.xml index e94d30e..0bb9011 100644 --- a/MaxSdk/AppLovin/Editor/Dependencies.xml +++ b/MaxSdk/AppLovin/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar b/MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar index 7575a83..60a43f0 100644 Binary files a/MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar and b/MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar differ diff --git a/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h b/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h index 4af5531..f5a250e 100644 --- a/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h +++ b/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h @@ -49,14 +49,6 @@ typedef void (*ALUnityBackgroundCallback)(const char* args); - (void)updateMRecPosition:(CGFloat)xOffset y:(CGFloat)yOffset forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; - (NSString *)mrecLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; -- (void)createCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset width:(CGFloat)width height:(CGFloat)height rotation:(CGFloat)rotation; -- (void)setCrossPromoAdPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; -- (void)showCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; -- (void)destroyCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; -- (void)hideCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; -- (void)updateCrossPromoAdPositionForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset width:(CGFloat)width height:(CGFloat)height rotation:(CGFloat)rotation; -- (NSString *)crossPromoAdLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; - - (void)loadInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; - (BOOL)isInterstitialReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier; - (void)showInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData; diff --git a/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m b/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m index eb874ac..67a0eab 100644 --- a/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m +++ b/MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m @@ -5,7 +5,7 @@ #import "MAUnityAdManager.h" -#define VERSION @"6.1.2" +#define VERSION @"6.4.3" #define KEY_WINDOW [UIApplication sharedApplication].keyWindow #define DEVICE_SPECIFIC_ADVIEW_AD_FORMAT ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) ? MAAdFormat.leader : MAAdFormat.banner @@ -24,6 +24,12 @@ extern "C" { void UnityPause(int pause); void UnitySendMessage(const char* obj, const char* method, const char* msg); + static const char * cStringCopy(NSString *string) + { + const char *value = string.UTF8String; + return value ? strdup(value) : NULL; + } + void max_unity_dispatch_on_main_thread(dispatch_block_t block) { if ( block ) @@ -59,8 +65,6 @@ extern "C" { @property (nonatomic, strong) NSMutableDictionary *adViewPositions; @property (nonatomic, strong) NSMutableDictionary *adViewOffsets; @property (nonatomic, strong) NSMutableDictionary *adViewWidths; -@property (nonatomic, strong) NSMutableDictionary *crossPromoAdViewHeights; -@property (nonatomic, strong) NSMutableDictionary *crossPromoAdViewRotations; @property (nonatomic, strong) NSMutableDictionary *verticalAdViewFormats; @property (nonatomic, strong) NSMutableDictionary *> *adViewConstraints; @property (nonatomic, strong) NSMutableDictionary *> *adViewExtraParametersToSetAfterCreate; @@ -117,8 +121,6 @@ static ALUnityBackgroundCallback backgroundCallback; self.adViewPositions = [NSMutableDictionary dictionaryWithCapacity: 2]; self.adViewOffsets = [NSMutableDictionary dictionaryWithCapacity: 2]; self.adViewWidths = [NSMutableDictionary dictionaryWithCapacity: 2]; - self.crossPromoAdViewHeights = [NSMutableDictionary dictionaryWithCapacity: 2]; - self.crossPromoAdViewRotations = [NSMutableDictionary dictionaryWithCapacity: 2]; self.verticalAdViewFormats = [NSMutableDictionary dictionaryWithCapacity: 2]; self.adViewConstraints = [NSMutableDictionary dictionaryWithCapacity: 2]; self.adViewExtraParametersToSetAfterCreate = [NSMutableDictionary dictionaryWithCapacity: 1]; @@ -188,19 +190,21 @@ static ALUnityBackgroundCallback backgroundCallback; self.sdk.mediationProvider = @"max"; [self.sdk initializeSdkWithCompletionHandler:^(ALSdkConfiguration *configuration) { - // Note: internal state should be updated first - completionHandler( configuration ); - - NSString *consentFlowUserGeographyStr = @(configuration.consentFlowUserGeography).stringValue; - NSString *consentDialogStateStr = @(configuration.consentDialogState).stringValue; - NSString *appTrackingStatus = @(configuration.appTrackingTransparencyStatus).stringValue; // Deliberately name it `appTrackingStatus` to be a bit more generic (in case Android introduces a similar concept) - [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : @"OnSdkInitializedEvent", - @"consentFlowUserGeography" : consentFlowUserGeographyStr, - @"consentDialogState" : consentDialogStateStr, - @"countryCode" : configuration.countryCode, - @"appTrackingStatus" : appTrackingStatus, - @"isSuccessfullyInitialized" : @([self.sdk isInitialized]), - @"isTestModeEnabled" : @([configuration isTestModeEnabled])}]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // Note: internal state should be updated first + completionHandler( configuration ); + + NSString *consentFlowUserGeographyStr = @(configuration.consentFlowUserGeography).stringValue; + NSString *consentDialogStateStr = @(configuration.consentDialogState).stringValue; + NSString *appTrackingStatus = @(configuration.appTrackingTransparencyStatus).stringValue; // Deliberately name it `appTrackingStatus` to be a bit more generic (in case Android introduces a similar concept) + [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : @"OnSdkInitializedEvent", + @"consentFlowUserGeography" : consentFlowUserGeographyStr, + @"consentDialogState" : consentDialogStateStr, + @"countryCode" : configuration.countryCode, + @"appTrackingStatus" : appTrackingStatus, + @"isSuccessfullyInitialized" : @([self.sdk isInitialized]), + @"isTestModeEnabled" : @([configuration isTestModeEnabled])}]; + }); }]; return self.sdk; @@ -387,49 +391,6 @@ static ALUnityBackgroundCallback backgroundCallback; return [self adViewLayoutForAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.mrec]; } -#pragma mark - Cross Promo Ads - -- (void)createCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset width:(CGFloat)width height:(CGFloat)height rotation:(CGFloat)rotation -{ - self.adViewWidths[adUnitIdentifier] = @(width); - self.crossPromoAdViewHeights[adUnitIdentifier] = @(height); - self.crossPromoAdViewRotations[adUnitIdentifier] = @(rotation); - [self createAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo atPosition: DEFAULT_AD_VIEW_POSITION withOffset: CGPointMake(xOffset, yOffset)]; -} - -- (void)setCrossPromoAdPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier -{ - [self setAdViewPlacement: placement forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - -- (void)updateCrossPromoAdPositionForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset width:(CGFloat)width height:(CGFloat)height rotation:(CGFloat)rotation -{ - self.adViewWidths[adUnitIdentifier] = @(width); - self.crossPromoAdViewHeights[adUnitIdentifier] = @(height); - self.crossPromoAdViewRotations[adUnitIdentifier] = @(rotation); - [self updateAdViewPosition: DEFAULT_AD_VIEW_POSITION withOffset: CGPointMake(xOffset, yOffset) forAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - -- (void)showCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier -{ - [self showAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - -- (void)destroyCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier -{ - [self destroyAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - -- (void)hideCrossPromoAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier -{ - [self hideAdViewWithAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - -- (NSString *)crossPromoAdLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier -{ - return [self adViewLayoutForAdUnitIdentifier: adUnitIdentifier adFormat: MAAdFormat.crossPromo]; -} - #pragma mark - Interstitials - (void)loadInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier @@ -594,7 +555,7 @@ static ALUnityBackgroundCallback backgroundCallback; - (NSString *)adInfoForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier { - if ( [adUnitIdentifier al_isValidString] ) return @""; + if ( ![adUnitIdentifier al_isValidString] ) return @""; MAAd *ad = [self adWithAdUnitIdentifier: adUnitIdentifier]; if ( !ad ) return @""; @@ -613,6 +574,7 @@ static ALUnityBackgroundCallback backgroundCallback; @"revenue" : [@(ad.revenue) stringValue], @"revenuePrecision" : ad.revenuePrecision, @"waterfallInfo" : [self createAdWaterfallInfo: ad.waterfall], + @"latencyMillis" : [self requestLatencyMillisFromRequestLatency: ad.requestLatency], @"dspName" : ad.DSPName ?: @""}; } @@ -631,11 +593,9 @@ static ALUnityBackgroundCallback backgroundCallback; { [networkResponsesArray addObject: [self createNetworkResponseInfo: response]]; } - waterfallInfoDict[@"networkResponses"] = networkResponsesArray; - // Convert latency from seconds to milliseconds to match Android. - long latencyMillis = waterfallInfo.latency * 1000; - waterfallInfoDict[@"latencyMillis"] = @(latencyMillis).stringValue; + waterfallInfoDict[@"networkResponses"] = networkResponsesArray; + waterfallInfoDict[@"latencyMillis"] = [self requestLatencyMillisFromRequestLatency: waterfallInfo.latency]; return waterfallInfoDict; } @@ -668,13 +628,12 @@ static ALUnityBackgroundCallback backgroundCallback; errorObject[@"errorMessage"] = error.message; errorObject[@"adLoadFailure"] = error.adLoadFailureInfo; errorObject[@"errorCode"] = @(error.code).stringValue; + errorObject[@"latencyMillis"] = [self requestLatencyMillisFromRequestLatency: error.requestLatency]; networkResponseDict[@"error"] = errorObject; } - // Convert latency from seconds to milliseconds to match Android. - long latencySeconds = response.latency * 1000; - networkResponseDict[@"latencyMillis"] = @(latencySeconds).stringValue; + networkResponseDict[@"latencyMillis"] = [self requestLatencyMillisFromRequestLatency: response.latency]; return networkResponseDict; } @@ -708,10 +667,6 @@ static ALUnityBackgroundCallback backgroundCallback; { name = @"OnMRecAdLoadedEvent"; } - else if ( MAAdFormat.crossPromo == adFormat ) - { - name = @"OnCrossPromoAdLoadedEvent"; - } else { name = @"OnBannerAdLoadedEvent"; @@ -747,115 +702,117 @@ static ALUnityBackgroundCallback backgroundCallback; return; } - @synchronized ( self.adInfoDictLock ) - { - self.adInfoDict[ad.adUnitIdentifier] = ad; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + @synchronized ( self.adInfoDictLock ) + { + self.adInfoDict[ad.adUnitIdentifier] = ad; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didFailToLoadAdForAdUnitIdentifier:(NSString *)adUnitIdentifier withError:(MAError *)error { - if ( !adUnitIdentifier ) - { - [self log: @"adUnitIdentifier cannot be nil from %@", [NSThread callStackSymbols]]; - return; - } - - NSString *name; - if ( self.adViews[adUnitIdentifier] ) - { - MAAdFormat *adFormat = self.adViewAdFormats[adUnitIdentifier]; - if ( MAAdFormat.mrec == adFormat ) + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + if ( !adUnitIdentifier ) { - name = @"OnMRecAdLoadFailedEvent"; + [self log: @"adUnitIdentifier cannot be nil from %@", [NSThread callStackSymbols]]; + return; } - else if ( MAAdFormat.crossPromo == adFormat ) + + NSString *name; + if ( self.adViews[adUnitIdentifier] ) { - name = @"OnCrossPromoAdLoadFailedEvent"; + MAAdFormat *adFormat = self.adViewAdFormats[adUnitIdentifier]; + if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdLoadFailedEvent"; + } + else + { + name = @"OnBannerAdLoadFailedEvent"; + } + } + else if ( self.interstitials[adUnitIdentifier] ) + { + name = @"OnInterstitialLoadFailedEvent"; + } + else if ( self.appOpenAds[adUnitIdentifier] ) + { + name = @"OnAppOpenAdLoadFailedEvent"; + } + else if ( self.rewardedAds[adUnitIdentifier] ) + { + name = @"OnRewardedAdLoadFailedEvent"; + } + else if ( self.rewardedInterstitialAds[adUnitIdentifier] ) + { + name = @"OnRewardedInterstitialAdLoadFailedEvent"; } else { - name = @"OnBannerAdLoadFailedEvent"; + [self log: @"invalid adUnitId from %@", [NSThread callStackSymbols]]; + return; } - } - else if ( self.interstitials[adUnitIdentifier] ) - { - name = @"OnInterstitialLoadFailedEvent"; - } - else if ( self.appOpenAds[adUnitIdentifier] ) - { - name = @"OnAppOpenAdLoadFailedEvent"; - } - else if ( self.rewardedAds[adUnitIdentifier] ) - { - name = @"OnRewardedAdLoadFailedEvent"; - } - else if ( self.rewardedInterstitialAds[adUnitIdentifier] ) - { - name = @"OnRewardedInterstitialAdLoadFailedEvent"; - } - else - { - [self log: @"invalid adUnitId from %@", [NSThread callStackSymbols]]; - return; - } - - @synchronized ( self.adInfoDictLock ) - { - [self.adInfoDict removeObjectForKey: adUnitIdentifier]; - } - - [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : name, - @"adUnitId" : adUnitIdentifier, - @"errorCode" : [@(error.code) stringValue], - @"errorMessage" : error.message, - @"waterfallInfo" : [self createAdWaterfallInfo: error.waterfall], - @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @""}]; + + @synchronized ( self.adInfoDictLock ) + { + [self.adInfoDict removeObjectForKey: adUnitIdentifier]; + } + + [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : name, + @"adUnitId" : adUnitIdentifier, + @"errorCode" : [@(error.code) stringValue], + @"errorMessage" : error.message, + @"waterfallInfo" : [self createAdWaterfallInfo: error.waterfall], + @"adLoadFailureInfo" : error.adLoadFailureInfo ?: @"", + @"latencyMillis" : [self requestLatencyMillisFromRequestLatency: error.requestLatency]}]; + }); } - (void)didClickAd:(MAAd *)ad { - NSString *name; - MAAdFormat *adFormat = ad.format; - if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) - { - name = @"OnBannerAdClickedEvent"; - } - else if ( MAAdFormat.mrec == adFormat ) - { - name = @"OnMRecAdClickedEvent"; - } - else if ( MAAdFormat.crossPromo == adFormat ) - { - name = @"OnCrossPromoAdClickedEvent"; - } - else if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialClickedEvent"; - } - else if ( MAAdFormat.appOpen == adFormat ) - { - name = @"OnAppOpenAdClickedEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdClickedEvent"; - } - else if ( MAAdFormat.rewardedInterstitial == adFormat ) - { - name = @"OnRewardedInterstitialAdClickedEvent"; - } - else - { - [self logInvalidAdFormat: adFormat]; - return; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + MAAdFormat *adFormat = ad.format; + if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) + { + name = @"OnBannerAdClickedEvent"; + } + else if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdClickedEvent"; + } + else if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialClickedEvent"; + } + else if ( MAAdFormat.appOpen == adFormat ) + { + name = @"OnAppOpenAdClickedEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdClickedEvent"; + } + else if ( MAAdFormat.rewardedInterstitial == adFormat ) + { + name = @"OnRewardedInterstitialAdClickedEvent"; + } + else + { + [self logInvalidAdFormat: adFormat]; + return; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didDisplayAd:(MAAd *)ad @@ -864,63 +821,71 @@ static ALUnityBackgroundCallback backgroundCallback; MAAdFormat *adFormat = ad.format; if ( ![adFormat isFullscreenAd] ) return; + // UnityPause needs to be called on the main thread. #if !IS_TEST_APP UnityPause(1); #endif - NSString *name; - if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialDisplayedEvent"; - } - else if ( MAAdFormat.appOpen == adFormat ) - { - name = @"OnAppOpenAdDisplayedEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdDisplayedEvent"; - } - else // rewarded inters - { - name = @"OnRewardedInterstitialAdDisplayedEvent"; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialDisplayedEvent"; + } + else if ( MAAdFormat.appOpen == adFormat ) + { + name = @"OnAppOpenAdDisplayedEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdDisplayedEvent"; + } + else // rewarded inters + { + name = @"OnRewardedInterstitialAdDisplayedEvent"; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didFailToDisplayAd:(MAAd *)ad withError:(MAError *)error { - // BMLs do not support [DISPLAY] events in Unity - MAAdFormat *adFormat = ad.format; - if ( ![adFormat isFullscreenAd] ) return; - - NSString *name; - if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialAdFailedToDisplayEvent"; - } - else if ( MAAdFormat.appOpen == adFormat ) - { - name = @"OnAppOpenAdFailedToDisplayEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdFailedToDisplayEvent"; - } - else // rewarded inters - { - name = @"OnRewardedInterstitialAdFailedToDisplayEvent"; - } - - NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - args[@"errorCode"] = [@(error.code) stringValue]; - args[@"errorMessage"] = error.message; - args[@"mediatedNetworkErrorCode"] = [@(error.mediatedNetworkErrorCode) stringValue]; - args[@"mediatedNetworkErrorMessage"] = error.mediatedNetworkErrorMessage; - args[@"waterfallInfo"] = [self createAdWaterfallInfo: error.waterfall]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + // BMLs do not support [DISPLAY] events in Unity + MAAdFormat *adFormat = ad.format; + if ( ![adFormat isFullscreenAd] ) return; + + NSString *name; + if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialAdFailedToDisplayEvent"; + } + else if ( MAAdFormat.appOpen == adFormat ) + { + name = @"OnAppOpenAdFailedToDisplayEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdFailedToDisplayEvent"; + } + else // rewarded inters + { + name = @"OnRewardedInterstitialAdFailedToDisplayEvent"; + } + + NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + args[@"errorCode"] = [@(error.code) stringValue]; + args[@"errorMessage"] = error.message; + args[@"mediatedNetworkErrorCode"] = [@(error.mediatedNetworkErrorCode) stringValue]; + args[@"mediatedNetworkErrorMessage"] = error.mediatedNetworkErrorMessage; + args[@"waterfallInfo"] = [self createAdWaterfallInfo: error.waterfall]; + args[@"latencyMillis"] = [self requestLatencyMillisFromRequestLatency: error.requestLatency]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didHideAd:(MAAd *)ad @@ -929,30 +894,34 @@ static ALUnityBackgroundCallback backgroundCallback; MAAdFormat *adFormat = ad.format; if ( ![adFormat isFullscreenAd] ) return; + // UnityPause needs to be called on the main thread. #if !IS_TEST_APP UnityPause(0); #endif - NSString *name; - if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialHiddenEvent"; - } - else if ( MAAdFormat.appOpen == adFormat ) - { - name = @"OnAppOpenAdHiddenEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdHiddenEvent"; - } - else // rewarded inters - { - name = @"OnRewardedInterstitialAdHiddenEvent"; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialHiddenEvent"; + } + else if ( MAAdFormat.appOpen == adFormat ) + { + name = @"OnAppOpenAdHiddenEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdHiddenEvent"; + } + else // rewarded inters + { + name = @"OnRewardedInterstitialAdHiddenEvent"; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didExpandAd:(MAAd *)ad @@ -964,26 +933,26 @@ static ALUnityBackgroundCallback backgroundCallback; return; } + // UnityPause needs to be called on the main thread. #if !IS_TEST_APP UnityPause(1); #endif - NSString *name; - if ( MAAdFormat.mrec == adFormat ) - { - name = @"OnMRecAdExpandedEvent"; - } - else if ( MAAdFormat.crossPromo == adFormat ) - { - name = @"OnCrossPromoAdExpandedEvent"; - } - else - { - name = @"OnBannerAdExpandedEvent"; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdExpandedEvent"; + } + else + { + name = @"OnBannerAdExpandedEvent"; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didCollapseAd:(MAAd *)ad @@ -995,26 +964,26 @@ static ALUnityBackgroundCallback backgroundCallback; return; } + // UnityPause needs to be called on the main thread. #if !IS_TEST_APP UnityPause(0); #endif - NSString *name; - if ( MAAdFormat.mrec == adFormat ) - { - name = @"OnMRecAdCollapsedEvent"; - } - else if ( MAAdFormat.crossPromo == adFormat ) - { - name = @"OnCrossPromoAdCollapsedEvent"; - } - else - { - name = @"OnBannerAdCollapsedEvent"; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdCollapsedEvent"; + } + else + { + name = @"OnBannerAdCollapsedEvent"; + } + + NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didStartRewardedVideoForAd:(MAAd *)ad @@ -1029,103 +998,110 @@ static ALUnityBackgroundCallback backgroundCallback; - (void)didRewardUserForAd:(MAAd *)ad withReward:(MAReward *)reward { - MAAdFormat *adFormat = ad.format; - if ( adFormat != MAAdFormat.rewarded && adFormat != MAAdFormat.rewardedInterstitial ) - { - [self logInvalidAdFormat: adFormat]; - return; - } - - NSString *rewardLabel = reward ? reward.label : @""; - NSInteger rewardAmountInt = reward ? reward.amount : 0; - NSString *rewardAmount = [@(rewardAmountInt) stringValue]; - - NSString *name = (adFormat == MAAdFormat.rewarded) ? @"OnRewardedAdReceivedRewardEvent" : @"OnRewardedInterstitialAdReceivedRewardEvent"; - - - NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - args[@"rewardLabel"] = rewardLabel; - args[@"rewardAmount"] = rewardAmount; - [MAUnityAdManager forwardUnityEventWithArgs: args]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + MAAdFormat *adFormat = ad.format; + if ( adFormat != MAAdFormat.rewarded && adFormat != MAAdFormat.rewardedInterstitial ) + { + [self logInvalidAdFormat: adFormat]; + return; + } + + NSString *rewardLabel = reward ? reward.label : @""; + NSInteger rewardAmountInt = reward ? reward.amount : 0; + NSString *rewardAmount = [@(rewardAmountInt) stringValue]; + + NSString *name = (adFormat == MAAdFormat.rewarded) ? @"OnRewardedAdReceivedRewardEvent" : @"OnRewardedInterstitialAdReceivedRewardEvent"; + + + NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + args[@"rewardLabel"] = rewardLabel; + args[@"rewardAmount"] = rewardAmount; + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didPayRevenueForAd:(MAAd *)ad { - NSString *name; - MAAdFormat *adFormat = ad.format; - if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) - { - name = @"OnBannerAdRevenuePaidEvent"; - } - else if ( MAAdFormat.mrec == adFormat ) - { - name = @"OnMRecAdRevenuePaidEvent"; - } - else if ( MAAdFormat.crossPromo == adFormat ) - { - name = @"OnCrossPromoAdRevenuePaidEvent"; - } - else if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialAdRevenuePaidEvent"; - } - else if ( MAAdFormat.appOpen == adFormat ) - { - name = @"OnAppOpenAdRevenuePaidEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdRevenuePaidEvent"; - } - else if ( MAAdFormat.rewardedInterstitial == adFormat ) - { - name = @"OnRewardedInterstitialAdRevenuePaidEvent"; - } - else - { - [self logInvalidAdFormat: adFormat]; - return; - } - - NSDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - [MAUnityAdManager forwardUnityEventWithArgs: args forwardInBackground: [adFormat isFullscreenAd]]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + MAAdFormat *adFormat = ad.format; + if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) + { + name = @"OnBannerAdRevenuePaidEvent"; + } + else if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdRevenuePaidEvent"; + } + else if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialAdRevenuePaidEvent"; + } + else if ( MAAdFormat.appOpen == adFormat ) + { + name = @"OnAppOpenAdRevenuePaidEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdRevenuePaidEvent"; + } + else if ( MAAdFormat.rewardedInterstitial == adFormat ) + { + name = @"OnRewardedInterstitialAdRevenuePaidEvent"; + } + else + { + [self logInvalidAdFormat: adFormat]; + return; + } + + NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + args[@"keepInBackground"] = @([adFormat isFullscreenAd]); + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (void)didGenerateCreativeIdentifier:(NSString *)creativeIdentifier forAd:(MAAd *)ad { - NSString *name; - MAAdFormat *adFormat = ad.format; - if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) - { - name = @"OnBannerAdReviewCreativeIdGeneratedEvent"; - } - else if ( MAAdFormat.mrec == adFormat ) - { - name = @"OnMRecAdReviewCreativeIdGeneratedEvent"; - } - else if ( MAAdFormat.interstitial == adFormat ) - { - name = @"OnInterstitialAdReviewCreativeIdGeneratedEvent"; - } - else if ( MAAdFormat.rewarded == adFormat ) - { - name = @"OnRewardedAdReviewCreativeIdGeneratedEvent"; - } - else if ( MAAdFormat.rewardedInterstitial == adFormat ) - { - name = @"OnRewardedInterstitialAdReviewCreativeIdGeneratedEvent"; - } - else - { - [self logInvalidAdFormat: adFormat]; - return; - } - - NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; - args[@"adReviewCreativeId"] = creativeIdentifier; - - // Forward the event in background for fullscreen ads so that the user gets the callback even while the ad is playing. - [MAUnityAdManager forwardUnityEventWithArgs: args forwardInBackground: [adFormat isFullscreenAd]]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + NSString *name; + MAAdFormat *adFormat = ad.format; + if ( MAAdFormat.banner == adFormat || MAAdFormat.leader == adFormat ) + { + name = @"OnBannerAdReviewCreativeIdGeneratedEvent"; + } + else if ( MAAdFormat.mrec == adFormat ) + { + name = @"OnMRecAdReviewCreativeIdGeneratedEvent"; + } + else if ( MAAdFormat.interstitial == adFormat ) + { + name = @"OnInterstitialAdReviewCreativeIdGeneratedEvent"; + } + else if ( MAAdFormat.rewarded == adFormat ) + { + name = @"OnRewardedAdReviewCreativeIdGeneratedEvent"; + } + else if ( MAAdFormat.rewardedInterstitial == adFormat ) + { + name = @"OnRewardedInterstitialAdReviewCreativeIdGeneratedEvent"; + } + else + { + [self logInvalidAdFormat: adFormat]; + return; + } + + NSMutableDictionary *args = [self defaultAdEventParametersForName: name withAd: ad]; + args[@"adReviewCreativeId"] = creativeIdentifier; + args[@"keepInBackground"] = @([adFormat isFullscreenAd]); + + // Forward the event in background for fullscreen ads so that the user gets the callback even while the ad is playing. + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); } - (NSMutableDictionary *)defaultAdEventParametersForName:(NSString *)name withAd:(MAAd *)ad @@ -1537,8 +1513,6 @@ static ALUnityBackgroundCallback backgroundCallback; [self.adViewPositions removeObjectForKey: adUnitIdentifier]; [self.adViewOffsets removeObjectForKey: adUnitIdentifier]; [self.adViewWidths removeObjectForKey: adUnitIdentifier]; - [self.crossPromoAdViewHeights removeObjectForKey: adUnitIdentifier]; - [self.crossPromoAdViewRotations removeObjectForKey: adUnitIdentifier]; [self.verticalAdViewFormats removeObjectForKey: adUnitIdentifier]; [self.disabledAdaptiveBannerAdUnitIdentifiers removeObject: adUnitIdentifier]; }); @@ -1678,8 +1652,6 @@ static ALUnityBackgroundCallback backgroundCallback; CGPoint adViewOffset = [adViewPositionValue CGPointValue]; BOOL isAdaptiveBannerDisabled = [self.disabledAdaptiveBannerAdUnitIdentifiers containsObject: adUnitIdentifier]; BOOL isWidthPtsOverridden = self.adViewWidths[adUnitIdentifier] != nil; - BOOL isCrossPromoHeightPtsOverridden = self.crossPromoAdViewHeights[adUnitIdentifier] != nil; - BOOL isCrossPromoRotationOverridden = self.crossPromoAdViewRotations[adUnitIdentifier] != nil; UIView *superview = adView.superview; if ( !superview ) return; @@ -1727,11 +1699,7 @@ static ALUnityBackgroundCallback backgroundCallback; // CGFloat adViewHeight; - if ( isCrossPromoHeightPtsOverridden ) - { - adViewHeight = self.crossPromoAdViewHeights[adUnitIdentifier].floatValue; - } - else if ( (adFormat == MAAdFormat.banner || adFormat == MAAdFormat.leader) && !isAdaptiveBannerDisabled ) + if ( (adFormat == MAAdFormat.banner || adFormat == MAAdFormat.leader) && !isAdaptiveBannerDisabled ) { adViewHeight = [adFormat adaptiveSizeForWidth: adViewWidth].height; } @@ -1959,11 +1927,6 @@ static ALUnityBackgroundCallback backgroundCallback; } } - if ( isCrossPromoRotationOverridden ) - { - adView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DEGREES_TO_RADIANS(self.crossPromoAdViewRotations[adUnitIdentifier].floatValue)); - } - self.adViewConstraints[adUnitIdentifier] = constraints; [NSLayoutConstraint activateConstraints: constraints]; @@ -1977,21 +1940,21 @@ static ALUnityBackgroundCallback backgroundCallback; } + (void)forwardUnityEventWithArgs:(NSDictionary *)args -{ - [MAUnityAdManager forwardUnityEventWithArgs: args forwardInBackground: NO]; -} - -+ (void)forwardUnityEventWithArgs:(NSDictionary *)args forwardInBackground:(BOOL)forwardInBackground { #if !IS_TEST_APP - char *serializedParameters = [self serializeParameters: args].UTF8String; - if ( forwardInBackground ) - { + void (^runnable)(void) = ^{ + const char *serializedParameters = cStringCopy([self serializeParameters: args]); backgroundCallback(serializedParameters); + }; + + // Always forward in background - we push it back to the main thread in Unity + if ( [NSThread isMainThread] ) + { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), runnable); } else { - UnitySendMessage("MaxSdkCallbacks", "ForwardEvent", serializedParameters); + runnable(); } #endif } @@ -2036,11 +1999,20 @@ static ALUnityBackgroundCallback backgroundCallback; } } +- (NSString *)requestLatencyMillisFromRequestLatency:(NSTimeInterval)requestLatency +{ + // Convert latency from seconds to milliseconds to match Android. + long requestLatencyMillis = requestLatency * 1000; + return @(requestLatencyMillis).stringValue; +} + #pragma mark - User Service - (void)didDismissUserConsentDialog { - [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : @"OnSdkConsentDialogDismissedEvent"}]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [MAUnityAdManager forwardUnityEventWithArgs: @{@"name" : @"OnSdkConsentDialogDismissedEvent"}]; + }); } #pragma mark - CMP Service @@ -2048,19 +2020,22 @@ static ALUnityBackgroundCallback backgroundCallback; - (void)showCMPForExistingUser { [self.sdk.cmpService showCMPForExistingUserWithCompletion:^(ALCMPError * _Nullable error) { - - NSMutableDictionary *args = [NSMutableDictionary dictionaryWithCapacity: 2]; - args[@"name"] = @"OnCmpCompletedEvent"; - - if ( error ) - { - args[@"error"] = @{@"code": @(error.code), - @"message": error.message, - @"cmpCode": @(error.cmpCode), - @"cmpMessage": error.cmpMessage}; - } - - [MAUnityAdManager forwardUnityEventWithArgs: args forwardInBackground: YES]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSMutableDictionary *args = [NSMutableDictionary dictionaryWithCapacity: 2]; + args[@"name"] = @"OnCmpCompletedEvent"; + + if ( error ) + { + args[@"error"] = @{@"code": @(error.code), + @"message": error.message, + @"cmpCode": @(error.cmpCode), + @"cmpMessage": error.cmpMessage, + @"keepInBackground": @(YES)}; + } + + [MAUnityAdManager forwardUnityEventWithArgs: args]; + }); }]; } diff --git a/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm b/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm index edac38f..5571964 100644 --- a/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm +++ b/MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm @@ -15,13 +15,13 @@ @property (assign, readonly, getter=al_isValidString) BOOL al_validString; @end -UIView* UnityGetGLView(); - // When native code plugin is implemented in .mm / .cpp file, then functions // should be surrounded with extern "C" block to conform C function naming rules extern "C" { static NSString *const TAG = @"MAUnityPlugin"; + + UIView* UnityGetGLView(); static ALSdk *_sdk; static MAUnityAdManager *_adManager; @@ -52,6 +52,18 @@ extern "C" static const char * cStringCopy(NSString *string); // Helper method to log errors void logUninitializedAccessError(const char *callingMethod); + + int getConsentStatusValue(NSNumber *consentStatus) + { + if ( consentStatus ) + { + return consentStatus.intValue; + } + else + { + return -1; + } + } bool isPluginInitialized() { @@ -785,51 +797,6 @@ extern "C" return cStringCopy([_adManager mrecLayoutForAdUnitIdentifier: NSSTRING(adUnitIdentifier)]); } - - void _MaxCreateCrossPromoAd(const char *adUnitIdentifier, const float x, const float y, const float width, const float height, const float rotation) - { - if (!isPluginInitialized()) return; - - [_adManager createCrossPromoAdWithAdUnitIdentifier: NSSTRING(adUnitIdentifier) x: x y: y width: width height: height rotation: rotation]; - } - - void _MaxSetCrossPromoAdPlacement(const char *adUnitIdentifier, const char *placement) - { - [_adManager setCrossPromoAdPlacement: NSSTRING(placement) forAdUnitIdentifier: NSSTRING(adUnitIdentifier)]; - } - - void _MaxUpdateCrossPromoAdPosition(const char *adUnitIdentifier, const float x, const float y, const float width, const float height, const float rotation) - { - [_adManager updateCrossPromoAdPositionForAdUnitIdentifier: NSSTRING(adUnitIdentifier) x: x y: y width: width height: height rotation: rotation]; - } - - void _MaxShowCrossPromoAd(const char *adUnitIdentifier) - { - if (!isPluginInitialized()) return; - - [_adManager showCrossPromoAdWithAdUnitIdentifier: NSSTRING(adUnitIdentifier)]; - } - - void _MaxDestroyCrossPromoAd(const char *adUnitIdentifier) - { - if (!isPluginInitialized()) return; - - [_adManager destroyCrossPromoAdWithAdUnitIdentifier: NSSTRING(adUnitIdentifier)]; - } - - void _MaxHideCrossPromoAd(const char *adUnitIdentifier) - { - if (!isPluginInitialized()) return; - - [_adManager hideCrossPromoAdWithAdUnitIdentifier: NSSTRING(adUnitIdentifier)]; - } - - const char * _MaxGetCrossPromoAdLayout(const char *adUnitIdentifier) - { - if (!isPluginInitialized()) return cStringCopy(@""); - - return cStringCopy([_adManager crossPromoAdLayoutForAdUnitIdentifier: NSSTRING(adUnitIdentifier)]); - } void _MaxLoadInterstitial(const char *adUnitIdentifier) { @@ -1060,30 +1027,28 @@ extern "C" return !ALUtils.simulator; } - int _MaxGetTcfConsentStatus(int vendorIdentifier) + int _MaxGetTcfVendorConsentStatus(int vendorIdentifier) { - NSNumber *consentStatus = [ALUtils tcfConsentStatusForVendorIdentifier: vendorIdentifier]; - if ( consentStatus ) - { - return consentStatus.intValue; - } - else - { - return -1; - } + NSNumber *consentStatus = [ALPrivacySettings tcfVendorConsentStatusForIdentifier: vendorIdentifier]; + return getConsentStatusValue(consentStatus); } int _MaxGetAdditionalConsentStatus(int atpIdentifier) { - NSNumber *consentStatus = [ALUtils additionalConsentStatusForATPIdentifier: atpIdentifier]; - if ( consentStatus ) - { - return consentStatus.intValue; - } - else - { - return -1; - } + NSNumber *consentStatus = [ALPrivacySettings additionalConsentStatusForIdentifier: atpIdentifier]; + return getConsentStatusValue(consentStatus); + } + + int _MaxGetPurposeConsentStatus(int purposeIdentifier) + { + NSNumber *consentStatus = [ALPrivacySettings purposeConsentStatusForIdentifier: purposeIdentifier]; + return getConsentStatusValue(consentStatus); + } + + int _MaxGetSpecialFeatureOptInStatus(int specialFeatureIdentifier) + { + NSNumber *consentStatus = [ALPrivacySettings specialFeatureOptInStatusForIdentifier: specialFeatureIdentifier]; + return getConsentStatusValue(consentStatus); } static const char * cStringCopy(NSString *string) @@ -1229,6 +1194,13 @@ extern "C" } } } + + int * _MaxGetSafeAreaInsets() + { + UIEdgeInsets safeAreaInsets = UnityGetGLView().safeAreaInsets; + static int insets[4] = {(int) safeAreaInsets.left, (int) safeAreaInsets.top, (int) safeAreaInsets.right, (int) safeAreaInsets.bottom}; + return insets; + } void _MaxShowCmpForExistingUser() { diff --git a/MaxSdk/Mediation.meta b/MaxSdk/Mediation.meta index 2b5c46b..103dd6f 100644 --- a/MaxSdk/Mediation.meta +++ b/MaxSdk/Mediation.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a8ba4aafafc4142d8872c03c93ed10e2 +guid: dcf2020c4018447c9b91170c0f62d799 labels: - al_max - al_max_export_path-MaxSdk/Mediation diff --git a/Mediation/BidMachine.meta b/MaxSdk/Mediation/BidMachine.meta similarity index 83% rename from Mediation/BidMachine.meta rename to MaxSdk/Mediation/BidMachine.meta index 0db1a77..f6fac18 100644 --- a/Mediation/BidMachine.meta +++ b/MaxSdk/Mediation/BidMachine.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5a4e6c1e82db1462f8a77b375f310066 +guid: 6b9d9d3ca994442dcb2c1abcd31077ad labels: - al_max - al_max_export_path-MaxSdk/Mediation/BidMachine diff --git a/Mediation/BidMachine/Editor.meta b/MaxSdk/Mediation/BidMachine/Editor.meta similarity index 84% rename from Mediation/BidMachine/Editor.meta rename to MaxSdk/Mediation/BidMachine/Editor.meta index 367076e..0f3541e 100644 --- a/Mediation/BidMachine/Editor.meta +++ b/MaxSdk/Mediation/BidMachine/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ab3608d83ecb4446a81e1f3cceda3413 +guid: 527c65004f8c84edbb4c14b8a2a04c5d labels: - al_max - al_max_export_path-MaxSdk/Mediation/BidMachine/Editor diff --git a/Mediation/BidMachine/Editor/Dependencies.xml b/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml similarity index 92% rename from Mediation/BidMachine/Editor/Dependencies.xml rename to MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml index 3374645..5257026 100644 --- a/Mediation/BidMachine/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml @@ -1,13 +1,13 @@ - + https://artifactory.bidmachine.io/bidmachine - + diff --git a/Mediation/BidMachine/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/BidMachine/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml.meta index 90f8b70..81f22af 100644 --- a/Mediation/BidMachine/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 123f162bdccf1417d8283effdde4fdbd +guid: 98a383532dccb495aa31190874842cbe labels: - al_max - al_max_export_path-MaxSdk/Mediation/BidMachine/Editor/Dependencies.xml diff --git a/Mediation/ByteDance.meta b/MaxSdk/Mediation/ByteDance.meta similarity index 83% rename from Mediation/ByteDance.meta rename to MaxSdk/Mediation/ByteDance.meta index 02d0de6..386938c 100644 --- a/Mediation/ByteDance.meta +++ b/MaxSdk/Mediation/ByteDance.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b8e9d79594b7846daaa13430b88ceafd +guid: a0fd9165dea16454ea59da2bf05462d2 labels: - al_max - al_max_export_path-MaxSdk/Mediation/ByteDance diff --git a/Mediation/ByteDance/Editor.meta b/MaxSdk/Mediation/ByteDance/Editor.meta similarity index 84% rename from Mediation/ByteDance/Editor.meta rename to MaxSdk/Mediation/ByteDance/Editor.meta index aa89af8..e54a766 100644 --- a/Mediation/ByteDance/Editor.meta +++ b/MaxSdk/Mediation/ByteDance/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b88237e7390c0473caf663fb2ec2093a +guid: ef8467ffb0e4447b79a8804884a7520a labels: - al_max - al_max_export_path-MaxSdk/Mediation/ByteDance/Editor diff --git a/Mediation/ByteDance/Editor/Dependencies.xml b/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml similarity index 92% rename from Mediation/ByteDance/Editor/Dependencies.xml rename to MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml index 1fede9e..24e33a8 100644 --- a/Mediation/ByteDance/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml @@ -1,13 +1,13 @@ - + https://artifact.bytedance.com/repository/pangle - + diff --git a/Mediation/ByteDance/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/ByteDance/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml.meta index d5e47bf..5205233 100644 --- a/Mediation/ByteDance/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e40f7461260e84fce92b6baa166d3ac5 +guid: 0828555cb1ce94702a4af6f3dce3d735 labels: - al_max - al_max_export_path-MaxSdk/Mediation/ByteDance/Editor/Dependencies.xml diff --git a/Mediation/Chartboost.meta b/MaxSdk/Mediation/Chartboost.meta similarity index 83% rename from Mediation/Chartboost.meta rename to MaxSdk/Mediation/Chartboost.meta index 9241140..fa1c98a 100644 --- a/Mediation/Chartboost.meta +++ b/MaxSdk/Mediation/Chartboost.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 736e27be8f4514d63bb1f9e77e789d71 +guid: 3647332764da440ae8d4de79ebf72832 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Chartboost diff --git a/Mediation/Chartboost/Editor.meta b/MaxSdk/Mediation/Chartboost/Editor.meta similarity index 84% rename from Mediation/Chartboost/Editor.meta rename to MaxSdk/Mediation/Chartboost/Editor.meta index 82ec3c2..38bff8d 100644 --- a/Mediation/Chartboost/Editor.meta +++ b/MaxSdk/Mediation/Chartboost/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5fc6a042b090a4a41af5345f13644aef +guid: a90f13141c35746f5a2996c8ad068fe9 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Chartboost/Editor diff --git a/Mediation/Chartboost/Editor/Dependencies.xml b/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml similarity index 94% rename from Mediation/Chartboost/Editor/Dependencies.xml rename to MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml index eb84026..2cd6ec2 100644 --- a/Mediation/Chartboost/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml @@ -1,7 +1,7 @@ - + https://cboost.jfrog.io/artifactory/chartboost-ads/ @@ -9,6 +9,6 @@ - + diff --git a/Mediation/Chartboost/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Chartboost/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml.meta index 485897b..02628eb 100644 --- a/Mediation/Chartboost/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ce9cd7b936c30476a80116051627795e +guid: 93b0a4618bd884871af0981a7867bb2f labels: - al_max - al_max_export_path-MaxSdk/Mediation/Chartboost/Editor/Dependencies.xml diff --git a/Mediation/Facebook.meta b/MaxSdk/Mediation/Facebook.meta similarity index 83% rename from Mediation/Facebook.meta rename to MaxSdk/Mediation/Facebook.meta index f402243..242605e 100644 --- a/Mediation/Facebook.meta +++ b/MaxSdk/Mediation/Facebook.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c12845df8707d4636928493032036922 +guid: 27b0caf5a05a845018297e973b16537e labels: - al_max - al_max_export_path-MaxSdk/Mediation/Facebook diff --git a/Mediation/Facebook/Editor.meta b/MaxSdk/Mediation/Facebook/Editor.meta similarity index 83% rename from Mediation/Facebook/Editor.meta rename to MaxSdk/Mediation/Facebook/Editor.meta index f28dd12..4beff5e 100644 --- a/Mediation/Facebook/Editor.meta +++ b/MaxSdk/Mediation/Facebook/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d41a4deeadbbe49b4abdb8c33ed8adff +guid: 28880992a399a48b7abe95b66649d711 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Facebook/Editor diff --git a/Mediation/Facebook/Editor/Dependencies.xml b/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml similarity index 95% rename from Mediation/Facebook/Editor/Dependencies.xml rename to MaxSdk/Mediation/Facebook/Editor/Dependencies.xml index 6bf87ae..e9c4ef1 100644 --- a/Mediation/Facebook/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml @@ -5,9 +5,9 @@ Since FAN SDK depends on older versions of a few support and play service versions `com.applovin.mediation:facebook-adapter:x.y.z.a` resolves to `com.applovin.mediation:facebook-adapter:+` which pulls down the beta versions of FAN SDK. Note that forcing the adapter is enough to stop Jar Resolver from pulling the latest FAN SDK. --> - + - + diff --git a/Mediation/Facebook/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Facebook/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Facebook/Editor/Dependencies.xml.meta index 457996c..69b5d2c 100644 --- a/Mediation/Facebook/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6b42926a78dd2468db1fc059229e6fa2 +guid: aea9bdf974328420db5ae118ef0d2b87 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Facebook/Editor/Dependencies.xml diff --git a/Mediation/Fyber.meta b/MaxSdk/Mediation/Fyber.meta similarity index 83% rename from Mediation/Fyber.meta rename to MaxSdk/Mediation/Fyber.meta index e2489ac..eddbcb6 100644 --- a/Mediation/Fyber.meta +++ b/MaxSdk/Mediation/Fyber.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2ddb16b7ed77641b0b48e4dcb5eb9313 +guid: 6aac123ddaf4f490f95b78bf39ca18d1 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Fyber diff --git a/Mediation/Fyber/Editor.meta b/MaxSdk/Mediation/Fyber/Editor.meta similarity index 83% rename from Mediation/Fyber/Editor.meta rename to MaxSdk/Mediation/Fyber/Editor.meta index a1acfa3..315e8c8 100644 --- a/Mediation/Fyber/Editor.meta +++ b/MaxSdk/Mediation/Fyber/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d1f48f8173f79496ab742e75fc4cbc93 +guid: e076e4ef7e2874ba69b108cc7a346c2a labels: - al_max - al_max_export_path-MaxSdk/Mediation/Fyber/Editor diff --git a/Mediation/Fyber/Editor/Dependencies.xml b/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml similarity index 92% rename from Mediation/Fyber/Editor/Dependencies.xml rename to MaxSdk/Mediation/Fyber/Editor/Dependencies.xml index 4634674..9f5f74e 100644 --- a/Mediation/Fyber/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/Mediation/Fyber/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml.meta similarity index 83% rename from Mediation/Fyber/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Fyber/Editor/Dependencies.xml.meta index d377240..fd0bbbf 100644 --- a/Mediation/Fyber/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ab63c200561ab4506b77e71f6019ca9a +guid: 5e123cdc08e804dffb2c40c4fbc83caf labels: - al_max - al_max_export_path-MaxSdk/Mediation/Fyber/Editor/Dependencies.xml diff --git a/Mediation/Google.meta b/MaxSdk/Mediation/Google.meta similarity index 83% rename from Mediation/Google.meta rename to MaxSdk/Mediation/Google.meta index e448707..6d09844 100644 --- a/Mediation/Google.meta +++ b/MaxSdk/Mediation/Google.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4c314c382c139449288577824fed1f00 +guid: 5b3d3bc3aa8a546de8fdd5ded2b7e050 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Google diff --git a/Mediation/Google/Editor.meta b/MaxSdk/Mediation/Google/Editor.meta similarity index 83% rename from Mediation/Google/Editor.meta rename to MaxSdk/Mediation/Google/Editor.meta index 7135f87..ea8dd55 100644 --- a/Mediation/Google/Editor.meta +++ b/MaxSdk/Mediation/Google/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 81a5cd1881bd74bb18b6a4e152979ad9 +guid: e8015bd045cea462c8f39c8a05867d08 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Google/Editor diff --git a/Mediation/Google/Editor/Dependencies.xml b/MaxSdk/Mediation/Google/Editor/Dependencies.xml similarity index 92% rename from Mediation/Google/Editor/Dependencies.xml rename to MaxSdk/Mediation/Google/Editor/Dependencies.xml index e46e764..fa65a71 100644 --- a/Mediation/Google/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Google/Editor/Dependencies.xml @@ -2,9 +2,9 @@ - + - + diff --git a/Mediation/Google/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Google/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Google/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Google/Editor/Dependencies.xml.meta index 13d9fb6..36bef72 100644 --- a/Mediation/Google/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Google/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ac3c45d913a734c548c6a8a224624bc9 +guid: 053b810d3594744e38b6fd0fa378fb57 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Google/Editor/Dependencies.xml diff --git a/Mediation/GoogleAdManager.meta b/MaxSdk/Mediation/GoogleAdManager.meta similarity index 83% rename from Mediation/GoogleAdManager.meta rename to MaxSdk/Mediation/GoogleAdManager.meta index 41cf27a..522b98a 100644 --- a/Mediation/GoogleAdManager.meta +++ b/MaxSdk/Mediation/GoogleAdManager.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0f32d9bbb13cf4fca977f251fe8ae54e +guid: 468d376e1f39442e8a96601e563b7e2a labels: - al_max - al_max_export_path-MaxSdk/Mediation/GoogleAdManager diff --git a/Mediation/GoogleAdManager/Editor.meta b/MaxSdk/Mediation/GoogleAdManager/Editor.meta similarity index 84% rename from Mediation/GoogleAdManager/Editor.meta rename to MaxSdk/Mediation/GoogleAdManager/Editor.meta index 3c86239..7b0912c 100644 --- a/Mediation/GoogleAdManager/Editor.meta +++ b/MaxSdk/Mediation/GoogleAdManager/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 309e4978918794c339a5b06630ca4380 +guid: 3e1635bfb5b164c389d38eb1e5e6e909 labels: - al_max - al_max_export_path-MaxSdk/Mediation/GoogleAdManager/Editor diff --git a/Mediation/GoogleAdManager/Editor/Dependencies.xml b/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml similarity index 88% rename from Mediation/GoogleAdManager/Editor/Dependencies.xml rename to MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml index 189df74..4b09798 100644 --- a/Mediation/GoogleAdManager/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml @@ -2,9 +2,9 @@ - + - + diff --git a/Mediation/GoogleAdManager/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/GoogleAdManager/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml.meta index 33b6e61..71b0087 100644 --- a/Mediation/GoogleAdManager/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ec7fdc0ed9424436a9dc4b3ec60c4d45 +guid: aebbf5e9af66e431fa6078021b2f762f labels: - al_max - al_max_export_path-MaxSdk/Mediation/GoogleAdManager/Editor/Dependencies.xml diff --git a/Mediation/InMobi.meta b/MaxSdk/Mediation/InMobi.meta similarity index 83% rename from Mediation/InMobi.meta rename to MaxSdk/Mediation/InMobi.meta index d9c7c4f..b674c95 100644 --- a/Mediation/InMobi.meta +++ b/MaxSdk/Mediation/InMobi.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d1f591c6c71fe43c39ebd8362cdee42f +guid: 5b17efb66f23c412ca4516e426406bdc labels: - al_max - al_max_export_path-MaxSdk/Mediation/InMobi diff --git a/Mediation/InMobi/Editor.meta b/MaxSdk/Mediation/InMobi/Editor.meta similarity index 83% rename from Mediation/InMobi/Editor.meta rename to MaxSdk/Mediation/InMobi/Editor.meta index 342a48d..a998cfd 100644 --- a/Mediation/InMobi/Editor.meta +++ b/MaxSdk/Mediation/InMobi/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f0ca013590c6e4cada30f485e014d804 +guid: a141703acd55a48c2a3e6e6599f90c64 labels: - al_max - al_max_export_path-MaxSdk/Mediation/InMobi/Editor diff --git a/Mediation/InMobi/Editor/Dependencies.xml b/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml similarity index 94% rename from Mediation/InMobi/Editor/Dependencies.xml rename to MaxSdk/Mediation/InMobi/Editor/Dependencies.xml index a1ed4d1..e0cc0e3 100644 --- a/Mediation/InMobi/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml @@ -1,12 +1,12 @@ - + - + diff --git a/Mediation/InMobi/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/InMobi/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/InMobi/Editor/Dependencies.xml.meta index e473693..1b62e82 100644 --- a/Mediation/InMobi/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/InMobi/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fc006bb35419a4f759875a1db7b0c002 +guid: bc66a0ef4503843ee9b1bf1b1e867367 labels: - al_max - al_max_export_path-MaxSdk/Mediation/InMobi/Editor/Dependencies.xml diff --git a/Mediation/IronSource.meta b/MaxSdk/Mediation/IronSource.meta similarity index 83% rename from Mediation/IronSource.meta rename to MaxSdk/Mediation/IronSource.meta index 2a8455f..151cb4b 100644 --- a/Mediation/IronSource.meta +++ b/MaxSdk/Mediation/IronSource.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 29324d5f5bc2a4b25a629f8172371077 +guid: 7e5d22a01f68c4ee49f7ae312d187aa9 labels: - al_max - al_max_export_path-MaxSdk/Mediation/IronSource diff --git a/Mediation/IronSource/Editor.meta b/MaxSdk/Mediation/IronSource/Editor.meta similarity index 84% rename from Mediation/IronSource/Editor.meta rename to MaxSdk/Mediation/IronSource/Editor.meta index afadae6..327f5d6 100644 --- a/Mediation/IronSource/Editor.meta +++ b/MaxSdk/Mediation/IronSource/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bc7cc0a01f21649f5beb12578ad01088 +guid: 531d860cac61f47d19e32f526470ae43 labels: - al_max - al_max_export_path-MaxSdk/Mediation/IronSource/Editor diff --git a/Mediation/IronSource/Editor/Dependencies.xml b/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml similarity index 91% rename from Mediation/IronSource/Editor/Dependencies.xml rename to MaxSdk/Mediation/IronSource/Editor/Dependencies.xml index 80ca59a..099c417 100644 --- a/Mediation/IronSource/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml @@ -1,13 +1,13 @@ - + https://android-sdk.is.com/ - + diff --git a/Mediation/IronSource/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/IronSource/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/IronSource/Editor/Dependencies.xml.meta index 814c463..f77e6f0 100644 --- a/Mediation/IronSource/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3877ffad630d74094a5bc7f0ce771e9d +guid: 19262406303f04f05b14b31b3c734d35 labels: - al_max - al_max_export_path-MaxSdk/Mediation/IronSource/Editor/Dependencies.xml diff --git a/Mediation/MediationAdapters.txt b/MaxSdk/Mediation/MediationAdapters.txt similarity index 100% rename from Mediation/MediationAdapters.txt rename to MaxSdk/Mediation/MediationAdapters.txt diff --git a/Mediation/MediationAdapters.txt.meta b/MaxSdk/Mediation/MediationAdapters.txt.meta similarity index 75% rename from Mediation/MediationAdapters.txt.meta rename to MaxSdk/Mediation/MediationAdapters.txt.meta index 629fd0b..41fb994 100644 --- a/Mediation/MediationAdapters.txt.meta +++ b/MaxSdk/Mediation/MediationAdapters.txt.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9a04a93e5a00046f498986cbab8a41ce +guid: 9a8f83e97729443c86120be3bb24190d labels: - al_max - al_max_export_path-MaxSdk/Mediation/MediationAdapters.txt diff --git a/Mediation/Mintegral.meta b/MaxSdk/Mediation/Mintegral.meta similarity index 83% rename from Mediation/Mintegral.meta rename to MaxSdk/Mediation/Mintegral.meta index 8ddb06b..fd3d83c 100644 --- a/Mediation/Mintegral.meta +++ b/MaxSdk/Mediation/Mintegral.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6f2161264cc274e589af866b30e9c171 +guid: 3efc678797bb440b4b754a4593b4a7bc labels: - al_max - al_max_export_path-MaxSdk/Mediation/Mintegral diff --git a/Mediation/Mintegral/Editor.meta b/MaxSdk/Mediation/Mintegral/Editor.meta similarity index 84% rename from Mediation/Mintegral/Editor.meta rename to MaxSdk/Mediation/Mintegral/Editor.meta index 20640a0..d189ce0 100644 --- a/Mediation/Mintegral/Editor.meta +++ b/MaxSdk/Mediation/Mintegral/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 050a1eb04323a43ae89766193d45c211 +guid: db1de4066dc4e4290b3879b34fa87de2 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Mintegral/Editor diff --git a/Mediation/Mintegral/Editor/Dependencies.xml b/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml similarity index 93% rename from Mediation/Mintegral/Editor/Dependencies.xml rename to MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml index aab67f1..0d71bb6 100644 --- a/Mediation/Mintegral/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml @@ -1,7 +1,7 @@ - + https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea @@ -9,6 +9,6 @@ - + diff --git a/Mediation/Mintegral/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Mintegral/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml.meta index 55781cf..415c4ab 100644 --- a/Mediation/Mintegral/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 424c8ca120d1c445fa71535de1415d06 +guid: 221b2a20a58a04f2cb4afb0779587206 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml diff --git a/Mediation/MobileFuse.meta b/MaxSdk/Mediation/MobileFuse.meta similarity index 83% rename from Mediation/MobileFuse.meta rename to MaxSdk/Mediation/MobileFuse.meta index a653835..af0bbc6 100644 --- a/Mediation/MobileFuse.meta +++ b/MaxSdk/Mediation/MobileFuse.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cdd55135b2b1445ff98507c60a6e8fb3 +guid: 1f51aa0efd73a4c5dabd3bd20504fd98 labels: - al_max - al_max_export_path-MaxSdk/Mediation/MobileFuse diff --git a/Mediation/MobileFuse/Editor.meta b/MaxSdk/Mediation/MobileFuse/Editor.meta similarity index 84% rename from Mediation/MobileFuse/Editor.meta rename to MaxSdk/Mediation/MobileFuse/Editor.meta index 80d7226..d19defa 100644 --- a/Mediation/MobileFuse/Editor.meta +++ b/MaxSdk/Mediation/MobileFuse/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a428cd8127ca14c1eb4c36b44d66c00d +guid: 5b294b15bf20e4100bb8fd4f2865870a labels: - al_max - al_max_export_path-MaxSdk/Mediation/MobileFuse/Editor diff --git a/Mediation/MobileFuse/Editor/Dependencies.xml b/MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml similarity index 88% rename from Mediation/MobileFuse/Editor/Dependencies.xml rename to MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml index a7bffb7..d3e7ffa 100644 --- a/Mediation/MobileFuse/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/Mediation/MobileFuse/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/MobileFuse/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml.meta index 351ee30..0286953 100644 --- a/Mediation/MobileFuse/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4b1c644f7bf454f848c5d23b2f83f994 +guid: 4dd9dbd046b334929bcb7f80b7ae9eb4 labels: - al_max - al_max_export_path-MaxSdk/Mediation/MobileFuse/Editor/Dependencies.xml diff --git a/Mediation/OguryPresage.meta b/MaxSdk/Mediation/OguryPresage.meta similarity index 83% rename from Mediation/OguryPresage.meta rename to MaxSdk/Mediation/OguryPresage.meta index 5a49830..75709d7 100644 --- a/Mediation/OguryPresage.meta +++ b/MaxSdk/Mediation/OguryPresage.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1498439a98d054421a655f46c1b0a979 +guid: 09a110e66ea38428a8a388a48813529f labels: - al_max - al_max_export_path-MaxSdk/Mediation/OguryPresage diff --git a/Mediation/OguryPresage/Editor.meta b/MaxSdk/Mediation/OguryPresage/Editor.meta similarity index 84% rename from Mediation/OguryPresage/Editor.meta rename to MaxSdk/Mediation/OguryPresage/Editor.meta index 4de35f7..af2d23b 100644 --- a/Mediation/OguryPresage/Editor.meta +++ b/MaxSdk/Mediation/OguryPresage/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 89202f48ff6c24437ab9b72c14e6592c +guid: deb1bc473b7934f93b82938ea36d0878 labels: - al_max - al_max_export_path-MaxSdk/Mediation/OguryPresage/Editor diff --git a/Mediation/OguryPresage/Editor/Dependencies.xml b/MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml similarity index 91% rename from Mediation/OguryPresage/Editor/Dependencies.xml rename to MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml index 2d5d6e4..fe086c8 100644 --- a/Mediation/OguryPresage/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml @@ -1,13 +1,13 @@ - + https://maven.ogury.co - + diff --git a/Mediation/OguryPresage/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/OguryPresage/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml.meta index 636a78e..1b56b07 100644 --- a/Mediation/OguryPresage/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 44e217a01f9b04d3c9a17d8e95b9e2c8 +guid: 4733055cb7d01490e9c36862b7d10163 labels: - al_max - al_max_export_path-MaxSdk/Mediation/OguryPresage/Editor/Dependencies.xml diff --git a/Mediation/Smaato.meta b/MaxSdk/Mediation/Smaato.meta similarity index 83% rename from Mediation/Smaato.meta rename to MaxSdk/Mediation/Smaato.meta index 8d062a3..eed48d7 100644 --- a/Mediation/Smaato.meta +++ b/MaxSdk/Mediation/Smaato.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f03bf15dfdfd444a7a8ef23206461549 +guid: 6035ebab3b5094cc2851242130f8724b labels: - al_max - al_max_export_path-MaxSdk/Mediation/Smaato diff --git a/Mediation/Smaato/Editor.meta b/MaxSdk/Mediation/Smaato/Editor.meta similarity index 83% rename from Mediation/Smaato/Editor.meta rename to MaxSdk/Mediation/Smaato/Editor.meta index 1ede9d2..48d1804 100644 --- a/Mediation/Smaato/Editor.meta +++ b/MaxSdk/Mediation/Smaato/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 55478c656b4ea4a1b9fa81760007214c +guid: d6ab91d259c064997b6b26c1739ef87d labels: - al_max - al_max_export_path-MaxSdk/Mediation/Smaato/Editor diff --git a/Mediation/Smaato/Editor/Dependencies.xml b/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml similarity index 94% rename from Mediation/Smaato/Editor/Dependencies.xml rename to MaxSdk/Mediation/Smaato/Editor/Dependencies.xml index f748272..195176e 100644 --- a/Mediation/Smaato/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml @@ -1,13 +1,13 @@ - + https://s3.amazonaws.com/smaato-sdk-releases/ - + diff --git a/Mediation/Smaato/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Smaato/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Smaato/Editor/Dependencies.xml.meta index ef60ec1..c76c78b 100644 --- a/Mediation/Smaato/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b74b1ad0814994aef880c11dc374a1b3 +guid: f6c345cc57a514902ba5fb68436f852f labels: - al_max - al_max_export_path-MaxSdk/Mediation/Smaato/Editor/Dependencies.xml diff --git a/Mediation/UnityAds.meta b/MaxSdk/Mediation/UnityAds.meta similarity index 83% rename from Mediation/UnityAds.meta rename to MaxSdk/Mediation/UnityAds.meta index ffed24d..8c49e51 100644 --- a/Mediation/UnityAds.meta +++ b/MaxSdk/Mediation/UnityAds.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 34596ba2f74a64f4692da45ed21c7d2f +guid: 7fb60924642d44bed95c2cc730a87327 labels: - al_max - al_max_export_path-MaxSdk/Mediation/UnityAds diff --git a/Mediation/UnityAds/Editor.meta b/MaxSdk/Mediation/UnityAds/Editor.meta similarity index 83% rename from Mediation/UnityAds/Editor.meta rename to MaxSdk/Mediation/UnityAds/Editor.meta index dc727f1..b66e846 100644 --- a/Mediation/UnityAds/Editor.meta +++ b/MaxSdk/Mediation/UnityAds/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 66b580ac41d5c4e9f8b96348f42cdef6 +guid: 30751f2dc322a40e588edfb7c978c9c0 labels: - al_max - al_max_export_path-MaxSdk/Mediation/UnityAds/Editor diff --git a/Mediation/UnityAds/Editor/Dependencies.xml b/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml similarity index 89% rename from Mediation/UnityAds/Editor/Dependencies.xml rename to MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml index 2307475..80bd63e 100644 --- a/Mediation/UnityAds/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/Mediation/UnityAds/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/UnityAds/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml.meta index 8b61ec3..937df6e 100644 --- a/Mediation/UnityAds/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d5d70db07cd3d4c90866131f5ff2ec5e +guid: 9950f1cb0da1e43efbeca604db142076 labels: - al_max - al_max_export_path-MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml diff --git a/Mediation/Verve.meta b/MaxSdk/Mediation/Verve.meta similarity index 83% rename from Mediation/Verve.meta rename to MaxSdk/Mediation/Verve.meta index 8d4004b..f249843 100644 --- a/Mediation/Verve.meta +++ b/MaxSdk/Mediation/Verve.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 465b78190ecd34d2ebb66bbdb663b8f7 +guid: a988eefd0908441f799ba02f389b0164 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Verve diff --git a/Mediation/Verve/Editor.meta b/MaxSdk/Mediation/Verve/Editor.meta similarity index 83% rename from Mediation/Verve/Editor.meta rename to MaxSdk/Mediation/Verve/Editor.meta index ac65b44..9ddb48f 100644 --- a/Mediation/Verve/Editor.meta +++ b/MaxSdk/Mediation/Verve/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1c0f8f4536e924c7daeb4e07b8a89fbd +guid: 942a73b8f38284e55849bd9986aefee8 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Verve/Editor diff --git a/Mediation/Verve/Editor/Dependencies.xml b/MaxSdk/Mediation/Verve/Editor/Dependencies.xml similarity index 79% rename from Mediation/Verve/Editor/Dependencies.xml rename to MaxSdk/Mediation/Verve/Editor/Dependencies.xml index bd63e62..af063bc 100644 --- a/Mediation/Verve/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Verve/Editor/Dependencies.xml @@ -1,12 +1,12 @@ - + https://verve.jfrog.io/artifactory/verve-gradle-release - + diff --git a/Mediation/Verve/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Verve/Editor/Dependencies.xml.meta similarity index 83% rename from Mediation/Verve/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Verve/Editor/Dependencies.xml.meta index fdab316..7edac19 100644 --- a/Mediation/Verve/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Verve/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ecb5509aa8c6f4e1781b9658779c7f70 +guid: bce11a786f6b54963a8085520a643ce8 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Verve/Editor/Dependencies.xml diff --git a/Mediation/Vungle.meta b/MaxSdk/Mediation/Vungle.meta similarity index 83% rename from Mediation/Vungle.meta rename to MaxSdk/Mediation/Vungle.meta index eb5cffa..7214e2e 100644 --- a/Mediation/Vungle.meta +++ b/MaxSdk/Mediation/Vungle.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 08ce07f8736a1441499e151152b0a8c8 +guid: e5a58f58ec6b64f2d8c8061c4051244c labels: - al_max - al_max_export_path-MaxSdk/Mediation/Vungle diff --git a/Mediation/Vungle/Editor.meta b/MaxSdk/Mediation/Vungle/Editor.meta similarity index 83% rename from Mediation/Vungle/Editor.meta rename to MaxSdk/Mediation/Vungle/Editor.meta index 2614207..1ea75cc 100644 --- a/Mediation/Vungle/Editor.meta +++ b/MaxSdk/Mediation/Vungle/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 415ba661fb43149518f25c225fc5486a +guid: 77b6ea05736a9458f8ef8762ee9b64bb labels: - al_max - al_max_export_path-MaxSdk/Mediation/Vungle/Editor diff --git a/Mediation/Vungle/Editor/Dependencies.xml b/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml similarity index 90% rename from Mediation/Vungle/Editor/Dependencies.xml rename to MaxSdk/Mediation/Vungle/Editor/Dependencies.xml index 6cf8c87..1823def 100644 --- a/Mediation/Vungle/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/Mediation/Vungle/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Vungle/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Vungle/Editor/Dependencies.xml.meta index 79d2da0..7038186 100644 --- a/Mediation/Vungle/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Vungle/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d8eb42a2c132f43e59186bc28da6006e +guid: 0d8ad3a6ddc4f44fab2efe607fe14f26 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Vungle/Editor/Dependencies.xml diff --git a/Mediation/Yandex.meta b/MaxSdk/Mediation/Yandex.meta similarity index 83% rename from Mediation/Yandex.meta rename to MaxSdk/Mediation/Yandex.meta index d280060..bc0cabf 100644 --- a/Mediation/Yandex.meta +++ b/MaxSdk/Mediation/Yandex.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 927af5b2250834fd5be82687e53be6ba +guid: 5d02f768bae96461c9a46ed20e652f8d labels: - al_max - al_max_export_path-MaxSdk/Mediation/Yandex diff --git a/Mediation/Yandex/Editor.meta b/MaxSdk/Mediation/Yandex/Editor.meta similarity index 83% rename from Mediation/Yandex/Editor.meta rename to MaxSdk/Mediation/Yandex/Editor.meta index 02d78cd..96a880c 100644 --- a/Mediation/Yandex/Editor.meta +++ b/MaxSdk/Mediation/Yandex/Editor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 57d88d0ec30464840aa603ef3533b7f6 +guid: 277e2383262e844708fc74a6104f4985 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Yandex/Editor diff --git a/Mediation/Yandex/Editor/Dependencies.xml b/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml similarity index 69% rename from Mediation/Yandex/Editor/Dependencies.xml rename to MaxSdk/Mediation/Yandex/Editor/Dependencies.xml index ac5cd5a..10c0495 100644 --- a/Mediation/Yandex/Editor/Dependencies.xml +++ b/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml @@ -1,9 +1,9 @@ - + - + diff --git a/Mediation/Yandex/Editor/Dependencies.xml.meta b/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml.meta similarity index 84% rename from Mediation/Yandex/Editor/Dependencies.xml.meta rename to MaxSdk/Mediation/Yandex/Editor/Dependencies.xml.meta index faadb36..495dede 100644 --- a/Mediation/Yandex/Editor/Dependencies.xml.meta +++ b/MaxSdk/Mediation/Yandex/Editor/Dependencies.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: eac827b694b384eedb459cbb1637e3f1 +guid: a77aaf886990c4e6ba469a4f083b9284 labels: - al_max - al_max_export_path-MaxSdk/Mediation/Yandex/Editor/Dependencies.xml diff --git a/MaxSdk/Mediation b/MaxSdk/Mediation~HEAD similarity index 100% rename from MaxSdk/Mediation rename to MaxSdk/Mediation~HEAD diff --git a/MaxSdk/Scripts/Editor.meta b/MaxSdk/Scripts/Editor.meta deleted file mode 100644 index 7adfefb..0000000 --- a/MaxSdk/Scripts/Editor.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b6903b66cb8984df289e6d66f9c52ddc -labels: -- al_max -- al_max_export_path-MaxSdk/Scripts/Editor -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs.meta b/MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs.meta deleted file mode 100644 index 07e4133..0000000 --- a/MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs.meta +++ /dev/null @@ -1,14 +0,0 @@ -fileFormatVersion: 2 -guid: 75fed160a41749d4990cee871ee618a4 -labels: -- al_max -- al_max_export_path-MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs b/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs deleted file mode 100644 index 816c336..0000000 --- a/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs +++ /dev/null @@ -1,590 +0,0 @@ -// -// MaxPostProcessBuildiOS.cs -// AppLovin MAX Unity Plugin -// -// Created by Santosh Bagadi on 8/5/20. -// Copyright © 2020 AppLovin. All rights reserved. -// - -#if UNITY_IOS || UNITY_IPHONE - -using AppLovinMax.Scripts.IntegrationManager.Editor; -#if UNITY_2019_3_OR_NEWER -using UnityEditor.iOS.Xcode.Extensions; -#endif -using UnityEngine.Networking; -using System; -using System.Linq; -using System.Collections.Generic; -using System.IO; -using UnityEditor; -using UnityEditor.Callbacks; -using UnityEditor.iOS.Xcode; -using UnityEngine; - -namespace AppLovinMax.Scripts.Editor -{ - [Serializable] - public class SkAdNetworkData - { - [SerializeField] public string[] SkAdNetworkIds; - } - - public class MaxPostProcessBuildiOS - { -#if !UNITY_2019_3_OR_NEWER - private const string UnityMainTargetName = "Unity-iPhone"; -#endif - private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do"; - private const string LegacyResourcesDirectoryName = "Resources"; - private const string AppLovinMaxResourcesDirectoryName = "AppLovinMAXResources"; - private const string AppLovinAdvertisingAttributionEndpoint = "https://postbacks-app.com"; - - private const string AppLovinSettingsPlistFileName = "AppLovin-Settings.plist"; - private const string KeyConsentFlowInfo = "ConsentFlowInfo"; - private const string KeyConsentFlowEnabled = "ConsentFlowEnabled"; - private const string KeyConsentFlowTermsOfService = "ConsentFlowTermsOfService"; - private const string KeyConsentFlowPrivacyPolicy = "ConsentFlowPrivacyPolicy"; - private const string KeyConsentFlowDebugUserGeography = "ConsentFlowDebugUserGeography"; - - private static readonly List DynamicLibrariesToEmbed = new List - { - "DTBiOSSDK.xcframework", - "FBAEMKit.xcframework", - "FBSDKCoreKit_Basics.xcframework", - "FBSDKCoreKit.xcframework", - "FBSDKGamingServicesKit.xcframework", - "FBSDKLoginKit.xcframework", - "FBSDKShareKit.xcframework", - "HyprMX.xcframework", - "LinkedinAudienceNetwork.xcframework", - "IASDKCore.xcframework", - "Maio.xcframework", - "MobileFuseSDK.xcframework", - "OMSDK_Appodeal.xcframework", - "OMSDK_Ogury.xcframework", - "OMSDK_Pubnativenet.xcframework", - "OMSDK_Smaato.xcframework" - }; - - private static string PluginMediationDirectory - { - get - { - var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory; - return Path.Combine(pluginParentDir, "MaxSdk/Mediation/"); - } - } - - [PostProcessBuildAttribute(int.MaxValue)] - public static void MaxPostProcessPbxProject(BuildTarget buildTarget, string buildPath) - { - var projectPath = PBXProject.GetPBXProjectPath(buildPath); - var project = new PBXProject(); - project.ReadFromFile(projectPath); - -#if UNITY_2019_3_OR_NEWER - var unityMainTargetGuid = project.GetUnityMainTargetGuid(); - var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid(); -#else - var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName); - var unityFrameworkTargetGuid = project.TargetGuidByName(UnityMainTargetName); -#endif - EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid); - - var internalSettingsEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled; - var userTrackingUsageDescriptionDe = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionDe : AppLovinSettings.Instance.UserTrackingUsageDescriptionDe; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionDe, "de", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionEn = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn : AppLovinSettings.Instance.UserTrackingUsageDescriptionEn; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEn, "en", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionEs = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEs : AppLovinSettings.Instance.UserTrackingUsageDescriptionEs; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEs, "es", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionFr = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionFr : AppLovinSettings.Instance.UserTrackingUsageDescriptionFr; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionFr, "fr", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionJa = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionJa : AppLovinSettings.Instance.UserTrackingUsageDescriptionJa; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionJa, "ja", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionKo = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionKo : AppLovinSettings.Instance.UserTrackingUsageDescriptionKo; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionKo, "ko", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionZhHans = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHans : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHans; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHans, "zh-Hans", buildPath, project, unityMainTargetGuid); - var userTrackingUsageDescriptionZhHant = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHant : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHant; - LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHant, "zh-Hant", buildPath, project, unityMainTargetGuid); - - AddSwiftSupport(buildPath, project, unityFrameworkTargetGuid, unityMainTargetGuid); - AddYandexSettingsIfNeeded(project, unityMainTargetGuid); - - project.WriteToFile(projectPath); - } - - private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid) - { - // Check that the Pods directory exists (it might not if a publisher is building with Generate Podfile setting disabled in EDM). - var podsDirectory = Path.Combine(buildPath, "Pods"); - if (!Directory.Exists(podsDirectory)) return; - - var dynamicLibraryPathsPresentInProject = new List(); - foreach (var dynamicLibraryToSearch in DynamicLibrariesToEmbed) - { - // both .framework and .xcframework are directories, not files - var directories = Directory.GetDirectories(podsDirectory, dynamicLibraryToSearch, SearchOption.AllDirectories); - if (directories.Length <= 0) continue; - - var dynamicLibraryAbsolutePath = directories[0]; - var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods"); - var relativePath = dynamicLibraryAbsolutePath.Substring(index); - dynamicLibraryPathsPresentInProject.Add(relativePath); - } - - if (dynamicLibraryPathsPresentInProject.Count <= 0) return; - -#if UNITY_2019_3_OR_NEWER - // Embed framework only if the podfile does not contain target `Unity-iPhone`. - if (!ContainsUnityIphoneTargetInPodfile(buildPath)) - { - foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject) - { - var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); - project.AddFileToEmbedFrameworks(targetGuid, fileGuid); - } - } -#else - string runpathSearchPaths; - runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); - runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; - - // Check if runtime search paths already contains the required search paths for dynamic libraries. - if (runpathSearchPaths.Contains("@executable_path/Frameworks")) return; - - runpathSearchPaths += "@executable_path/Frameworks"; - project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); -#endif - } - - private static void LocalizeUserTrackingDescriptionIfNeeded(string localizedUserTrackingDescription, string localeCode, string buildPath, PBXProject project, string targetGuid) - { - // Use the legacy resources directory name if the build is being appended (the "Resources" directory already exists if it is an incremental build). - var resourcesDirectoryName = Directory.Exists(Path.Combine(buildPath, LegacyResourcesDirectoryName)) ? LegacyResourcesDirectoryName : AppLovinMaxResourcesDirectoryName; - var resourcesDirectoryPath = Path.Combine(buildPath, resourcesDirectoryName); - var localeSpecificDirectoryName = localeCode + ".lproj"; - var localeSpecificDirectoryPath = Path.Combine(resourcesDirectoryPath, localeSpecificDirectoryName); - var infoPlistStringsFilePath = Path.Combine(localeSpecificDirectoryPath, "InfoPlist.strings"); - - // Check if localization has been disabled between builds, and remove them as needed. - if (ShouldRemoveLocalization(localizedUserTrackingDescription)) - { - if (!File.Exists(infoPlistStringsFilePath)) return; - - File.Delete(infoPlistStringsFilePath); - return; - } - - // Create intermediate directories as needed. - if (!Directory.Exists(resourcesDirectoryPath)) - { - Directory.CreateDirectory(resourcesDirectoryPath); - } - - if (!Directory.Exists(localeSpecificDirectoryPath)) - { - Directory.CreateDirectory(localeSpecificDirectoryPath); - } - - var localizedDescriptionLine = "\"NSUserTrackingUsageDescription\" = \"" + localizedUserTrackingDescription + "\";\n"; - // File already exists, update it in case the value changed between builds. - if (File.Exists(infoPlistStringsFilePath)) - { - var output = new List(); - var lines = File.ReadAllLines(infoPlistStringsFilePath); - var keyUpdated = false; - foreach (var line in lines) - { - if (line.Contains("NSUserTrackingUsageDescription")) - { - output.Add(localizedDescriptionLine); - keyUpdated = true; - } - else - { - output.Add(line); - } - } - - if (!keyUpdated) - { - output.Add(localizedDescriptionLine); - } - - File.WriteAllText(infoPlistStringsFilePath, string.Join("\n", output.ToArray()) + "\n"); - } - // File doesn't exist, create one. - else - { - File.WriteAllText(infoPlistStringsFilePath, "/* Localized versions of Info.plist keys - Generated by AL MAX plugin */\n" + localizedDescriptionLine); - } - - var localeSpecificDirectoryRelativePath = Path.Combine(resourcesDirectoryName, localeSpecificDirectoryName); - var guid = project.AddFolderReference(localeSpecificDirectoryRelativePath, localeSpecificDirectoryRelativePath); - project.AddFileToBuild(targetGuid, guid); - } - - private static bool ShouldRemoveLocalization(string localizedUserTrackingDescription) - { - if (string.IsNullOrEmpty(localizedUserTrackingDescription)) return true; - - var settings = AppLovinSettings.Instance; - var internalSettings = AppLovinInternalSettings.Instance; - - return (!internalSettings.ConsentFlowEnabled || !internalSettings.UserTrackingUsageLocalizationEnabled) - && !settings.ConsentFlowEnabled || !settings.UserTrackingUsageLocalizationEnabled; - } - - private static void AddSwiftSupport(string buildPath, PBXProject project, string unityFrameworkTargetGuid, string unityMainTargetGuid) - { - var swiftFileRelativePath = "Classes/MAXSwiftSupport.swift"; - var swiftFilePath = Path.Combine(buildPath, swiftFileRelativePath); - - // Add Swift file - CreateSwiftFile(swiftFilePath); - var swiftFileGuid = project.AddFile(swiftFileRelativePath, swiftFileRelativePath, PBXSourceTree.Source); - project.AddFileToBuild(unityFrameworkTargetGuid, swiftFileGuid); - - // Add Swift version property if needed - var swiftVersion = project.GetBuildPropertyForAnyConfig(unityFrameworkTargetGuid, "SWIFT_VERSION"); - if (string.IsNullOrEmpty(swiftVersion)) - { - project.SetBuildProperty(unityFrameworkTargetGuid, "SWIFT_VERSION", "5.0"); - } - - // Enable Swift modules - project.AddBuildProperty(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES", "YES"); - project.AddBuildProperty(unityMainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES"); - } - - private static void CreateSwiftFile(string swiftFilePath) - { - if (File.Exists(swiftFilePath)) return; - - // Create a file to write to. - using (var writer = File.CreateText(swiftFilePath)) - { - writer.WriteLine("//\n// MAXSwiftSupport.swift\n//"); - writer.WriteLine("\nimport Foundation\n"); - writer.WriteLine("// This file ensures the project includes Swift support."); - writer.WriteLine("// It is automatically generated by the MAX Unity Plugin."); - writer.Close(); - } - } - - [PostProcessBuildAttribute(int.MaxValue)] - public static void MaxPostProcessPlist(BuildTarget buildTarget, string path) - { - var plistPath = Path.Combine(path, "Info.plist"); - var plist = new PlistDocument(); - plist.ReadFromFile(plistPath); - - SetSdkKeyIfNeeded(plist); - SetAttributionReportEndpointIfNeeded(plist); - - EnableVerboseLoggingIfNeeded(plist); - AddGoogleApplicationIdIfNeeded(plist); - - AddSdkSettingsIfNeeded(plist, path); - EnableTermsFlowIfNeeded(plist); - AddSkAdNetworksInfoIfNeeded(plist); - - plist.WriteToFile(plistPath); - } - - private static void SetSdkKeyIfNeeded(PlistDocument plist) - { - var sdkKey = AppLovinSettings.Instance.SdkKey; - if (string.IsNullOrEmpty(sdkKey)) return; - - const string AppLovinVerboseLoggingOnKey = "AppLovinSdkKey"; - plist.root.SetString(AppLovinVerboseLoggingOnKey, sdkKey); - } - - private static void SetAttributionReportEndpointIfNeeded(PlistDocument plist) - { - if (AppLovinSettings.Instance.SetAttributionReportEndpoint) - { - plist.root.SetString("NSAdvertisingAttributionReportEndpoint", AppLovinAdvertisingAttributionEndpoint); - } - else - { - PlistElement attributionReportEndPoint; - plist.root.values.TryGetValue("NSAdvertisingAttributionReportEndpoint", out attributionReportEndPoint); - - // Check if we had previously set the attribution endpoint and un-set it. - if (attributionReportEndPoint != null && AppLovinAdvertisingAttributionEndpoint.Equals(attributionReportEndPoint.AsString())) - { - plist.root.values.Remove("NSAdvertisingAttributionReportEndpoint"); - } - } - } - - private static void EnableVerboseLoggingIfNeeded(PlistDocument plist) - { - if (!EditorPrefs.HasKey(MaxSdkLogger.KeyVerboseLoggingEnabled)) return; - - var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled); - const string AppLovinVerboseLoggingOnKey = "AppLovinVerboseLoggingOn"; - if (enabled) - { - plist.root.SetBoolean(AppLovinVerboseLoggingOnKey, enabled); - } - else - { - plist.root.values.Remove(AppLovinVerboseLoggingOnKey); - } - } - - private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist) - { - if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return; - - const string googleApplicationIdentifier = "GADApplicationIdentifier"; - var appId = AppLovinSettings.Instance.AdMobIosAppId; - // Log error if the App ID is not set. - if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-")) - { - Debug.LogError("[AppLovin MAX] Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window."); - return; - } - - plist.root.SetString(googleApplicationIdentifier, appId); - } - - private static void AddYandexSettingsIfNeeded(PBXProject project, string unityMainTargetGuid) - { - if (!AppLovinIntegrationManager.IsAdapterInstalled("Yandex")) return; - - if (MaxSdkUtils.CompareVersions(PlayerSettings.iOS.targetOSVersionString, "12.0") == MaxSdkUtils.VersionComparisonResult.Lesser) - { - Debug.LogWarning("Your iOS target version is under the minimum required version by Yandex. Please update it to 12.0 or newer in your ProjectSettings and rebuild your project."); - return; - } - - project.SetBuildProperty(unityMainTargetGuid, "GENERATE_INFOPLIST_FILE", "NO"); - } - - private static void AddSdkSettingsIfNeeded(PlistDocument infoPlist, string buildPath) - { - // Right now internal settings is only needed for Consent Flow. Remove this setting once we add more settings. - if (!AppLovinInternalSettings.Instance.ConsentFlowEnabled) return; - - var sdkSettingsPlistPath = Path.Combine(buildPath, AppLovinSettingsPlistFileName); - var sdkSettingsPlist = new PlistDocument(); - if (File.Exists(sdkSettingsPlistPath)) - { - sdkSettingsPlist.ReadFromFile(sdkSettingsPlistPath); - } - - EnableConsentFlowIfNeeded(sdkSettingsPlist, infoPlist); - - sdkSettingsPlist.WriteToFile(sdkSettingsPlistPath); - - var projectPath = PBXProject.GetPBXProjectPath(buildPath); - var project = new PBXProject(); - project.ReadFromFile(projectPath); - -#if UNITY_2019_3_OR_NEWER - var unityMainTargetGuid = project.GetUnityMainTargetGuid(); -#else - var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName); -#endif - - var guid = project.AddFile(AppLovinSettingsPlistFileName, AppLovinSettingsPlistFileName, PBXSourceTree.Source); - project.AddFileToBuild(unityMainTargetGuid, guid); - project.WriteToFile(projectPath); - } - - private static void EnableConsentFlowIfNeeded(PlistDocument applovinSettingsPlist, PlistDocument infoPlist) - { - var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled; - var userTrackingUsageDescription = AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn; - var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl; - if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl)) - { - AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" + - "Both values must be included to enable the SDK's consent flow."); - - // No need to update the info.plist here. Default consent flow state will be determined on the SDK side. - return; - } - - var consentFlowInfoRoot = applovinSettingsPlist.root.CreateDict(KeyConsentFlowInfo); - consentFlowInfoRoot.SetBoolean(KeyConsentFlowEnabled, consentFlowEnabled); - consentFlowInfoRoot.SetString(KeyConsentFlowPrivacyPolicy, privacyPolicyUrl); - - var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl; - if (MaxSdkUtils.IsValidString(termsOfServiceUrl)) - { - consentFlowInfoRoot.SetString(KeyConsentFlowTermsOfService, termsOfServiceUrl); - } - - var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography; - if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr) - { - consentFlowInfoRoot.SetString(KeyConsentFlowDebugUserGeography, "gdpr"); - } - - infoPlist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription); - } - - private static void EnableTermsFlowIfNeeded(PlistDocument plist) - { - // Check if terms flow is enabled. No need to update info.plist if consent flow is disabled. - var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled; - if (!consentFlowEnabled) return; - - // Check if terms flow is enabled for this format. - var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform; - if (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.iOS) return; - - var userTrackingUsageDescription = AppLovinSettings.Instance.UserTrackingUsageDescriptionEn; - var privacyPolicyUrl = AppLovinSettings.Instance.ConsentFlowPrivacyPolicyUrl; - if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl)) - { - AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" + - "Both values must be included to enable the SDK's consent flow."); - - // No need to update the info.plist here. Default consent flow state will be determined on the SDK side. - return; - } - - var consentFlowInfoRoot = plist.root.CreateDict("AppLovinConsentFlowInfo"); - consentFlowInfoRoot.SetBoolean("AppLovinConsentFlowEnabled", consentFlowEnabled); - consentFlowInfoRoot.SetString("AppLovinConsentFlowPrivacyPolicy", privacyPolicyUrl); - - var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl; - if (!string.IsNullOrEmpty(termsOfServiceUrl)) - { - consentFlowInfoRoot.SetString("AppLovinConsentFlowTermsOfService", termsOfServiceUrl); - } - - plist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription); - } - - private static void AddSkAdNetworksInfoIfNeeded(PlistDocument plist) - { - var skAdNetworkData = GetSkAdNetworkData(); - var skAdNetworkIds = skAdNetworkData.SkAdNetworkIds; - // Check if we have a valid list of SKAdNetworkIds that need to be added. - if (skAdNetworkIds == null || skAdNetworkIds.Length < 1) return; - - // - // Add the SKAdNetworkItems to the plist. It should look like following: - // - // SKAdNetworkItems - // - // - // SKAdNetworkIdentifier - // ABC123XYZ.skadnetwork - // - // - // SKAdNetworkIdentifier - // 123QWE456.skadnetwork - // - // - // SKAdNetworkIdentifier - // 987XYZ123.skadnetwork - // - // - // - PlistElement skAdNetworkItems; - plist.root.values.TryGetValue("SKAdNetworkItems", out skAdNetworkItems); - var existingSkAdNetworkIds = new HashSet(); - // Check if SKAdNetworkItems array is already in the Plist document and collect all the IDs that are already present. - if (skAdNetworkItems != null && skAdNetworkItems.GetType() == typeof(PlistElementArray)) - { - var plistElementDictionaries = skAdNetworkItems.AsArray().values.Where(plistElement => plistElement.GetType() == typeof(PlistElementDict)); - foreach (var plistElement in plistElementDictionaries) - { - PlistElement existingId; - plistElement.AsDict().values.TryGetValue("SKAdNetworkIdentifier", out existingId); - if (existingId == null || existingId.GetType() != typeof(PlistElementString) || string.IsNullOrEmpty(existingId.AsString())) continue; - - existingSkAdNetworkIds.Add(existingId.AsString()); - } - } - // Else, create an array of SKAdNetworkItems into which we will add our IDs. - else - { - skAdNetworkItems = plist.root.CreateArray("SKAdNetworkItems"); - } - - foreach (var skAdNetworkId in skAdNetworkIds) - { - // Skip adding IDs that are already in the array. - if (existingSkAdNetworkIds.Contains(skAdNetworkId)) continue; - - var skAdNetworkItemDict = skAdNetworkItems.AsArray().AddDict(); - skAdNetworkItemDict.SetString("SKAdNetworkIdentifier", skAdNetworkId); - } - } - - private static SkAdNetworkData GetSkAdNetworkData() - { - var uriBuilder = new UriBuilder("https://unity.applovin.com/max/1.0/skadnetwork_ids"); - - // Get the list of installed ad networks to be passed up - var maxMediationDirectory = PluginMediationDirectory; - if (Directory.Exists(maxMediationDirectory)) - { - var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory); - var installedNetworks = mediationNetworkDirectories.Select(Path.GetFileName).ToList(); - if (AppLovinSettings.Instance.AddApsSkAdNetworkIds) - { - installedNetworks.Add("AmazonPublisherServices"); - } - - var adNetworks = string.Join(",", installedNetworks.ToArray()); - if (!string.IsNullOrEmpty(adNetworks)) - { - uriBuilder.Query += string.Format("ad_networks={0}", adNetworks); - } - } - - using (var unityWebRequest = UnityWebRequest.Get(uriBuilder.ToString())) - { - var operation = unityWebRequest.SendWebRequest(); - // Wait for the download to complete or the request to timeout. - while (!operation.isDone) { } - -#if UNITY_2020_1_OR_NEWER - if (unityWebRequest.result != UnityWebRequest.Result.Success) -#else - if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError) -#endif - { - MaxSdkLogger.UserError("Failed to retrieve SKAdNetwork IDs with error: " + unityWebRequest.error); - return new SkAdNetworkData(); - } - - try - { - return JsonUtility.FromJson(unityWebRequest.downloadHandler.text); - } - catch (Exception exception) - { - MaxSdkLogger.UserError("Failed to parse data '" + unityWebRequest.downloadHandler.text + "' with exception: " + exception); - return new SkAdNetworkData(); - } - } - } - -#if UNITY_2019_3_OR_NEWER - private static bool ContainsUnityIphoneTargetInPodfile(string buildPath) - { - var podfilePath = Path.Combine(buildPath, "Podfile"); - if (!File.Exists(podfilePath)) return false; - - var lines = File.ReadAllLines(podfilePath); - return lines.Any(line => line.Contains(TargetUnityIphonePodfileLine)); - } -#endif - } -} - -#endif diff --git a/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs.meta b/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs.meta deleted file mode 100644 index 78d2f6d..0000000 --- a/MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs.meta +++ /dev/null @@ -1,14 +0,0 @@ -fileFormatVersion: 2 -guid: 29959b3cd36c484a9d57d6b7ca7f7bfa -labels: -- al_max -- al_max_export_path-MaxSdk/Scripts/Editor/MaxPostProcessBuildiOS.cs -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef b/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef deleted file mode 100644 index e4bb2e0..0000000 --- a/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "MaxSdk.Scripts.Editor", - "references": [ - "MaxSdk.Scripts", - "MaxSdk.Scripts.IntegrationManager.Editor" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [] -} diff --git a/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef.meta b/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef.meta deleted file mode 100644 index b13c71a..0000000 --- a/MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef.meta +++ /dev/null @@ -1,6 +0,0 @@ -fileFormatVersion: 2 -guid: 691e0eb4b7a542dba2219d48c3254f1c -labels: -- al_max -- al_max_export_path-MaxSdk/Scripts/Editor/MaxSdk.Scripts.Editor.asmdef -timeCreated: 1591749791 diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs index 2b3e87b..c1e8ed3 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs @@ -26,7 +26,6 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor // TODO: Make this list dynamic. public static readonly Dictionary MinAdapterVersions = new Dictionary() { - {"ADCOLONY_NETWORK", "android_4.2.3.1_ios_4.3.1.1"}, {"ADMOB_NETWORK", "android_19.3.0.3_ios_7.65.0.0"}, {"CHARTBOOST_NETWORK", "android_8.1.0.7_ios_8.2.1.3"}, {"FACEBOOK_MEDIATE", "android_6.0.0.1_ios_6.0.0.3"}, @@ -38,7 +37,6 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor {"SMAATO_NETWORK", "android_21.5.2.5_ios_21.5.2.3"}, {"TIKTOK_NETWORK", "android_3.1.0.1.6_ios_3.2.5.1.1"}, {"UNITY_NETWORK", "android_3.4.8.2_ios_3.4.8.2"}, - {"VERIZON_NETWORK", "android_1.6.0.5_ios_1.7.1.1"}, {"VUNGLE_NETWORK", "android_6.7.1.2_ios_6.7.1.3"}, {"YANDEX_NETWORK", "android_2.170.2_ios_2.18.0.1"} }; diff --git a/MaxSdk/Scripts/Editor/MaxInitialization.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInitialize.cs similarity index 93% rename from MaxSdk/Scripts/Editor/MaxInitialization.cs rename to MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInitialize.cs index a1dc1df..4f61d97 100644 --- a/MaxSdk/Scripts/Editor/MaxInitialization.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInitialize.cs @@ -12,13 +12,16 @@ using System.IO; using System.Linq; using UnityEditor; -namespace AppLovinMax.Scripts.Editor +namespace AppLovinMax.Scripts.IntegrationManager.Editor { [InitializeOnLoad] - public class MaxInitialize + public class AppLovinInitialize { private static readonly List ObsoleteNetworks = new List { + "AdColony", + "Criteo", + "Nend", "Snap", "Tapjoy", "VerizonAds", @@ -27,6 +30,10 @@ namespace AppLovinMax.Scripts.Editor private static readonly List ObsoleteFileExportPathsToDelete = new List { + // The `MaxSdk/Scripts/Editor` folder contents have been moved into `MaxSdk/Scripts/IntegrationManager/Editor`. + "MaxSdk/Scripts/Editor", + "MaxSdk/Scripts/Editor.meta", + // The `EventSystemChecker` has been renamed to `MaxEventSystemChecker`. "MaxSdk/Scripts/EventSystemChecker.cs", "MaxSdk/Scripts/EventSystemChecker.cs.meta", @@ -54,7 +61,7 @@ namespace AppLovinMax.Scripts.Editor "MaxSdk/Mediation/GoogleAdManager/Editor/MaxSdk.Mediation.GoogleAdManager.Editor.asmdef.meta", "Plugins/Android/MaxMediationGoogleAdManager.androidlib", "Plugins/Android/MaxMediationGoogleAdManager.androidlib.meta", - + // The `VariableService` has been removed. "MaxSdk/Scripts/MaxVariableServiceAndroid.cs", "MaxSdk/Scripts/MaxVariableServiceAndroid.cs.meta", @@ -64,7 +71,7 @@ namespace AppLovinMax.Scripts.Editor "MaxSdk/Scripts/MaxVariableServiceUnityEditor.cs.meta" }; - static MaxInitialize() + static AppLovinInitialize() { #if UNITY_IOS // Check that the publisher is targeting iOS 9.0+ diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs index 3b1b9d9..1536e66 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs @@ -467,19 +467,37 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor /// Checks whether or not an adapter with the given version or newer exists. /// /// The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder. - /// The min adapter version to check for. Can be null if we want to check for any version. + /// The min adapter version to check for. Can be null if we want to check for any version. /// true if an adapter with the min version is installed. - public static bool IsAdapterInstalled(string adapterName, string version = null) + public static bool IsAdapterInstalled(string adapterName, string iosVersion = null) // TODO: Add Android version check. { var dependencyFilePath = MaxSdkUtils.GetAssetPathForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml"); if (!File.Exists(dependencyFilePath)) return false; // If version is null, we just need the adapter installed. We don't have to check for a specific version. - if (version == null) return true; + if (iosVersion == null) return true; - var currentVersion = AppLovinIntegrationManager.GetCurrentVersions(dependencyFilePath); - var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, version); - return iosVersionComparison != MaxSdkUtils.VersionComparisonResult.Lesser; + var currentVersion = GetCurrentVersions(dependencyFilePath); + var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion); + return iosVersionComparison != VersionComparisonResult.Lesser; + } + + /// + /// Checks whether or not an adapter older than the given version exists. + /// + /// TODO: Consolidate this method with and return a state enum. + /// + /// The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder. + /// The adapter version to check for. + /// true if an adapter older than the provided version is installed. + public static bool IsAdapterOlderThanMinVersionInstalled(string adapterName, string iosVersion) // TODO: Add Android version check. + { + var dependencyFilePath = MaxSdkUtils.GetAssetPathForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml"); + if (!File.Exists(dependencyFilePath)) return false; + + var currentVersion = GetCurrentVersions(dependencyFilePath); + var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion); + return iosVersionComparison == VersionComparisonResult.Lesser; } #region Utility Methods diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs index 5c3f2d1..8598f30 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs @@ -35,6 +35,9 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor private const string qualityServiceRequiresGradleBuildErrorMsg = "AppLovin Quality Service integration via AppLovin Integration Manager requires Custom Gradle Template enabled or Unity 2018.2 or higher.\n" + "If you would like to continue using your existing setup, please add Quality Service Plugin to your build.gradle manually."; + private const string customGradleVersionTooltip = "To set the version to 6.9.3, set the field to: https://services.gradle.org/distributions/gradle-6.9.3-bin.zip"; + private const string customGradleToolsVersionTooltip = "To set the version to 4.2.0, set the field to: 4.2.0"; + private readonly string[] termsFlowPlatforms = new string[3] {"Both", "Android", "iOS"}; private readonly string[] debugUserGeographies = new string[2] {"Not Set", "GDPR"}; @@ -142,6 +145,26 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor } private void OnEnable() + { + // Script reloads can cause AppLovinSettings.Instance to be null for one frame, + // so we load the Integration Manager on the following frame + if (AppLovinSettings.Instance == null) + { + AppLovinEditorCoroutine.StartCoroutine(WaitForNextFrameForEnable()); + } + else + { + OnWindowEnabled(); + } + } + + private IEnumerator WaitForNextFrameForEnable() + { + yield return new WaitForEndOfFrame(); + OnWindowEnabled(); + } + + private void OnWindowEnabled() { AppLovinIntegrationManager.downloadPluginProgressCallback = OnDownloadPluginProgress; @@ -431,7 +454,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor private void DrawNetworkDetailRow(Network network) { string action; - var currentVersion = network.CurrentVersions.Unity; + var currentVersion = network.CurrentVersions != null ? network.CurrentVersions.Unity : ""; var latestVersion = network.LatestVersions.Unity; bool isActionEnabled; bool isInstalled; @@ -621,11 +644,12 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor GUILayout.EndHorizontal(); } - private string DrawTextField(string fieldTitle, string text, GUILayoutOption labelWidth, GUILayoutOption textFieldWidthOption = null, bool isTextFieldEditable = true) + private string DrawTextField(string fieldTitle, string text, GUILayoutOption labelWidth, GUILayoutOption textFieldWidthOption = null, bool isTextFieldEditable = true, string tooltip = "") { GUILayout.BeginHorizontal(); GUILayout.Space(4); - EditorGUILayout.LabelField(new GUIContent(fieldTitle), labelWidth); + var guiContent = MaxSdkUtils.IsValidString(tooltip) ? new GUIContent(fieldTitle, tooltip) : new GUIContent(fieldTitle); + EditorGUILayout.LabelField(guiContent, labelWidth); GUILayout.Space(4); if (isTextFieldEditable) { @@ -687,6 +711,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor AppLovinInternalSettings.Instance.ConsentFlowEnabled = true; AppLovinSettings.Instance.ConsentFlowEnabled = false; } + GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(4); @@ -750,7 +775,6 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor Application.OpenURL(userTrackingUsageDescriptionDocsLink); } - GUILayout.Space(4); GUILayout.EndHorizontal(); GUILayout.Space(4); @@ -782,6 +806,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor { Application.OpenURL(documentationTermsAndPrivacyPolicyFlow); } + GUILayout.Space(4); GUILayout.EndHorizontal(); @@ -880,6 +905,9 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor var verboseLoggingEnabled = DrawOtherSettingsToggle(EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled, false), " Enable Verbose Logging"); EditorPrefs.SetBool(MaxSdkLogger.KeyVerboseLoggingEnabled, verboseLoggingEnabled); GUILayout.Space(5); + AppLovinSettings.Instance.CustomGradleVersionUrl = DrawTextField("Custom Gradle Version URL", AppLovinSettings.Instance.CustomGradleVersionUrl, GUILayout.Width(privacySettingLabelWidth), privacySettingFieldWidthOption, tooltip: customGradleVersionTooltip); + AppLovinSettings.Instance.CustomGradleToolsVersion = DrawTextField("Custom Gradle Tools Version", AppLovinSettings.Instance.CustomGradleToolsVersion, GUILayout.Width(privacySettingLabelWidth), privacySettingFieldWidthOption, tooltip: customGradleToolsVersionTooltip); + EditorGUILayout.HelpBox("This will overwrite the gradle build tools version in your base gradle template.", MessageType.Info); } GUILayout.Space(5); diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs similarity index 100% rename from MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup rename to MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup.meta b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup.meta deleted file mode 100644 index 0749642..0000000 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 028aec80942df459ab226487b786042c -labels: -- al_max -- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs.backup -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroid.cs similarity index 59% rename from MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs rename to MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroid.cs index c0d1e13..1c34801 100644 --- a/MaxSdk/Scripts/Editor/MaxPostProcessBuildAndroid.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroid.cs @@ -12,8 +12,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using System.Xml.Linq; -using AppLovinMax.ThirdParty.MiniJson; using UnityEditor; using UnityEditor.Android; using UnityEngine; @@ -23,7 +23,7 @@ namespace AppLovinMax.Scripts.Editor /// /// A post processor used to update the Android project once it is generated. /// - public class MaxPostProcessBuildAndroid : IPostGenerateGradleAndroidProject + public class AppLovinPostProcessAndroid : IPostGenerateGradleAndroidProject { #if UNITY_2019_3_OR_NEWER private const string PropertyAndroidX = "android.useAndroidX"; @@ -36,7 +36,23 @@ namespace AppLovinMax.Scripts.Editor private const string KeyMetaDataAppLovinSdkKey = "applovin.sdk.key"; private const string KeyMetaDataAppLovinVerboseLoggingOn = "applovin.sdk.verbose_logging"; private const string KeyMetaDataGoogleApplicationId = "com.google.android.gms.ads.APPLICATION_ID"; - private const string KeyMetaDataGoogleAdManagerApp = "com.google.android.gms.ads.AD_MANAGER_APP"; + private const string KeyMetaDataGoogleOptimizeInitialization = "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"; + private const string KeyMetaDataGoogleOptimizeAdLoading = "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"; + + private const string KeyMetaDataMobileFuseAutoInit = "com.mobilefuse.sdk.disable_auto_init"; + private const string KeyMetaDataMyTargetAutoInit = "com.my.target.autoInitMode"; + +#if UNITY_2022_3_OR_NEWER + // To match "'com.android.library' version '7.3.1'" line in build.gradle + private static readonly Regex TokenGradleVersionLibrary = new Regex(".*id ['\"]com\\.android\\.library['\"] version"); + private static readonly Regex TokenGradleVersion = new Regex(".*id ['\"]com\\.android\\.application['\"] version"); +#else + // To match "classpath 'com.android.tools.build:gradle:4.0.1'" line in build.gradle + private static readonly Regex TokenGradleVersion = new Regex(".*classpath ['\"]com\\.android\\.tools\\.build:gradle:.*"); +#endif + + // To match "distributionUrl=..." in gradle-wrapper.properties file + private static readonly Regex TokenDistributionUrl = new Regex(".*distributionUrl.*"); private static readonly XNamespace AndroidNamespace = "http://schemas.android.com/apk/res/android"; @@ -52,10 +68,17 @@ namespace AppLovinMax.Scripts.Editor public void OnPostGenerateGradleAndroidProject(string path) { #if UNITY_2019_3_OR_NEWER + var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle"); var gradlePropertiesPath = Path.Combine(path, "../gradle.properties"); + var gradleWrapperPropertiesPath = Path.Combine(path, "../gradle/wrapper/gradle-wrapper.properties"); #else + var rootGradleBuildFilePath = Path.Combine(path, "build.gradle"); var gradlePropertiesPath = Path.Combine(path, "gradle.properties"); + var gradleWrapperPropertiesPath = Path.Combine(path, "gradle/wrapper/gradle-wrapper.properties"); #endif + + UpdateGradleVersionsIfNeeded(gradleWrapperPropertiesPath, rootGradleBuildFilePath); + var gradlePropertiesUpdated = new List(); // If the gradle properties file already exists, make sure to add any previous properties. @@ -144,6 +167,8 @@ namespace AppLovinMax.Scripts.Editor AddSdkKeyIfNeeded(elementApplication); EnableVerboseLoggingIfNeeded(elementApplication); AddGoogleApplicationIdIfNeeded(elementApplication, metaDataElements); + AddGoogleOptimizationFlagsIfNeeded(elementApplication, metaDataElements); + DisableAutoInitIfNeeded(elementApplication, metaDataElements); // Save the updated manifest file. manifest.Save(manifestPath); @@ -235,6 +260,101 @@ namespace AppLovinMax.Scripts.Editor } } + private static void AddGoogleOptimizationFlagsIfNeeded(XElement elementApplication, IEnumerable metaDataElements) + { + if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return; + + var googleOptimizeInitializationMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeInitialization); + // If meta data doesn't exist, add it + if (googleOptimizeInitializationMetaData == null) + { + elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeInitialization, true)); + } + + var googleOptimizeAdLoadingMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeAdLoading); + // If meta data doesn't exist, add it + if (googleOptimizeAdLoadingMetaData == null) + { + elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeAdLoading, true)); + } + } + + private static void DisableAutoInitIfNeeded(XElement elementApplication, IEnumerable metaDataElements) + { + if (AppLovinIntegrationManager.IsAdapterInstalled("MobileFuse")) + { + var mobileFuseMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMobileFuseAutoInit); + // If MobileFuse meta data doesn't exist, add it + if (mobileFuseMetaData == null) + { + elementApplication.Add(CreateMetaDataElement(KeyMetaDataMobileFuseAutoInit, true)); + } + } + + if (AppLovinIntegrationManager.IsAdapterInstalled("MyTarget")) + { + var myTargetMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMyTargetAutoInit); + // If MyTarget meta data doesn't exist, add it + if (myTargetMetaData == null) + { + elementApplication.Add(CreateMetaDataElement(KeyMetaDataMyTargetAutoInit, 0)); + } + } + } + + private static void UpdateGradleVersionsIfNeeded(string gradleWrapperPropertiesPath, string rootGradleBuildFilePath) + { + var customGradleVersionUrl = AppLovinSettings.Instance.CustomGradleVersionUrl; + var customGradleToolsVersion = AppLovinSettings.Instance.CustomGradleToolsVersion; + + if (MaxSdkUtils.IsValidString(customGradleVersionUrl)) + { + var newDistributionUrl = string.Format("distributionUrl={0}", customGradleVersionUrl); + if (ReplaceStringInFile(gradleWrapperPropertiesPath, TokenDistributionUrl, newDistributionUrl)) + { + MaxSdkLogger.D("Distribution url set to " + newDistributionUrl); + } + else + { + MaxSdkLogger.E("Failed to set distribution URL"); + } + } + + if (MaxSdkUtils.IsValidString(customGradleToolsVersion)) + { +#if UNITY_2022_3_OR_NEWER + // Unity 2022.3+ requires Gradle Plugin version 7.1.2+. + if (MaxSdkUtils.CompareVersions(customGradleToolsVersion, "7.1.2") == MaxSdkUtils.VersionComparisonResult.Lesser) + { + MaxSdkLogger.E("Failed to set gradle plugin version. Unity 2022.3+ requires gradle plugin version 7.1.2+"); + return; + } + + var newGradleVersionLibraryLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.library' version '{0}' apply false", customGradleToolsVersion)); + if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersionLibrary, newGradleVersionLibraryLine)) + { + MaxSdkLogger.D("Gradle library version set to " + newGradleVersionLibraryLine); + } + else + { + MaxSdkLogger.E("Failed to set gradle library version"); + } + + var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.application' version '{0}' apply false", customGradleToolsVersion)); +#else + var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("classpath 'com.android.tools.build:gradle:{0}'", customGradleToolsVersion)); +#endif + if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersion, newGradleVersionLine)) + { + MaxSdkLogger.D("Gradle version set to " + newGradleVersionLine); + } + else + { + MaxSdkLogger.E("Failed to set gradle plugin version"); + } + } + } + /// /// Creates and returns a meta-data element with the given name and value. /// @@ -265,6 +385,31 @@ namespace AppLovinMax.Scripts.Editor return null; } + + /// + /// Finds the first line that contains regexToMatch and replaces the whole line with replacement + /// + /// Path to the file you want to replace a line in + /// Regex to search for in the line you want to replace + /// String that you want as the new line + /// Returns whether the string was successfully replaced or not + private static bool ReplaceStringInFile(string path, Regex regexToMatch, string replacement) + { + if (!File.Exists(path)) return false; + + var lines = File.ReadAllLines(path); + for (var i = 0; i < lines.Length; i++) + { + if (regexToMatch.IsMatch(lines[i])) + { + lines[i] = replacement; + File.WriteAllLines(path, lines); + return true; + } + } + + return false; + } } } diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs index 41c1561..2620739 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs @@ -8,25 +8,107 @@ #if UNITY_IOS || UNITY_IPHONE -using System.Text; -using UnityEngine.Networking; -using Debug = UnityEngine.Debug; +using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text; using UnityEditor; using UnityEditor.Callbacks; +#if UNITY_2019_3_OR_NEWER +using UnityEditor.iOS.Xcode.Extensions; +#endif +using UnityEditor.iOS.Xcode; +using UnityEngine; +using Debug = UnityEngine.Debug; +using UnityEngine.Networking; namespace AppLovinMax.Scripts.IntegrationManager.Editor { - /// - /// Adds AppLovin Quality Service to the iOS project once the project has been exported. - /// - /// 1. Downloads the Quality Service ruby script. - /// 2. Runs the script using Ruby which integrates AppLovin Quality Service to the project. - /// + [Serializable] + public class SkAdNetworkData + { + [SerializeField] public string[] SkAdNetworkIds; + } + public class AppLovinPostProcessiOS { private const string OutputFileName = "AppLovinQualityServiceSetup.rb"; +#if UNITY_2019_3_OR_NEWER + private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do"; + private const string UseFrameworksPodfileLine = "use_frameworks!"; + private const string UseFrameworksDynamicPodfileLine = "use_frameworks! :linkage => :dynamic"; + private const string UseFrameworksStaticPodfileLine = "use_frameworks! :linkage => :static"; +#else + private const string UnityMainTargetName = "Unity-iPhone"; +#endif + private const string LegacyResourcesDirectoryName = "Resources"; + private const string AppLovinMaxResourcesDirectoryName = "AppLovinMAXResources"; + private const string AppLovinAdvertisingAttributionEndpoint = "https://postbacks-app.com"; + + private const string AppLovinSettingsPlistFileName = "AppLovin-Settings.plist"; + private const string KeyConsentFlowInfo = "ConsentFlowInfo"; + private const string KeyConsentFlowEnabled = "ConsentFlowEnabled"; + private const string KeyConsentFlowTermsOfService = "ConsentFlowTermsOfService"; + private const string KeyConsentFlowPrivacyPolicy = "ConsentFlowPrivacyPolicy"; + private const string KeyConsentFlowDebugUserGeography = "ConsentFlowDebugUserGeography"; + + private static List DynamicLibrariesToEmbed + { + get + { + var dynamicLibrariesToEmbed = new List + { + "AppLovinSDK.xcframework", + "DTBiOSSDK.xcframework", + "FBAEMKit.xcframework", + "FBSDKCoreKit_Basics.xcframework", + "FBSDKCoreKit.xcframework", + "FBSDKGamingServicesKit.xcframework", + "FBSDKLoginKit.xcframework", + "FBSDKShareKit.xcframework", + "HyprMX.xcframework", + "Maio.xcframework", + "MobileFuseSDK.xcframework", + "MolocoSDK.xcframework", + "OMSDK_Appodeal.xcframework", + "OMSDK_Ogury.xcframework", + "OMSDK_Pubnativenet.xcframework", + "OMSDK_Smaato.xcframework" + }; + + // LinkedIn Audience Network SDK is distributed as a static library starting version 1.2.0 + if (AppLovinIntegrationManager.IsAdapterOlderThanMinVersionInstalled("LinkedIn", "1.2.0.0")) + { + dynamicLibrariesToEmbed.Add("LinkedinAudienceNetwork.xcframework"); + } + + // Fyber/IA SDK is distributed as a static library starting version 8.2.7 + if (AppLovinIntegrationManager.IsAdapterOlderThanMinVersionInstalled("Fyber", "8.2.7.0")) + { + dynamicLibrariesToEmbed.Add("IASDKCore.xcframework"); + } + + return dynamicLibrariesToEmbed; + } + } + + private static string PluginMediationDirectory + { + get + { + var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory; + return Path.Combine(pluginParentDir, "MaxSdk/Mediation/"); + } + } + + /// + /// Adds AppLovin Quality Service to the iOS project once the project has been exported. + /// + /// 1. Downloads the Quality Service ruby script. + /// 2. Runs the script using Ruby which integrates AppLovin Quality Service to the project. + /// [PostProcessBuild(int.MaxValue)] // We want to run Quality Service script last. public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath) { @@ -92,6 +174,537 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor MaxSdkLogger.UserDebug(result.Message); } } + + [PostProcessBuildAttribute(int.MaxValue)] + public static void MaxPostProcessPbxProject(BuildTarget buildTarget, string buildPath) + { + var projectPath = PBXProject.GetPBXProjectPath(buildPath); + var project = new PBXProject(); + project.ReadFromFile(projectPath); + +#if UNITY_2019_3_OR_NEWER + var unityMainTargetGuid = project.GetUnityMainTargetGuid(); + var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid(); +#else + var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName); + var unityFrameworkTargetGuid = project.TargetGuidByName(UnityMainTargetName); +#endif + EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid); + + var internalSettingsEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled; + var userTrackingUsageDescriptionDe = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionDe : AppLovinSettings.Instance.UserTrackingUsageDescriptionDe; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionDe, "de", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionEn = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn : AppLovinSettings.Instance.UserTrackingUsageDescriptionEn; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEn, "en", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionEs = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEs : AppLovinSettings.Instance.UserTrackingUsageDescriptionEs; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEs, "es", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionFr = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionFr : AppLovinSettings.Instance.UserTrackingUsageDescriptionFr; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionFr, "fr", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionJa = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionJa : AppLovinSettings.Instance.UserTrackingUsageDescriptionJa; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionJa, "ja", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionKo = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionKo : AppLovinSettings.Instance.UserTrackingUsageDescriptionKo; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionKo, "ko", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionZhHans = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHans : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHans; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHans, "zh-Hans", buildPath, project, unityMainTargetGuid); + var userTrackingUsageDescriptionZhHant = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHant : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHant; + LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHant, "zh-Hant", buildPath, project, unityMainTargetGuid); + + AddSwiftSupport(buildPath, project, unityFrameworkTargetGuid, unityMainTargetGuid); + AddYandexSettingsIfNeeded(project, unityMainTargetGuid); + + project.WriteToFile(projectPath); + } + + private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid) + { + // Check that the Pods directory exists (it might not if a publisher is building with Generate Podfile setting disabled in EDM). + var podsDirectory = Path.Combine(buildPath, "Pods"); + if (!Directory.Exists(podsDirectory)) return; + + var dynamicLibraryPathsPresentInProject = new List(); + foreach (var dynamicLibraryToSearch in DynamicLibrariesToEmbed) + { + // both .framework and .xcframework are directories, not files + var directories = Directory.GetDirectories(podsDirectory, dynamicLibraryToSearch, SearchOption.AllDirectories); + if (directories.Length <= 0) continue; + + var dynamicLibraryAbsolutePath = directories[0]; + var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods"); + var relativePath = dynamicLibraryAbsolutePath.Substring(index); + dynamicLibraryPathsPresentInProject.Add(relativePath); + } + + if (dynamicLibraryPathsPresentInProject.Count <= 0) return; + +#if UNITY_2019_3_OR_NEWER + if (ShouldEmbedDynamicLibraries(buildPath)) + { + foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject) + { + var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath); + project.AddFileToEmbedFrameworks(targetGuid, fileGuid); + } + } +#else + string runpathSearchPaths; + runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS"); + runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " "; + + // Check if runtime search paths already contains the required search paths for dynamic libraries. + if (runpathSearchPaths.Contains("@executable_path/Frameworks")) return; + + runpathSearchPaths += "@executable_path/Frameworks"; + project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths); +#endif + } + + private static void LocalizeUserTrackingDescriptionIfNeeded(string localizedUserTrackingDescription, string localeCode, string buildPath, PBXProject project, string targetGuid) + { + // Use the legacy resources directory name if the build is being appended (the "Resources" directory already exists if it is an incremental build). + var resourcesDirectoryName = Directory.Exists(Path.Combine(buildPath, LegacyResourcesDirectoryName)) ? LegacyResourcesDirectoryName : AppLovinMaxResourcesDirectoryName; + var resourcesDirectoryPath = Path.Combine(buildPath, resourcesDirectoryName); + var localeSpecificDirectoryName = localeCode + ".lproj"; + var localeSpecificDirectoryPath = Path.Combine(resourcesDirectoryPath, localeSpecificDirectoryName); + var infoPlistStringsFilePath = Path.Combine(localeSpecificDirectoryPath, "InfoPlist.strings"); + + // Check if localization has been disabled between builds, and remove them as needed. + if (ShouldRemoveLocalization(localizedUserTrackingDescription)) + { + if (!File.Exists(infoPlistStringsFilePath)) return; + + File.Delete(infoPlistStringsFilePath); + return; + } + + // Create intermediate directories as needed. + if (!Directory.Exists(resourcesDirectoryPath)) + { + Directory.CreateDirectory(resourcesDirectoryPath); + } + + if (!Directory.Exists(localeSpecificDirectoryPath)) + { + Directory.CreateDirectory(localeSpecificDirectoryPath); + } + + var localizedDescriptionLine = "\"NSUserTrackingUsageDescription\" = \"" + localizedUserTrackingDescription + "\";\n"; + // File already exists, update it in case the value changed between builds. + if (File.Exists(infoPlistStringsFilePath)) + { + var output = new List(); + var lines = File.ReadAllLines(infoPlistStringsFilePath); + var keyUpdated = false; + foreach (var line in lines) + { + if (line.Contains("NSUserTrackingUsageDescription")) + { + output.Add(localizedDescriptionLine); + keyUpdated = true; + } + else + { + output.Add(line); + } + } + + if (!keyUpdated) + { + output.Add(localizedDescriptionLine); + } + + File.WriteAllText(infoPlistStringsFilePath, string.Join("\n", output.ToArray()) + "\n"); + } + // File doesn't exist, create one. + else + { + File.WriteAllText(infoPlistStringsFilePath, "/* Localized versions of Info.plist keys - Generated by AL MAX plugin */\n" + localizedDescriptionLine); + } + + var localeSpecificDirectoryRelativePath = Path.Combine(resourcesDirectoryName, localeSpecificDirectoryName); + var guid = project.AddFolderReference(localeSpecificDirectoryRelativePath, localeSpecificDirectoryRelativePath); + project.AddFileToBuild(targetGuid, guid); + } + + private static bool ShouldRemoveLocalization(string localizedUserTrackingDescription) + { + if (string.IsNullOrEmpty(localizedUserTrackingDescription)) return true; + + var settings = AppLovinSettings.Instance; + var internalSettings = AppLovinInternalSettings.Instance; + + return (!internalSettings.ConsentFlowEnabled || !internalSettings.UserTrackingUsageLocalizationEnabled) + && (!settings.ConsentFlowEnabled || !settings.UserTrackingUsageLocalizationEnabled); + } + + private static void AddSwiftSupport(string buildPath, PBXProject project, string unityFrameworkTargetGuid, string unityMainTargetGuid) + { + var swiftFileRelativePath = "Classes/MAXSwiftSupport.swift"; + var swiftFilePath = Path.Combine(buildPath, swiftFileRelativePath); + + // Add Swift file + CreateSwiftFile(swiftFilePath); + var swiftFileGuid = project.AddFile(swiftFileRelativePath, swiftFileRelativePath, PBXSourceTree.Source); + project.AddFileToBuild(unityFrameworkTargetGuid, swiftFileGuid); + + // Add Swift version property if needed + var swiftVersion = project.GetBuildPropertyForAnyConfig(unityFrameworkTargetGuid, "SWIFT_VERSION"); + if (string.IsNullOrEmpty(swiftVersion)) + { + project.SetBuildProperty(unityFrameworkTargetGuid, "SWIFT_VERSION", "5.0"); + } + + // Enable Swift modules + project.AddBuildProperty(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES", "YES"); + project.AddBuildProperty(unityMainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES"); + } + + private static void CreateSwiftFile(string swiftFilePath) + { + if (File.Exists(swiftFilePath)) return; + + // Create a file to write to. + using (var writer = File.CreateText(swiftFilePath)) + { + writer.WriteLine("//\n// MAXSwiftSupport.swift\n//"); + writer.WriteLine("\nimport Foundation\n"); + writer.WriteLine("// This file ensures the project includes Swift support."); + writer.WriteLine("// It is automatically generated by the MAX Unity Plugin."); + writer.Close(); + } + } + + [PostProcessBuildAttribute(int.MaxValue)] + public static void MaxPostProcessPlist(BuildTarget buildTarget, string path) + { + var plistPath = Path.Combine(path, "Info.plist"); + var plist = new PlistDocument(); + plist.ReadFromFile(plistPath); + + SetSdkKeyIfNeeded(plist); + SetAttributionReportEndpointIfNeeded(plist); + + EnableVerboseLoggingIfNeeded(plist); + AddGoogleApplicationIdIfNeeded(plist); + + AddSdkSettingsIfNeeded(plist, path); + EnableTermsFlowIfNeeded(plist); + AddSkAdNetworksInfoIfNeeded(plist); + + plist.WriteToFile(plistPath); + } + + private static void SetSdkKeyIfNeeded(PlistDocument plist) + { + var sdkKey = AppLovinSettings.Instance.SdkKey; + if (string.IsNullOrEmpty(sdkKey)) return; + + const string AppLovinVerboseLoggingOnKey = "AppLovinSdkKey"; + plist.root.SetString(AppLovinVerboseLoggingOnKey, sdkKey); + } + + private static void SetAttributionReportEndpointIfNeeded(PlistDocument plist) + { + if (AppLovinSettings.Instance.SetAttributionReportEndpoint) + { + plist.root.SetString("NSAdvertisingAttributionReportEndpoint", AppLovinAdvertisingAttributionEndpoint); + } + else + { + PlistElement attributionReportEndPoint; + plist.root.values.TryGetValue("NSAdvertisingAttributionReportEndpoint", out attributionReportEndPoint); + + // Check if we had previously set the attribution endpoint and un-set it. + if (attributionReportEndPoint != null && AppLovinAdvertisingAttributionEndpoint.Equals(attributionReportEndPoint.AsString())) + { + plist.root.values.Remove("NSAdvertisingAttributionReportEndpoint"); + } + } + } + + private static void EnableVerboseLoggingIfNeeded(PlistDocument plist) + { + if (!EditorPrefs.HasKey(MaxSdkLogger.KeyVerboseLoggingEnabled)) return; + + var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled); + const string AppLovinVerboseLoggingOnKey = "AppLovinVerboseLoggingOn"; + if (enabled) + { + plist.root.SetBoolean(AppLovinVerboseLoggingOnKey, enabled); + } + else + { + plist.root.values.Remove(AppLovinVerboseLoggingOnKey); + } + } + + private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist) + { + if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.IsAdapterInstalled("GoogleAdManager")) return; + + const string googleApplicationIdentifier = "GADApplicationIdentifier"; + var appId = AppLovinSettings.Instance.AdMobIosAppId; + // Log error if the App ID is not set. + if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-")) + { + Debug.LogError("[AppLovin MAX] Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window."); + return; + } + + plist.root.SetString(googleApplicationIdentifier, appId); + } + + private static void AddYandexSettingsIfNeeded(PBXProject project, string unityMainTargetGuid) + { + if (!AppLovinIntegrationManager.IsAdapterInstalled("Yandex")) return; + + if (MaxSdkUtils.CompareVersions(PlayerSettings.iOS.targetOSVersionString, "12.0") == MaxSdkUtils.VersionComparisonResult.Lesser) + { + Debug.LogWarning("Your iOS target version is under the minimum required version by Yandex. Please update it to 12.0 or newer in your ProjectSettings and rebuild your project."); + return; + } + + project.SetBuildProperty(unityMainTargetGuid, "GENERATE_INFOPLIST_FILE", "NO"); + } + + private static void AddSdkSettingsIfNeeded(PlistDocument infoPlist, string buildPath) + { + // Right now internal settings is only needed for Consent Flow. Remove this setting once we add more settings. + if (!AppLovinInternalSettings.Instance.ConsentFlowEnabled) return; + + var sdkSettingsPlistPath = Path.Combine(buildPath, AppLovinSettingsPlistFileName); + var sdkSettingsPlist = new PlistDocument(); + if (File.Exists(sdkSettingsPlistPath)) + { + sdkSettingsPlist.ReadFromFile(sdkSettingsPlistPath); + } + + EnableConsentFlowIfNeeded(sdkSettingsPlist, infoPlist); + + sdkSettingsPlist.WriteToFile(sdkSettingsPlistPath); + + var projectPath = PBXProject.GetPBXProjectPath(buildPath); + var project = new PBXProject(); + project.ReadFromFile(projectPath); + +#if UNITY_2019_3_OR_NEWER + var unityMainTargetGuid = project.GetUnityMainTargetGuid(); +#else + var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName); +#endif + + var guid = project.AddFile(AppLovinSettingsPlistFileName, AppLovinSettingsPlistFileName, PBXSourceTree.Source); + project.AddFileToBuild(unityMainTargetGuid, guid); + project.WriteToFile(projectPath); + } + + private static void EnableConsentFlowIfNeeded(PlistDocument applovinSettingsPlist, PlistDocument infoPlist) + { + var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled; + var userTrackingUsageDescription = AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn; + var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl; + if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl)) + { + AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" + + "Both values must be included to enable the SDK's consent flow."); + + // No need to update the info.plist here. Default consent flow state will be determined on the SDK side. + return; + } + + var consentFlowInfoRoot = applovinSettingsPlist.root.CreateDict(KeyConsentFlowInfo); + consentFlowInfoRoot.SetBoolean(KeyConsentFlowEnabled, consentFlowEnabled); + consentFlowInfoRoot.SetString(KeyConsentFlowPrivacyPolicy, privacyPolicyUrl); + + var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl; + if (MaxSdkUtils.IsValidString(termsOfServiceUrl)) + { + consentFlowInfoRoot.SetString(KeyConsentFlowTermsOfService, termsOfServiceUrl); + } + + var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography; + if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr) + { + consentFlowInfoRoot.SetString(KeyConsentFlowDebugUserGeography, "gdpr"); + } + + infoPlist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription); + } + + private static void EnableTermsFlowIfNeeded(PlistDocument plist) + { + // Check if terms flow is enabled. No need to update info.plist if consent flow is disabled. + var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled; + if (!consentFlowEnabled) return; + + // Check if terms flow is enabled for this format. + var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform; + if (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.iOS) return; + + var userTrackingUsageDescription = AppLovinSettings.Instance.UserTrackingUsageDescriptionEn; + var privacyPolicyUrl = AppLovinSettings.Instance.ConsentFlowPrivacyPolicyUrl; + if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl)) + { + AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" + + "Both values must be included to enable the SDK's consent flow."); + + // No need to update the info.plist here. Default consent flow state will be determined on the SDK side. + return; + } + + var consentFlowInfoRoot = plist.root.CreateDict("AppLovinConsentFlowInfo"); + consentFlowInfoRoot.SetBoolean("AppLovinConsentFlowEnabled", consentFlowEnabled); + consentFlowInfoRoot.SetString("AppLovinConsentFlowPrivacyPolicy", privacyPolicyUrl); + + var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl; + if (!string.IsNullOrEmpty(termsOfServiceUrl)) + { + consentFlowInfoRoot.SetString("AppLovinConsentFlowTermsOfService", termsOfServiceUrl); + } + + plist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription); + } + + private static void AddSkAdNetworksInfoIfNeeded(PlistDocument plist) + { + var skAdNetworkData = GetSkAdNetworkData(); + var skAdNetworkIds = skAdNetworkData.SkAdNetworkIds; + // Check if we have a valid list of SKAdNetworkIds that need to be added. + if (skAdNetworkIds == null || skAdNetworkIds.Length < 1) return; + + // + // Add the SKAdNetworkItems to the plist. It should look like following: + // + // SKAdNetworkItems + // + // + // SKAdNetworkIdentifier + // ABC123XYZ.skadnetwork + // + // + // SKAdNetworkIdentifier + // 123QWE456.skadnetwork + // + // + // SKAdNetworkIdentifier + // 987XYZ123.skadnetwork + // + // + // + PlistElement skAdNetworkItems; + plist.root.values.TryGetValue("SKAdNetworkItems", out skAdNetworkItems); + var existingSkAdNetworkIds = new HashSet(); + // Check if SKAdNetworkItems array is already in the Plist document and collect all the IDs that are already present. + if (skAdNetworkItems != null && skAdNetworkItems.GetType() == typeof(PlistElementArray)) + { + var plistElementDictionaries = skAdNetworkItems.AsArray().values.Where(plistElement => plistElement.GetType() == typeof(PlistElementDict)); + foreach (var plistElement in plistElementDictionaries) + { + PlistElement existingId; + plistElement.AsDict().values.TryGetValue("SKAdNetworkIdentifier", out existingId); + if (existingId == null || existingId.GetType() != typeof(PlistElementString) || string.IsNullOrEmpty(existingId.AsString())) continue; + + existingSkAdNetworkIds.Add(existingId.AsString()); + } + } + // Else, create an array of SKAdNetworkItems into which we will add our IDs. + else + { + skAdNetworkItems = plist.root.CreateArray("SKAdNetworkItems"); + } + + foreach (var skAdNetworkId in skAdNetworkIds) + { + // Skip adding IDs that are already in the array. + if (existingSkAdNetworkIds.Contains(skAdNetworkId)) continue; + + var skAdNetworkItemDict = skAdNetworkItems.AsArray().AddDict(); + skAdNetworkItemDict.SetString("SKAdNetworkIdentifier", skAdNetworkId); + } + } + + private static SkAdNetworkData GetSkAdNetworkData() + { + var uriBuilder = new UriBuilder("https://unity.applovin.com/max/1.0/skadnetwork_ids"); + + // Get the list of installed ad networks to be passed up + var maxMediationDirectory = PluginMediationDirectory; + if (Directory.Exists(maxMediationDirectory)) + { + var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory); + var installedNetworks = mediationNetworkDirectories.Select(Path.GetFileName).ToList(); + if (AppLovinSettings.Instance.AddApsSkAdNetworkIds) + { + installedNetworks.Add("AmazonPublisherServices"); + } + + var adNetworks = string.Join(",", installedNetworks.ToArray()); + if (!string.IsNullOrEmpty(adNetworks)) + { + uriBuilder.Query += string.Format("ad_networks={0}", adNetworks); + } + } + + using (var unityWebRequest = UnityWebRequest.Get(uriBuilder.ToString())) + { + var operation = unityWebRequest.SendWebRequest(); + // Wait for the download to complete or the request to timeout. + while (!operation.isDone) { } + +#if UNITY_2020_1_OR_NEWER + if (unityWebRequest.result != UnityWebRequest.Result.Success) +#else + if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError) +#endif + { + MaxSdkLogger.UserError("Failed to retrieve SKAdNetwork IDs with error: " + unityWebRequest.error); + return new SkAdNetworkData(); + } + + try + { + return JsonUtility.FromJson(unityWebRequest.downloadHandler.text); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Failed to parse data '" + unityWebRequest.downloadHandler.text + "' with exception: " + exception); + return new SkAdNetworkData(); + } + } + } + +#if UNITY_2019_3_OR_NEWER + /// + /// |-----------------------------------------------------------------------------------------------------------------------------------------------------| + /// | embed | use_frameworks! (:linkage => :dynamic) | use_frameworks! :linkage => :static | `use_frameworks!` line not present | + /// |---------------------------|------------------------------------------|---------------------------------------|--------------------------------------| + /// | Unity-iPhone present | Do not embed dynamic libraries | Embed dynamic libraries | Do not embed dynamic libraries | + /// | Unity-iPhone not present | Embed dynamic libraries | Embed dynamic libraries | Embed dynamic libraries | + /// |-----------------------------------------------------------------------------------------------------------------------------------------------------| + /// + /// An iOS build path + /// Whether or not the dynamic libraries should be embedded. + private static bool ShouldEmbedDynamicLibraries(string buildPath) + { + var podfilePath = Path.Combine(buildPath, "Podfile"); + if (!File.Exists(podfilePath)) return false; + + // If the Podfile doesn't have a `Unity-iPhone` target, we should embed the dynamic libraries. + var lines = File.ReadAllLines(podfilePath); + var containsUnityIphoneTarget = lines.Any(line => line.Contains(TargetUnityIphonePodfileLine)); + if (!containsUnityIphoneTarget) return true; + + // If the Podfile does not have a `use_frameworks! :linkage => static` line, we should not embed the dynamic libraries. + var useFrameworksStaticLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksStaticPodfileLine)); + if (useFrameworksStaticLineIndex == -1) return false; + + // If more than one of the `use_frameworks!` lines are present, CocoaPods will use the last one. + var useFrameworksLineIndex = Array.FindIndex(lines, line => line.Trim() == UseFrameworksPodfileLine); // Check for exact line to avoid matching `use_frameworks! :linkage => static/dynamic` + var useFrameworksDynamicLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksDynamicPodfileLine)); + + // Check if `use_frameworks! :linkage => :static` is the last line of the three. If it is, we should embed the dynamic libraries. + return useFrameworksLineIndex < useFrameworksStaticLineIndex && useFrameworksDynamicLineIndex < useFrameworksStaticLineIndex; + } +#endif } } diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs index 48b4d0e..87152a9 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs @@ -544,7 +544,7 @@ namespace AppLovinMax.Scripts.IntegrationManager.Editor return outputLines; } - private static string GetFormattedBuildScriptLine(string buildScriptLine) + public static string GetFormattedBuildScriptLine(string buildScriptLine) { #if UNITY_2022_2_OR_NEWER return " " diff --git a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs index 540cbe8..df88d8d 100644 --- a/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs +++ b/MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs @@ -60,6 +60,9 @@ public class AppLovinSettings : ScriptableObject [SerializeField] private bool setAttributionReportEndpoint; [SerializeField] private bool addApsSkAdNetworkIds; + [SerializeField] private string customGradleVersionUrl; + [SerializeField] private string customGradleToolsVersion; + [SerializeField] private bool consentFlowEnabled; [SerializeField] private Platform consentFlowPlatform; [SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty; @@ -128,9 +131,13 @@ public class AppLovinSettings : ScriptableObject Directory.CreateDirectory(settingsDir); } - instance = CreateInstance(); - AssetDatabase.CreateAsset(instance, settingsFilePath); - MaxSdkLogger.D("Creating new AppLovinSettings asset at path: " + settingsFilePath); + // On script reload AssetDatabase.FindAssets() can fail and will overwrite AppLovinSettings without this check + if (!File.Exists(settingsFilePath)) + { + instance = CreateInstance(); + AssetDatabase.CreateAsset(instance, settingsFilePath); + MaxSdkLogger.D("Creating new AppLovinSettings asset at path: " + settingsFilePath); + } } return instance; @@ -173,6 +180,24 @@ public class AppLovinSettings : ScriptableObject set { Instance.addApsSkAdNetworkIds = value; } } + /// + /// A URL to set the distributionUrl in the gradle-wrapper.properties file (ex: https\://services.gradle.org/distributions/gradle-6.9.3-bin.zip) + /// + public string CustomGradleVersionUrl + { + get { return Instance.customGradleVersionUrl; } + set { Instance.customGradleVersionUrl = value; } + } + + /// + /// A string to set the custom gradle tools version (ex: com.android.tools.build:gradle:4.2.0) + /// + public string CustomGradleToolsVersion + { + get { return Instance.customGradleToolsVersion; } + set { Instance.customGradleToolsVersion = value; } + } + /// /// Whether or not AppLovin Consent Flow is enabled. /// diff --git a/MaxSdk/Scripts/MaxEventExecutor.cs b/MaxSdk/Scripts/MaxEventExecutor.cs new file mode 100644 index 0000000..ee229be --- /dev/null +++ b/MaxSdk/Scripts/MaxEventExecutor.cs @@ -0,0 +1,108 @@ +// +// MaxEventExecutor.cs +// Max Unity Plugin +// +// Created by Jonathan Liu on 1/22/2024. +// Copyright © 2024 AppLovin. All rights reserved. +// + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Events; + +namespace AppLovinMax.Internal +{ + public class MaxEventExecutor : MonoBehaviour + { + private static MaxEventExecutor instance; + private static List adEventsQueue = new List(); + + private static volatile bool adEventsQueueEmpty = true; + + struct MaxAction + { + public Action action; + public string eventName; + + public MaxAction(Action actionToExecute, string nameOfEvent) + { + action = actionToExecute; + eventName = nameOfEvent; + } + } + + public static void InitializeIfNeeded() + { + if (instance != null) return; + + var executor = new GameObject("MaxEventExecutor"); + executor.hideFlags = HideFlags.HideAndDontSave; + DontDestroyOnLoad(executor); + instance = executor.AddComponent(); + } + + #region Public API + +#if UNITY_EDITOR + public static MaxEventExecutor Instance + { + get + { + InitializeIfNeeded(); + return instance; + } + } +#endif + + public static void ExecuteOnMainThread(Action action, string eventName) + { + lock (adEventsQueue) + { + adEventsQueue.Add(new MaxAction(action, eventName)); + adEventsQueueEmpty = false; + } + } + + public static void InvokeOnMainThread(UnityEvent unityEvent, string eventName) + { + ExecuteOnMainThread(() => unityEvent.Invoke(), eventName); + } + + #endregion + + public void Update() + { + if (adEventsQueueEmpty) return; + + var actionsToExecute = new List(); + lock (adEventsQueue) + { + actionsToExecute.AddRange(adEventsQueue); + adEventsQueue.Clear(); + adEventsQueueEmpty = true; + } + + foreach (var maxAction in actionsToExecute) + { + if (maxAction.action.Target != null) + { + try + { + maxAction.action.Invoke(); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Caught exception in publisher event: " + maxAction.eventName + ", exception: " + exception); + Debug.LogException(exception); + } + } + } + } + + public void Disable() + { + instance = null; + } + } +} diff --git a/MaxSdk/Scripts/Editor/MaxInitialization.cs.meta b/MaxSdk/Scripts/MaxEventExecutor.cs.meta similarity index 68% rename from MaxSdk/Scripts/Editor/MaxInitialization.cs.meta rename to MaxSdk/Scripts/MaxEventExecutor.cs.meta index a96a577..18ba126 100644 --- a/MaxSdk/Scripts/Editor/MaxInitialization.cs.meta +++ b/MaxSdk/Scripts/MaxEventExecutor.cs.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: bc0c5693335e0408a95293c0d7b61137 +guid: 4715dd62632564dc4810a4dc98243f4a labels: - al_max -- al_max_export_path-MaxSdk/Scripts/Editor/MaxInitialization.cs +- al_max_export_path-MaxSdk/Scripts/MaxEventExecutor.cs MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/MaxSdk/Scripts/MaxSdk.cs b/MaxSdk/Scripts/MaxSdk.cs index 9d24ee3..0620166 100644 --- a/MaxSdk/Scripts/MaxSdk.cs +++ b/MaxSdk/Scripts/MaxSdk.cs @@ -18,7 +18,7 @@ public class MaxSdk : MaxSdkUnityEditor #endif { - private const string _version = "6.1.2"; + private const string _version = "6.4.3"; /// /// Returns the current plugin version. diff --git a/MaxSdk/Scripts/MaxSdkAndroid.cs b/MaxSdk/Scripts/MaxSdkAndroid.cs index 0ed7612..fd38238 100644 --- a/MaxSdk/Scripts/MaxSdkAndroid.cs +++ b/MaxSdk/Scripts/MaxSdkAndroid.cs @@ -20,7 +20,7 @@ public class MaxSdkAndroid : MaxSdkBase static MaxSdkAndroid() { - InitCallbacks(); + InitializeEventExecutor(); } #region Initialization @@ -30,6 +30,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// This method must be called before any other SDK operation /// + /// AppLovin SDK Key. Must not be null. public static void SetSdkKey(string sdkKey) { MaxUnityPluginClass.CallStatic("setSdkKey", sdkKey); @@ -69,7 +70,7 @@ public class MaxSdkAndroid : MaxSdkBase /// For example, a username or email. We'll include this in the postback when we ping your currency endpoint from our server. /// /// - /// The user identifier to be set. + /// The user identifier to be set. Must not be null. public static void SetUserId(string userId) { MaxUnityPluginClass.CallStatic("setUserId", userId); @@ -131,8 +132,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Returns the arbitrary ad value for a given ad unit identifier with key. Returns null if no ad is loaded. /// - /// - /// Ad value key + /// Ad unit identifier for which to get the ad value for. Must not be null. + /// Ad value key. Must not be null. /// Arbitrary ad value for a given key, or null if no ad is loaded. public static string GetAdValue(string adUnitIdentifier, string key) { @@ -247,8 +248,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Create a new banner. /// - /// Ad unit identifier of the banner to create - /// Banner position + /// Ad unit identifier of the banner to create. Must not be null. + /// Banner position. Must not be null. public static void CreateBanner(string adUnitIdentifier, BannerPosition bannerPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create banner"); @@ -258,7 +259,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Create a new banner with a custom position. /// - /// Ad unit identifier of the banner to create + /// Ad unit identifier of the banner to create. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -275,7 +276,7 @@ public class MaxSdkAndroid : MaxSdkBase /// NOTE: The method loads the first banner ad and initiates an automated banner refresh process. /// You only need to call this method if you pause banner refresh. /// - /// Ad unit identifier of the banner to load + /// Ad unit identifier of the banner to load. Must not be null. public static void LoadBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load banner"); @@ -285,7 +286,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set the banner placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the banner to set the placement for + /// Ad unit identifier of the banner to set the placement for. Must not be null. /// Placement to set public static void SetBannerPlacement(string adUnitIdentifier, string placement) { @@ -296,7 +297,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Starts or resumes auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to start auto-refresh + /// Ad unit identifier of the banner for which to start auto-refresh. Must not be null. public static void StartBannerAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "start banner auto-refresh"); @@ -306,7 +307,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Pauses auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to stop auto-refresh + /// Ad unit identifier of the banner for which to stop auto-refresh. Must not be null. public static void StopBannerAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "stop banner auto-refresh"); @@ -316,8 +317,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Updates the position of the banner to the new position provided. /// - /// The ad unit identifier of the banner for which to update the position - /// A new position for the banner + /// The ad unit identifier of the banner for which to update the position. Must not be null. + /// A new position for the banner. Must not be null. public static void UpdateBannerPosition(string adUnitIdentifier, BannerPosition bannerPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "update banner position"); @@ -327,7 +328,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Updates the position of the banner to the new coordinates provided. /// - /// The ad unit identifier of the banner for which to update the position + /// The ad unit identifier of the banner for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -342,7 +343,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Overrides the width of the banner in dp. /// - /// The ad unit identifier of the banner for which to override the width for + /// The ad unit identifier of the banner for which to override the width for. Must not be null. /// The desired width of the banner in dp public static void SetBannerWidth(string adUnitIdentifier, float width) { @@ -353,7 +354,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Show banner at a position determined by the 'CreateBanner' call. /// - /// Ad unit identifier of the banner to show + /// Ad unit identifier of the banner to show. Must not be null. public static void ShowBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show banner"); @@ -363,7 +364,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Remove banner from the ad view and destroy it. /// - /// Ad unit identifier of the banner to destroy + /// Ad unit identifier of the banner to destroy. Must not be null. public static void DestroyBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy banner"); @@ -373,8 +374,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Hide banner. /// - /// Ad unit identifier of the banner to hide - /// + /// Ad unit identifier of the banner to hide. Must not be null. public static void HideBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide banner"); @@ -384,9 +384,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set non-transparent background color for banners to be fully functional. /// - /// Ad unit identifier of the banner to set background color for - /// A background color to set for the ad - /// + /// Ad unit identifier of the banner to set background color for. Must not be null. + /// A background color to set for the ad. Must not be null. public static void SetBannerBackgroundColor(string adUnitIdentifier, Color color) { ValidateAdUnitIdentifier(adUnitIdentifier, "set background color"); @@ -396,8 +395,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the banner to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetBannerExtraParameter(string adUnitIdentifier, string key, string value) { @@ -408,8 +407,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the banner to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetBannerLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -428,7 +427,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// The custom data to tie the showing banner ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// Banner ad unit identifier of the banner to set the custom data for. + /// Banner ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetBannerCustomData(string adUnitIdentifier, string customData) { @@ -440,7 +439,7 @@ public class MaxSdkAndroid : MaxSdkBase /// The banner position on the screen. When setting the banner position via or , /// the banner is placed within the safe area of the screen. This returns the absolute position of the banner on screen. /// - /// Ad unit identifier of the banner for which to get the position on screen. + /// Ad unit identifier of the banner for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetBannerLayout(string adUnitIdentifier) { @@ -456,8 +455,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Create a new MREC. /// - /// Ad unit identifier of the MREC to create - /// MREC position + /// Ad unit identifier of the MREC to create. Must not be null. + /// MREC position. Must not be null. public static void CreateMRec(string adUnitIdentifier, AdViewPosition mrecPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create MREC"); @@ -467,7 +466,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Create a new MREC with a custom position. /// - /// Ad unit identifier of the MREC to create + /// Ad unit identifier of the MREC to create. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -484,7 +483,7 @@ public class MaxSdkAndroid : MaxSdkBase /// NOTE: The method loads the first MREC ad and initiates an automated MREC refresh process. /// You only need to call this method if you pause MREC refresh. /// - /// Ad unit identifier of the MREC to load + /// Ad unit identifier of the MREC to load. Must not be null. public static void LoadMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load MREC"); @@ -494,7 +493,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set the MREC placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the MREC to set the placement for + /// Ad unit identifier of the MREC to set the placement for. Must not be null. /// Placement to set public static void SetMRecPlacement(string adUnitIdentifier, string placement) { @@ -505,7 +504,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Starts or resumes auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to start auto-refresh + /// Ad unit identifier of the MREC for which to start auto-refresh. Must not be null. public static void StartMRecAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "start MREC auto-refresh"); @@ -515,7 +514,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Pauses auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to stop auto-refresh + /// Ad unit identifier of the MREC for which to stop auto-refresh. Must not be null. public static void StopMRecAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "stop MREC auto-refresh"); @@ -525,8 +524,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Updates the position of the MREC to the new position provided. /// - /// The ad unit identifier of the MREC for which to update the position - /// A new position for the MREC + /// The ad unit identifier of the MREC for which to update the position. Must not be null. + /// A new position for the MREC. Must not be null. public static void UpdateMRecPosition(string adUnitIdentifier, AdViewPosition mrecPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "update MREC position"); @@ -536,7 +535,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Updates the position of the MREC to the new coordinates provided. /// - /// The ad unit identifier of the MREC for which to update the position + /// The ad unit identifier of the MREC for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -551,7 +550,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Show MREC at a position determined by the 'CreateMRec' call. /// - /// Ad unit identifier of the MREC to show + /// Ad unit identifier of the MREC to show. Must not be null. public static void ShowMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show MREC"); @@ -561,7 +560,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Remove MREC from the ad view and destroy it. /// - /// Ad unit identifier of the MREC to destroy + /// Ad unit identifier of the MREC to destroy. Must not be null. public static void DestroyMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy MREC"); @@ -571,7 +570,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Hide MREC. /// - /// Ad unit identifier of the MREC to hide + /// Ad unit identifier of the MREC to hide. Must not be null. public static void HideMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide MREC"); @@ -581,8 +580,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the MREC to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetMRecExtraParameter(string adUnitIdentifier, string key, string value) { @@ -593,8 +592,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the MREC to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetMRecLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -613,7 +612,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// The custom data to tie the showing MREC ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// MREC Ad unit identifier of the banner to set the custom data for. + /// MREC Ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetMRecCustomData(string adUnitIdentifier, string customData) { @@ -625,7 +624,7 @@ public class MaxSdkAndroid : MaxSdkBase /// The MREC position on the screen. When setting the banner position via or , /// the banner is placed within the safe area of the screen. This returns the absolute position of the MREC on screen. /// - /// Ad unit identifier of the MREC for which to get the position on screen. + /// Ad unit identifier of the MREC for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetMRecLayout(string adUnitIdentifier) { @@ -636,106 +635,12 @@ public class MaxSdkAndroid : MaxSdkBase #endregion - #region Cross Promo Ads - - /// - /// Create a new cross promo ad with a custom position. - /// - /// Ad unit identifier of the cross promo ad to create - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void CreateCrossPromoAd(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "create cross promo ad"); - MaxUnityPluginClass.CallStatic("createCrossPromoAd", adUnitIdentifier, x, y, width, height, rotation); - } - - /// - /// Set the cross promo ad placement for an ad unit identifier to tie the future ad events to. - /// - /// Ad unit identifier of the cross promo ad to set the placement for - /// Placement to set - public static void SetCrossPromoAdPlacement(string adUnitIdentifier, string placement) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "set cross promo ad placement"); - MaxUnityPluginClass.CallStatic("setCrossPromoAdPlacement", adUnitIdentifier, placement); - } - - /// - /// Updates the position of the cross promo ad to the new coordinates provided. - /// - /// The ad unit identifier of the cross promo ad for which to update the position - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo ad is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void UpdateCrossPromoAdPosition(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "update cross promo ad position"); - MaxUnityPluginClass.CallStatic("updateCrossPromoAdPosition", adUnitIdentifier, x, y, width, height, rotation); - } - - /// - /// Show cross promo ad at a position determined by the 'CreateCrossPromoAd' call. - /// - /// Ad unit identifier of the cross promo ad to show - public static void ShowCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "show cross promo ad"); - MaxUnityPluginClass.CallStatic("showCrossPromoAd", adUnitIdentifier); - } - - /// - /// Remove cross promo ad from the ad view and destroy it. - /// - /// Ad unit identifier of the cross promo ad to destroy - public static void DestroyCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "destroy cross promo ad"); - MaxUnityPluginClass.CallStatic("destroyCrossPromoAd", adUnitIdentifier); - } - - /// - /// Hide cross promo ad. - /// - /// Ad unit identifier of the cross promo ad to hide - public static void HideCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "hide cross promo ad"); - MaxUnityPluginClass.CallStatic("hideCrossPromoAd", adUnitIdentifier); - } - - /// - /// The cross promo ad position on the screen. When setting the cross promo ad position via or , - /// the cross promo ad is placed within the safe area of the screen. This returns the absolute position of the cross promo ad on screen. - /// - /// Ad unit identifier of the cross promo ad for which to get the position on screen. - /// A representing the banner position on screen. - public static Rect GetCrossPromoAdLayout(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "get cross promo ad layout"); - var positionRect = MaxUnityPluginClass.CallStatic("getCrossPromoAdLayout", adUnitIdentifier); - return GetRectFromString(positionRect); - } - - #endregion - #region Interstitials /// /// Start loading an interstitial. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. public static void LoadInterstitial(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load interstitial"); @@ -745,7 +650,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Check if interstitial ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsInterstitialReady(string adUnitIdentifier) { @@ -756,7 +661,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Present loaded interstitial for a given placement to tie ad events to. Note: if the interstitial is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowInterstitial(string adUnitIdentifier, string placement = null, string customData = null) @@ -776,8 +681,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the interstitial to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the interstitial to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetInterstitialExtraParameter(string adUnitIdentifier, string key, string value) { @@ -788,8 +693,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the interstitial to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the interstitial to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetInterstitialLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -812,7 +717,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Start loading an app open ad. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. public static void LoadAppOpenAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load app open ad"); @@ -822,7 +727,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Check if app open ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsAppOpenAdReady(string adUnitIdentifier) { @@ -833,7 +738,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Present loaded app open ad for a given placement to tie ad events to. Note: if the app open ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowAppOpenAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -853,8 +758,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the app open ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetAppOpenAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -865,8 +770,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the app open ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetAppOpenAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -889,7 +794,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Start loading an rewarded ad. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. public static void LoadRewardedAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded ad"); @@ -899,7 +804,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Check if rewarded ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedAdReady(string adUnitIdentifier) { @@ -910,7 +815,7 @@ public class MaxSdkAndroid : MaxSdkBase /// ready to be /// Present loaded rewarded ad for a given placement to tie ad events to. Note: if the rewarded ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -930,8 +835,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -942,8 +847,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetRewardedAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -966,7 +871,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Start loading an rewarded interstitial ad. /// - /// Ad unit identifier of the rewarded interstitial ad to load + /// Ad unit identifier of the rewarded interstitial ad to load. Must not be null. public static void LoadRewardedInterstitialAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded interstitial ad"); @@ -976,7 +881,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Check if rewarded interstitial ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded interstitial ad to load + /// Ad unit identifier of the rewarded interstitial ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedInterstitialAdReady(string adUnitIdentifier) { @@ -987,7 +892,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Present loaded rewarded interstitial ad for a given placement to tie ad events to. Note: if the rewarded interstitial ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the rewarded interstitial to show + /// Ad unit identifier of the rewarded interstitial to show. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedInterstitialAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1007,8 +912,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded interstitial to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedInterstitialAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1019,8 +924,8 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded interstitial to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetRewardedInterstitialAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1043,7 +948,7 @@ public class MaxSdkAndroid : MaxSdkBase /// /// Track an event using AppLovin. /// - /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. + /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. Must not be null. /// A dictionary containing key-value pairs further describing this event. public static void TrackEvent(string name, IDictionary parameters = null) { @@ -1149,6 +1054,25 @@ public class MaxSdkAndroid : MaxSdkBase MaxUnityPluginClass.CallStatic("setExtraParameter", key, value); } + /// + /// Get the native insets in pixels for the safe area. + /// These insets are used to position ads within the safe area of the screen. + /// + public static SafeAreaInsets GetSafeAreaInsets() + { + // Use an int array instead of json serialization for performance + var insets = MaxUnityPluginClass.CallStatic("getSafeAreaInsets"); + + // Convert from points to pixels + var screenDensity = MaxSdkUtils.GetScreenDensity(); + for (var i = 0; i < insets.Length; i++) + { + insets[i] *= (int) screenDensity; + } + + return new SafeAreaInsets(insets); + } + #endregion #region Private diff --git a/MaxSdk/Scripts/MaxSdkBase.cs b/MaxSdk/Scripts/MaxSdkBase.cs index dfe1228..ebd9864 100644 --- a/MaxSdk/Scripts/MaxSdkBase.cs +++ b/MaxSdk/Scripts/MaxSdkBase.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Linq; using System.Text; using AppLovinMax.ThirdParty.MiniJson; +using AppLovinMax.Internal; using UnityEngine; #if UNITY_IOS && !UNITY_EDITOR @@ -168,7 +169,6 @@ public abstract class MaxSdkBase sdkConfiguration.ConsentFlowUserGeography = ConsentFlowUserGeography.Unknown; } - #pragma warning disable 0618 var consentDialogStateStr = MaxSdkUtils.GetStringFromDictionary(eventProps, "consentDialogState", ""); if ("1".Equals(consentDialogStateStr)) @@ -325,6 +325,7 @@ public abstract class MaxSdkBase public double Revenue { get; private set; } public string RevenuePrecision { get; private set; } public WaterfallInfo WaterfallInfo { get; private set; } + public long LatencyMillis { get; private set; } public string DspName { get; private set; } public AdInfo(IDictionary adInfoDictionary) @@ -338,6 +339,7 @@ public abstract class MaxSdkBase Revenue = MaxSdkUtils.GetDoubleFromDictionary(adInfoDictionary, "revenue", -1); RevenuePrecision = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "revenuePrecision"); WaterfallInfo = new WaterfallInfo(MaxSdkUtils.GetDictionaryFromDictionary(adInfoDictionary, "waterfallInfo", new Dictionary())); + LatencyMillis = MaxSdkUtils.GetLongFromDictionary(adInfoDictionary, "latencyMillis"); DspName = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "dspName"); } @@ -351,6 +353,7 @@ public abstract class MaxSdkBase ", placement: " + Placement + ", revenue: " + Revenue + ", revenuePrecision: " + RevenuePrecision + + ", latency: " + LatencyMillis + ", dspName: " + DspName + "]"; } } @@ -469,6 +472,7 @@ public abstract class MaxSdkBase public string MediatedNetworkErrorMessage { get; private set; } public string AdLoadFailureInfo { get; private set; } public WaterfallInfo WaterfallInfo { get; private set; } + public long LatencyMillis { get; private set; } public ErrorInfo(IDictionary errorInfoDictionary) { @@ -478,6 +482,7 @@ public abstract class MaxSdkBase MediatedNetworkErrorMessage = MaxSdkUtils.GetStringFromDictionary(errorInfoDictionary, "mediatedNetworkErrorMessage", ""); AdLoadFailureInfo = MaxSdkUtils.GetStringFromDictionary(errorInfoDictionary, "adLoadFailureInfo", ""); WaterfallInfo = new WaterfallInfo(MaxSdkUtils.GetDictionaryFromDictionary(errorInfoDictionary, "waterfallInfo", new Dictionary())); + LatencyMillis = MaxSdkUtils.GetLongFromDictionary(errorInfoDictionary, "latencyMillis"); } public override string ToString() @@ -491,10 +496,42 @@ public abstract class MaxSdkBase stringbuilder.Append(", mediatedNetworkMessage: ").Append(MediatedNetworkErrorMessage); } + stringbuilder.Append(", latency: ").Append(LatencyMillis); return stringbuilder.Append(", adLoadFailureInfo: ").Append(AdLoadFailureInfo).Append("]").ToString(); } } + /// + /// Inset values for the safe area on the screen used to render banner ads. + /// + public class SafeAreaInsets + { + public int Left { get; private set; } + public int Top { get; private set; } + public int Right { get; private set; } + public int Bottom { get; private set; } + + /// + /// Creates a new instance of . + /// + /// An integer array with insets values in the order of left, top, right, and bottom + internal SafeAreaInsets(int[] insets) + { + Left = insets[0]; + Top = insets[1]; + Right = insets[2]; + Bottom = insets[3]; + } + + public override string ToString() + { + return "[SafeAreaInsets: Left: " + Left + + ", Top: " + Top + + ", Right: " + Right + + ", Bottom: " + Bottom + "]"; + } + } + /// /// The CMP service, which provides direct APIs for interfacing with the Google-certified CMP installed, if any. /// @@ -511,16 +548,10 @@ public abstract class MaxSdkBase } } - // Allocate the MaxSdkCallbacks singleton, which receives all callback events from the native SDKs. - protected static void InitCallbacks() + // Allocate the MaxEventExecutor singleton which handles pushing callbacks from the background to the main thread. + protected static void InitializeEventExecutor() { - var type = typeof(MaxSdkCallbacks); - var mgr = new GameObject("MaxSdkCallbacks", type) - .GetComponent(); // Its Awake() method sets Instance. - if (MaxSdkCallbacks.Instance != mgr) - { - MaxSdkLogger.UserWarning("It looks like you have the " + type.Name + " on a GameObject in your scene. Please remove the script from your scene."); - } + MaxEventExecutor.InitializeIfNeeded(); } /// @@ -562,7 +593,7 @@ public abstract class MaxSdkBase { try { - MaxSdkCallbacks.Instance.ForwardEvent(propsStr); + MaxSdkCallbacks.ForwardEvent(propsStr); } catch (Exception exception) { diff --git a/MaxSdk/Scripts/MaxSdkCallbacks.cs b/MaxSdk/Scripts/MaxSdkCallbacks.cs index bf3084f..8654dfb 100644 --- a/MaxSdk/Scripts/MaxSdkCallbacks.cs +++ b/MaxSdk/Scripts/MaxSdkCallbacks.cs @@ -7,30 +7,10 @@ using System.Collections.Generic; using System.Globalization; using UnityEngine; using AppLovinMax.ThirdParty.MiniJson; +using AppLovinMax.Internal; -public class MaxSdkCallbacks : MonoBehaviour +public static class MaxSdkCallbacks { -#if UNITY_EDITOR - private static MaxSdkCallbacks instance; -#endif - - public static MaxSdkCallbacks Instance - { -#if UNITY_EDITOR - get - { - if (instance != null) return instance; - - instance = new GameObject("MaxSdkCallbacks", typeof(MaxSdkCallbacks)).GetComponent(); - DontDestroyOnLoad(instance); - - return instance; - } -#else - get; private set; -#endif - } - // Fired when the SDK has finished initializing private static Action _onSdkInitializedEvent; public static event Action OnSdkInitializedEvent @@ -844,100 +824,6 @@ public class MaxSdkCallbacks : MonoBehaviour } } - private static Action _onCrossPromoAdLoadedEvent; - private static Action _onCrossPromoAdLoadFailedEvent; - private static Action _onCrossPromoAdClickedEvent; - private static Action _onCrossPromoAdRevenuePaidEvent; - private static Action _onCrossPromoAdExpandedEvent; - private static Action _onCrossPromoAdCollapsedEvent; - - public class CrossPromo - { - public static event Action OnAdLoadedEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdLoadedEvent"); - _onCrossPromoAdLoadedEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdLoadedEvent"); - _onCrossPromoAdLoadedEvent -= value; - } - } - - public static event Action OnAdLoadFailedEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdLoadFailedEvent"); - _onCrossPromoAdLoadFailedEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdLoadFailedEvent"); - _onCrossPromoAdLoadFailedEvent -= value; - } - } - - public static event Action OnAdClickedEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdClickedEvent"); - _onCrossPromoAdClickedEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdClickedEvent"); - _onCrossPromoAdClickedEvent -= value; - } - } - - public static event Action OnAdRevenuePaidEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdRevenuePaidEvent"); - _onCrossPromoAdRevenuePaidEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdRevenuePaidEvent"); - _onCrossPromoAdRevenuePaidEvent -= value; - } - } - - public static event Action OnAdExpandedEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdExpandedEvent"); - _onCrossPromoAdExpandedEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdExpandedEvent"); - _onCrossPromoAdExpandedEvent -= value; - } - } - - public static event Action OnAdCollapsedEvent - { - add - { - LogSubscribedToEvent("OnCrossPromoAdCollapsedEvent"); - _onCrossPromoAdCollapsedEvent += value; - } - remove - { - LogUnsubscribedToEvent("OnCrossPromoAdCollapsedEvent"); - _onCrossPromoAdCollapsedEvent -= value; - } - } - } - private static Action _onBannerAdLoadedEvent; private static Action _onBannerAdLoadFailedEvent; private static Action _onBannerAdClickedEvent; @@ -1312,18 +1198,7 @@ public class MaxSdkCallbacks : MonoBehaviour } } -#if !UNITY_EDITOR - void Awake() - { - if (Instance == null) - { - Instance = this; - DontDestroyOnLoad(gameObject); - } - } -#endif - - public void ForwardEvent(string eventPropsStr) + public static void ForwardEvent(string eventPropsStr) { var eventProps = Json.Deserialize(eventPropsStr) as Dictionary; if (eventProps == null) @@ -1332,6 +1207,7 @@ public class MaxSdkCallbacks : MonoBehaviour return; } + var keepInBackground = MaxSdkUtils.GetBoolFromDictionary(eventProps, "keepInBackground", false); var eventName = MaxSdkUtils.GetStringFromDictionary(eventProps, "name", ""); if (eventName == "OnInitialCallbackEvent") { @@ -1340,11 +1216,11 @@ public class MaxSdkCallbacks : MonoBehaviour else if (eventName == "OnSdkInitializedEvent") { var sdkConfiguration = MaxSdkBase.SdkConfiguration.Create(eventProps); - InvokeEvent(_onSdkInitializedEvent, sdkConfiguration, eventName); + InvokeEvent(_onSdkInitializedEvent, sdkConfiguration, eventName, keepInBackground); } else if (eventName == "OnSdkConsentDialogDismissedEvent") { - InvokeEvent(_onSdkConsentDialogDismissedEvent, eventName); + InvokeEvent(_onSdkConsentDialogDismissedEvent, eventName, keepInBackground); } else if (eventName == "OnCmpCompletedEvent") { @@ -1358,223 +1234,197 @@ public class MaxSdkCallbacks : MonoBehaviour var adUnitIdentifier = MaxSdkUtils.GetStringFromDictionary(eventProps, "adUnitId", ""); if (eventName == "OnBannerAdLoadedEvent") { - InvokeEvent(_onBannerAdLoadedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onBannerAdLoadedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onBannerAdLoadedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onBannerAdLoadedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdLoadFailedEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onBannerAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onBannerAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onBannerAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onBannerAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdClickedEvent") { - InvokeEvent(_onBannerAdClickedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onBannerAdClickedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onBannerAdClickedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onBannerAdClickedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdRevenuePaidEvent") { - InvokeEvent(_onBannerAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onBannerAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdReviewCreativeIdGeneratedEvent") { var adReviewCreativeId = MaxSdkUtils.GetStringFromDictionary(eventProps, "adReviewCreativeId", ""); - InvokeEvent(_onBannerAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName); + InvokeEvent(_onBannerAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdExpandedEvent") { - InvokeEvent(_onBannerAdExpandedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onBannerAdExpandedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onBannerAdExpandedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onBannerAdExpandedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnBannerAdCollapsedEvent") { - InvokeEvent(_onBannerAdCollapsedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onBannerAdCollapsedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onBannerAdCollapsedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onBannerAdCollapsedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdLoadedEvent") { - InvokeEvent(_onMRecAdLoadedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onMRecAdLoadedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onMRecAdLoadedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onMRecAdLoadedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdLoadFailedEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onMRecAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onMRecAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onMRecAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onMRecAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdClickedEvent") { - InvokeEvent(_onMRecAdClickedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onMRecAdClickedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onMRecAdClickedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onMRecAdClickedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdRevenuePaidEvent") { - InvokeEvent(_onMRecAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onMRecAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdReviewCreativeIdGeneratedEvent") { var adReviewCreativeId = MaxSdkUtils.GetStringFromDictionary(eventProps, "adReviewCreativeId", ""); - InvokeEvent(_onMRecAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName); + InvokeEvent(_onMRecAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdExpandedEvent") { - InvokeEvent(_onMRecAdExpandedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onMRecAdExpandedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onMRecAdExpandedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onMRecAdExpandedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnMRecAdCollapsedEvent") { - InvokeEvent(_onMRecAdCollapsedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onMRecAdCollapsedEventV2, adUnitIdentifier, adInfo, eventName); - } - else if (eventName == "OnCrossPromoAdLoadedEvent") - { - InvokeEvent(_onCrossPromoAdLoadedEvent, adUnitIdentifier, adInfo, eventName); - } - else if (eventName == "OnCrossPromoAdLoadFailedEvent") - { - var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - - InvokeEvent(_onCrossPromoAdLoadFailedEvent, adUnitIdentifier, errorInfo, eventName); - } - else if (eventName == "OnCrossPromoAdClickedEvent") - { - InvokeEvent(_onCrossPromoAdClickedEvent, adUnitIdentifier, adInfo, eventName); - } - else if (eventName == "OnCrossPromoAdRevenuePaidEvent") - { - InvokeEvent(_onCrossPromoAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); - } - else if (eventName == "OnCrossPromoAdExpandedEvent") - { - InvokeEvent(_onCrossPromoAdExpandedEvent, adUnitIdentifier, adInfo, eventName); - } - else if (eventName == "OnCrossPromoAdCollapsedEvent") - { - InvokeEvent(_onCrossPromoAdCollapsedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onMRecAdCollapsedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onMRecAdCollapsedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialLoadedEvent") { - InvokeEvent(_onInterstitialAdLoadedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onInterstitialAdLoadedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onInterstitialAdLoadedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onInterstitialAdLoadedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialLoadFailedEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onInterstitialLoadFailedEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onInterstitialLoadFailedEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onInterstitialAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onInterstitialAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialHiddenEvent") { - InvokeEvent(_onInterstitialAdHiddenEvent, adUnitIdentifier, eventName); - InvokeEvent(_onInterstitialAdHiddenEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onInterstitialAdHiddenEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onInterstitialAdHiddenEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialDisplayedEvent") { - InvokeEvent(_onInterstitialAdDisplayedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onInterstitialAdDisplayedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onInterstitialAdDisplayedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onInterstitialAdDisplayedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialAdFailedToDisplayEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onInterstitialAdFailedToDisplayEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onInterstitialAdFailedToDisplayEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onInterstitialAdFailedToDisplayEventV2, adUnitIdentifier, errorInfo, adInfo, eventName); + InvokeEvent(_onInterstitialAdFailedToDisplayEventV2, adUnitIdentifier, errorInfo, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialClickedEvent") { - InvokeEvent(_onInterstitialAdClickedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onInterstitialAdClickedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onInterstitialAdClickedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onInterstitialAdClickedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialAdRevenuePaidEvent") { - InvokeEvent(_onInterstitialAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onInterstitialAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnInterstitialAdReviewCreativeIdGeneratedEvent") { var adReviewCreativeId = MaxSdkUtils.GetStringFromDictionary(eventProps, "adReviewCreativeId", ""); - InvokeEvent(_onInterstitialAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName); + InvokeEvent(_onInterstitialAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdLoadedEvent") { - InvokeEvent(_onAppOpenAdLoadedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onAppOpenAdLoadedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdLoadFailedEvent") { var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onAppOpenAdLoadFailedEvent, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onAppOpenAdLoadFailedEvent, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdHiddenEvent") { - InvokeEvent(_onAppOpenAdHiddenEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onAppOpenAdHiddenEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdDisplayedEvent") { - InvokeEvent(_onAppOpenAdDisplayedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onAppOpenAdDisplayedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdFailedToDisplayEvent") { var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onAppOpenAdFailedToDisplayEvent, adUnitIdentifier, errorInfo, adInfo, eventName); + InvokeEvent(_onAppOpenAdFailedToDisplayEvent, adUnitIdentifier, errorInfo, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdClickedEvent") { - InvokeEvent(_onAppOpenAdClickedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onAppOpenAdClickedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnAppOpenAdRevenuePaidEvent") { - InvokeEvent(_onAppOpenAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onAppOpenAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdLoadedEvent") { - InvokeEvent(_onRewardedAdLoadedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onRewardedAdLoadedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedAdLoadedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onRewardedAdLoadedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdLoadFailedEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onRewardedAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onRewardedAdLoadFailedEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onRewardedAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onRewardedAdLoadFailedEventV2, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdDisplayedEvent") { - InvokeEvent(_onRewardedAdDisplayedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onRewardedAdDisplayedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedAdDisplayedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onRewardedAdDisplayedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdHiddenEvent") { - InvokeEvent(_onRewardedAdHiddenEvent, adUnitIdentifier, eventName); - InvokeEvent(_onRewardedAdHiddenEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedAdHiddenEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onRewardedAdHiddenEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdClickedEvent") { - InvokeEvent(_onRewardedAdClickedEvent, adUnitIdentifier, eventName); - InvokeEvent(_onRewardedAdClickedEventV2, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedAdClickedEvent, adUnitIdentifier, eventName, keepInBackground); + InvokeEvent(_onRewardedAdClickedEventV2, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdRevenuePaidEvent") { - InvokeEvent(_onRewardedAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdReviewCreativeIdGeneratedEvent") { var adReviewCreativeId = MaxSdkUtils.GetStringFromDictionary(eventProps, "adReviewCreativeId", ""); - InvokeEvent(_onRewardedAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName); + InvokeEvent(_onRewardedAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdFailedToDisplayEvent") { var errorCode = MaxSdkUtils.GetIntFromDictionary(eventProps, "errorCode", -1); - InvokeEvent(_onRewardedAdFailedToDisplayEvent, adUnitIdentifier, errorCode, eventName); + InvokeEvent(_onRewardedAdFailedToDisplayEvent, adUnitIdentifier, errorCode, eventName, keepInBackground); var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onRewardedAdFailedToDisplayEventV2, adUnitIdentifier, errorInfo, adInfo, eventName); + InvokeEvent(_onRewardedAdFailedToDisplayEventV2, adUnitIdentifier, errorInfo, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedAdReceivedRewardEvent") { @@ -1584,45 +1434,45 @@ public class MaxSdkCallbacks : MonoBehaviour Amount = MaxSdkUtils.GetIntFromDictionary(eventProps, "rewardAmount", 0) }; - InvokeEvent(_onRewardedAdReceivedRewardEvent, adUnitIdentifier, reward, eventName); - InvokeEvent(_onRewardedAdReceivedRewardEventV2, adUnitIdentifier, reward, adInfo, eventName); + InvokeEvent(_onRewardedAdReceivedRewardEvent, adUnitIdentifier, reward, eventName, keepInBackground); + InvokeEvent(_onRewardedAdReceivedRewardEventV2, adUnitIdentifier, reward, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdLoadedEvent") { - InvokeEvent(_onRewardedInterstitialAdLoadedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdLoadedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdLoadFailedEvent") { var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onRewardedInterstitialAdLoadFailedEvent, adUnitIdentifier, errorInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdLoadFailedEvent, adUnitIdentifier, errorInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdDisplayedEvent") { - InvokeEvent(_onRewardedInterstitialAdDisplayedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdDisplayedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdHiddenEvent") { - InvokeEvent(_onRewardedInterstitialAdHiddenEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdHiddenEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdClickedEvent") { - InvokeEvent(_onRewardedInterstitialAdClickedEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdClickedEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdRevenuePaidEvent") { - InvokeEvent(_onRewardedInterstitialAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdRevenuePaidEvent, adUnitIdentifier, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdReviewCreativeIdGeneratedEvent") { var adReviewCreativeId = MaxSdkUtils.GetStringFromDictionary(eventProps, "adReviewCreativeId", ""); - InvokeEvent(_onRewardedInterstitialAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdReviewCreativeIdGeneratedEvent, adUnitIdentifier, adReviewCreativeId, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdFailedToDisplayEvent") { var errorInfo = new MaxSdkBase.ErrorInfo(eventProps); - InvokeEvent(_onRewardedInterstitialAdFailedToDisplayEvent, adUnitIdentifier, errorInfo, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdFailedToDisplayEvent, adUnitIdentifier, errorInfo, adInfo, eventName, keepInBackground); } else if (eventName == "OnRewardedInterstitialAdReceivedRewardEvent") { @@ -1632,7 +1482,7 @@ public class MaxSdkCallbacks : MonoBehaviour Amount = MaxSdkUtils.GetIntFromDictionary(eventProps, "rewardAmount", 0) }; - InvokeEvent(_onRewardedInterstitialAdReceivedRewardEvent, adUnitIdentifier, reward, adInfo, eventName); + InvokeEvent(_onRewardedInterstitialAdReceivedRewardEvent, adUnitIdentifier, reward, adInfo, eventName, keepInBackground); } else { @@ -1650,36 +1500,96 @@ public class MaxSdkCallbacks : MonoBehaviour } #endif - private static void InvokeEvent(Action evt, string eventName) + private static void InvokeEvent(Action evt, string eventName, bool keepInBackground) { if (!CanInvokeEvent(evt)) return; MaxSdkLogger.UserDebug("Invoking event: " + eventName); - evt(); + if (keepInBackground) + { + try + { + evt(); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Caught exception in publisher event: " + eventName + ", exception: " + exception); + Debug.LogException(exception); + } + } + else + { + MaxEventExecutor.ExecuteOnMainThread(evt, eventName); + } } - private static void InvokeEvent(Action evt, T param, string eventName) + private static void InvokeEvent(Action evt, T param, string eventName, bool keepInBackground) { if (!CanInvokeEvent(evt)) return; MaxSdkLogger.UserDebug("Invoking event: " + eventName + ". Param: " + param); - evt(param); + if (keepInBackground) + { + try + { + evt(param); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Caught exception in publisher event: " + eventName + ", exception: " + exception); + Debug.LogException(exception); + } + } + else + { + MaxEventExecutor.ExecuteOnMainThread(() => evt(param), eventName); + } } - private static void InvokeEvent(Action evt, T1 param1, T2 param2, string eventName) + private static void InvokeEvent(Action evt, T1 param1, T2 param2, string eventName, bool keepInBackground) { if (!CanInvokeEvent(evt)) return; MaxSdkLogger.UserDebug("Invoking event: " + eventName + ". Params: " + param1 + ", " + param2); - evt(param1, param2); + if (keepInBackground) + { + try + { + evt(param1, param2); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Caught exception in publisher event: " + eventName + ", exception: " + exception); + Debug.LogException(exception); + } + } + else + { + MaxEventExecutor.ExecuteOnMainThread(() => evt(param1, param2), eventName); + } } - private static void InvokeEvent(Action evt, T1 param1, T2 param2, T3 param3, string eventName) + private static void InvokeEvent(Action evt, T1 param1, T2 param2, T3 param3, string eventName, bool keepInBackground) { if (!CanInvokeEvent(evt)) return; MaxSdkLogger.UserDebug("Invoking event: " + eventName + ". Params: " + param1 + ", " + param2 + ", " + param3); - evt(param1, param2, param3); + if (keepInBackground) + { + try + { + evt(param1, param2, param3); + } + catch (Exception exception) + { + MaxSdkLogger.UserError("Caught exception in publisher event: " + eventName + ", exception: " + exception); + Debug.LogException(exception); + } + } + else + { + MaxEventExecutor.ExecuteOnMainThread(() => evt(param1, param2, param3), eventName); + } } private static bool CanInvokeEvent(Delegate evt) @@ -1768,13 +1678,6 @@ public class MaxSdkCallbacks : MonoBehaviour _onMRecAdExpandedEventV2 = null; _onMRecAdCollapsedEventV2 = null; - _onCrossPromoAdLoadedEvent = null; - _onCrossPromoAdLoadFailedEvent = null; - _onCrossPromoAdClickedEvent = null; - _onCrossPromoAdRevenuePaidEvent = null; - _onCrossPromoAdExpandedEvent = null; - _onCrossPromoAdCollapsedEvent = null; - _onBannerAdLoadedEvent = null; _onBannerAdLoadFailedEvent = null; _onBannerAdClickedEvent = null; diff --git a/MaxSdk/Scripts/MaxSdkUnityEditor.cs b/MaxSdk/Scripts/MaxSdkUnityEditor.cs index 61c93b1..11ff89b 100644 --- a/MaxSdk/Scripts/MaxSdkUnityEditor.cs +++ b/MaxSdk/Scripts/MaxSdkUnityEditor.cs @@ -6,6 +6,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; +using AppLovinMax.Internal; using AppLovinMax.ThirdParty.MiniJson; #if UNITY_EDITOR using UnityEditor; @@ -28,6 +29,7 @@ public class MaxSdkUnityEditor : MaxSdkBase private static bool _doNotSell = false; private static bool _isDoNotSellSet = false; private static bool _showStubAds = true; + private static SafeAreaInsets _safeAreaInsets = new SafeAreaInsets(new int[] {0, 0, 0, 0}); private static readonly HashSet RequestedAdUnits = new HashSet(); private static readonly HashSet ReadyAdUnits = new HashSet(); private static readonly Dictionary StubBanners = new Dictionary(); @@ -49,6 +51,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// This method must be called before any other SDK operation /// + /// AppLovin SDK key. Must not be null. public static void SetSdkKey(string sdkKey) { _hasSdkKey = true; @@ -111,7 +114,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// For example, a username or email. We'll include this in the postback when we ping your currency endpoint from our server. /// /// - /// The user identifier to be set. + /// The user identifier to be set. Must not be null. public static void SetUserId(string userId) { } /// @@ -184,8 +187,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Returns the arbitrary ad value for a given ad unit identifier with key. Returns null if no ad is loaded. /// - /// - /// Ad value key + /// Ad unit identifier for which to get the ad value for. Must not be null. + /// Ad value key. Must not be null. /// Arbitrary ad value for a given key, or null if no ad is loaded. public static string GetAdValue(string adUnitIdentifier, string key) { @@ -297,8 +300,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Create a new banner. /// - /// Ad unit identifier of the banner to create - /// Banner position + /// Ad unit identifier of the banner to create. Must not be null. + /// Banner position. Must not be null. public static void CreateBanner(string adUnitIdentifier, BannerPosition bannerPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create banner"); @@ -312,14 +315,14 @@ public class MaxSdkUnityEditor : MaxSdkBase ExecuteWithDelay(1f, () => { var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnBannerAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Create a new banner with a custom position. /// - /// Ad unit identifier of the banner to create + /// Ad unit identifier of the banner to create. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -356,7 +359,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// NOTE: The method loads the first banner ad and initiates an automated banner refresh process. /// You only need to call this method if you pause banner refresh. /// - /// Ad unit identifier of the banner to load + /// Ad unit identifier of the banner to load. Must not be null. public static void LoadBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load banner"); @@ -364,14 +367,14 @@ public class MaxSdkUnityEditor : MaxSdkBase ExecuteWithDelay(1f, () => { var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnBannerAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Set the banner placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the banner to set the placement for + /// Ad unit identifier of the banner to set the placement for. Must not be null. /// Placement to set public static void SetBannerPlacement(string adUnitIdentifier, string placement) { @@ -381,7 +384,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Starts or resumes auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to start auto-refresh + /// Ad unit identifier of the banner for which to start auto-refresh. Must not be null. public static void StartBannerAutoRefresh(string adUnitIdentifier) { MaxSdkLogger.UserDebug("Starting banner auto refresh."); @@ -390,7 +393,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Pauses auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to stop auto-refresh + /// Ad unit identifier of the banner for which to stop auto-refresh. Must not be null. public static void StopBannerAutoRefresh(string adUnitIdentifier) { MaxSdkLogger.UserDebug("Stopping banner auto refresh."); @@ -399,8 +402,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Updates the position of the banner to the new position provided. /// - /// The ad unit identifier of the banner for which to update the position - /// A new position for the banner + /// The ad unit identifier of the banner for which to update the position. Must not be null. + /// A new position for the banner. Must not be null. public static void UpdateBannerPosition(string adUnitIdentifier, BannerPosition bannerPosition) { Debug.Log("[AppLovin MAX] Updating banner position to '" + bannerPosition + "' for ad unit id '" + adUnitIdentifier + "'"); @@ -409,7 +412,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Updates the position of the banner to the new coordinates provided. /// - /// The ad unit identifier of the banner for which to update the position + /// The ad unit identifier of the banner for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -423,7 +426,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Overrides the width of the banner in points/dp. /// - /// The ad unit identifier of the banner for which to override the width for + /// The ad unit identifier of the banner for which to override the width for. Must not be null. /// The desired width of the banner in points/dp public static void SetBannerWidth(string adUnitIdentifier, float width) { @@ -434,7 +437,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Show banner at a position determined by the 'CreateBanner' call. /// - /// Ad unit identifier of the banner to show + /// Ad unit identifier of the banner to show. Must not be null. public static void ShowBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show banner"); @@ -456,7 +459,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Remove banner from the ad view and destroy it. /// - /// Ad unit identifier of the banner to destroy + /// Ad unit identifier of the banner to destroy. Must not be null. public static void DestroyBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy banner"); @@ -472,8 +475,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Hide banner. /// - /// Ad unit identifier of the banner to hide - /// + /// Ad unit identifier of the banner to hide. Must not be null. public static void HideBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide banner"); @@ -488,9 +490,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set non-transparent background color for banners to be fully functional. /// - /// Ad unit identifier of the banner to set background color for - /// A background color to set for the ad - /// + /// Ad unit identifier of the banner to set background color for. Must not be null. + /// A background color to set for the ad. Must not be null. public static void SetBannerBackgroundColor(string adUnitIdentifier, Color color) { ValidateAdUnitIdentifier(adUnitIdentifier, "set background color"); @@ -505,8 +506,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set an extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the banner to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetBannerExtraParameter(string adUnitIdentifier, string key, string value) { @@ -516,8 +517,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set a local extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the banner to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. public static void SetBannerLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -527,7 +528,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// The custom data to tie the showing banner ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// Banner ad unit identifier of the banner to set the custom data for. + /// Banner ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetBannerCustomData(string adUnitIdentifier, string customData) { @@ -538,7 +539,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// The banner position on the screen. When setting the banner position via or , /// the banner is placed within the safe area of the screen. This returns the absolute position of the banner on screen. /// - /// Ad unit identifier of the banner for which to get the position on screen. + /// Ad unit identifier of the banner for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetBannerLayout(string adUnitIdentifier) { @@ -553,8 +554,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Create a new MREC. /// - /// Ad unit identifier of the MREC to create - /// MREC position + /// Ad unit identifier of the MREC to create. Must not be null. + /// MREC position. Must not be null. public static void CreateMRec(string adUnitIdentifier, AdViewPosition mrecPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create MREC"); @@ -563,14 +564,14 @@ public class MaxSdkUnityEditor : MaxSdkBase ExecuteWithDelay(1f, () => { var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnMRecAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Create a new MREC with a custom position. /// - /// Ad unit identifier of the MREC to create + /// Ad unit identifier of the MREC to create. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -587,7 +588,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// NOTE: The method loads the first MREC ad and initiates an automated MREC refresh process. /// You only need to call this method if you pause MREC refresh. /// - /// Ad unit identifier of the MREC to load + /// Ad unit identifier of the MREC to load. Must not be null. public static void LoadMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load MREC"); @@ -595,14 +596,14 @@ public class MaxSdkUnityEditor : MaxSdkBase ExecuteWithDelay(1f, () => { var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnMRecAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Set the MREC placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the MREC to set the placement for + /// Ad unit identifier of the MREC to set the placement for. Must not be null. /// Placement to set public static void SetMRecPlacement(string adUnitIdentifier, string placement) { @@ -612,7 +613,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Starts or resumes auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to start auto-refresh + /// Ad unit identifier of the MREC for which to start auto-refresh. Must not be null. public static void StartMRecAutoRefresh(string adUnitIdentifier) { MaxSdkLogger.UserDebug("Starting banner auto refresh."); @@ -621,7 +622,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Pauses auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to stop auto-refresh + /// Ad unit identifier of the MREC for which to stop auto-refresh. Must not be null. public static void StopMRecAutoRefresh(string adUnitIdentifier) { MaxSdkLogger.UserDebug("Stopping banner auto refresh."); @@ -630,8 +631,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Updates the position of the MREC to the new position provided. /// - /// The ad unit identifier of the MREC for which to update the position - /// A new position for the MREC + /// The ad unit identifier of the MREC for which to update the position. Must not be null. + /// A new position for the MREC. Must not be null. public static void UpdateMRecPosition(string adUnitIdentifier, AdViewPosition mrecPosition) { MaxSdkLogger.UserDebug("Updating MREC position to '" + mrecPosition + "' for ad unit id '" + adUnitIdentifier + "'"); @@ -640,7 +641,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Updates the position of the MREC to the new coordinates provided. /// - /// The ad unit identifier of the MREC for which to update the position + /// The ad unit identifier of the MREC for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -654,7 +655,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Show MREC at a position determined by the 'CreateMRec' call. /// - /// Ad unit identifier of the MREC to show + /// Ad unit identifier of the MREC to show. Must not be null. public static void ShowMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show MREC"); @@ -668,7 +669,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Remove MREC from the ad view and destroy it. /// - /// Ad unit identifier of the MREC to destroy + /// Ad unit identifier of the MREC to destroy. Must not be null. public static void DestroyMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy MREC"); @@ -677,7 +678,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Hide MREC. /// - /// Ad unit identifier of the MREC to hide + /// Ad unit identifier of the MREC to hide. Must not be null. public static void HideMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide MREC"); @@ -686,8 +687,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set an extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the MREC to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetMRecExtraParameter(string adUnitIdentifier, string key, string value) { @@ -697,8 +698,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set a local extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the MREC to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. public static void SetMRecLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -708,7 +709,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// The custom data to tie the showing MREC ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// MREC Ad unit identifier of the banner to set the custom data for. + /// MREC Ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetMRecCustomData(string adUnitIdentifier, string customData) { @@ -719,7 +720,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// The MREC position on the screen. When setting the MREC position via or , /// the MREC is placed within the safe area of the screen. This returns the absolute position of the MREC on screen. /// - /// Ad unit identifier of the MREC for which to get the position on screen. + /// Ad unit identifier of the MREC for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetMRecLayout(string adUnitIdentifier) { @@ -729,99 +730,6 @@ public class MaxSdkUnityEditor : MaxSdkBase #endregion - #region Cross Promo Ads - - /// - /// Create a new cross promo ad with a custom position. - /// - /// Ad unit identifier of the cross promo ad to create - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void CreateCrossPromoAd(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "create cross promo ad"); - RequestAdUnit(adUnitIdentifier); - } - - /// - /// Set the cross promo ad placement for an ad unit identifier to tie the future ad events to. - /// - /// Ad unit identifier of the cross promo ad to set the placement for - /// Placement to set - public static void SetCrossPromoAdPlacement(string adUnitIdentifier, string placement) - { - MaxSdkLogger.UserDebug("Setting cross promo ad placement to '" + placement + "' for ad unit id '" + adUnitIdentifier + "'"); - } - - /// - /// Updates the position of the cross promo ad to the new coordinates provided. - /// - /// The ad unit identifier of the cross promo ad for which to update the position - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo ad is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void UpdateCrossPromoAdPosition(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - MaxSdkLogger.UserDebug("Updating cross promo ad position to (" + x + "," + y + ") with size " + width + " x " + height + " and rotation of " + rotation + " degrees"); - } - - /// - /// Show cross promo ad at a position determined by the 'CreateCrossPromoAd' call. - /// - /// Ad unit identifier of the cross promo ad to show - public static void ShowCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "show cross promo ad"); - - if (!IsAdUnitRequested(adUnitIdentifier)) - { - MaxSdkLogger.UserWarning("Cross promo ad '" + adUnitIdentifier + "' was not created, can not show it"); - } - } - - /// - /// Remove cross promo ad from the ad view and destroy it. - /// - /// Ad unit identifier of the cross promo ad to destroy - public static void DestroyCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "destroy cross promo ad"); - } - - /// - /// Hide cross promo ad. - /// - /// Ad unit identifier of the cross promo ad to hide - public static void HideCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "hide cross promo ad"); - } - - /// - /// The cross promo ad position on the screen. When setting the cross promo ad position via or , - /// the cross promo ad is placed within the safe area of the screen. This returns the absolute position of the cross promo ad on screen. - /// - /// Ad unit identifier of the cross promo ad for which to get the position on screen. - /// A representing the banner position on screen. - public static Rect GetCrossPromoAdLayout(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "get cross promo ad layout"); - return Rect.zero; - } - - #endregion - #region Interstitials /// @@ -838,7 +746,7 @@ public class MaxSdkUnityEditor : MaxSdkBase AddReadyAdUnit(adUnitIdentifier); var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnInterstitialLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } @@ -906,12 +814,12 @@ public class MaxSdkUnityEditor : MaxSdkBase closeButton.onClick.AddListener(() => { var adHiddenEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnInterstitialHiddenEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adHiddenEventProps); + MaxSdkCallbacks.ForwardEvent(adHiddenEventProps); Object.Destroy(stubInterstitial); }); var adDisplayedEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnInterstitialDisplayedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adDisplayedEventProps); + MaxSdkCallbacks.ForwardEvent(adDisplayedEventProps); #endif } @@ -944,7 +852,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Start loading an app open ad. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. public static void LoadAppOpenAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load app open ad"); @@ -955,14 +863,14 @@ public class MaxSdkUnityEditor : MaxSdkBase AddReadyAdUnit(adUnitIdentifier); var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnAppOpenAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Check if app open ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsAppOpenAdReady(string adUnitIdentifier) { @@ -981,7 +889,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Present loaded app open ad for a given placement to tie ad events to. Note: if the app open ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowAppOpenAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1023,20 +931,20 @@ public class MaxSdkUnityEditor : MaxSdkBase closeButton.onClick.AddListener(() => { var adHiddenEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnAppOpenAdHiddenEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adHiddenEventProps); + MaxSdkCallbacks.ForwardEvent(adHiddenEventProps); Object.Destroy(stubAppOpenAd); }); var adDisplayedEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnAppOpenAdDisplayedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adDisplayedEventProps); + MaxSdkCallbacks.ForwardEvent(adDisplayedEventProps); #endif } /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the app open ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetAppOpenAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1046,8 +954,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the app open ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. public static void SetAppOpenAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1061,7 +969,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Start loading an rewarded ad. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. public static void LoadRewardedAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded ad"); @@ -1071,14 +979,14 @@ public class MaxSdkUnityEditor : MaxSdkBase { AddReadyAdUnit(adUnitIdentifier); var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Check if rewarded ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedAdReady(string adUnitIdentifier) { @@ -1097,7 +1005,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Present loaded rewarded ad for a given placement to tie ad events to. Note: if the rewarded ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1147,11 +1055,11 @@ public class MaxSdkUnityEditor : MaxSdkBase rewardEventPropsDict["rewardLabel"] = "coins"; rewardEventPropsDict["rewardAmount"] = "5"; var rewardEventProps = Json.Serialize(rewardEventPropsDict); - MaxSdkCallbacks.Instance.ForwardEvent(rewardEventProps); + MaxSdkCallbacks.ForwardEvent(rewardEventProps); } var adHiddenEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedAdHiddenEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adHiddenEventProps); + MaxSdkCallbacks.ForwardEvent(adHiddenEventProps); Object.Destroy(stubRewardedAd); }); rewardButton.onClick.AddListener(() => @@ -1161,15 +1069,15 @@ public class MaxSdkUnityEditor : MaxSdkBase }); var adDisplayedEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedAdDisplayedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adDisplayedEventProps); + MaxSdkCallbacks.ForwardEvent(adDisplayedEventProps); #endif } /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1179,8 +1087,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. public static void SetRewardedAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1194,7 +1102,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Start loading an rewarded interstitial ad. /// - /// Ad unit identifier of the rewarded interstitial ad to load + /// Ad unit identifier of the rewarded interstitial ad to load. Must not be null. public static void LoadRewardedInterstitialAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded interstitial ad"); @@ -1204,14 +1112,14 @@ public class MaxSdkUnityEditor : MaxSdkBase { AddReadyAdUnit(adUnitIdentifier); var eventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedInterstitialAdLoadedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(eventProps); + MaxSdkCallbacks.ForwardEvent(eventProps); }); } /// /// Check if rewarded interstitial ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedInterstitialAdReady(string adUnitIdentifier) { @@ -1230,7 +1138,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Present loaded rewarded interstitial ad for a given placement to tie ad events to. Note: if the rewarded interstitial ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the rewarded interstitial to show + /// Ad unit identifier of the rewarded interstitial to show. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedInterstitialAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1280,11 +1188,11 @@ public class MaxSdkUnityEditor : MaxSdkBase rewardEventPropsDict["rewardLabel"] = "coins"; rewardEventPropsDict["rewardAmount"] = "5"; var rewardEventProps = Json.Serialize(rewardEventPropsDict); - MaxSdkCallbacks.Instance.ForwardEvent(rewardEventProps); + MaxSdkCallbacks.ForwardEvent(rewardEventProps); } var adHiddenEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedInterstitialAdHiddenEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adHiddenEventProps); + MaxSdkCallbacks.ForwardEvent(adHiddenEventProps); Object.Destroy(stubRewardedAd); }); rewardButton.onClick.AddListener(() => @@ -1294,15 +1202,15 @@ public class MaxSdkUnityEditor : MaxSdkBase }); var adDisplayedEventProps = Json.Serialize(CreateBaseEventPropsDictionary("OnRewardedAdDisplayedEvent", adUnitIdentifier)); - MaxSdkCallbacks.Instance.ForwardEvent(adDisplayedEventProps); + MaxSdkCallbacks.ForwardEvent(adDisplayedEventProps); #endif } /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded interstitial ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedInterstitialAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1312,8 +1220,8 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded interstitial ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. public static void SetRewardedInterstitialAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1327,7 +1235,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// Track an event using AppLovin. /// - /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. + /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. Must not be null. /// A dictionary containing key-value pairs further describing this event. public static void TrackEvent(string name, IDictionary parameters = null) { } @@ -1395,7 +1303,7 @@ public class MaxSdkUnityEditor : MaxSdkBase /// /// String list of advertising identifiers from devices to receive test ads. public static void SetTestDeviceAdvertisingIdentifiers(string[] advertisingIdentifiers) - { + { if (IsInitialized()) { MaxSdkLogger.UserError("Test Device Advertising Identifiers must be set before SDK initialization."); @@ -1421,6 +1329,15 @@ public class MaxSdkUnityEditor : MaxSdkBase /// The value for the extra parameter. May be null. public static void SetExtraParameter(string key, string value) { } + /// + /// Get the native insets in pixels for the safe area. + /// These insets are used to position ads within the safe area of the screen. + /// + public static SafeAreaInsets GetSafeAreaInsets() + { + return _safeAreaInsets; + } + #endregion #region Internal @@ -1481,7 +1398,7 @@ public class MaxSdkUnityEditor : MaxSdkBase private static void ExecuteWithDelay(float seconds, Action action) { - MaxSdkCallbacks.Instance.StartCoroutine(ExecuteAction(seconds, action)); + MaxEventExecutor.Instance.StartCoroutine(ExecuteAction(seconds, action)); } private static IEnumerator ExecuteAction(float seconds, Action action) diff --git a/MaxSdk/Scripts/MaxSdkUtils.cs b/MaxSdk/Scripts/MaxSdkUtils.cs index 063106d..cbab2d3 100644 --- a/MaxSdk/Scripts/MaxSdkUtils.cs +++ b/MaxSdk/Scripts/MaxSdkUtils.cs @@ -350,27 +350,21 @@ public class MaxSdkUtils } /// - /// Parses the IAB TCF String to determine the consent status for the IAB vendor with the provided ID. + /// Parses the IABTCF_VendorConsents string to determine the consent status of the IAB vendor with the provided ID. + /// NOTE: Must be called after AppLovin MAX SDK has been initialized. /// /// Vendor ID as defined in the Global Vendor List. - /// The consent status of the IAB vendor. Returns true if the vendor has consent, false if not, or null if no TCF string is available on disk. + /// true if the vendor has consent, false if not, or null if TC data is not available on disk. /// Current Version of Global Vendor List public static bool? GetTcfConsentStatus(int vendorId) { var tcfConsentStatus = GetPlatformSpecificTcfConsentStatus(vendorId); - if (tcfConsentStatus == -1) - { - return null; - } - else - { - return tcfConsentStatus == 1; - } + return GetConsentStatusValue(tcfConsentStatus); } #if UNITY_IOS [DllImport("__Internal")] - private static extern int _MaxGetTcfConsentStatus(int vendorIdentifier); + private static extern int _MaxGetTcfVendorConsentStatus(int vendorIdentifier); #endif private static int GetPlatformSpecificTcfConsentStatus(int vendorId) @@ -378,34 +372,28 @@ public class MaxSdkUtils #if UNITY_EDITOR return -1; #elif UNITY_IOS - return _MaxGetTcfConsentStatus(vendorId); + return _MaxGetTcfVendorConsentStatus(vendorId); #elif UNITY_ANDROID - return MaxUnityPluginClass.CallStatic("getTcfConsentStatus", vendorId); + return MaxUnityPluginClass.CallStatic("getTcfVendorConsentStatus", vendorId); #else return -1; #endif } /// - /// Parses the Google UMP's Additional Consent (AC) string to determine the consent status for the advertising entity represented by the provided Ad Technology Provider (ATP) ID. + /// Parses the IABTCF_AddtlConsent string to determine the consent status of the advertising entity with the provided Ad Technology Provider (ATP) ID. + /// NOTE: Must be called after AppLovin MAX SDK has been initialized. /// - /// The ID representing the advertising entity (e.g. 89 for Meta Audience Network). + /// ATP ID of the advertising entity (e.g. 89 for Meta Audience Network). /// - /// The consent status of the advertising entity. Returns true if the entity has consent, false if not, or null if no AC string is available on disk. + /// true if the advertising entity has consent, false if not, or null if no AC string is available on disk or the ATP network was not listed in the CMP flow. /// /// Google’s Additional Consent Mode technical specification /// List of Google ATPs and their IDs public static bool? GetAdditionalConsentStatus(int atpId) { var additionalConsentStatus = GetPlatformSpecificAdditionalConsentStatus(atpId); - if (additionalConsentStatus == -1) - { - return null; - } - else - { - return additionalConsentStatus == 1; - } + return GetConsentStatusValue(additionalConsentStatus); } #if UNITY_IOS @@ -426,6 +414,80 @@ public class MaxSdkUtils #endif } + /// + /// Parses the IABTCF_PurposeConsents String to determine the consent status of the IAB defined data processing purpose. + /// NOTE: Must be called after AppLovin MAX SDK has been initialized. + /// + /// Purpose ID. + /// true if the purpose has consent, false if not, or null if TC data is not available on disk. + /// see IAB Europe Transparency and Consent Framework Policies (Appendix A) for purpose definitions. + public static bool? GetPurposeConsentStatus(int purposeId) + { + var purposeConsentStatus = GetPlatformSpecificPurposeConsentStatus(purposeId); + return GetConsentStatusValue(purposeConsentStatus); + } + +#if UNITY_IOS + [DllImport("__Internal")] + private static extern int _MaxGetPurposeConsentStatus(int purposeIdentifier); +#endif + + private static int GetPlatformSpecificPurposeConsentStatus(int purposeId) + { +#if UNITY_EDITOR + return -1; +#elif UNITY_IOS + return _MaxGetPurposeConsentStatus(purposeId); +#elif UNITY_ANDROID + return MaxUnityPluginClass.CallStatic("getPurposeConsentStatus", purposeId); +#else + return -1; +#endif + } + + /// + /// Parses the IABTCF_SpecialFeaturesOptIns String to determine the opt-in status of the IAB defined special feature. + /// NOTE: Must be called after AppLovin MAX SDK has been initialized. + /// + /// Special feature ID. + /// true if the user opted in for the special feature, false if not, or null if TC data is not available on disk. + /// IAB Europe Transparency and Consent Framework Policies (Appendix A) for special features + public static bool? GetSpecialFeatureOptInStatus(int specialFeatureId) + { + var specialFeatureOptInStatus = GetPlatformSpecificSpecialFeatureOptInStatus(specialFeatureId); + return GetConsentStatusValue(specialFeatureOptInStatus); + } + +#if UNITY_IOS + [DllImport("__Internal")] + private static extern int _MaxGetSpecialFeatureOptInStatus(int specialFeatureIdentifier); +#endif + + private static int GetPlatformSpecificSpecialFeatureOptInStatus(int specialFeatureId) + { +#if UNITY_EDITOR + return -1; +#elif UNITY_IOS + return _MaxGetSpecialFeatureOptInStatus(specialFeatureId); +#elif UNITY_ANDROID + return MaxUnityPluginClass.CallStatic("getSpecialFeatureOptInStatus", specialFeatureId); +#else + return -1; +#endif + } + + private static bool? GetConsentStatusValue(int consentStatus) + { + if (consentStatus == -1) + { + return null; + } + else + { + return consentStatus == 1; + } + } + /// /// Compares AppLovin MAX Unity mediation adapter plugin versions. Returns , , /// or as the first version is less than, equal to, or greater than the second. @@ -493,7 +555,6 @@ public class MaxSdkUtils iosComparison = VersionComparisonResult.Lesser; } - // If either one of the Android or iOS version is greater, the entire version should be greater. return (androidComparison == VersionComparisonResult.Greater || iosComparison == VersionComparisonResult.Greater) ? VersionComparisonResult.Greater : VersionComparisonResult.Lesser; } @@ -520,7 +581,7 @@ public class MaxSdkUtils var versionABetaNumber = 0; if (isVersionABeta) { - var components = versionA.Split(new[] {"-beta"}, StringSplitOptions.None); + var components = versionA.Split(new[] { "-beta" }, StringSplitOptions.None); versionA = components[0]; versionABetaNumber = int.TryParse(components[1], out piece) ? piece : 0; } @@ -529,7 +590,7 @@ public class MaxSdkUtils var versionBBetaNumber = 0; if (isVersionBBeta) { - var components = versionB.Split(new[] {"-beta"}, StringSplitOptions.None); + var components = versionB.Split(new[] { "-beta" }, StringSplitOptions.None); versionB = components[0]; versionBBetaNumber = int.TryParse(components[1], out piece) ? piece : 0; } diff --git a/MaxSdk/Scripts/MaxSdkiOS.cs b/MaxSdk/Scripts/MaxSdkiOS.cs index 4254776..d128f1a 100644 --- a/MaxSdk/Scripts/MaxSdkiOS.cs +++ b/MaxSdk/Scripts/MaxSdkiOS.cs @@ -15,7 +15,7 @@ public class MaxSdkiOS : MaxSdkBase static MaxSdkiOS() { - InitCallbacks(); + InitializeEventExecutor(); } #if UNITY_IOS @@ -34,6 +34,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// This method must be called before any other SDK operation /// + /// AppLovin SDK key. Must not be null. public static void SetSdkKey(string sdkKey) { _MaxSetSdkKey(sdkKey); @@ -82,7 +83,7 @@ public class MaxSdkiOS : MaxSdkBase /// For example, a username or email. We'll include this in the postback when we ping your currency endpoint from our server. /// /// - /// The user identifier to be set. + /// The user identifier to be set. Must not be null. public static void SetUserId(string userId) { _MaxSetUserId(userId); @@ -156,8 +157,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Returns the arbitrary ad value for a given ad unit identifier with key. Returns null if no ad is loaded. /// - /// - /// Ad value key + /// Ad unit identifier for which to get the ad value for. Must not be null. + /// Ad value key. Must not be null. /// Arbitrary ad value for a given key, or null if no ad is loaded. public static string GetAdValue(string adUnitIdentifier, string key) { @@ -305,8 +306,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Create a new banner. /// - /// Ad unit identifier of the banner to create - /// Banner position + /// Ad unit identifier of the banner to create. Must not be null. + /// Banner position. Must not be null. public static void CreateBanner(string adUnitIdentifier, BannerPosition bannerPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create banner"); @@ -319,7 +320,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Create a new banner with a custom position. /// - /// Ad unit identifier of the banner to create + /// Ad unit identifier of the banner to create. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -339,7 +340,7 @@ public class MaxSdkiOS : MaxSdkBase /// NOTE: The method loads the first banner ad and initiates an automated banner refresh process. /// You only need to call this method if you pause banner refresh. /// - /// Ad unit identifier of the banner to load + /// Ad unit identifier of the banner to load. Must not be null. public static void LoadBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load banner"); @@ -352,7 +353,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set the banner placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the banner to set the placement for + /// Ad unit identifier of the banner to set the placement for. Must not be null. /// Placement to set public static void SetBannerPlacement(string adUnitIdentifier, string placement) { @@ -366,7 +367,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Starts or resumes auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to start auto-refresh + /// Ad unit identifier of the banner for which to start auto-refresh. Must not be null. public static void StartBannerAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "start banner auto-refresh"); @@ -379,7 +380,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Pauses auto-refreshing of the banner for the given ad unit identifier. /// - /// Ad unit identifier of the banner for which to stop auto-refresh + /// Ad unit identifier of the banner for which to stop auto-refresh. Must not be null. public static void StopBannerAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "stop banner auto-refresh"); @@ -392,8 +393,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Updates the position of the banner to the new position provided. /// - /// The ad unit identifier of the banner for which to update the position - /// A new position for the banner + /// The ad unit identifier of the banner for which to update the position. Must not be null. + /// A new position for the banner. Must not be null. public static void UpdateBannerPosition(string adUnitIdentifier, BannerPosition bannerPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "update banner position"); @@ -406,7 +407,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Updates the position of the banner to the new coordinates provided. /// - /// The ad unit identifier of the banner for which to update the position + /// The ad unit identifier of the banner for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the banner relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the banner relative to the top left corner of the screen. /// @@ -424,7 +425,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Overrides the width of the banner in points. /// - /// The ad unit identifier of the banner for which to override the width for + /// The ad unit identifier of the banner for which to override the width for. Must not be null. /// The desired width of the banner in points public static void SetBannerWidth(string adUnitIdentifier, float width) { @@ -438,7 +439,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Show banner at a position determined by the 'CreateBanner' call. /// - /// Ad unit identifier of the banner to show + /// Ad unit identifier of the banner to show. Must not be null. public static void ShowBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show banner"); @@ -451,7 +452,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Remove banner from the ad view and destroy it. /// - /// Ad unit identifier of the banner to destroy + /// Ad unit identifier of the banner to destroy. Must not be null. public static void DestroyBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy banner"); @@ -464,7 +465,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Hide banner. /// - /// Ad unit identifier of the banner to hide + /// Ad unit identifier of the banner to hide. Must not be null. public static void HideBanner(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide banner"); @@ -477,7 +478,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set non-transparent background color for banners to be fully functional. /// - /// Ad unit identifier of the banner to set background color for + /// Ad unit identifier of the banner to set background color for. Must not be null. /// A background color to set for the ad public static void SetBannerBackgroundColor(string adUnitIdentifier, Color color) { @@ -491,8 +492,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the banner to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetBannerExtraParameter(string adUnitIdentifier, string key, string value) { @@ -509,8 +510,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the banner ad. /// - /// Ad unit identifier of the banner to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the banner to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetBannerLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -533,7 +534,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// The custom data to tie the showing banner ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// Banner ad unit identifier of the banner to set the custom data for. + /// Banner ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetBannerCustomData(string adUnitIdentifier, string customData) { @@ -548,7 +549,7 @@ public class MaxSdkiOS : MaxSdkBase /// The banner position on the screen. When setting the banner position via or , /// the banner is placed within the safe area of the screen. This returns the absolute position of the banner on screen. /// - /// Ad unit identifier of the banner for which to get the position on screen. + /// Ad unit identifier of the banner for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetBannerLayout(string adUnitIdentifier) { @@ -567,8 +568,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Create a new MREC. /// - /// Ad unit identifier of the MREC to create - /// MREC position + /// Ad unit identifier of the MREC to create. Must not be null. + /// MREC position. Must not be null. public static void CreateMRec(string adUnitIdentifier, AdViewPosition mrecPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "create MREC"); @@ -581,7 +582,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Create a new MREC with a custom position. /// - /// Ad unit identifier of the MREC to create + /// Ad unit identifier of the MREC to create. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -601,7 +602,7 @@ public class MaxSdkiOS : MaxSdkBase /// NOTE: The method loads the first MREC ad and initiates an automated MREC refresh process. /// You only need to call this method if you pause MREC refresh. /// - /// Ad unit identifier of the MREC to load + /// Ad unit identifier of the MREC to load. Must not be null. public static void LoadMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load MREC"); @@ -614,7 +615,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set the MREC placement for an ad unit identifier to tie the future ad events to. /// - /// Ad unit identifier of the MREC to set the placement for + /// Ad unit identifier of the MREC to set the placement for. Must not be null. /// Placement to set public static void SetMRecPlacement(string adUnitIdentifier, string placement) { @@ -628,7 +629,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Starts or resumes auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to start auto-refresh + /// Ad unit identifier of the MREC for which to start auto-refresh. Must not be null. public static void StartMRecAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "start MREC auto-refresh"); @@ -641,7 +642,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Pauses auto-refreshing of the MREC for the given ad unit identifier. /// - /// Ad unit identifier of the MREC for which to stop auto-refresh + /// Ad unit identifier of the MREC for which to stop auto-refresh. Must not be null. public static void StopMRecAutoRefresh(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "stop MREC auto-refresh"); @@ -654,8 +655,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Updates the position of the MREC to the new position provided. /// - /// The ad unit identifier of the MREC for which to update the position - /// A new position for the MREC + /// The ad unit identifier of the MREC for which to update the position. Must not be null. + /// A new position for the MREC. Must not be null. public static void UpdateMRecPosition(string adUnitIdentifier, AdViewPosition mrecPosition) { ValidateAdUnitIdentifier(adUnitIdentifier, "update MREC position"); @@ -668,7 +669,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Updates the position of the MREC to the new coordinates provided. /// - /// The ad unit identifier of the MREC for which to update the position + /// The ad unit identifier of the MREC for which to update the position. Must not be null. /// The X coordinate (horizontal position) of the MREC relative to the top left corner of the screen. /// The Y coordinate (vertical position) of the MREC relative to the top left corner of the screen. /// @@ -686,7 +687,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Show MREC at a position determined by the 'CreateMRec' call. /// - /// Ad unit identifier of the MREC to show + /// Ad unit identifier of the MREC to show. Must not be null. public static void ShowMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "show MREC"); @@ -699,7 +700,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Remove MREC from the ad view and destroy it. /// - /// Ad unit identifier of the MREC to destroy + /// Ad unit identifier of the MREC to destroy. Must not be null. public static void DestroyMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "destroy MREC"); @@ -712,7 +713,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Hide MREC. /// - /// Ad unit identifier of the MREC to hide + /// Ad unit identifier of the MREC to hide. Must not be null. public static void HideMRec(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "hide MREC"); @@ -725,8 +726,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the MREC to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetMRecExtraParameter(string adUnitIdentifier, string key, string value) { @@ -743,8 +744,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the MREC ad. /// - /// Ad unit identifier of the MREC to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the MREC to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetMRecLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -767,7 +768,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// The custom data to tie the showing MREC ad to, for ILRD and rewarded postbacks via the {CUSTOM_DATA} macro. Maximum size is 8KB. /// - /// MREC Ad unit identifier of the banner to set the custom data for. + /// MREC Ad unit identifier of the banner to set the custom data for. Must not be null. /// The custom data to be set. public static void SetMRecCustomData(string adUnitIdentifier, string customData) { @@ -782,7 +783,7 @@ public class MaxSdkiOS : MaxSdkBase /// The MREC position on the screen. When setting the banner position via or , /// the banner is placed within the safe area of the screen. This returns the absolute position of the MREC on screen. /// - /// Ad unit identifier of the MREC for which to get the position on screen. + /// Ad unit identifier of the MREC for which to get the position on screen. Must not be null. /// A representing the banner position on screen. public static Rect GetMRecLayout(string adUnitIdentifier) { @@ -793,121 +794,6 @@ public class MaxSdkiOS : MaxSdkBase #endregion - #region Cross Promo Ads - - [DllImport("__Internal")] - private static extern void _MaxCreateCrossPromoAd(string adUnitIdentifier, float x, float y, float width, float height, float rotation); - - /// - /// Create a new cross promo ad with a custom position. - /// - /// Ad unit identifier of the cross promo ad to create - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void CreateCrossPromoAd(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "create cross promo ad"); - _MaxCreateCrossPromoAd(adUnitIdentifier, x, y, width, height, rotation); - } - - [DllImport("__Internal")] - private static extern void _MaxSetCrossPromoAdPlacement(string adUnitIdentifier, string placement); - - /// - /// Set the cross promo ad placement for an ad unit identifier to tie the future ad events to. - /// - /// Ad unit identifier of the cross promo ad to set the placement for - /// Placement to set - public static void SetCrossPromoAdPlacement(string adUnitIdentifier, string placement) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "set cross promo ad placement"); - _MaxSetCrossPromoAdPlacement(adUnitIdentifier, placement); - } - - [DllImport("__Internal")] - private static extern void _MaxUpdateCrossPromoAdPosition(string adUnitIdentifier, float x, float y, float width, float height, float rotation); - - /// - /// Updates the position of the cross promo ad to the new coordinates provided. - /// - /// The ad unit identifier of the cross promo ad for which to update the position - /// The X coordinate (horizontal position) of the cross promo ad relative to the top left corner of the screen. - /// The Y coordinate (vertical position) of the cross promo ad relative to the top left corner of the screen. - /// The width of the cross promo ad. - /// The height of the cross promo ad. - /// The rotation of the cross promo ad in degrees. - /// - /// The cross promo ad is placed within the safe area of the screen. You can use this to get the absolute position Rect of the cross promo ad on screen. - /// - public static void UpdateCrossPromoAdPosition(string adUnitIdentifier, float x, float y, float width, float height, float rotation) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "update cross promo ad position"); - _MaxUpdateCrossPromoAdPosition(adUnitIdentifier, x, y, width, height, rotation); - } - - [DllImport("__Internal")] - private static extern void _MaxShowCrossPromoAd(string adUnitIdentifier); - - /// - /// Show cross promo ad at a position determined by the 'CreateCrossPromoAd' call. - /// - /// Ad unit identifier of the cross promo ad to show - public static void ShowCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "show cross promo ad"); - _MaxShowCrossPromoAd(adUnitIdentifier); - } - - [DllImport("__Internal")] - private static extern void _MaxDestroyCrossPromoAd(string adUnitIdentifier); - - /// - /// Remove cross promo ad from the ad view and destroy it. - /// - /// Ad unit identifier of the cross promo ad to destroy - public static void DestroyCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "destroy cross promo ad"); - _MaxDestroyCrossPromoAd(adUnitIdentifier); - } - - [DllImport("__Internal")] - private static extern void _MaxHideCrossPromoAd(string adUnitIdentifier); - - /// - /// Hide cross promo ad. - /// - /// Ad unit identifier of the cross promo ad to hide - public static void HideCrossPromoAd(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "hide cross promo ad"); - _MaxHideCrossPromoAd(adUnitIdentifier); - } - - [DllImport("__Internal")] - private static extern string _MaxGetCrossPromoAdLayout(string adUnitIdentifier); - - /// - /// The cross promo ad position on the screen. When setting the cross promo ad position via or , - /// the cross promo ad is placed within the safe area of the screen. This returns the absolute position of the cross promo ad on screen. - /// - /// Ad unit identifier of the cross promo ad for which to get the position on screen. - /// A representing the banner position on screen. - public static Rect GetCrossPromoAdLayout(string adUnitIdentifier) - { - ValidateAdUnitIdentifier(adUnitIdentifier, "get cross promo ad layout"); - var positionRect = _MaxGetCrossPromoAdLayout(adUnitIdentifier); - return GetRectFromString(positionRect); - } - - #endregion - #region Interstitials [DllImport("__Internal")] @@ -916,7 +802,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Start loading an interstitial. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. public static void LoadInterstitial(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load interstitial"); @@ -929,7 +815,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Check if interstitial ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the interstitial ad to check if it's ready to be displayed. + /// Ad unit identifier of the interstitial ad to check if it's ready to be displayed. Must not be null. /// True if the ad is ready to be displayed public static bool IsInterstitialReady(string adUnitIdentifier) { @@ -943,7 +829,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Present loaded interstitial for a given placement to tie ad events to. Note: if the interstitial is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowInterstitial(string adUnitIdentifier, string placement = null, string customData = null) @@ -966,8 +852,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the interstitial to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the interstitial to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetInterstitialExtraParameter(string adUnitIdentifier, string key, string value) { @@ -984,8 +870,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the interstitial to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the interstitial to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetInterstitialLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1012,7 +898,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Start loading an app open ad. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. public static void LoadAppOpenAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load app open ad"); @@ -1025,7 +911,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Check if app open ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the app open ad ad to check if it's ready to be displayed. + /// Ad unit identifier of the app open ad ad to check if it's ready to be displayed. Must not be null. /// True if the ad is ready to be displayed public static bool IsAppOpenAdReady(string adUnitIdentifier) { @@ -1039,7 +925,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Present loaded app open ad for a given placement to tie ad events to. Note: if the app open ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the app open ad to load + /// Ad unit identifier of the app open ad to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowAppOpenAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1062,8 +948,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the app open ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetAppOpenAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1080,8 +966,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the app open ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the app open ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetAppOpenAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1108,7 +994,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Start loading an rewarded ad. /// - /// Ad unit identifier of the rewarded ad to load + /// Ad unit identifier of the rewarded ad to load. Must not be null. public static void LoadRewardedAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded ad"); @@ -1121,7 +1007,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Check if rewarded ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded ad to check if it's ready to be displayed. + /// Ad unit identifier of the rewarded ad to check if it's ready to be displayed. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedAdReady(string adUnitIdentifier) { @@ -1135,7 +1021,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Present loaded rewarded ad for a given placement to tie ad events to. Note: if the rewarded ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the interstitial to load + /// Ad unit identifier of the interstitial to load. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1158,8 +1044,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1176,8 +1062,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetRewardedAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1204,7 +1090,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Start loading an rewarded interstitial ad. /// - /// Ad unit identifier of the rewarded interstitial ad to load + /// Ad unit identifier of the rewarded interstitial ad to load. Must not be null. public static void LoadRewardedInterstitialAd(string adUnitIdentifier) { ValidateAdUnitIdentifier(adUnitIdentifier, "load rewarded interstitial ad"); @@ -1217,7 +1103,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Check if rewarded interstitial ad ad is loaded and ready to be displayed. /// - /// Ad unit identifier of the rewarded interstitial ad to check if it's ready to be displayed + /// Ad unit identifier of the rewarded interstitial ad to check if it's ready to be displayed. Must not be null. /// True if the ad is ready to be displayed public static bool IsRewardedInterstitialAdReady(string adUnitIdentifier) { @@ -1231,7 +1117,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Present loaded rewarded interstitial ad for a given placement to tie ad events to. Note: if the rewarded interstitial ad is not ready to be displayed nothing will happen. /// - /// Ad unit identifier of the rewarded interstitial to show + /// Ad unit identifier of the rewarded interstitial to show. Must not be null. /// The placement to tie the showing ad's events to /// The custom data to tie the showing ad's events to. Maximum size is 8KB. public static void ShowRewardedInterstitialAd(string adUnitIdentifier, string placement = null, string customData = null) @@ -1254,8 +1140,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set an extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial ad to set the extra parameter for. - /// The key for the extra parameter. + /// Ad unit identifier of the rewarded interstitial ad to set the extra parameter for. Must not be null. + /// The key for the extra parameter. Must not be null. /// The value for the extra parameter. public static void SetRewardedInterstitialAdExtraParameter(string adUnitIdentifier, string key, string value) { @@ -1272,8 +1158,8 @@ public class MaxSdkiOS : MaxSdkBase /// /// Set a local extra parameter for the ad. /// - /// Ad unit identifier of the rewarded interstitial ad to set the local extra parameter for. - /// The key for the local extra parameter. + /// Ad unit identifier of the rewarded interstitial ad to set the local extra parameter for. Must not be null. + /// The key for the local extra parameter. Must not be null. /// The value for the local extra parameter. Accepts the following types: , null, IList, IDictionary, string, primitive types public static void SetRewardedInterstitialAdLocalExtraParameter(string adUnitIdentifier, string key, object value) { @@ -1300,7 +1186,7 @@ public class MaxSdkiOS : MaxSdkBase /// /// Track an event using AppLovin. /// - /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. + /// An event from the list of pre-defined events may be found in MaxEvents.cs as part of the AppLovin SDK framework. Must not be null. /// A dictionary containing key-value pairs further describing this event. public static void TrackEvent(string name, IDictionary parameters = null) { @@ -1431,6 +1317,30 @@ public class MaxSdkiOS : MaxSdkBase _MaxSetExtraParameter(key, value); } + [DllImport("__Internal")] + private static extern IntPtr _MaxGetSafeAreaInsets(); + + /// + /// Get the native insets in pixels for the safe area. + /// These insets are used to position ads within the safe area of the screen. + /// + public static SafeAreaInsets GetSafeAreaInsets() + { + // Use an int array instead of json serialization for performance + var insetsPtr = _MaxGetSafeAreaInsets(); + var insets = new int[4]; + Marshal.Copy(insetsPtr, insets, 0, 4); + + // Convert from points to pixels + var screenDensity = MaxSdkUtils.GetScreenDensity(); + for (var i = 0; i < insets.Length; i++) + { + insets[i] *= (int) screenDensity; + } + + return new SafeAreaInsets(insets); + } + #endregion #region Private diff --git a/Mediation.meta b/Mediation.meta deleted file mode 100644 index 3f88ba8..0000000 --- a/Mediation.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bf43583e6cbdf4100992c490f06b0236 -labels: -- al_max -- al_max_export_path-MaxSdk/Mediation -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: