Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions AppsFlyerSDK/Source/AppsFlyerSDK/AppsFlyer_UPL_Android.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
import com.appsflyer.internal.platform_extension.PluginInfo;
import java.util.HashMap;
import java.util.Map;

import com.appsflyer.AFAdRevenueData;
import com.appsflyer.MediationNetwork;
import com.appsflyer.AppsFlyerLib;

import java.util.Currency;

import android.util.Log;
</insert>
</gameActivityImportAdditions>
<gameActivityClassAdditions>
Expand Down Expand Up @@ -92,6 +100,27 @@
AppsFlyerLib.getInstance().disableAppSetId();
}

public void afLogAdRevenue(
String monetizationNetwork,
int mediationNetwork,
double revenue,
String currency,
Map<String, String> customData)
{
AFAdRevenueData adRevenueData = new AFAdRevenueData(monetizationNetwork, getAFMediationNetwork(mediationNetwork), currency, revenue);

Map<String, Object> additionalParameters = new HashMap<>();

if(customData.containsKey("Country")) additionalParameters.put(AdRevenueScheme.COUNTRY, customData.get("Country"));
if(customData.containsKey("UnitID")) additionalParameters.put(AdRevenueScheme.AD_UNIT, customData.get("UnitID"));
if(customData.containsKey("AdType")) additionalParameters.put(AdRevenueScheme.AD_TYPE, customData.get("AdType"));
if(customData.containsKey("Placement")) additionalParameters.put(AdRevenueScheme.PLACEMENT, customData.get("Placement"));

AppsFlyerLib.getInstance().logAdRevenue(adRevenueData, additionalParameters);

Log.debug("AppsflyerLog Track ad revenue");
}

// Deprecated
public void afSetConsentData(boolean isGDPR, boolean hasConsentForDataUsage, boolean hasConsentForAdsPersonalization) {
AppsFlyerConsent consent;
Expand All @@ -117,6 +146,25 @@

AppsFlyerLib.getInstance().setConsentData(consent);
}

public MediationNetwork getAFMediationNetwork(int network){
switch (network) {
case 0: return MediationNetwork.IRONSOURCE;
case 1: return MediationNetwork.APPLOVIN_MAX;
case 2: return MediationNetwork.GOOGLE_ADMOB;
case 3: return MediationNetwork.FYBER;
case 4: return MediationNetwork.APPODEAL;
case 5: return MediationNetwork.ADMOST;
case 6: return MediationNetwork.TOPON;
case 7: return MediationNetwork.TRADPLUS;
case 8: return MediationNetwork.YANDEX;
case 9: return MediationNetwork.CHARTBOOST;
case 10: return MediationNetwork.UNITY;
case 11: return MediationNetwork.CUSTOM_MEDIATION;
case 12: return MediationNetwork.DIRECT_MONETIZATION_NETWORK;
default: return MediationNetwork.CUSTOM_MEDIATION;
}
}
</insert>
</gameActivityClassAdditions>
</root>
69 changes: 69 additions & 0 deletions AppsFlyerSDK/Source/AppsFlyerSDK/Private/AppsFlyerSDKBlueprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,26 @@ static void onAppOpenAttribution(NSDictionary *attributionData) {
static void onAppOpenAttributionFailure(NSString *error) {
NSLog(@"%@", error);
}

static AppsFlyerAdRevenueMediationNetworkType mediationNetworkIOSTypeFromEnum(EAFMediationNetwork network) {
switch (network)
{
case EAFMediationNetwork::Ironsource: return AppsFlyerAdRevenueMediationNetworkTypeIronSource;
case EAFMediationNetwork::Applovinmax: return AppsFlyerAdRevenueMediationNetworkTypeApplovinMax;
case EAFMediationNetwork::Googleadmob: return AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob;
case EAFMediationNetwork::Fyber: return AppsFlyerAdRevenueMediationNetworkTypeFyber;
case EAFMediationNetwork::Appodeal: return AppsFlyerAdRevenueMediationNetworkTypeAppodeal;
case EAFMediationNetwork::Admost: return AppsFlyerAdRevenueMediationNetworkTypeAdmost;
case EAFMediationNetwork::Topon: return AppsFlyerAdRevenueMediationNetworkTypeTopon;
case EAFMediationNetwork::Tradplus: return AppsFlyerAdRevenueMediationNetworkTypeTradplus;
case EAFMediationNetwork::Yandex: return AppsFlyerAdRevenueMediationNetworkTypeYandex;
case EAFMediationNetwork::Chartboost: return AppsFlyerAdRevenueMediationNetworkTypeChartBoost;
case EAFMediationNetwork::Unity: return AppsFlyerAdRevenueMediationNetworkTypeUnity;
case EAFMediationNetwork::CustomMediation: return AppsFlyerAdRevenueMediationNetworkTypeCustom;
case EAFMediationNetwork::DirectMonetizationNetwork: return AppsFlyerAdRevenueMediationNetworkTypeDirectMonetization;
default: return AppsFlyerAdRevenueMediationNetworkTypeCustom;
}
}
#endif
UAppsFlyerSDKBlueprint::UAppsFlyerSDKBlueprint(const FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer) {}

Expand Down Expand Up @@ -649,6 +669,55 @@ void UAppsFlyerSDKBlueprint::SetConsentDataTOptional(
);
}

void UAppsFlyerSDKBlueprint::logAdRevenue(FString monetizationNetwork, EAFMediationNetwork mediationNetwork, float revenue, FString currency, TMap <FString, FString> extraData)
{
#if PLATFORM_ANDROID
JNIEnv* env = FAndroidApplication::GetJavaEnv();
jmethodID method = FJavaWrapper::FindMethod(env,
FJavaWrapper::GameActivityClassID,
"afLogAdRevenue",
"(Ljava/lang/String;IDLjava/lang/String;Ljava/util/Map;)V", false);

jclass mapClass = env->FindClass("java/util/HashMap");
jmethodID mapConstructor = env->GetMethodID(mapClass, "<init>", "()V");
jobject map = env->NewObject(mapClass, mapConstructor);
jmethodID putMethod = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
for (const TPair<FString, FString>& pair : extraData) {
env->CallObjectMethod(map, putMethod, env->NewStringUTF(TCHAR_TO_UTF8(*pair.Key)), env->NewStringUTF(TCHAR_TO_UTF8(*pair.Value)));
}

jstring jNetworkName = env->NewStringUTF(TCHAR_TO_UTF8(*monetizationNetwork));
jint jMediation = static_cast<jint>(mediationNetwork);
jstring jCurrency = env->NewStringUTF(TCHAR_TO_UTF8(*currency));

FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, method, jNetworkName, jMediation, revenue, jCurrency, map);

env->DeleteLocalRef(jNetworkName);
env->DeleteLocalRef(jCurrency);
#elif PLATFORM_IOS
dispatch_async(dispatch_get_main_queue(), ^ {
AFAdRevenueData* AdRevenue = [[AFAdRevenueData alloc]
initWithMonetizationNetwork: monetizationNetwork.GetNSString()
mediationNetwork: mediationNetworkIOSTypeFromEnum(mediationNetwork)
currencyIso4217Code: currency.GetNSString()
eventRevenue: [NSNumber numberWithFloat: revenue]
];

NSMutableDictionary* additionalParameters = [[NSMutableDictionary alloc] init];
if (extraData.Contains("Country")) [additionalParameters setValue:extraData["Country"].GetNSString() forKey:kAppsFlyerAdRevenueCountry];
if (extraData.Contains("AdType")) [additionalParameters setValue:extraData["AdType"].GetNSString() forKey:kAppsFlyerAdRevenueAdType];
if (extraData.Contains("UnitID")) [additionalParameters setValue:extraData["UnitID"].GetNSString() forKey:kAppsFlyerAdRevenueAdUnit];
if (extraData.Contains("Placement")) [additionalParameters setValue:extraData["Placement"].GetNSString() forKey:kAppsFlyerAdRevenuePlacement];

[[AppsFlyerLib shared] logAdRevenue:AdRevenue additionalParameters:additionalParameters];
});
#else
return;
#endif

UE_LOG(LogAppsFlyerSDKBlueprint, Log, TEXT("Log ad revenue"));
}

void UAppsFlyerSDKBlueprint::ValidateAndLogInAppPurchase(
const FAFSDKPurchaseDetails& PurchaseDetails,
const TMap<FString, FString>& PurchaseAdditionalDetails)
Expand Down
29 changes: 29 additions & 0 deletions AppsFlyerSDK/Source/AppsFlyerSDK/Public/AppsFlyerSDKBlueprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ enum class EAFValidateAndLogStatus : uint8
Error UMETA(DisplayName = "Error")
};

UENUM(BlueprintType)
enum class EAFMediationNetwork : uint8
{
Ironsource UMETA(DisplayName = "IronSource"),
Applovinmax UMETA(DisplayName = "ApplovinMax"),
Googleadmob UMETA(DisplayName = "GoogleAdmob"),
Fyber UMETA(DisplayName = "Fyber"),
Appodeal UMETA(DisplayName = "Appodeal"),
Admost UMETA(DisplayName = "Admost"),
Topon UMETA(DisplayName = "Topon"),
Tradplus UMETA(DisplayName = "TradPlus"),
Yandex UMETA(DisplayName = "Yandex"),
Chartboost UMETA(DisplayName = "Chartboost"),
Unity UMETA(DisplayName = "Unity"),
CustomMediation UMETA(DisplayName = "Custom Mediation"),
DirectMonetizationNetwork UMETA(DisplayName = "Direct Monetization Network")
};

USTRUCT(BlueprintType)
struct FAFSDKPurchaseDetails
{
Expand Down Expand Up @@ -137,6 +155,17 @@ class APPSFLYERSDK_API UAppsFlyerSDKBlueprint : public UBlueprintFunctionLibrary
TOptional<bool> HasConsentForAdStorage
);

/*!
* Log revenue from ads
* @param monetizationNetwork - Monetization network the ad was shown by, such as AdMob, UnityAds, Facebook e.t.c.
* @param mediationNetwork - Mediation network.
* @param revenue - Ad revenue (in millions)
* @param currency - Currency code
* @param extraData - Optional extra info for ad revenue. Can have "Country", "UnitID", "AdType" and "Placement" keys.
*/
UFUNCTION(BlueprintCallable, Category = AppsFlyerSDK, DisplayName = "AppsFlyerSDK log ad revenue")
static void logAdRevenue(FString monetizationNetwork, EAFMediationNetwork mediationNetwork, float revenue, FString currency, TMap <FString, FString> extraData);

/*!
* Validates and logs an in-app purchase using the updated VAL V2 flow.
* This method should be called after a successful transaction.
Expand Down