From a2f0996c490ce0b978273a11c50d092ff344306f Mon Sep 17 00:00:00 2001 From: Valentin Petrovych <72038591+ValentinPostindustria@users.noreply.github.com> Date: Wed, 23 Mar 2022 15:19:13 +0200 Subject: [PATCH] Apply bid loader from rendering instead of demand fetcher (#381) * feat(unification): connect BidLoader from rendering #370 Add Native json object. Add saving Native ad to cache. * feat(unification): configure auto refresh #370 Add pbs debug field to Bid request. * feat(unification): add setter for auto refresh interval in seconds #370 * feat(unification): fix ad units types #370 * feat(unification): rebase conflicts resolves #370 --- .../prebidkotlindemo/AdTypesRepository.kt | 30 +++- .../prebidkotlindemo/CustomApplication.kt | 13 +- .../mobile/prebidkotlindemo/DemoActivity.kt | 1 + .../main/java/org/prebid/mobile/AdUnit.java | 136 +++++++++++++----- .../java/org/prebid/mobile/BannerAdUnit.java | 3 +- .../org/prebid/mobile/BannerBaseAdUnit.java | 3 +- .../org/prebid/mobile/InterstitialAdUnit.java | 5 +- .../java/org/prebid/mobile/NativeAdUnit.java | 31 +++- .../java/org/prebid/mobile/NativeAsset.java | 7 +- .../org/prebid/mobile/NativeDataAsset.java | 22 +++ .../org/prebid/mobile/NativeImageAsset.java | 35 +++++ .../org/prebid/mobile/NativeTitleAsset.java | 23 +++ .../java/org/prebid/mobile/PrebidMobile.java | 8 +- .../prebid/mobile/RewardedVideoAdUnit.java | 6 +- .../src/main/java/org/prebid/mobile/Util.java | 3 +- .../java/org/prebid/mobile/VideoAdUnit.java | 3 +- .../org/prebid/mobile/VideoBaseAdUnit.java | 3 +- .../mobile/VideoInterstitialAdUnit.java | 5 +- .../rendering/bidding/data/bid/Bid.java | 8 ++ .../bidding/data/bid/BidResponse.java | 8 ++ .../bidding/display/BidResponseCache.java | 4 +- .../rendering/models/openrtb/BidRequest.java | 2 + .../models/openrtb/bidRequests/Imp.java | 9 ++ .../models/openrtb/bidRequests/Native.java | 101 +++++++++++++ .../parameters/BasicParameterBuilder.java | 10 +- .../configuration/AdUnitConfiguration.java | 22 +-- .../NativeAdUnitConfiguration.java | 3 +- 27 files changed, 418 insertions(+), 86 deletions(-) create mode 100644 PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Native.java diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/AdTypesRepository.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/AdTypesRepository.kt index a99608e83..abad04ad3 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/AdTypesRepository.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/AdTypesRepository.kt @@ -1,6 +1,8 @@ package org.prebid.mobile.prebidkotlindemo import com.mopub.mobileads.MoPubView +import org.prebid.mobile.Host +import org.prebid.mobile.PrebidMobile import org.prebid.mobile.prebidkotlindemo.ads.GamBanner import org.prebid.mobile.prebidkotlindemo.ads.GamInterstitial import org.prebid.mobile.prebidkotlindemo.ads.MoPubBanner @@ -24,12 +26,14 @@ object AdTypesRepository { AdType( "Banner 320x50", onCreate = { _, wrapper, autoRefreshTime -> + useTestServer() + PrebidMobile.setStoredAuctionResponse("response-prebid-banner-320-50") GamBanner.create( wrapper, autoRefreshTime, 320, 50, // TODO: Problem with ids "/5300653/pavliuchyk_test_adunit_1x1_puc", - "625c6125-f19e-4d5b-95c5-55501526b2a4" + "imp-prebid-banner-320-50" ) }, onDestroy = { GamBanner.destroy() } @@ -37,6 +41,7 @@ object AdTypesRepository { AdType( "Banner 300x250", onCreate = { _, wrapper, autoRefreshTime -> + useAppNexusServer() GamBanner.create( wrapper, autoRefreshTime, 300, 250, @@ -49,6 +54,7 @@ object AdTypesRepository { AdType( "Interstitial", onCreate = { activity, _, autoRefreshTime -> + useAppNexusServer() GamInterstitial.create( activity, autoRefreshTime, // TODO: Problem with ids @@ -64,11 +70,13 @@ object AdTypesRepository { AdType( "Banner 320x50", onCreate = { _, wrapper, autoRefreshTime -> + useTestServer() + PrebidMobile.setStoredAuctionResponse("response-prebid-banner-320-50") MoPubBanner.create( wrapper, autoRefreshTime, 320, 50, MoPubView.MoPubAdSize.HEIGHT_50, "42b99af979cd474ea32f497c044b5d71", - "625c6125-f19e-4d5b-95c5-55501526b2a4" + "imp-prebid-banner-320-50" ) }, onDestroy = { MoPubBanner.destroy() } @@ -76,6 +84,7 @@ object AdTypesRepository { AdType( "Banner 300x250", onCreate = { _, wrapper, autoRefreshTime -> + useAppNexusServer() MoPubBanner.create( wrapper, autoRefreshTime, 300, 250, MoPubView.MoPubAdSize.HEIGHT_250, @@ -89,6 +98,7 @@ object AdTypesRepository { AdType( "Interstitial", onCreate = { activity, _, autoRefreshTime -> + useAppNexusServer() MoPubInterstitial.create( activity, autoRefreshTime, // TODO: Problem with ids @@ -331,7 +341,21 @@ object AdTypesRepository { } ) ) - ) + fun useOpenXServer() { + PrebidMobile.setPrebidServerAccountId("0689a263-318d-448b-a3d4-b02e8a709d9d") + PrebidMobile.setPrebidServerHost(Host.createCustomHost("https://prebid.openx.net/openrtb2/auction")) + } + + private fun useTestServer() { + PrebidMobile.setPrebidServerAccountId("0689a263-318d-448b-a3d4-b02e8a709d9d") + PrebidMobile.setPrebidServerHost(Host.createCustomHost("https://prebid-server-test-j.prebid.org/openrtb2/auction")) + } + + private fun useAppNexusServer() { + PrebidMobile.setPrebidServerAccountId("bfa84af2-bd16-4d35-96ad-31c6bb888df0") + PrebidMobile.setPrebidServerHost(Host.APPNEXUS) + } + } \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/CustomApplication.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/CustomApplication.kt index f122773e1..5a426fd17 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/CustomApplication.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/CustomApplication.kt @@ -29,7 +29,6 @@ import com.google.android.gms.ads.RequestConfiguration import com.mopub.common.MoPub import com.mopub.common.SdkConfiguration import com.mopub.common.logging.MoPubLog -import org.prebid.mobile.Host import org.prebid.mobile.PrebidMobile class CustomApplication : Application() { @@ -49,22 +48,16 @@ class CustomApplication : Application() { private fun initMopubSDK() { val sdkConfiguration = SdkConfiguration.Builder("42b99af979cd474ea32f497c044b5d71") - sdkConfiguration.withLogLevel(MoPubLog.LogLevel.DEBUG) + sdkConfiguration.withLogLevel(MoPubLog.LogLevel.NONE) MoPub.initializeSdk(this, sdkConfiguration.build()) { Log.d("MoPub", "Initialized successfully!") } } private fun initPrebidSDK() { - PrebidMobile.setPrebidServerAccountId("bfa84af2-bd16-4d35-96ad-31c6bb888df0") - PrebidMobile.setPrebidServerHost(Host.APPNEXUS) - PrebidMobile.setShareGeoLocation(true) +// PrebidMobile.setPbsDebug(true) PrebidMobile.setApplicationContext(applicationContext) - - val host = Host.CUSTOM - host.hostUrl = "https://prebid.openx.net/openrtb2/auction" - PrebidMobile.setPrebidServerHost(host) - PrebidMobile.setPrebidServerAccountId("0689a263-318d-448b-a3d4-b02e8a709d9d") + PrebidMobile.setShareGeoLocation(true) } private fun initAdMob() { diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt index 68685b3ee..3995d995f 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt @@ -55,6 +55,7 @@ class DemoActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_demo) + AdTypesRepository.useOpenXServer() useFakeGDPR() parseArguments() initViews() diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/AdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/AdUnit.java index da2f5133a..4dba43dfa 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/AdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/AdUnit.java @@ -23,64 +23,72 @@ import android.text.TextUtils; import androidx.annotation.IntRange; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import org.prebid.mobile.rendering.bidding.data.FetchDemandResult; +import org.prebid.mobile.rendering.bidding.data.bid.BidResponse; +import org.prebid.mobile.rendering.bidding.listeners.BidRequesterListener; +import org.prebid.mobile.rendering.bidding.loader.BidLoader; +import org.prebid.mobile.rendering.errors.AdException; import org.prebid.mobile.tasksmanager.TasksManager; import org.prebid.mobile.units.configuration.AdUnitConfiguration; import java.util.*; -public abstract class AdUnit { +import static org.prebid.mobile.PrebidMobile.AUTO_REFRESH_DELAY_MAX; +import static org.prebid.mobile.PrebidMobile.AUTO_REFRESH_DELAY_MIN; - private static final int MIN_AUTO_REFRESH_PERIOD_MILLIS = 30_000; +public abstract class AdUnit { - private int periodMillis = 0; // No auto refresh - private DemandFetcher fetcher; protected AdUnitConfiguration configuration = new AdUnitConfiguration(); - AdUnit(@NonNull String configId, @NonNull AdType adType) { + @Nullable + protected BidLoader bidLoader; + @Nullable + protected Object adObject; + + AdUnit(@NonNull String configId, @NonNull AdUnitConfiguration.AdUnitIdentifierType adType) { configuration.setConfigId(configId); - configuration.setAdType(adType); + configuration.setAdUnitIdentifierType(adType); } - public void setAutoRefreshPeriodMillis(@IntRange(from = MIN_AUTO_REFRESH_PERIOD_MILLIS) int periodMillis) { - if (periodMillis < MIN_AUTO_REFRESH_PERIOD_MILLIS) { - LogUtil.warning("periodMillis less then:" + MIN_AUTO_REFRESH_PERIOD_MILLIS); - return; - } - this.periodMillis = periodMillis; - if (fetcher != null) { - fetcher.setPeriodMillis(periodMillis); - } + /** + * @deprecated Please use setAutoRefreshInterval() in seconds! + */ + @Deprecated + public void setAutoRefreshPeriodMillis( + @IntRange(from = AUTO_REFRESH_DELAY_MIN, to = AUTO_REFRESH_DELAY_MAX) int periodMillis + ) { + configuration.setAutoRefreshDelay(periodMillis / 1000); + } + + public void setAutoRefreshInterval( + @IntRange(from = AUTO_REFRESH_DELAY_MIN / 1000, to = AUTO_REFRESH_DELAY_MAX / 1000) int seconds + ) { + configuration.setAutoRefreshDelay(seconds); } public void resumeAutoRefresh() { LogUtil.verbose("Resuming auto refresh..."); - if (fetcher != null) { - fetcher.start(); + if (bidLoader != null) { + bidLoader.setupRefreshTimer(); } } public void stopAutoRefresh() { LogUtil.verbose("Stopping auto refresh..."); - if (fetcher != null) { - fetcher.stop(); + if (bidLoader != null) { + bidLoader.cancelRefresh(); } } public void fetchDemand(@NonNull final OnCompleteListener2 listener) { - final Map keywordsMap = new HashMap<>(); - fetchDemand(keywordsMap, new OnCompleteListener() { - @Override - public void onComplete(final ResultCode resultCode) { - TasksManager.getInstance().executeOnMainThread(new Runnable() { - @Override - public void run() { - listener.onComplete(resultCode, keywordsMap.size() != 0 ? Collections.unmodifiableMap(keywordsMap) : null); - } - }); - } + fetchDemand(keywordsMap, resultCode -> { + TasksManager.getInstance().executeOnMainThread(() -> + listener.onComplete(resultCode, keywordsMap.size() != 0 ? Collections.unmodifiableMap(keywordsMap) : null) + ); }); } @@ -130,17 +138,25 @@ public void fetchDemand(@NonNull Object adObj, @NonNull OnCompleteListener liste } if (Util.supportedAdObject(adObj)) { - fetcher = new DemandFetcher(adObj); - fetcher.setPeriodMillis(periodMillis); - fetcher.setConfiguration(configuration); - fetcher.setListener(listener); - if (periodMillis >= 30000) { - LogUtil.verbose("Start fetching bids with auto refresh millis: " + periodMillis); + adObject = adObj; + bidLoader = new BidLoader( + context, + configuration, + createBidListener(listener) + ); + + if (configuration.getAutoRefreshDelay() > 0) { + BidLoader.BidRefreshListener bidRefreshListener = () -> true; + bidLoader.setBidRefreshListener(bidRefreshListener); + LogUtil.verbose("Start fetching bids with auto refresh millis: " + configuration.getAutoRefreshDelay()); } else { + bidLoader.setBidRefreshListener(null); LogUtil.verbose("Start a single fetching."); } - fetcher.start(); + + bidLoader.load(); } else { + adObject = null; listener.onComplete(ResultCode.INVALID_AD_OBJECT); } @@ -249,6 +265,52 @@ public void setPbAdSlot(String pbAdSlot) { configuration.setPbAdSlot(pbAdSlot); } + + protected BidRequesterListener createBidListener(OnCompleteListener originalListener) { + return new BidRequesterListener() { + @Override + public void onFetchCompleted(BidResponse response) { + HashMap keywords = response.getTargeting(); + Util.apply(keywords, adObject); + originalListener.onComplete(ResultCode.SUCCESS); + } + + @Override + public void onError(AdException exception) { + Util.apply(null, adObject); + originalListener.onComplete(convertToResultCode(exception)); + } + }; + } + + protected ResultCode convertToResultCode(AdException renderingException) { + FetchDemandResult fetchDemandResult = FetchDemandResult.parseErrorMessage(renderingException.getMessage()); + LogUtil.error("Prebid", "Can't download bids: " + fetchDemandResult); + switch (fetchDemandResult) { + case INVALID_ACCOUNT_ID: + return ResultCode.INVALID_ACCOUNT_ID; + case INVALID_CONFIG_ID: + return ResultCode.INVALID_CONFIG_ID; + case INVALID_SIZE: + return ResultCode.INVALID_SIZE; + case INVALID_CONTEXT: + return ResultCode.INVALID_CONTEXT; + case INVALID_AD_OBJECT: + return ResultCode.INVALID_AD_OBJECT; + case INVALID_HOST_URL: + return ResultCode.INVALID_HOST_URL; + case NETWORK_ERROR: + return ResultCode.NETWORK_ERROR; + case TIMEOUT: + return ResultCode.TIMEOUT; + case NO_BIDS: + return ResultCode.NO_BIDS; + default: + return ResultCode.PREBID_SERVER_ERROR; + } + } + + @VisibleForTesting public AdUnitConfiguration getConfiguration() { return configuration; diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerAdUnit.java index 819e800ab..1f7f3a592 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerAdUnit.java @@ -17,13 +17,14 @@ package org.prebid.mobile; import androidx.annotation.NonNull; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; import java.util.HashSet; public class BannerAdUnit extends BannerBaseAdUnit { public BannerAdUnit(@NonNull String configId, int width, int height) { - super(configId, AdType.BANNER); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.BANNER); configuration.addSize(new AdSize(width, height)); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerBaseAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerBaseAdUnit.java index 2c1cf544d..b5889efd2 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerBaseAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/BannerBaseAdUnit.java @@ -18,12 +18,13 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; import java.util.List; public abstract class BannerBaseAdUnit extends AdUnit { - BannerBaseAdUnit(@NonNull String configId, @NonNull AdType adType) { + BannerBaseAdUnit(@NonNull String configId, @NonNull AdUnitConfiguration.AdUnitIdentifierType adType) { super(configId, adType); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/InterstitialAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/InterstitialAdUnit.java index 1763f06fc..b0a1c0b79 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/InterstitialAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/InterstitialAdUnit.java @@ -18,11 +18,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.prebid.mobile.rendering.models.AdPosition; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; public class InterstitialAdUnit extends BannerBaseAdUnit { public InterstitialAdUnit(@NonNull String configId) { - super(configId, AdType.INTERSTITIAL); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.INTERSTITIAL); + configuration.setAdPosition(AdPosition.FULLSCREEN); } public InterstitialAdUnit(@NonNull String configId, int minWidthPerc, int minHeightPerc) { diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAdUnit.java index fb6613ff6..8f1b68759 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAdUnit.java @@ -3,8 +3,14 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import org.json.JSONObject; +import org.prebid.mobile.rendering.bidding.data.bid.BidResponse; +import org.prebid.mobile.rendering.bidding.listeners.BidRequesterListener; +import org.prebid.mobile.rendering.errors.AdException; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; import org.prebid.mobile.units.configuration.NativeAdUnitConfiguration; +import java.util.HashMap; + /** * For details of the configuration of native imps, please check this documentation: * https://www.iab.com/wp-content/uploads/2018/03/OpenRTB-Native-Ads-Specification-Final-1.2.pdf @@ -16,11 +22,32 @@ public class NativeAdUnit extends AdUnit { private final NativeAdUnitConfiguration nativeConfiguration; public NativeAdUnit(@NonNull String configId) { - super(configId, AdType.NATIVE); - configuration.initNativeConfiguration(); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.NATIVE); nativeConfiguration = configuration.getNativeConfiguration(); } + @Override + protected BidRequesterListener createBidListener(OnCompleteListener originalListener) { + return new BidRequesterListener() { + @Override + public void onFetchCompleted(BidResponse response) { + HashMap keywords = response.getTargeting(); + Util.apply(keywords, adObject); + + String cacheId = CacheManager.save(response.getWinningBidJson()); + Util.saveCacheId(cacheId, adObject); + + originalListener.onComplete(ResultCode.SUCCESS); + } + + @Override + public void onError(AdException exception) { + Util.apply(null, adObject); + originalListener.onComplete(convertToResultCode(exception)); + } + }; + } + public enum CONTEXT_TYPE { CONTENT_CENTRIC(1), SOCIAL_CENTRIC(2), diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAsset.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAsset.java index 775191106..227151f93 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAsset.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeAsset.java @@ -1,6 +1,9 @@ package org.prebid.mobile; +import org.json.JSONObject; + public abstract class NativeAsset { + enum REQUEST_ASSET { TITLE, IMAGE, @@ -17,8 +20,6 @@ public REQUEST_ASSET getType() { return type; } - - - + public abstract JSONObject getJsonObject(); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeDataAsset.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeDataAsset.java index c810877fb..2db5ef5b4 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeDataAsset.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeDataAsset.java @@ -2,6 +2,7 @@ import org.json.JSONArray; import org.json.JSONObject; +import org.prebid.mobile.rendering.utils.logger.LogUtil; public class NativeDataAsset extends NativeAsset { public NativeDataAsset() { @@ -101,4 +102,25 @@ public void setAssetExt(Object assetExt) { this.assetExt = assetExt; } } + + @Override + public JSONObject getJsonObject() { + JSONObject result = new JSONObject(); + + try { + result.putOpt("required", required ? 1 : 0); + result.putOpt("ext", assetExt); + + JSONObject dataObject = new JSONObject(); + dataObject.putOpt("type", dataType != null ? dataType.getID() : null); + dataObject.putOpt("len", len); + dataObject.putOpt("ext", dataExt); + + result.put("data", dataObject); + } catch (Exception exception) { + LogUtil.error("NativeTitleAsset", "Can't create json object: " + exception.getMessage()); + } + + return result; + } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeImageAsset.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeImageAsset.java index 4973d1718..d71225a28 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeImageAsset.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeImageAsset.java @@ -2,6 +2,7 @@ import org.json.JSONArray; import org.json.JSONObject; +import org.prebid.mobile.rendering.utils.logger.LogUtil; import java.util.ArrayList; @@ -135,4 +136,38 @@ public void setImageExt(Object imageExt) { public Object getImageExt() { return imageExt; } + + + @Override + public JSONObject getJsonObject() { + JSONObject result = new JSONObject(); + + try { + result.putOpt("required", required ? 1 : 0); + result.putOpt("ext", assetExt); + + JSONObject imageObject = new JSONObject(); + imageObject.putOpt("type", type != null ? type.getID() : null); + + imageObject.put("w", w); + imageObject.put("wmin", wmin); + imageObject.put("h", h); + imageObject.put("hmin", hmin); + imageObject.putOpt("ext", imageExt); + + if (!mimes.isEmpty()) { + JSONArray mimesArray = new JSONArray(); + for (String mime : mimes) { + mimesArray.put(mime); + } + imageObject.putOpt("mimes", mimesArray); + } + + result.put("img", imageObject); + } catch (Exception exception) { + LogUtil.error("NativeImageAsset", "Can't create json object: " + exception.getMessage()); + } + + return result; + } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeTitleAsset.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeTitleAsset.java index 297d6207c..e53957e7d 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeTitleAsset.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/NativeTitleAsset.java @@ -2,8 +2,10 @@ import org.json.JSONArray; import org.json.JSONObject; +import org.prebid.mobile.rendering.utils.logger.LogUtil; public class NativeTitleAsset extends NativeAsset { + private int len; private boolean required; private Object titleExt; @@ -48,4 +50,25 @@ public void setAssetExt(Object assetExt) { this.assetExt = assetExt; } } + + @Override + public JSONObject getJsonObject() { + JSONObject result = new JSONObject(); + + try { + result.putOpt("required", required ? 1 : 0); + result.putOpt("ext", assetExt); + + JSONObject titleObject = new JSONObject(); + titleObject.putOpt("len", len); + titleObject.putOpt("ext", titleExt); + + result.put("title", titleObject); + } catch (Exception exception) { + LogUtil.error("NativeTitleAsset", "Can't create json object: " + exception.getMessage()); + } + + return result; + } + } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/PrebidMobile.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/PrebidMobile.java index 8160aaf9a..a3431e1a0 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/PrebidMobile.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/PrebidMobile.java @@ -56,18 +56,18 @@ public class PrebidMobile { /** * Maximum refresh interval allowed. 120 seconds */ - public static final int AUTO_REFRESH_DELAY_MAX = 120000; + public static final int AUTO_REFRESH_DELAY_MAX = 120_000; /** * Default refresh interval. 60 seconds * Used when the refresh interval is not in the AUTO_REFRESH_DELAY_MIN & AUTO_REFRESH_DELAY_MAX range. */ - public static final int AUTO_REFRESH_DELAY_DEFAULT = 60000; + public static final int AUTO_REFRESH_DELAY_DEFAULT = 60_000; /** - * Minimum refresh interval allowed. 15 seconds + * Minimum refresh interval allowed. 30 seconds */ - public static final int AUTO_REFRESH_DELAY_MIN = 15000; + public static final int AUTO_REFRESH_DELAY_MIN = 30_000; /** * Open measurement SDK version diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/RewardedVideoAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/RewardedVideoAdUnit.java index 7b94bcb5e..aa7c81028 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/RewardedVideoAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/RewardedVideoAdUnit.java @@ -17,11 +17,15 @@ package org.prebid.mobile; import androidx.annotation.NonNull; +import org.prebid.mobile.rendering.models.AdPosition; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; public class RewardedVideoAdUnit extends VideoBaseAdUnit { public RewardedVideoAdUnit(@NonNull String configId) { - super(configId, AdType.REWARDED_VIDEO); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.VAST); + configuration.setRewarded(true); + configuration.setAdPosition(AdPosition.FULLSCREEN); } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index b1935c446..140418019 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -421,7 +421,8 @@ static void apply(HashMap bids, Object adObj) { } } - static void saveCacheId(@NonNull String cacheId, Object adObject) { + static void saveCacheId(@Nullable String cacheId, Object adObject) { + if (adObject == null) return; if (adObject.getClass() == getClassFromString(ANDROID_OS_BUNDLE)) { Bundle adBundle = (Bundle) adObject; adBundle.putString(NativeAdUnit.BUNDLE_KEY_CACHE_ID, cacheId); diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoAdUnit.java index 47d3bea78..2534e91c4 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoAdUnit.java @@ -17,13 +17,14 @@ package org.prebid.mobile; import androidx.annotation.NonNull; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; import java.util.HashSet; public class VideoAdUnit extends VideoBaseAdUnit { public VideoAdUnit(@NonNull String configId, int width, int height) { - super(configId, AdType.VIDEO); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.VAST); configuration.addSize(new AdSize(width, height)); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoBaseAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoBaseAdUnit.java index 0f69a4650..c8df8fa28 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoBaseAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoBaseAdUnit.java @@ -18,12 +18,13 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; import java.util.List; public abstract class VideoBaseAdUnit extends AdUnit { - VideoBaseAdUnit(@NonNull String configId, @NonNull AdType adType) { + VideoBaseAdUnit(@NonNull String configId, @NonNull AdUnitConfiguration.AdUnitIdentifierType adType) { super(configId, adType); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoInterstitialAdUnit.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoInterstitialAdUnit.java index fd98638a2..fd41d73a5 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoInterstitialAdUnit.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/VideoInterstitialAdUnit.java @@ -17,11 +17,14 @@ package org.prebid.mobile; import androidx.annotation.NonNull; +import org.prebid.mobile.rendering.models.AdPosition; +import org.prebid.mobile.units.configuration.AdUnitConfiguration; public class VideoInterstitialAdUnit extends VideoBaseAdUnit { public VideoInterstitialAdUnit(@NonNull String configId) { - super(configId, AdType.VIDEO_INTERSTITIAL); + super(configId, AdUnitConfiguration.AdUnitIdentifierType.VAST); + configuration.setAdPosition(AdPosition.FULLSCREEN); } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/Bid.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/Bid.java index 3e3d259f3..0155b1eba 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/Bid.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/Bid.java @@ -84,6 +84,9 @@ public class Bid { // of creatives for which iurl should be representative private String mCid; + // Bid json string. Used only for CacheManager. + private String jsonString; + // Tactic ID to enable buyers to label bids for reporting to the // exchange the tactic through which their bid was submitted private String mTactic; @@ -236,11 +239,16 @@ public int getExp() { return mExp; } + public String getJsonString() { + return jsonString; + } + public static Bid fromJSONObject(JSONObject jsonObject) { Bid bid = new Bid(); if (jsonObject == null) { return bid; } + bid.jsonString = jsonObject.toString(); bid.mId = jsonObject.optString("id", null); bid.mImpId = jsonObject.optString("impid", null); bid.mPrice = jsonObject.optDouble("price", 0); diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/BidResponse.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/BidResponse.java index 26ad72d96..0f41f4730 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/BidResponse.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/data/bid/BidResponse.java @@ -57,6 +57,7 @@ public class BidResponse { private boolean mHasParseError = false; private String mParseError; + private String winningBidJson; private long mCreationTime; @@ -104,7 +105,13 @@ public int getNbr() { return mNbr; } + public String getWinningBidJson() { + return winningBidJson; + } + private void parseJson(String json) { + winningBidJson = json; + try { JSONObject responseJson = new JSONObject(json); mId = responseJson.optString("id"); @@ -153,6 +160,7 @@ public Bid getWinningBid() { for (Seatbid seatbid : mSeatbids) { for (Bid bid : seatbid.getBids()) { if (hasWinningKeywords(bid.getPrebid())) { + winningBidJson = bid.getJsonString(); return bid; } } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/display/BidResponseCache.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/display/BidResponseCache.java index 967367b2e..79cddd341 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/display/BidResponseCache.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/bidding/display/BidResponseCache.java @@ -65,8 +65,8 @@ public static synchronized BidResponseCache getInstance() { * * @param response Parsed bid response */ - void putBidResponse( - final BidResponse response) { + public void putBidResponse( + final BidResponse response) { putBidResponse(response.getId(), response); } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/BidRequest.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/BidRequest.java index 5ad8d6c87..d296ebe7f 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/BidRequest.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/BidRequest.java @@ -21,6 +21,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.prebid.mobile.PrebidMobile; import org.prebid.mobile.rendering.models.openrtb.bidRequests.*; import org.prebid.mobile.rendering.models.openrtb.bidRequests.source.Source; @@ -58,6 +59,7 @@ public JSONObject getJsonObject() throws JSONException { toJSON(jsonObject, "user", (mUser != null) ? mUser.getJsonObject() : null); toJSON(jsonObject, "source", mSource != null ? mSource.getJsonObject() : null); toJSON(jsonObject, "ext", mExt != null ? mExt.getJsonObject() : null); + toJSON(jsonObject, "test", PrebidMobile.getPbsDebug() ? 1 : null); return jsonObject; } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Imp.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Imp.java index 8adb23663..8390ff468 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Imp.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Imp.java @@ -32,6 +32,7 @@ public class Imp extends BaseBid { public Banner banner = null; public Video video = null; public Pmp pmp = null; + public Native nativeObj; private Ext mExt = null; public Integer clickBrowser = null; @@ -51,6 +52,7 @@ public JSONObject getJsonObject() throws JSONException { toJSON(jsonObject, "banner", (banner != null) ? banner.getJsonObject() : null); toJSON(jsonObject, "video", (video != null) ? video.getJsonObject() : null); + toJSON(jsonObject, "native", (nativeObj != null) ? nativeObj.getJsonObject() : null); toJSON(jsonObject, "pmp", (pmp != null) ? pmp.getJsonObject() : null); toJSON(jsonObject, "ext", (mExt != null) ? mExt.getJsonObject() : null); @@ -79,4 +81,11 @@ public Video getVideo() { return video; } + public Native getNative() { + if (nativeObj == null) { + nativeObj = new Native(); + } + return nativeObj; + } + } diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Native.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Native.java new file mode 100644 index 000000000..bae920b4b --- /dev/null +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/models/openrtb/bidRequests/Native.java @@ -0,0 +1,101 @@ +package org.prebid.mobile.rendering.models.openrtb.bidRequests; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.prebid.mobile.NativeAsset; +import org.prebid.mobile.NativeEventTracker; +import org.prebid.mobile.PrebidMobile; +import org.prebid.mobile.units.configuration.NativeAdUnitConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public class Native extends BaseBid { + private JSONObject mRequest; + private Ext mExt; + + // Won't be implemented in 1.1 + private int[] mApi; + private int[] mBattr; + + public JSONObject getJsonObject() throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("request", mRequest.toString()); + jsonObject.put("ver", PrebidMobile.NATIVE_VERSION); + jsonObject.putOpt("ext", mExt != null ? mExt.getJsonObject() : null); + return jsonObject; + } + + public void setRequestFrom(NativeAdUnitConfiguration config) { + mRequest = new JSONObject(); + try { + mRequest.put("ver", PrebidMobile.NATIVE_VERSION); + if (config.getContextType() != null) { + mRequest.put("context", config.getContextType().getID()); + } + if (config.getContextSubtype() != null) { + mRequest.put("contextsubtype", config.getContextSubtype().getID()); + } + if (config.getPlacementType() != null) { + mRequest.put("plcmttype", config.getPlacementType().getID()); + } + if (config.getSeq() >= 0) { + mRequest.put("seq", config.getSeq()); + } + mRequest.put("assets", getAssetsJsonArray(config.getAssets())); + if (!config.getEventTrackers().isEmpty()) { + mRequest.put("eventtrackers", getTrackersJsonArray(config.getEventTrackers())); + } + if (config.getPrivacy()) { + mRequest.put("privacy", 1); + } + mRequest.putOpt("ext", config.getExt() != null + ? config.getExt() + : null); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public Ext getExt() { + if (mExt == null) { + mExt = new Ext(); + } + return mExt; + } + + private JSONArray getAssetsJsonArray(List assetList) throws JSONException { + JSONArray assetJsonArray = new JSONArray(); + for (NativeAsset asset : assetList) { + assetJsonArray.put(asset.getJsonObject()); + } + return assetJsonArray; + } + + private JSONArray getTrackersJsonArray(List trackerList) + throws JSONException { + JSONArray trackersJsonArray = new JSONArray(); + for (NativeEventTracker eventTracker : trackerList) { + JSONObject evenTrackerJson = new JSONObject(); + if (eventTracker.getEvent() != null) { + evenTrackerJson.put("event", eventTracker.getEvent().getID()); + } + + ArrayList eventTrackingMethods = eventTracker.getMethods(); + if (eventTrackingMethods != null) { + JSONArray methodsArray = new JSONArray(); + for (NativeEventTracker.EVENT_TRACKING_METHOD method : eventTrackingMethods) { + methodsArray.put(method.getID()); + } + evenTrackerJson.put("methods", methodsArray); + } + + if (eventTracker.getExtObject() != null) { + evenTrackerJson.put("ext", eventTracker.getExtObject()); + } + trackersJsonArray.put(evenTrackerJson); + } + return trackersJsonArray; + } +} \ No newline at end of file diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/networking/parameters/BasicParameterBuilder.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/networking/parameters/BasicParameterBuilder.java index 9458c4c19..249701cae 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/networking/parameters/BasicParameterBuilder.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/rendering/networking/parameters/BasicParameterBuilder.java @@ -103,7 +103,9 @@ private void configureImpObject(Imp imp, String uuid) { if (mAdConfiguration != null) { setDisplayManager(imp); setCommonImpValues(imp, uuid); - if (mAdConfiguration.isAdType(AdUnitConfiguration.AdUnitIdentifierType.VAST)) { + if (mAdConfiguration.getNativeConfiguration() != null) { + setNativeImpValues(imp); + } else if (mAdConfiguration.isAdType(AdUnitConfiguration.AdUnitIdentifierType.VAST)) { setVideoImpValues(imp); } else { setBannerImpValues(imp); @@ -232,6 +234,12 @@ private void setBannerImpValues(Imp imp) { imp.banner = banner; } + private void setNativeImpValues(Imp imp) { + if (mAdConfiguration.getNativeConfiguration() != null) { + imp.getNative().setRequestFrom(mAdConfiguration.getNativeConfiguration()); + } + } + private void setCommonImpValues(Imp imp, String uuid) { imp.id = uuid; boolean isInterstitial = mAdConfiguration.isAdType(AdUnitConfiguration.AdUnitIdentifierType.VAST) || diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/AdUnitConfiguration.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/AdUnitConfiguration.java index ea4170e29..cdf53495e 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/AdUnitConfiguration.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/AdUnitConfiguration.java @@ -202,17 +202,17 @@ public boolean isBuiltInVideo() { return isBuiltInVideo; } - public void setAutoRefreshDelay(int autoRefreshDelay) { - if (autoRefreshDelay < 0) { + public void setAutoRefreshDelay(int autoRefreshDelayInSeconds) { + if (autoRefreshDelayInSeconds < 0) { LogUtil.error(TAG, "Auto refresh delay can't be less then 0."); return; } - if (autoRefreshDelay == 0) { + if (autoRefreshDelayInSeconds == 0) { LogUtil.debug(TAG, "Only one request, without auto refresh."); autoRefreshDelayInMillis = 0; return; } - autoRefreshDelayInMillis = Utils.clampAutoRefresh(autoRefreshDelay); + autoRefreshDelayInMillis = Utils.clampAutoRefresh(autoRefreshDelayInSeconds); } public int getAutoRefreshDelay() { @@ -228,6 +228,9 @@ public int getVideoSkipOffset() { } public void setAdUnitIdentifierType(@Nullable AdUnitIdentifierType adUnitIdentifierType) { + if (adUnitIdentifierType == AdUnitIdentifierType.NATIVE) { + nativeConfiguration = new NativeAdUnitConfiguration(); + } this.adUnitIdentifierType = adUnitIdentifierType; } @@ -306,17 +309,6 @@ public int getBroadcastId() { } - public boolean isNative() { - return nativeConfiguration != null; - } - - /** - * Creates native configuration. - */ - public void initNativeConfiguration() { - nativeConfiguration = new NativeAdUnitConfiguration(); - } - @Nullable public NativeAdUnitConfiguration getNativeConfiguration() { return nativeConfiguration; diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/NativeAdUnitConfiguration.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/NativeAdUnitConfiguration.java index 7cc195d49..77d929784 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/NativeAdUnitConfiguration.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/units/configuration/NativeAdUnitConfiguration.java @@ -6,6 +6,7 @@ import org.prebid.mobile.NativeEventTracker; import java.util.ArrayList; +import java.util.List; public class NativeAdUnitConfiguration { @@ -25,7 +26,7 @@ public void addEventTracker(NativeEventTracker tracker) { nativeEventTrackers.add(tracker); } - public ArrayList getEventTrackers() { + public List getEventTrackers() { return nativeEventTrackers; }