diff --git a/.circleci/config.yml b/.circleci/config.yml index ecea48b5a..a5b953b01 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,14 +8,25 @@ version: 2.1 # See: https://circleci.com/docs/2.0/orb-intro/ orbs: android: circleci/android@1.0.3 - # Define a job to be invoked later in a workflow. # See: https://circleci.com/docs/2.0/configuration-reference/#jobs jobs: + android-test: + executor: + name: android/android-machine + steps: + - checkout + - android/start-emulator-and-run-tests: + post-emulator-launch-assemble-command: ./gradlew PrebidDemoKotlin:assembleAndroidTest + test-command: ./gradlew PrebidDemoKotlin:connectedDebugAndroidTest + system-image: system-images;android-30;google_apis;x86 # Below is the definition of your job to build and test your app, you can rename and customize it as you want. build: # These next lines define the Android machine image executor. # See: https://circleci.com/docs/2.0/executor-types/ + parameters: + buildCommand: + type: string executor: name: android/android-machine @@ -24,11 +35,8 @@ jobs: steps: # Checkout the code as the first step. - checkout - - # And finally run the release build - run: - name: Build Frameworks - command: scripts/buildPrebidMobile.sh + command: << parameters.buildCommand >> # Below is the definition of your job to build and test your app, you can rename and customize it as you want. test: @@ -36,13 +44,11 @@ jobs: # See: https://circleci.com/docs/2.0/executor-types/ executor: name: android/android-machine - # Add steps to the job # See: https://circleci.com/docs/2.0/configuration-reference/#steps steps: # Checkout the code as the first step. - checkout - # And finally run the release build - run: name: Test Frameworks @@ -54,5 +60,16 @@ workflows: sample: # This is the name of the workflow, feel free to change it to better match your workflow. # Inside the workflow, you define the jobs you want to run. jobs: - - build - - test + - build: + name: Build Java Demo + buildCommand: ./gradlew PrebidDemoJava:assembleDebug + - build: + name: Build Internal Test App + buildCommand: ./gradlew PrebidInternalTestApp:assembleDebug + - build: + name: Build PrebidMobile Frameworks + buildCommand: scripts/buildPrebidMobile.sh -nojar + - test: + name: Run Unit Tests - Prebid Mobile + - android-test: + name: Run Smoke UI Tests - Demo App Kotlin - Android 11 diff --git a/Example/PrebidDemoKotlin/build.gradle b/Example/PrebidDemoKotlin/build.gradle index c31693437..0a418ff76 100644 --- a/Example/PrebidDemoKotlin/build.gradle +++ b/Example/PrebidDemoKotlin/build.gradle @@ -59,4 +59,5 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' + androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' } diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ExampleInstrumentedTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ExampleInstrumentedTest.kt deleted file mode 100644 index 56392f567..000000000 --- a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.prebid.mobile.prebidkotlindemo - -import android.content.Context -import androidx.test.core.app.ApplicationProvider -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - val context = ApplicationProvider.getApplicationContext() - assertEquals("org.prebid.mobile.prebidkotlindemo", context.packageName) - } -} diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BannerAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BannerAdsTest.kt new file mode 100644 index 000000000..9100bc593 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BannerAdsTest.kt @@ -0,0 +1,28 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until +import junit.framework.Assert.assertNotNull +import junit.framework.Assert.assertTrue +import org.junit.Test +import org.prebid.mobile.prebidkotlindemo.utils.TestConstants + +class BannerAdsTest : BaseAdsTest() { + @Test + fun bannerAdsShouldBeDisplayed() { + testAd(TestConstants.GAM,TestConstants.BANNER_320x50) + testAd(TestConstants.IN_APP,TestConstants.BANNER_320x50) + testAd(TestConstants.IN_APP_GAM,TestConstants.BANNER_320x50) + testAd(TestConstants.IN_APP_ADMOB,TestConstants.BANNER_320x50) + testAd(TestConstants.IN_APP,TestConstants.BANNER_MULTISIZE) + testAd(TestConstants.GAM,TestConstants.BANNER_MULTISIZE) + } + + override fun checkAd(adServer: String,adName:String) { + val frameAdWrapperSelector = By.textContains("banner") + val findAd = device.wait(Until.findObject(frameAdWrapperSelector), timeout) + assertNotNull(findAd) + device.pressBack() + } + +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BaseAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BaseAdsTest.kt new file mode 100644 index 000000000..7ef7d44c8 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/BaseAdsTest.kt @@ -0,0 +1,128 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import android.content.Context +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.* +import junit.framework.AssertionFailedError +import org.hamcrest.CoreMatchers.notNullValue +import org.junit.After +import org.junit.Assert.assertThat +import org.junit.Before +import org.junit.runner.RunWith +import androidx.test.uiautomator.UiSelector + +import androidx.test.uiautomator.UiObject + + + + +@RunWith(AndroidJUnit4::class) +@SdkSuppress(minSdkVersion = 18) +abstract class BaseAdsTest { + protected val packageName = "org.prebid.mobile.prebidkotlindemo" + protected val timeout = 7000L + protected lateinit var device: UiDevice + + private lateinit var adServerSpinner: UiObject + private lateinit var adTypeSpinner: UiObject + private lateinit var showAdButton: UiObject + + private val adsErrorMessagesQueue = ArrayDeque() + + @Before + fun startMainActivityFromHomeScreen() { + initDevice() + startActivity() + device.wait( + Until.hasObject(By.pkg(packageName).depth(0)), + timeout + ) + initMainScreenComponents() + + } + @After + fun checkErrors(){ + displayErrorMessages() + } + + private fun initDevice() { + device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + device.pressHome() + val launcherPackage: String = device.launcherPackageName + assertThat(launcherPackage, notNullValue()) + device.wait( + Until.hasObject(By.pkg(launcherPackage).depth(0)), + timeout + ) + } + + private fun startActivity() { + val context = ApplicationProvider.getApplicationContext() + val intent = context.packageManager.getLaunchIntentForPackage( + packageName + ).apply { + this?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + } + context.startActivity(intent) + + } + + private fun initMainScreenComponents() { + adServerSpinner = device.findObject( + UiSelector().resourceId("$packageName:id/spinnerAdServer") + ) + adTypeSpinner = device.findObject( + UiSelector().resourceId("$packageName:id/spinnerAdType") + ) + showAdButton = device.findObject( + UiSelector().resourceId("$packageName:id/btnShowAd") + ) + } + + protected fun testAd(adServer: String, adName: String, retryCount: Int = 2) { + runCatching { + goToAd(adServer, adName) + checkAd(adServer,adName) + }.getOrElse { throwable -> + if (retryCount != 0) { + restartApp() + testAd(adServer, adName, retryCount - 1) + } else { + adsErrorMessagesQueue.add("$adServer - $adName ${throwable.stackTraceToString()}") + restartApp() + } + } + } + private fun displayErrorMessages() { + val failedTestsMessage = adsErrorMessagesQueue.joinToString(separator = System.lineSeparator()) + if (failedTestsMessage.isNotEmpty()){ + adsErrorMessagesQueue.clear() + throw AssertionError(failedTestsMessage) + } + } + + protected abstract fun checkAd(adServer: String,adName: String) + + private fun goToAd(adServer: String, adName: String) { + adServerSpinner.click() + selectSpinnerValue(adServer) + adTypeSpinner.click() + selectSpinnerValue(adName) + showAdButton.click() + } + + private fun selectSpinnerValue(value: String) { + device.findObject(By.text(value)).click() + } + private fun restartApp(){ + Runtime.getRuntime().exec(arrayOf("am", "force-stop", packageName)) + device.pressHome() + startActivity() + } + + +} diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/DisplayInterstitialAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/DisplayInterstitialAdsTest.kt new file mode 100644 index 000000000..051e595c1 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/DisplayInterstitialAdsTest.kt @@ -0,0 +1,51 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until +import junit.framework.Assert.assertNotNull +import org.junit.Test +import org.prebid.mobile.prebidkotlindemo.utils.TestConstants + +class DisplayInterstitialAdsTest : BaseAdsTest() { + @Test + fun displayInterstitialAdsShouldBeDisplayed() { + testAd(TestConstants.IN_APP, TestConstants.DISPLAY_INTERSTITIAL) + testAd(TestConstants.GAM, TestConstants.DISPLAY_INTERSTITIAL) + testAd(TestConstants.IN_APP_ADMOB, TestConstants.DISPLAY_INTERSTITIAL) + testAd(TestConstants.IN_APP_GAM, TestConstants.DISPLAY_INTERSTITIAL) + } + + @Test + fun multiformatInterstitialAdsShouldBeDisplayed() { + testAd(TestConstants.IN_APP, TestConstants.MULTIFORMAT_INTERSTITIAL) + } + + override fun checkAd(adServer: String, adName: String) { + val closeButton = By.res(packageName, "iv_close_interstitial") + val gamCloseButton = By.desc("Interstitial close button") + val ad = By.clazz("android.view.View") + val videoAd = By.res(packageName, "exo_subtitles") + + val findAd = if (adName == TestConstants.MULTIFORMAT_INTERSTITIAL) { + val findVideoAd = device.wait(Until.findObject(videoAd), timeout) + findVideoAd ?: device.wait(Until.findObject(ad), timeout) + } else { + device.wait(Until.findObject(ad), timeout) + } + assertNotNull(findAd) + + val findCloseButton = if (adServer == TestConstants.GAM) { + device.wait(Until.findObject(gamCloseButton), timeout) + } else { + device.wait(Until.findObject(closeButton), timeout) + } + assertNotNull(findCloseButton) + + findCloseButton.click() + Thread.sleep(1000) + device.pressBack() + + + } + +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/MraidAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/MraidAdsTest.kt new file mode 100644 index 000000000..71cc7f7bc --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/MraidAdsTest.kt @@ -0,0 +1,83 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until +import junit.framework.TestCase.assertNotNull +import org.junit.Test +import org.prebid.mobile.prebidkotlindemo.utils.TestConstants + +class MraidAdsTest:BaseAdsTest() { + @Test + fun mraidAdsShouldBeDisplayed(){ + testAd(TestConstants.IN_APP,TestConstants.MRAID_RESIZE) + testAd(TestConstants.IN_APP,TestConstants.MRAID_RESIZE_WITH_ERRORS) + testAd(TestConstants.IN_APP,TestConstants.MRAID_EXPAND) + } + + override fun checkAd(adServer: String,adName:String) { + when (adName){ + TestConstants.MRAID_EXPAND -> checkMraidExpand() + TestConstants.MRAID_RESIZE -> checkMraidResize() + TestConstants.MRAID_RESIZE_WITH_ERRORS -> checkMraidResizeWithErrors() + } + } + + private fun checkMraidResize() { + val clickToResize = By.text("Click to Resize") + val findClickToResize = device.wait(Until.findObject(clickToResize), timeout) + assertNotNull(findClickToResize) + findClickToResize.click() + + val closeButton = By.text("X") + val findCloseButton = device.wait(Until.findObject(closeButton), timeout) + assertNotNull(findCloseButton) + findCloseButton.click() + device.pressBack() + } + private fun checkMraidResizeWithErrors() { + val clickToggleScreen = By.res("toggleOffscreenDiv") + val findClickToggleScreen = device.wait(Until.findObject(clickToggleScreen), timeout) + assertNotNull(findClickToggleScreen) + findClickToggleScreen.click() + + val resizeLeft = By.res("resizeLeftText") + val findResizeLeft = device.wait(Until.findObject(resizeLeft), timeout) + assertNotNull(findResizeLeft) + findResizeLeft.click() + + val resizeRight = By.res("resizeRightText") + val findResizeRight = device.wait(Until.findObject(resizeRight), timeout) + assertNotNull(findResizeRight) + findResizeRight.click() + + val resizeUp = By.res("resizeUpText") + val findResizeUp = device.wait(Until.findObject(resizeUp), timeout) + assertNotNull(findResizeUp) + findResizeUp.click() + + val resizeDown = By.res("resizeDownText") + val findResizeDown = device.wait(Until.findObject(resizeDown), timeout) + assertNotNull(findResizeDown) + findResizeDown.click() + + val closeButton = By.res("closeButtonDiv") + val findCloseButton = device.wait(Until.findObject(closeButton),timeout) + assertNotNull(findCloseButton) + findCloseButton.click() + + device.pressBack() + } + private fun checkMraidExpand() { + val clickToExpand = By.res("maindiv") + val findClickToExpand = device.wait(Until.findObject(clickToExpand), timeout) + assertNotNull(findClickToExpand) + findClickToExpand.click() + + val closeButton = By.res("closediv") + val findCloseButton = device.wait(Until.findObject(closeButton), timeout) + assertNotNull(findCloseButton) + findCloseButton.click() + device.pressBack() + } + +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/NativeAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/NativeAdsTest.kt new file mode 100644 index 000000000..96d5ce248 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/NativeAdsTest.kt @@ -0,0 +1,54 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import androidx.test.uiautomator.By +import androidx.test.uiautomator.BySelector +import androidx.test.uiautomator.Until +import junit.framework.TestCase.assertNotNull +import org.junit.Test +import org.prebid.mobile.prebidkotlindemo.utils.TestConstants + +class NativeAdsTest : BaseAdsTest() { + @Test + fun nativeAdsShouldBeDisplayed() { + testAd(TestConstants.GAM,TestConstants.NATIVE_AD) + testAd(TestConstants.IN_APP, TestConstants.NATIVE_AD) + testAd(TestConstants.IN_APP_GAM, TestConstants.NATIVE_AD) + testAd(TestConstants.IN_APP_ADMOB, TestConstants.NATIVE_AD) + } + + override fun checkAd(adServer: String, adName: String) { + val ad = nativeAd(adServer) + val findAd = device.wait(Until.findObject(ad), timeout) + assertNotNull(findAd) + device.pressBack() + } + + private fun nativeAd(adServer: String): BySelector { + return when (adServer) { + TestConstants.GAM -> By.clazz("android.webkit.WebView") + TestConstants.IN_APP_ADMOB -> By.clazz("android.widget.LinearLayout") + .hasChild( + By.clazz("android.widget.LinearLayout") + ) + .hasChild( + By.res(packageName,"tvBody") + ) + .hasChild( + By.res(packageName,"imgMedia") + ) + else -> By.clazz("android.widget.LinearLayout") + .hasChild( + By.clazz("android.widget.LinearLayout") + ) + .hasChild( + By.clazz("android.widget.ImageView") + ) + .hasChild( + By.clazz("android.widget.TextView") + ) + .hasChild( + By.clazz("android.widget.Button") + ) + } + } +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/VideoAdsTest.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/VideoAdsTest.kt new file mode 100644 index 000000000..676317be7 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/ui/VideoAdsTest.kt @@ -0,0 +1,92 @@ +package org.prebid.mobile.prebidkotlindemo.ui + +import androidx.test.uiautomator.By +import androidx.test.uiautomator.BySelector +import androidx.test.uiautomator.Until +import junit.framework.Assert +import junit.framework.TestCase +import junit.framework.TestCase.assertNotNull +import org.junit.Test +import org.prebid.mobile.prebidkotlindemo.utils.TestConstants + +class VideoAdsTest : BaseAdsTest() { + @Test + fun videoAdsShouldBeDisplayed(){ + testAd(TestConstants.GAM, TestConstants.VIDEO_REWARDED) + testAd(TestConstants.IN_APP_GAM, TestConstants.VIDEO_REWARDED) + testAd(TestConstants.IN_APP, TestConstants.VIDEO_REWARDED) + testAd(TestConstants.IN_APP_ADMOB, TestConstants.VIDEO_REWARDED) + testAd(TestConstants.IN_APP, TestConstants.VIDEO_INTERSTITIAL_WITH_END_CARD) + testAd(TestConstants.IN_APP,TestConstants.VIDEO_BANNER) + testAd(TestConstants.IN_APP_GAM,TestConstants.VIDEO_BANNER) + } + + override fun checkAd(adServer: String, adName: String) { + when (adName) { + TestConstants.VIDEO_BANNER -> checkVideoBannerAd() + TestConstants.VIDEO_REWARDED -> checkVideoRewardedAd(adServer) + TestConstants.VIDEO_INTERSTITIAL_WITH_END_CARD -> checkVideoInterstitialAd() + } + } + + private fun checkVideoInterstitialAd() { + val ad = By.res(packageName, "exo_subtitles") + val endCard = By.text("Pbs_intestitial_320x480") + val closeButton = By.res(packageName, "iv_close_interstitial") + val skipButton = By.res(packageName, "iv_skip") + + val findAd = device.wait(Until.findObject(ad), timeout) + assertNotNull(findAd) + + val findSkipButton = device.wait(Until.findObject(skipButton), timeout * 3) + assertNotNull(findSkipButton) + findSkipButton.click() + + val findEndCard = device.wait(Until.findObject(endCard), timeout) + assertNotNull(findEndCard) + + val findCloseButton = device.wait(Until.findObject(closeButton), timeout) + assertNotNull(findCloseButton) + findCloseButton.click() + Thread.sleep(1000) + device.pressBack() + } + + private fun checkVideoBannerAd() { + val ad = By.res(packageName, "exo_subtitles") + val volumeButton = By.clazz("android.widget.ImageView") + + val findAd = device.wait(Until.findObject(ad), timeout) + assertNotNull(findAd) + val findVolumeButton = device.wait(Until.findObject(volumeButton), timeout) + assertNotNull(findVolumeButton) + device.pressBack() + } + + private fun checkVideoRewardedAd(adServer: String) { + val ad: BySelector + val endCard: BySelector + val closeButton: BySelector + if (adServer == TestConstants.GAM){ + ad = By.res("video_container") + endCard = By.text("recycling_300x250") + closeButton = By.clazz("android.widget.Button") + } else { + ad = By.res(packageName, "exo_subtitles") + endCard = By.text("Pbs_intestitial_320x480") + closeButton = By.res(packageName, "iv_close_interstitial") + } + val findAd = device.wait(Until.findObject(ad), timeout) + assertNotNull(findAd) + + val findEndCard = device.wait(Until.findObject(endCard), timeout * 3) + assertNotNull(findEndCard) + + val findCloseButton = device.wait(Until.findObject(closeButton), timeout) + assertNotNull(findCloseButton) + findCloseButton.click() + Thread.sleep(1000) + device.pressBack() + } + +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/utils/TestConstants.kt b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/utils/TestConstants.kt new file mode 100644 index 000000000..8cda20915 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/androidTest/java/org/prebid/mobile/prebidkotlindemo/utils/TestConstants.kt @@ -0,0 +1,27 @@ +package org.prebid.mobile.prebidkotlindemo.utils + +object TestConstants { + /** Ad Types*/ + const val BANNER_320x50 = "Banner 320x50" + const val BANNER_MULTISIZE = "Banner Multisize" + + const val DISPLAY_INTERSTITIAL = "Display Interstitial" + const val MULTIFORMAT_INTERSTITIAL = "Multiformat Interstitial" + + const val VIDEO_BANNER = "Video Banner" + const val VIDEO_REWARDED = "Rewarded Interstitial" + const val VIDEO_INTERSTITIAL_WITH_END_CARD = "Video Interstitial With End Card" + + const val MRAID_RESIZE = "MRAID Resize" + const val MRAID_RESIZE_WITH_ERRORS = "MRAID Resize with errors" + const val MRAID_EXPAND = "MRAID Expand 1-part" + + const val NATIVE_AD = "Native Ad" + + /** Ad Servers*/ + const val IN_APP = "In-App" + const val GAM = "Google Ad Manager" + const val IN_APP_GAM = "In-App + Google Ad Manager" + const val IN_APP_ADMOB = "In-App + AdMob" + +} \ No newline at end of file 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 db2a4f274..45f2b9496 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 @@ -3,9 +3,7 @@ package org.prebid.mobile.prebidkotlindemo import org.prebid.mobile.Host import org.prebid.mobile.PrebidMobile import org.prebid.mobile.api.data.AdUnitFormat -import org.prebid.mobile.prebidkotlindemo.ads.GamBanner -import org.prebid.mobile.prebidkotlindemo.ads.GamInterstitial -import org.prebid.mobile.prebidkotlindemo.ads.GamVideoInterstitial +import org.prebid.mobile.prebidkotlindemo.ads.* import org.prebid.mobile.prebidkotlindemo.ads.inapp.* import org.prebid.mobile.prebidkotlindemo.ads.inappadmob.InAppAdMobBanner import org.prebid.mobile.prebidkotlindemo.ads.inappadmob.InAppAdMobInterstitial @@ -33,6 +31,14 @@ object AdTypesRepository { }, onDestroy = { GamBanner.destroy() } ), + AdType("Banner Multisize", onCreate = { _, wrapper, autorefreshTime -> + GamBanner.create( + wrapper, autorefreshTime, 320, 50, + "/21808260008/prebid_demo_app_original_api_banner_multisize", + "imp-prebid-banner-multisize", + "response-prebid-banner-multisize" + ) + }), AdType( "Banner 300x250", onCreate = { _, wrapper, autoRefreshTime -> @@ -46,6 +52,19 @@ object AdTypesRepository { }, onDestroy = { GamBanner.destroy() } ), + AdType( + "Native Ad", + onCreate = { _, wrapper, autoRefreshTime -> + GamNative.create( + wrapper, + "/21808260008/unified_native_ad_unit", + "imp-prebid-banner-native-styles", + autoRefreshTime, + "response-prebid-banner-native-styles" + ) + }, + onDestroy = { GamNative.destroy() } + ), AdType( "Display Interstitial", onCreate = { activity, _, autoRefreshTime -> @@ -66,10 +85,21 @@ object AdTypesRepository { activity, "/21808260008/prebid-demo-app-original-api-video-interstitial", "imp-prebid-video-interstitial-320-480", - "response-prebid-video-interstitial-320-480" + "response-prebid-video-interstitial-320-480-original-api" ) }, onDestroy = { GamVideoInterstitial.destroy() } + ),AdType( + "Rewarded Interstitial", + onCreate = { activity, _, _ -> + GamVideoRewarded.create( + activity, + "/21808260008/prebid-demo-app-original-api-video-interstitial", + "imp-prebid-video-rewarded-320-480", + "response-prebid-video-rewarded-320-480-original-api" + ) + }, + onDestroy = { GamVideoRewarded.destroy() } ) ), @@ -87,22 +117,82 @@ object AdTypesRepository { onDestroy = { InAppBanner.destroy() } ), AdType( - "Interstitial", + "Banner Multisize", + onCreate = { _, wrapper, autoRefreshTime -> + InAppBanner.create( + wrapper, autoRefreshTime / 1000, + 728, 90, + "imp-prebid-banner-multisize", + "response-prebid-banner-multisize" + ) + }, + onDestroy = { InAppBanner.destroy() } + ), + AdType( + "Native Ad", + onCreate = { activity, wrapper, _ -> + InAppNative.create( + "imp-prebid-banner-native-styles", + wrapper, activity, + "response-prebid-banner-native-styles" + ) + }, + onDestroy = { InAppNative.destroy() } + ), + AdType( + "MRAID Resize", + onCreate = { _, wrapper, autoRefreshTime -> + InAppBanner.create( + wrapper, autoRefreshTime / 1000, + 320, 50, + "imp-prebid-mraid-resize", + "response-prebid-mraid-resize" + ) + }, + onDestroy = { GamBanner.destroy() } + ), + AdType( + "MRAID Expand 1-part", + onCreate = { _, wrapper, autoRefreshTime -> + InAppBanner.create( + wrapper, autoRefreshTime / 1000, + 320, 50, + "imp-prebid-mraid-expand-1-part", + "response-prebid-mraid-expand-1-part" + ) + }, + onDestroy = { GamBanner.destroy() } + ), + AdType( + "MRAID Resize with errors", + onCreate = { _, wrapper, autoRefreshTime -> + InAppBanner.create( + wrapper, autoRefreshTime / 1000, + 300, 100, + "imp-prebid-mraid-resize-with-errors", + "response-prebid-mraid-resize-with-errors" + ) + }, + onDestroy = { GamBanner.destroy() } + ), + AdType( + "Display Interstitial", onCreate = { context, _, _ -> InAppInterstitial.create( context, 30, 30, "imp-prebid-display-interstitial-320-480", - "response-prebid-display-interstitial-320-480" + "response-prebid-display-interstitial-320-480", + EnumSet.of(AdUnitFormat.DISPLAY) ) }, onDestroy = { InAppInterstitial.destroy() } ), AdType( "Video Banner", - onCreate = { _, wrapper, autoRefreshTime -> + onCreate = { _, wrapper, _ -> InAppVideoBanner.create( - wrapper, autoRefreshTime / 1000, + wrapper, 300, 250, "imp-prebid-video-outstream", "response-prebid-video-outstream" @@ -121,6 +211,33 @@ object AdTypesRepository { }, onDestroy = { InAppVideoInterstitial.destroy() } ), + AdType( + "Video Interstitial With End Card", + onCreate = { context, _, _ -> + InAppVideoInterstitial.create( + context, + "imp-prebid-video-interstitial-320-480-with-end-card", + "response-prebid-video-interstitial-320-480-with-end-card" + ) + }, + onDestroy = { InAppVideoInterstitial.destroy() } + ), + AdType( + "Multiformat Interstitial", + onCreate = { context, _, _ -> + val storedAuctionResponses = listOf( + "response-prebid-video-interstitial-320-480", + "response-prebid-display-interstitial-320-480" + ) + InAppInterstitial.create( + context, 30, 30, + "imp-prebid-video-interstitial-320-480", + storedAuctionResponses.random(), + EnumSet.of(AdUnitFormat.VIDEO, AdUnitFormat.DISPLAY) + ) + }, + onDestroy = { InAppVideoInterstitial.destroy() } + ), AdType( "Rewarded Interstitial", onCreate = { context, _, _ -> @@ -131,7 +248,7 @@ object AdTypesRepository { ) }, onDestroy = { InAppRewardedInterstitial.destroy() } - ) + ), ), "In-App + Google Ad Manager" to listOf( @@ -149,7 +266,20 @@ object AdTypesRepository { onDestroy = { InAppGamBanner.destroy() } ), AdType( - "Interstitial", + "Native Ad", + onCreate = { _, wrapper, _ -> + InAppGamNative.create( + wrapper, + "/21808260008/apollo_custom_template_native_ad_unit", + "imp-prebid-banner-native-styles", + "11934135", + "response-prebid-banner-native-styles" + ) + }, + onDestroy = { InAppGamNative.destroy() } + ), + AdType( + "Display Interstitial", onCreate = { context, _, _ -> InAppGamInterstitial.create( context, @@ -191,7 +321,7 @@ object AdTypesRepository { onCreate = { activity, _, _ -> InAppGamRewardedInterstitial.create( activity, - "/21808260008/prebid_oxb_rewarded_video_test", + "/21808260008/prebid-demo-app-original-api-video-interstitial", "imp-prebid-video-rewarded-320-480", "response-prebid-video-rewarded-320-480" ) @@ -202,7 +332,7 @@ object AdTypesRepository { "In-App + AdMob" to listOf( AdType( - "Banner", + "Banner 320x50", onCreate = { activity, wrapper, autoRefreshTime -> InAppAdMobBanner.create( activity, wrapper, autoRefreshTime, @@ -234,14 +364,14 @@ object AdTypesRepository { activity, "ca-app-pub-1875909575462531/6393291067", "imp-prebid-video-interstitial-320-480", - EnumSet.of(AdUnitFormat.VIDEO),"" + + EnumSet.of(AdUnitFormat.VIDEO), "" + "response-prebid-video-interstitial-320-480" ) }, onDestroy = { InAppAdMobInterstitial.destroy() } ), AdType( - "Rewarded", + "Rewarded Interstitial", onCreate = { activity, _, _ -> InAppAdMobRewarded.create( activity, @@ -253,7 +383,7 @@ object AdTypesRepository { onDestroy = { InAppAdMobRewarded.destroy() } ), AdType( - "Native", + "Native Ad", onCreate = { _, wrapper, _ -> // TODO: Problems with ids (current example's type is not Native) InAppAdMobNative.create( @@ -271,7 +401,7 @@ object AdTypesRepository { "In-App + Applovin MAX" to listOf( AdType( - "Banner", + "Banner 320x50", onCreate = { _, wrapper, autoRefreshTime -> PrebidMobile.setStoredAuctionResponse("response-prebid-banner-320-50") InAppMaxBanner.create( 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 f7c215015..019c8bba6 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 @@ -55,7 +55,7 @@ class CustomApplication : Application() { } private fun initAdMob() { - MobileAds.initialize(this) { status -> + MobileAds.initialize(this) { Log.d("MobileAds", "Initialization complete.") } val configuration = RequestConfiguration.Builder().setTestDeviceIds( @@ -66,7 +66,7 @@ class CustomApplication : Application() { private fun initApplovinMax() { AppLovinSdk.getInstance(this).mediationProvider = "max" - AppLovinSdk.getInstance(this).initializeSdk { configuration: AppLovinSdkConfiguration -> } + AppLovinSdk.getInstance(this).initializeSdk { } AppLovinSdk.getInstance(this).settings.setVerboseLogging(false) } diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/MainActivity.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/MainActivity.kt index 8974e86a7..0a66cc20b 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/MainActivity.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/MainActivity.kt @@ -64,6 +64,7 @@ class MainActivity : AppCompatActivity() { val repository = AdTypesRepository.get() val primaryAdServers = ArrayList(repository.keys) val spinner = binding.spinnerAdServer + spinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, primaryAdServers) spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(adapterView: AdapterView<*>, view: View, pos: Int, l: Long) { diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamBanner.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamBanner.kt index cf9a2562a..df20dc707 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamBanner.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamBanner.kt @@ -18,7 +18,7 @@ object GamBanner { private const val TAG = "GamBanner" - private var adUnit: AdUnit? = null + private var adUnit: BannerAdUnit? = null fun create( wrapper: ViewGroup, @@ -31,6 +31,7 @@ object GamBanner { ) { val adView = AdManagerAdView(wrapper.context) adView.adUnitId = adUnitId + PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) adView.adListener = object : AdListener() { @@ -49,11 +50,13 @@ object GamBanner { } } adView.setAdSizes(AdSize(width, height)) - wrapper.addView(adView) val request = AdManagerAdRequest.Builder().build() adUnit = BannerAdUnit(configId, width, height) + if (configId.contains("multisize")) { + adUnit?.addAdditionalSize(728, 90) + } adUnit?.setAutoRefreshPeriodMillis(autoRefreshTime) adUnit?.fetchDemand(request) { resultCode -> Log.d(TAG, "Result code: $resultCode") diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamNative.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamNative.kt new file mode 100644 index 000000000..ca03d727d --- /dev/null +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamNative.kt @@ -0,0 +1,93 @@ +package org.prebid.mobile.prebidkotlindemo.ads + +import android.util.Log +import android.view.ViewGroup +import com.google.android.gms.ads.AdListener +import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.admanager.AdManagerAdRequest +import com.google.android.gms.ads.admanager.AdManagerAdView +import org.prebid.mobile.* +import org.prebid.mobile.NativeEventTracker.EVENT_TRACKING_METHOD +import java.lang.Exception +import java.util.ArrayList + +object GamNative { + private const val TAG: String = "GamNative" + + private var nativeAdUnit: NativeAdUnit? = null + + fun create( + wrapper: ViewGroup, + adUnitId: String, + configId: String?, + autoRefreshTime: Int, + storedAuctionResponse: String + ) { + nativeAdUnit = NativeAdUnit(configId!!) + PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) + configureNativeAdUnit(nativeAdUnit!!) + val gamView = AdManagerAdView(wrapper.context) + gamView.adListener = object : AdListener() { + override fun onAdLoaded() { + Log.d(TAG, "On ad loaded") + } + } + gamView.adUnitId = adUnitId + gamView.setAdSizes(AdSize.FLUID) + wrapper.removeAllViews() + wrapper.addView(gamView) + val builder = AdManagerAdRequest.Builder() + nativeAdUnit!!.setAutoRefreshInterval(autoRefreshTime) + nativeAdUnit!!.fetchDemand(builder) { + val request = builder.build() + gamView.loadAd(request) + } + } + + fun destroy() { + if (nativeAdUnit != null) { + nativeAdUnit!!.stopAutoRefresh() + nativeAdUnit = null + } + } + + + private fun configureNativeAdUnit(adUnit: NativeAdUnit) { + adUnit.setContextType(NativeAdUnit.CONTEXT_TYPE.SOCIAL_CENTRIC) + adUnit.setPlacementType(NativeAdUnit.PLACEMENTTYPE.CONTENT_FEED) + adUnit.setContextSubType(NativeAdUnit.CONTEXTSUBTYPE.GENERAL_SOCIAL) + val methods = ArrayList() + methods.add(EVENT_TRACKING_METHOD.IMAGE) + try { + val tracker = NativeEventTracker(NativeEventTracker.EVENT_TYPE.IMPRESSION, methods) + adUnit.addEventTracker(tracker) + } catch (e: Exception) { + e.printStackTrace() + } + val title = NativeTitleAsset() + title.setLength(90) + title.isRequired = true + adUnit.addAsset(title) + val icon = NativeImageAsset(20, 20, 20, 20) + icon.imageType = NativeImageAsset.IMAGE_TYPE.ICON + icon.isRequired = true + adUnit.addAsset(icon) + val image = NativeImageAsset(200, 200, 200, 200) + image.imageType = NativeImageAsset.IMAGE_TYPE.MAIN + image.isRequired = true + adUnit.addAsset(image) + val data = NativeDataAsset() + data.len = 90 + data.dataType = NativeDataAsset.DATA_TYPE.SPONSORED + data.isRequired = true + adUnit.addAsset(data) + val body = NativeDataAsset() + body.isRequired = true + body.dataType = NativeDataAsset.DATA_TYPE.DESC + adUnit.addAsset(body) + val cta = NativeDataAsset() + cta.isRequired = true + cta.dataType = NativeDataAsset.DATA_TYPE.CTATEXT + adUnit.addAsset(cta) + } +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamVideoRewarded.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamVideoRewarded.kt new file mode 100644 index 000000000..efb7c6809 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/GamVideoRewarded.kt @@ -0,0 +1,69 @@ +package org.prebid.mobile.prebidkotlindemo.ads + +import android.R +import android.app.Activity +import android.os.Build +import android.util.Log +import androidx.appcompat.app.AlertDialog +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.ads.admanager.AdManagerAdRequest +import com.google.android.gms.ads.admanager.AdManagerInterstitialAd +import com.google.android.gms.ads.admanager.AdManagerInterstitialAdLoadCallback +import com.google.android.gms.ads.rewarded.RewardItem +import com.google.android.gms.ads.rewarded.RewardedAd +import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback +import org.prebid.mobile.* + + +object GamVideoRewarded { + private const val TAG: String = "GamVideoRewarded" + + private var adUnit: RewardedVideoAdUnit? = null + + fun create( + activity: Activity, + adUnitId: String, + configId: String, + storedAuctionResponse: String + ) { + val parameters = VideoBaseAdUnit.Parameters() + parameters.mimes = listOf("video/mp4") + parameters.protocols = listOf(Signals.Protocols.VAST_2_0) + parameters.playbackMethod = listOf(Signals.PlaybackMethod.AutoPlaySoundOff) + val builder = AdManagerAdRequest.Builder() + adUnit = RewardedVideoAdUnit(configId) + PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) + adUnit!!.parameters = parameters + adUnit!!.fetchDemand(builder) { + val request = builder.build() + RewardedAd.load( + activity, + adUnitId, + request, + createListener(activity) + ) + } + } + + fun destroy() { + if (adUnit != null) { + adUnit!!.stopAutoRefresh() + adUnit = null + } + } + + private fun createListener(activity: Activity): RewardedAdLoadCallback { + return object : RewardedAdLoadCallback() { + override fun onAdLoaded(rewardedAd: RewardedAd) { + Log.e(TAG, "Ad Loaded") + rewardedAd.show( + activity + ) { } + } + + override fun onAdFailedToLoad(loadAdError: LoadAdError) { + Log.e(TAG, loadAdError.message) + } + } + } +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppInterstitial.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppInterstitial.kt index 5c8b33ea2..6b62b1640 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppInterstitial.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppInterstitial.kt @@ -3,9 +3,11 @@ package org.prebid.mobile.prebidkotlindemo.ads.inapp import android.content.Context import org.prebid.mobile.AdSize import org.prebid.mobile.PrebidMobile +import org.prebid.mobile.api.data.AdUnitFormat import org.prebid.mobile.api.exceptions.AdException import org.prebid.mobile.api.rendering.InterstitialAdUnit import org.prebid.mobile.api.rendering.listeners.InterstitialAdUnitListener +import java.util.* object InAppInterstitial { @@ -16,9 +18,10 @@ object InAppInterstitial { minPercentageWidth: Int, minPercentageHeight: Int, configId: String, - storedAuctionResponse: String + storedAuctionResponse: String, + adFormats: EnumSet ) { - adUnit = InterstitialAdUnit(context, configId) + adUnit = InterstitialAdUnit(context, configId,adFormats) PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) adUnit?.setMinSizePercentage(AdSize(minPercentageWidth, minPercentageHeight)) adUnit?.setInterstitialAdUnitListener(object : diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppNative.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppNative.kt new file mode 100644 index 000000000..a392c0137 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppNative.kt @@ -0,0 +1,127 @@ +package org.prebid.mobile.prebidkotlindemo.ads.inapp + +import android.app.Activity +import android.os.Bundle +import org.prebid.mobile.* +import org.prebid.mobile.api.mediation.MediationNativeAdUnit +import android.content.Intent +import android.net.Uri + +import android.widget.TextView + +import android.view.ViewGroup +import android.widget.Button +import android.widget.ImageView + +import android.widget.LinearLayout + +import org.prebid.mobile.PrebidNativeAd +import org.prebid.mobile.prebidkotlindemo.utils.DownloadImageTask +import org.prebid.mobile.rendering.utils.ntv.NativeAdProvider + + +object InAppNative { + private var nativeAdUnit: MediationNativeAdUnit? = null + + fun create(configId: String, wrapper:ViewGroup,activity: Activity,storedAuctionResponse: String) { + val extras = Bundle() + nativeAdUnit = MediationNativeAdUnit(configId, extras) + PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) + configureNativeAdUnit(nativeAdUnit!!) + nativeAdUnit?.fetchDemand { + inflatePrebidNativeAd(NativeAdProvider.getNativeAd(extras)!!,activity,wrapper) + } + } + + fun destroy() { + nativeAdUnit?.destroy() + nativeAdUnit = null + PrebidMobile.setStoredAuctionResponse(null) + } + + private fun inflatePrebidNativeAd(ad: PrebidNativeAd,activity: Activity,wrapper:ViewGroup) { + val nativeContainer = LinearLayout(activity) + nativeContainer.orientation = LinearLayout.VERTICAL + val iconAndTitle = LinearLayout(activity) + iconAndTitle.orientation = LinearLayout.HORIZONTAL + val icon = ImageView(activity) + icon.layoutParams = LinearLayout.LayoutParams(160, 160) + icon.loadImage(ad.iconUrl) + iconAndTitle.addView(icon) + val title = TextView(activity) + title.textSize = 20f + title.text = ad.title + iconAndTitle.addView(title) + nativeContainer.addView(iconAndTitle) + val image = ImageView(activity) + image.layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + image.loadImage(ad.imageUrl) + nativeContainer.addView(image) + val description = TextView(activity) + description.textSize = 18f + description.text = ad.description + nativeContainer.addView(description) + val cta = Button(activity) + cta.text = ad.callToAction + cta.setOnClickListener { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://openx.com")) + activity.startActivity(browserIntent) + } + nativeContainer.addView(cta) + wrapper.addView(nativeContainer) + } + + private fun ImageView.loadImage(imageUrl:String){ + DownloadImageTask(this).execute(imageUrl) + } + + private fun configureNativeAdUnit(nativeAdUnit: MediationNativeAdUnit) { + nativeAdUnit.setContextType(NativeAdUnit.CONTEXT_TYPE.SOCIAL_CENTRIC) + nativeAdUnit.setPlacementType(NativeAdUnit.PLACEMENTTYPE.CONTENT_FEED) + nativeAdUnit.setContextSubType(NativeAdUnit.CONTEXTSUBTYPE.GENERAL_SOCIAL) + + val methods: ArrayList = ArrayList() + methods.add(NativeEventTracker.EVENT_TRACKING_METHOD.IMAGE) + methods.add(NativeEventTracker.EVENT_TRACKING_METHOD.JS) + try { + val tracker = NativeEventTracker(NativeEventTracker.EVENT_TYPE.IMPRESSION, methods) + nativeAdUnit.addEventTracker(tracker) + } catch (e: Exception) { + e.printStackTrace() + } + + val title = NativeTitleAsset() + title.setLength(90) + title.isRequired = true + nativeAdUnit.addAsset(title) + + val icon = NativeImageAsset(20, 20, 20, 20) + icon.imageType = NativeImageAsset.IMAGE_TYPE.ICON + icon.isRequired = true + nativeAdUnit.addAsset(icon) + + val image = NativeImageAsset(200, 200, 200, 200) + image.imageType = NativeImageAsset.IMAGE_TYPE.MAIN + image.isRequired = true + nativeAdUnit.addAsset(image) + + val data = NativeDataAsset() + data.len = 90 + data.dataType = NativeDataAsset.DATA_TYPE.SPONSORED + data.isRequired = true + nativeAdUnit.addAsset(data) + + val body = NativeDataAsset() + body.isRequired = true + body.dataType = NativeDataAsset.DATA_TYPE.DESC + nativeAdUnit.addAsset(body) + + val cta = NativeDataAsset() + cta.isRequired = true + cta.dataType = NativeDataAsset.DATA_TYPE.CTATEXT + nativeAdUnit.addAsset(cta) + } +} \ No newline at end of file diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppVideoBanner.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppVideoBanner.kt index ad7495ed3..f7cdd85ac 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppVideoBanner.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inapp/InAppVideoBanner.kt @@ -17,7 +17,6 @@ object InAppVideoBanner { fun create( wrapper: ViewGroup, - autoRefreshTime: Int, width: Int, height: Int, configId: String, diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappadmob/InAppAdMobInterstitial.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappadmob/InAppAdMobInterstitial.kt index 0160b8744..67a43ff1f 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappadmob/InAppAdMobInterstitial.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappadmob/InAppAdMobInterstitial.kt @@ -45,7 +45,11 @@ object InAppAdMobInterstitial { InterstitialAd.load(activity, adUnitId, request, object : InterstitialAdLoadCallback() { override fun onAdLoaded(interstitial: InterstitialAd) { interstitialAd = interstitial - interstitialAd?.show(activity) + val mediationAdapter = interstitial.responseInfo.mediationAdapterClassName + if (mediationAdapter!!.contains("prebid")) { + interstitialAd?.show(activity) + } + } override fun onAdFailedToLoad(error: LoadAdError) { diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappgam/InAppGamNative.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappgam/InAppGamNative.kt new file mode 100644 index 000000000..5798ffc43 --- /dev/null +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/ads/inappgam/InAppGamNative.kt @@ -0,0 +1,191 @@ +package org.prebid.mobile.prebidkotlindemo.ads.inappgam + +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.ImageView +import android.widget.TextView +import android.widget.Toast +import com.google.android.gms.ads.AdListener +import com.google.android.gms.ads.AdLoader +import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.ads.admanager.AdManagerAdRequest +import com.google.android.gms.ads.admanager.AdManagerAdView +import com.google.android.gms.ads.formats.OnAdManagerAdViewLoadedListener +import com.google.android.gms.ads.nativead.NativeAd +import com.google.android.gms.ads.nativead.NativeCustomFormatAd +import org.prebid.mobile.* +import org.prebid.mobile.NativeEventTracker.EVENT_TRACKING_METHOD +import org.prebid.mobile.addendum.AdViewUtils +import java.lang.Exception +import java.util.ArrayList +import org.prebid.mobile.prebidkotlindemo.R +import org.prebid.mobile.prebidkotlindemo.utils.DownloadImageTask +import org.prebid.mobile.rendering.bidding.data.bid.Prebid + +object InAppGamNative { + private const val TAG: String = "InAppGamNative" + + private var adView: AdManagerAdView? = null + private var unifiedNativeAd: NativeAd? = null + private var adUnit: NativeAdUnit? = null + private var adLoader: AdLoader? = null + + fun create( + wrapper: ViewGroup, + adUnitId: String, + configId: String?, + customFormatId: String, + storedAuctionResponse: String + ) { + adUnit = NativeAdUnit(configId!!) + PrebidMobile.setStoredAuctionResponse(storedAuctionResponse) + configureNativeAdUnit(adUnit!!) + val adRequest = AdManagerAdRequest.Builder().build() + adLoader = createAdLoader(wrapper, adUnitId, customFormatId) + adUnit!!.fetchDemand(adRequest) { + adLoader!!.loadAd(adRequest) + } + } + + fun destroy() { + if (adView != null) { + adView!!.destroy() + adView = null + } + if (unifiedNativeAd != null) { + unifiedNativeAd!!.destroy() + unifiedNativeAd = null + } + if (adUnit != null) { + adUnit!!.stopAutoRefresh() + adUnit = null + } + adLoader = null + } + + private fun inflatePrebidNativeAd( + ad: PrebidNativeAd, + wrapper: ViewGroup + ) { + val nativeContainer = View.inflate(wrapper.context, R.layout.layout_native, null) + ad.registerView(nativeContainer, object : PrebidNativeAdEventListener { + override fun onAdClicked() {} + + override fun onAdImpression() {} + + override fun onAdExpired() {} + }) + val icon = nativeContainer.findViewById(R.id.imgIcon) + loadImage(icon, ad.iconUrl) + val title = nativeContainer.findViewById(R.id.tvTitle) + title.text = ad.title + val image = nativeContainer.findViewById(R.id.imgImage) + loadImage(image, ad.imageUrl) + val description = nativeContainer.findViewById(R.id.tvDesc) + description.text = ad.description + val cta = nativeContainer.findViewById