diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java new file mode 100644 index 000000000..014668e60 --- /dev/null +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java @@ -0,0 +1,559 @@ +/* + * Copyright 2018-2019 Prebid.org, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.prebid.mobile.app; + +import android.graphics.Color; +import android.os.Bundle; +import android.view.View; +import android.widget.FrameLayout; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.ActivityTestRule; + +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.AdSize; +import com.google.android.gms.ads.doubleclick.PublisherAdRequest; +import com.google.android.gms.ads.doubleclick.PublisherAdView; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.prebid.mobile.AdUnit; +import org.prebid.mobile.BannerAdUnit; +import org.prebid.mobile.Host; +import org.prebid.mobile.LogUtil; +import org.prebid.mobile.OnCompleteListener; +import org.prebid.mobile.PrebidMobile; +import org.prebid.mobile.ResultCode; +import org.prebid.mobile.Util; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; + +import javax.annotation.Nullable; + +import okhttp3.HttpUrl; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +@RunWith(AndroidJUnit4.class) +public class AdManagerComplexTest { + @Rule + public ActivityTestRule testActivityRule = new ActivityTestRule<>(TestActivity.class); + + MockWebServer mockServer; + + @Before + public void setUp() { + mockServer = new MockWebServer(); + try { + mockServer.start(); + } catch (IOException e) { + fail("Mock server start failed."); + } + } + + @After + public void tearDown() throws Exception { + mockServer.shutdown(); + mockServer = null; + } + + @Test + public void testPublisherAdRequestBuilder() throws Exception { + + //given + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_env\": \"mobile-app\",\n" + + " \"hb_cache_hostpath\": \"https://prebid-cache-europe.rubiconproject.com/cache\",\n" + + " \"hb_size_rubicon\": \"300x250\",\n" + + " \"hb_cache_id\": \"a2f41588-4727-425c-9ef0-3b382debef1e\",\n" + + " \"hb_cache_path_rubicon\": \"/cache\",\n" + + " \"hb_cache_host_rubicon\": \"prebid-cache-europe.rubiconproject.com\",\n" + + " \"hb_pb\": \"1.20\",\n" + + " \"hb_pb_rubicon\": \"1.20\",\n" + + " \"hb_cache_id_rubicon\": \"a2f41588-4727-425c-9ef0-3b382debef1e\",\n" + + " \"hb_cache_path\": \"/cache\",\n" + + " \"hb_size\": \"300x250\",\n" + + " \"hb_cache_hostpath_rubicon\": \"https://prebid-cache-europe.rubiconproject.com/cache\",\n" + + " \"hb_env_rubicon\": \"mobile-app\",\n" + + " \"hb_bidder\": \"rubicon\",\n" + + " \"hb_bidder_rubicon\": \"rubicon\",\n" + + " \"hb_cache_host\": \"prebid-cache-europe.rubiconproject.com\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilder"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + final ReferenceWrapper customTargetingBundleWrapper = new ReferenceWrapper<>(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + customTargetingBundleWrapper.value = customTargetingBundle; + } + }); + + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle = customTargetingBundleWrapper.value; + + assertEquals(16, customTargetingBundle.keySet().size()); + + assertEquals("mobile-app", customTargetingBundle.getString("hb_env")); + assertEquals("https://prebid-cache-europe.rubiconproject.com/cache", customTargetingBundle.getString("hb_cache_hostpath")); + assertEquals("300x250", customTargetingBundle.getString("hb_size_rubicon")); + assertEquals("a2f41588-4727-425c-9ef0-3b382debef1e", customTargetingBundle.getString("hb_cache_id")); + assertEquals("/cache", customTargetingBundle.getString("hb_cache_path_rubicon")); + assertEquals("prebid-cache-europe.rubiconproject.com", customTargetingBundle.getString("hb_cache_host_rubicon")); + assertEquals("1.20", customTargetingBundle.getString("hb_pb")); + assertEquals("1.20", customTargetingBundle.getString("hb_pb_rubicon")); + assertEquals("a2f41588-4727-425c-9ef0-3b382debef1e", customTargetingBundle.getString("hb_cache_id_rubicon")); + assertEquals("/cache", customTargetingBundle.getString("hb_cache_path")); + assertEquals("300x250", customTargetingBundle.getString("hb_size")); + assertEquals("https://prebid-cache-europe.rubiconproject.com/cache", customTargetingBundle.getString("hb_cache_hostpath_rubicon")); + assertEquals("mobile-app", customTargetingBundle.getString("hb_env_rubicon")); + assertEquals("rubicon", customTargetingBundle.getString("hb_bidder")); + assertEquals("rubicon", customTargetingBundle.getString("hb_bidder_rubicon")); + assertEquals("prebid-cache-europe.rubiconproject.com", customTargetingBundle.getString("hb_cache_host")); + + } + + @Test + public void testPublisherAdRequestBuilderWithRefresh() throws Exception { + //given + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_1\",\n" + + " \"key1\": \"value1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_2\",\n" + + " \"key5\": \"value5\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilderWithRefresh"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + final ReferenceWrapper customTargetingBundleWrapper1 = new ReferenceWrapper<>(); + final ReferenceWrapper customTargetingBundleWrapper2 = new ReferenceWrapper<>(); + final IntegerWrapper requestCountWrapper = new IntegerWrapper(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + adUnit.setAutoRefreshPeriodMillis(30_001); + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + requestCountWrapper.value++; + + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + if (requestCountWrapper.value == 1) { + customTargetingBundleWrapper1.value = (Bundle)customTargetingBundle.clone(); + } else if (requestCountWrapper.value == 2) { + customTargetingBundleWrapper2.value = (Bundle)customTargetingBundle.clone(); + } + } + }); + + try { + Thread.sleep(31_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle1 = customTargetingBundleWrapper1.value; + Bundle customTargetingBundle2 = customTargetingBundleWrapper2.value; + + assertEquals(2, requestCountWrapper.value); + + assertEquals(2, customTargetingBundle1.keySet().size()); + assertEquals("top_bid_1", customTargetingBundle1.getString("hb_cache_id")); + assertEquals("value1", customTargetingBundle1.getString("key1")); + + assertEquals(2, customTargetingBundle2.keySet().size()); + assertEquals(null, customTargetingBundle2.getString("key1")); + assertEquals("top_bid_2", customTargetingBundle2.getString("hb_cache_id")); + assertEquals("value5", customTargetingBundle2.getString("key5")); + } + + @Test + public void testPublisherAdRequest() throws Exception { + PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + builder.addCustomTargeting("key1", "value1"); + builder.addCustomTargeting("key2", "value2"); + + PublisherAdRequest publisherAdRequest1 = builder.build(); + Bundle bundle1 = publisherAdRequest1.getCustomTargeting(); + + assertEquals(2, bundle1.keySet().size()); + assertEquals("value1", bundle1.getString("key1")); + assertEquals("value2", bundle1.getString("key2")); + + bundle1.remove("key2"); + assertEquals(1, bundle1.keySet().size()); + assertEquals("value1", bundle1.getString("key1")); + + PublisherAdRequest publisherAdRequest2 = builder.build(); + Bundle bundle2 = publisherAdRequest2.getCustomTargeting(); + assertEquals(1, bundle2.keySet().size()); + assertEquals("value1", bundle2.getString("key1")); + + } + + @Test + public void testPublisherAdRequestBuilderUseCase() throws Exception { + //given + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_1\",\n" + + " \"key1\": \"value1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilderUseCase"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + final ReferenceWrapper customTargetingBundleWrapper1 = new ReferenceWrapper<>(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + builder.addCustomTargeting("key2", "value2"); + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + customTargetingBundleWrapper1.value = (Bundle)customTargetingBundle.clone(); + + } + }); + + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle = customTargetingBundleWrapper1.value; + + assertEquals(3, customTargetingBundle.keySet().size()); + assertEquals("top_bid_1", customTargetingBundle.getString("hb_cache_id")); + assertEquals("value1", customTargetingBundle.getString("key1")); + assertEquals("value2", customTargetingBundle.getString("key2")); + + } + + //30x250 -> 728x90 + @Test + public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { + + final CountDownLatch lock = new CountDownLatch(1); + + PrebidMobile.setPrebidServerHost(Host.RUBICON); + PrebidMobile.setPrebidServerAccountId(Constants.PBS_ACCOUNT_ID_RUBICON); + PrebidMobile.setStoredAuctionResponse("1001-rubicon-300x250"); + + TestActivity activity = testActivityRule.getActivity(); + + final IntegerWrapper firstTransactionCount = new IntegerWrapper(); + final IntegerWrapper secondTransactionCount = new IntegerWrapper(); + + final int transactionFailRepeatCount = 5; + final int screenshotDelayMillis = 3_000; + final int transactionFailDelayMillis = 3_000; + + final FrameLayout adFrame = activity.findViewById(R.id.adFrame); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + adFrame.removeAllViews(); + } + }); + + final PublisherAdView dfpAdView = new PublisherAdView(activity); + //Programmatic fix + dfpAdView.setAdUnitId("/5300653/test_adunit_pavliuchyk_300x250_puc_ucTagData_prebid-server.rubiconproject.com"); + dfpAdView.setAdSizes(new AdSize(300, 250)); + + //Targeting creative + /* + dfpAdView.setAdUnitId("/5300653/Banner_PUC_b397711"); + dfpAdView.setAdSizes(new AdSize(300, 250), new AdSize(728, 90)); + */ + + final BannerAdUnit bannerAdUnit = new BannerAdUnit(Constants.PBS_CONFIG_ID_300x250_RUBICON, 300, 250); + + final PublisherAdRequest request = new PublisherAdRequest.Builder().build(); + final OnCompleteListener completeListener = new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + dfpAdView.loadAd(request); + } + }; + + dfpAdView.setAdListener(new AdListener() { + + private void notifyResult() { + lock.countDown(); + } + + private void update(boolean isSuccess) { + if (isSuccess) { + + if (firstTransactionCount.value != -1) { + firstTransactionCount.value = -1; + + PrebidMobile.setStoredAuctionResponse("1001-rubicon-300x50"); + + bannerAdUnit.fetchDemand(request, completeListener); + } else if (secondTransactionCount.value != -1) { + secondTransactionCount.value = -1; + + notifyResult(); + } + + } else { + try { + Thread.sleep(transactionFailDelayMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if (firstTransactionCount.value != -1) { + if (firstTransactionCount.value > transactionFailRepeatCount -2) { + fail("first Transaction Count == " + transactionFailRepeatCount); + } else { + //repeat + firstTransactionCount.value++; + bannerAdUnit.fetchDemand(request, completeListener); + } + } else if (secondTransactionCount.value != -1) { + if (secondTransactionCount.value > transactionFailRepeatCount -2) { + fail("second Transaction Count == " + transactionFailRepeatCount); + } else { + //repeat + secondTransactionCount.value++; + bannerAdUnit.fetchDemand(request, completeListener); + } + } else { + fail("Unexpected"); + } + + } + + } + + @Override + public void onAdLoaded() { + super.onAdLoaded(); + + //Programmatic fix + Util.findPrebidCreativeSize(dfpAdView, new Util.CreativeSizeCompletionHandler() { + @Override + public void onSize(final Util.CreativeSize size) { + if (size != null) { + + dfpAdView.setAdSizes(new AdSize(size.getWidth(), size.getHeight())); + + final View child = dfpAdView.getChildAt(0); + child.setBackgroundColor(Color.RED); + + dfpAdView.post(new Runnable() { + @Override + public void run() { + + float density = dfpAdView.getResources().getDisplayMetrics().density; + double dpW = Math.ceil(child.getMinimumWidth() / density); + double dpH = Math.ceil(child.getMinimumHeight() / density); + + try { + Thread.sleep(screenshotDelayMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + assertEquals((int)dpW, size.getWidth()); + assertEquals((int)dpH, size.getHeight()); + + update(true); + + } + }); + + } else { + LogUtil.w("size is null"); + update(false); + } + } + }); + + //Targeting creative + /* + try { + Thread.sleep(screenshotDelayMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + update(true); + */ + } + + @Override + public void onAdFailedToLoad(int i) { + super.onAdFailedToLoad(i); + LogUtil.w("onAdFailedToLoad:" + i); + + update(false); + } + }); + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + adFrame.addView(dfpAdView); + } + }); + + bannerAdUnit.fetchDemand(request, completeListener); + + //TravisCI fix + Thread.sleep(2 * transactionFailRepeatCount * transactionFailDelayMillis + 2 * screenshotDelayMillis); + //local test +// lock.await(); + + try { + Thread.sleep(screenshotDelayMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + assertEquals(-1, firstTransactionCount.value); + assertEquals(-1, secondTransactionCount.value); + + } + + private static class ReferenceWrapper { + @Nullable + T value = null; + } + + private static class IntegerWrapper { + int value = 0; + } + +} diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java deleted file mode 100644 index df88e2248..000000000 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2018-2019 Prebid.org, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.prebid.mobile.app; - -import android.graphics.Color; -import android.view.View; -import android.widget.FrameLayout; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.rule.ActivityTestRule; - -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdSize; -import com.google.android.gms.ads.doubleclick.PublisherAdRequest; -import com.google.android.gms.ads.doubleclick.PublisherAdView; - -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.prebid.mobile.BannerAdUnit; -import org.prebid.mobile.Host; -import org.prebid.mobile.LogUtil; -import org.prebid.mobile.OnCompleteListener; -import org.prebid.mobile.PrebidMobile; -import org.prebid.mobile.ResultCode; -import org.prebid.mobile.Util; - -import java.util.concurrent.CountDownLatch; - -import static org.junit.Assert.assertEquals; - -@RunWith(AndroidJUnit4.class) -public class DFPBannerComplexTest { - @Rule - public ActivityTestRule m = new ActivityTestRule<>(TestActivity.class); - - //30x250 -> 728x90 - @Test - public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { - - final CountDownLatch lock = new CountDownLatch(1); - - PrebidMobile.setPrebidServerHost(Host.RUBICON); - PrebidMobile.setPrebidServerAccountId(Constants.PBS_ACCOUNT_ID_RUBICON); - PrebidMobile.setStoredAuctionResponse(Constants.PBS_STORED_RESPONSE_300x250_RUBICON); - - TestActivity activity = m.getActivity(); - - final IntegerWrapper firstTransactionCount = new IntegerWrapper(); - final IntegerWrapper secondTransactionCount = new IntegerWrapper(); - - final int transactionFailRepeatCount = 5; - final int screenshotDelayMillis = 3_000; - final int transactionFailDelayMillis = 3_000; - - final FrameLayout adFrame = activity.findViewById(R.id.adFrame); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - adFrame.removeAllViews(); - } - }); - - final PublisherAdView dfpAdView = new PublisherAdView(activity); - //Programmatic fix - dfpAdView.setAdUnitId("/5300653/test_adunit_pavliuchyk_300x250_puc_ucTagData_prebid-server.rubiconproject.com"); - dfpAdView.setAdSizes(new AdSize(300, 250)); - - //Targeting creative - /* - dfpAdView.setAdUnitId("/5300653/Banner_PUC_b397711"); - dfpAdView.setAdSizes(new AdSize(300, 250), new AdSize(728, 90)); - */ - - final BannerAdUnit bannerAdUnit = new BannerAdUnit(Constants.PBS_CONFIG_ID_300x250_RUBICON, 300, 250); - - final PublisherAdRequest request = new PublisherAdRequest.Builder().build(); - final OnCompleteListener completeListener = new OnCompleteListener() { - @Override - public void onComplete(ResultCode resultCode) { - dfpAdView.loadAd(request); - } - }; - - dfpAdView.setAdListener(new AdListener() { - - private void notifyResult() { - lock.countDown(); - } - - private void update(boolean isSuccess) { - if (isSuccess) { - - if (firstTransactionCount.getValue() != -1) { - firstTransactionCount.value = -1; - //TODO make a call - - //TODO PrebidMobile.setStoredAuctionResponse(728x90); -// bannerAdUnit.addAdditionalSize(728, 90); - bannerAdUnit.fetchDemand(request, completeListener); - } else if (secondTransactionCount.getValue() != -1) { - secondTransactionCount.value = -1; - - notifyResult(); - } - - } else { - try { - Thread.sleep(transactionFailDelayMillis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - if (firstTransactionCount.getValue() != -1) { - if (firstTransactionCount.getValue() > transactionFailRepeatCount -2) { - Assert.fail("first Transaction Count == " + transactionFailRepeatCount); - } else { - //repeat - firstTransactionCount.value++; - bannerAdUnit.fetchDemand(request, completeListener); - } - } else if (secondTransactionCount.getValue() != -1) { - if (secondTransactionCount.getValue() > transactionFailRepeatCount -2) { - Assert.fail("second Transaction Count == " + transactionFailRepeatCount); - } else { - //repeat - secondTransactionCount.value++; - bannerAdUnit.fetchDemand(request, completeListener); - } - } else { - Assert.fail("Unexpected"); - } - - } - - } - - @Override - public void onAdLoaded() { - super.onAdLoaded(); - - //Programmatic fix - Util.findPrebidCreativeSize(dfpAdView, new Util.CreativeSizeCompletionHandler() { - @Override - public void onSize(final Util.CreativeSize size) { - if (size != null) { - - dfpAdView.setAdSizes(new AdSize(size.getWidth(), size.getHeight())); - - final View child = dfpAdView.getChildAt(0); - child.setBackgroundColor(Color.RED); - - dfpAdView.post(new Runnable() { - @Override - public void run() { - - float density = dfpAdView.getResources().getDisplayMetrics().density; - double dpW = Math.ceil(child.getMinimumWidth() / density); - double dpH = Math.ceil(child.getMinimumHeight() / density); - - try { - Thread.sleep(screenshotDelayMillis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - assertEquals((int)dpW, size.getWidth()); - assertEquals((int)dpH, size.getHeight()); - - update(true); - - } - }); - - } else { - LogUtil.w("size is null"); - update(false); - } - } - }); - - //Targeting creative - /* - try { - Thread.sleep(screenshotDelayMillis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - update(true); - */ - } - - @Override - public void onAdFailedToLoad(int i) { - super.onAdFailedToLoad(i); - LogUtil.w("onAdFailedToLoad:" + i); - - update(false); - } - }); - - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - adFrame.addView(dfpAdView); - } - }); - - bannerAdUnit.fetchDemand(request, completeListener); - - //TravisCI fix - Thread.sleep(2 * transactionFailRepeatCount * transactionFailDelayMillis + 2 * screenshotDelayMillis); - //local test -// lock.await(); - - try { - Thread.sleep(screenshotDelayMillis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - assertEquals(-1, firstTransactionCount.getValue()); - assertEquals(-1, secondTransactionCount.getValue()); - - - } - - private static class IntegerWrapper { - int value = 0; - - public int getValue() { - return value; - } - } - -} diff --git a/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java b/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java index d525d7bfe..1b2db463d 100644 --- a/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java +++ b/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java @@ -84,6 +84,7 @@ public class DemoActivity extends AppCompatActivity implements MoPubRewardedVide AdUnit adUnit; ResultCode resultCode; + //Used by UI tests PublisherAdRequest request; MoPubView adView; @@ -275,7 +276,6 @@ public void onAdLoaded() { nativeAdView.setAdSizes(AdSize.FLUID); adFrame.addView(nativeAdView); final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); NativeAdUnit nativeAdUnit = (NativeAdUnit) adUnit; nativeAdUnit.setContextType(NativeAdUnit.CONTEXT_TYPE.SOCIAL_CENTRIC); nativeAdUnit.setPlacementType(NativeAdUnit.PLACEMENTTYPE.CONTENT_FEED); @@ -321,12 +321,13 @@ public void onAdLoaded() { nativeAdUnit.addAsset(cta); int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); nativeAdUnit.setAutoRefreshPeriodMillis(millis); - nativeAdUnit.fetchDemand(request, new OnCompleteListener() { + nativeAdUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + request = builder.build(); nativeAdView.loadAd(request); - DemoActivity.this.request = request; refreshCount++; } }); @@ -451,14 +452,17 @@ public void failure(@NonNull PbFindSizeError error) { }); final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - final PublisherAdRequest request = builder.build(); + //region PrebidMobile Mobile API 1.0 usage int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); adUnit.setAutoRefreshPeriodMillis(millis); - adUnit.fetchDemand(request, new OnCompleteListener() { + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { + DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amBanner.loadAd(request); refreshCount++; } @@ -628,12 +632,13 @@ public void onInterstitialDismissed(MoPubInterstitial interstitial) { private void loadAMInterstitial() { int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); adUnit.setAutoRefreshPeriodMillis(millis); - PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); - adUnit.fetchDemand(request, new OnCompleteListener() { + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amInterstitial.loadAd(request); refreshCount++; } @@ -744,12 +749,13 @@ private void setupMPRubiconRewardedVideo() { //Load private void loadAMRewardedVideo() { - PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); - adUnit.fetchDemand(request, new OnCompleteListener() { + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amRewardedAd.loadAd(request, new RewardedAdLoadCallback() { @Override public void onRewardedAdLoaded() { 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 a5c0c1a01..bae4e92a3 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 @@ -105,15 +105,13 @@ class DemoActivity : AppCompatActivity() { adFrame.addView(dfpAdView) val builder = PublisherAdRequest.Builder() - val request = builder.build() - //region PrebidMobile Mobile API 1.0 usage val millis = intent.getIntExtra(Constants.AUTO_REFRESH_NAME, 0) adUnit!!.setAutoRefreshPeriodMillis(millis) - adUnit!!.fetchDemand(request, object : OnCompleteListener { + adUnit!!.fetchDemand(builder, object : OnCompleteListener { override fun onComplete(resultCode: ResultCode) { this@DemoActivity.resultCode = resultCode - dfpAdView.loadAd(request) + dfpAdView.loadAd(builder.build()) refreshCount++ } }) 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 0850d89f0..27e706e8b 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 @@ -54,7 +54,8 @@ public class Util { static final String MOPUB_BANNER_VIEW_CLASS = "com.mopub.mobileads.MoPubView"; static final String MOPUB_INTERSTITIAL_CLASS = "com.mopub.mobileads.MoPubInterstitial"; - static final String DFP_AD_REQUEST_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest"; + static final String AD_MANAGER_REQUEST_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest"; + static final String AD_MANAGER_REQUEST_BUILDER_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest$Builder"; private static final Random RANDOM = new Random(); private static final HashSet reservedKeys; private static final int MoPubQueryStringLimit = 4000; @@ -411,8 +412,8 @@ static boolean supportedAdObject(Object adObj) { if (adObj == null) return false; if (adObj.getClass() == getClassFromString(MOPUB_BANNER_VIEW_CLASS) || adObj.getClass() == getClassFromString(MOPUB_INTERSTITIAL_CLASS) - || adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS) - + || adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_CLASS) + || adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_BUILDER_CLASS) || adObj.getClass() == HashMap.class) return true; return false; @@ -423,9 +424,12 @@ static void apply(HashMap bids, Object adObj) { if (adObj.getClass() == getClassFromString(MOPUB_BANNER_VIEW_CLASS) || adObj.getClass() == getClassFromString(MOPUB_INTERSTITIAL_CLASS)) { handleMoPubKeywordsUpdate(bids, adObj); - } else if (adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS)) { - handleDFPCustomTargetingUpdate(bids, adObj); - } else if (adObj.getClass() == HashMap.class) { + } else if (adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_CLASS)) { + handleAdManagerCustomTargeting(bids, adObj); + } else if (adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_BUILDER_CLASS)) { + handleAdManagerBuilderCustomTargeting(bids, adObj); + } + else if (adObj.getClass() == HashMap.class) { if (bids != null && !bids.isEmpty()) { ((HashMap) adObj).putAll(bids); } @@ -454,10 +458,10 @@ private static void handleMoPubKeywordsUpdate(HashMap bids, Obje } } - private static void handleDFPCustomTargetingUpdate(HashMap bids, Object adObj) { - removeUsedCustomTargetingForDFP(adObj); + private static void handleAdManagerCustomTargeting(HashMap bids, Object publisherAdRequest) { + removeUsedCustomTargetingForDFP(publisherAdRequest); if (bids != null && !bids.isEmpty()) { - Bundle bundle = (Bundle) Util.callMethodOnObject(adObj, "getCustomTargeting"); + Bundle bundle = (Bundle) Util.callMethodOnObject(publisherAdRequest, "getCustomTargeting"); if (bundle != null) { // retrieve keywords from mopub adview for (String key : bids.keySet()) { @@ -468,6 +472,18 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } } + private static void handleAdManagerBuilderCustomTargeting(HashMap bids, Object publisherAdRequestBuilder) { + Object publisherAdRequest = Util.callMethodOnObject(publisherAdRequestBuilder, "build"); + removeUsedCustomTargetingForDFP(publisherAdRequest); + + if (bids != null && !bids.isEmpty()) { + for (String key : bids.keySet()) { + Util.callMethodOnObject(publisherAdRequestBuilder, "addCustomTargeting", key, bids.get(key)); + addReservedKeys(key); + } + } + } + private static void addReservedKeys(String key) { synchronized (reservedKeys) { reservedKeys.add(key); @@ -498,8 +514,8 @@ private static void removeUsedKeywordsForMoPub(Object adViewObj) { } } - private static void removeUsedCustomTargetingForDFP(Object adRequestObj) { - Bundle bundle = (Bundle) Util.callMethodOnObject(adRequestObj, "getCustomTargeting"); + private static void removeUsedCustomTargetingForDFP(Object publisherAdRequest) { + Bundle bundle = (Bundle) Util.callMethodOnObject(publisherAdRequest, "getCustomTargeting"); if (bundle != null && reservedKeys != null) { for (String key : reservedKeys) { bundle.remove(key); diff --git a/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java b/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java index 70f8488d9..24c27bb6b 100644 --- a/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java +++ b/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java @@ -63,7 +63,8 @@ public void testCallMethodOnObject() throws Exception { public void testGetClassFromString() throws Exception { assertEquals(MoPubView.class, Util.getClassFromString(Util.MOPUB_BANNER_VIEW_CLASS)); assertEquals(MoPubInterstitial.class, Util.getClassFromString(Util.MOPUB_INTERSTITIAL_CLASS)); - assertEquals(PublisherAdRequest.class, Util.getClassFromString(Util.DFP_AD_REQUEST_CLASS)); + assertEquals(PublisherAdRequest.class, Util.getClassFromString(Util.AD_MANAGER_REQUEST_CLASS)); + assertEquals(PublisherAdRequest.Builder.class, Util.getClassFromString(Util.AD_MANAGER_REQUEST_BUILDER_CLASS)); } @Test @@ -93,18 +94,22 @@ public void testApplyBidsToDFOAdObject() throws Exception { HashMap bids = new HashMap<>(); bids.put("hb_pb", "0.50"); bids.put("hb_cache_id", "123456"); + + Util.apply(bids, builder); PublisherAdRequest request = builder.build(); + assertEquals(3, request.getCustomTargeting().size()); + assertEquals("Value", request.getCustomTargeting().get("Key")); + assertEquals("0.50", request.getCustomTargeting().get("hb_pb")); + assertEquals("123456", request.getCustomTargeting().get("hb_cache_id")); + Util.apply(bids, request); assertEquals(3, request.getCustomTargeting().size()); - assertTrue(request.getCustomTargeting().containsKey("Key")); assertEquals("Value", request.getCustomTargeting().get("Key")); - assertTrue(request.getCustomTargeting().containsKey("hb_pb")); assertEquals("0.50", request.getCustomTargeting().get("hb_pb")); - assertTrue(request.getCustomTargeting().containsKey("hb_cache_id")); assertEquals("123456", request.getCustomTargeting().get("hb_cache_id")); + Util.apply(null, request); assertEquals(1, request.getCustomTargeting().size()); - assertTrue(request.getCustomTargeting().containsKey("Key")); assertEquals("Value", request.getCustomTargeting().get("Key")); } @@ -117,6 +122,8 @@ public void testSupportedAdObject() throws Exception { assertTrue(Util.supportedAdObject(interstitial)); PublisherAdRequest request = new PublisherAdRequest.Builder().build(); assertTrue(Util.supportedAdObject(request)); + PublisherAdRequest.Builder requestBuilder = new PublisherAdRequest.Builder(); + assertTrue(Util.supportedAdObject(requestBuilder)); Object object = new Object(); assertFalse(Util.supportedAdObject(object)); }