diff --git a/ThirdPartyAdapters/yandex/.gitignore b/ThirdPartyAdapters/yandex/.gitignore
new file mode 100644
index 000000000..916b2457a
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/.gitignore
@@ -0,0 +1,7 @@
+*.iml
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/CHANGELOG.md b/ThirdPartyAdapters/yandex/CHANGELOG.md
new file mode 100644
index 000000000..1c1c57a84
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Change Log
+All notable changes to Yandex Adapter for AdMob Mediation will be documented in this file.
+
+## Version 6.0.1.0
+
+#### Updated
+* Added support for Google Mobile Ads SDK 22.2.0
+* Added support for Yandex Mobile Ads SDK version to 6.0.1
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/build.gradle b/ThirdPartyAdapters/yandex/build.gradle
new file mode 100644
index 000000000..042d2fe9c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/build.gradle
@@ -0,0 +1,29 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext {
+ kotlinVersion = '1.8.0'
+ }
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/ThirdPartyAdapters/yandex/gradle.properties b/ThirdPartyAdapters/yandex/gradle.properties
new file mode 100644
index 000000000..d015431a8
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/gradle.properties
@@ -0,0 +1,2 @@
+android.useAndroidX=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.jar b/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..13372aef5
Binary files /dev/null and b/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.properties b/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..235737bec
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Sep 25 16:33:41 PDT 2023
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/ThirdPartyAdapters/yandex/gradlew b/ThirdPartyAdapters/yandex/gradlew
new file mode 100755
index 000000000..9d82f7891
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/ThirdPartyAdapters/yandex/gradlew.bat b/ThirdPartyAdapters/yandex/gradlew.bat
new file mode 100644
index 000000000..8a0b282aa
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/ThirdPartyAdapters/yandex/settings.gradle b/ThirdPartyAdapters/yandex/settings.gradle
new file mode 100644
index 000000000..b6b44dc7b
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/settings.gradle
@@ -0,0 +1 @@
+include ':yandex'
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/yandex/build.gradle b/ThirdPartyAdapters/yandex/yandex/build.gradle
new file mode 100644
index 000000000..344a9818c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/build.gradle
@@ -0,0 +1,145 @@
+plugins {
+ id 'com.android.library'
+ id 'maven-publish'
+ id 'org.jetbrains.kotlin.android'
+}
+
+/**
+ * Extra properties used by the project.
+ */
+ext {
+ // String property to store the proper name of the mediation network adapter.
+ adapterName = "Yandex"
+ // String property to store version name.
+ stringVersion = "6.0.1.0"
+ // String property to store group id.
+ stringGroupId = "com.google.ads.mediation"
+}
+
+kotlin {
+ jvmToolchain(11)
+}
+
+android {
+ compileSdkVersion 31
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 31
+ versionCode 6000100
+ versionName stringVersion
+ buildConfigField('String', 'ADAPTER_VERSION', "\"${stringVersion}\"")
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation 'com.yandex.android:mobileads:6.0.1'
+ implementation 'com.yandex.android:mobmetricalib:5.0.0'
+ implementation 'androidx.annotation:annotation:1.1.0'
+ implementation 'com.google.android.gms:play-services-ads:22.2.0'
+}
+
+/**
+ * Jar task to make a sources jar.
+ */
+task sourcesJar(type: Jar) {
+ archiveClassifier = 'sources'
+ from android.sourceSets.main.java.srcDirs
+}
+
+/**
+ * Publish closure consisting of maven publications.
+ */
+publishing {
+ publications {
+ adapterPublications(MavenPublication) {
+ groupId = stringGroupId
+ artifactId = project.name
+ version = stringVersion
+
+ // Add the aar artifact to publication.
+ artifact("$buildDir/outputs/aar/${project.name}-release.aar") {
+ builtBy build
+ }
+
+ // Add the sources jar artifact to the publication.
+ artifact(sourcesJar)
+
+ // Generate the pom file.
+ pom {
+ name = "${adapterName} mediation adapter for the Google Mobile Ads SDK"
+ description = "The ${adapterName} mediation adapter is a library that handles " +
+ "communication between the Google Mobile Ads SDK and the ${adapterName} " +
+ "SDK. It enables you to load ads from ${adapterName} using the mediation " +
+ "feature in the Google Mobile Ads SDK."
+ url = "https://developers.google.com/admob/android/mediation/${project.name}"
+ licenses {
+ license {
+ name = 'Apache-2.0'
+ url = 'https://github.com/googleads/googleads-mobile-android-mediation/blob/master/LICENSE'
+ distribution = 'repo'
+ }
+ }
+ }
+
+ // Add the required dependencies to the generated `pom.xml` file.
+ pom.withXml {
+ final dependenciesNode = asNode().appendNode('dependencies')
+ configurations.implementation.allDependencies.each {
+ // Exclude filetree dependencies.
+ if (it.name != 'unspecified') {
+ println("Adding dependency: " + it.group + ":" + it.name + ":" + it.version)
+
+ final dependencyNode = dependenciesNode.appendNode('dependency')
+ dependencyNode.appendNode('groupId', it.group)
+ dependencyNode.appendNode('artifactId', it.name)
+ dependencyNode.appendNode('version', it.version)
+ if (it.artifacts.size() > 0) {
+ dependencyNode.appendNode('type', it.artifacts[0].type)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Copy artifacts into a single directory for redistribution.
+ */
+task copyArtifactsForDistribution(type: Copy) {
+ from "$buildDir/outputs/aar/${project.name}-release.aar",
+ "$buildDir/libs/${project.name}-sources.jar",
+ "$buildDir/publications/adapterPublications/pom-default.xml"
+ into "$buildDir/distribution"
+}
+
+/**
+ * Create `zip` file for redistribution under `build/distribution` directory.
+ */
+task packageDistribution(type: Zip) {
+ from("$buildDir/distribution") {
+ rename("${project.name}-release.aar", "${project.name}-${stringVersion}.aar")
+ rename("${project.name}-sources.jar", "${project.name}-${stringVersion}-sources.jar")
+ rename("pom-default.xml", "${project.name}-${stringVersion}.pom")
+ }
+
+ archiveFileName = "${adapterName}AndroidAdapter-${stringVersion}.zip"
+ destinationDirectory = file("${rootProject.projectDir}/build/distribution")
+}
+
+build.dependsOn clean
+build.mustRunAfter clean
+copyArtifactsForDistribution.dependsOn(build, sourcesJar, generatePomFileForAdapterPublicationsPublication)
+packageDistribution.dependsOn copyArtifactsForDistribution
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/yandex/proguard-rules.pro b/ThirdPartyAdapters/yandex/yandex/proguard-rules.pro
new file mode 100644
index 000000000..d6d833d0c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/sbagadi/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/AndroidManifest.xml b/ThirdPartyAdapters/yandex/yandex/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..8dc133555
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/YandexAdapter.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/YandexAdapter.kt
new file mode 100644
index 000000000..49aef0e93
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/YandexAdapter.kt
@@ -0,0 +1,211 @@
+package com.google.ads.mediation.yandex
+
+import android.content.Context
+import com.google.ads.mediation.yandex.banner.BannerAdViewWrapper
+import com.google.ads.mediation.yandex.banner.MediationAdEventListener
+import com.google.ads.mediation.yandex.banner.YandexAdSizeProvider
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.ads.mediation.yandex.base.AdMobServerExtrasParserProvider
+import com.google.ads.mediation.yandex.base.AdRequestMapper
+import com.google.ads.mediation.yandex.base.MediationAdRequestWrapper
+import com.google.ads.mediation.yandex.base.YandexAdRequestCreator
+import com.google.ads.mediation.yandex.base.YandexErrorConverter
+import com.google.ads.mediation.yandex.base.YandexVersionInfoProvider
+import com.google.ads.mediation.yandex.interstitial.InterstitialAdLoadListenerFactory
+import com.google.ads.mediation.yandex.interstitial.InterstitialLoaderFactory
+import com.google.ads.mediation.yandex.nativeads.YandexNativeAdLoadListener
+import com.google.ads.mediation.yandex.rewarded.RewardedAdLoadListenerFactory
+import com.google.ads.mediation.yandex.rewarded.RewardedLoaderFactory
+import com.google.android.gms.ads.mediation.Adapter
+import com.google.android.gms.ads.mediation.InitializationCompleteCallback
+import com.google.android.gms.ads.mediation.MediationAdLoadCallback
+import com.google.android.gms.ads.mediation.MediationBannerAd
+import com.google.android.gms.ads.mediation.MediationBannerAdCallback
+import com.google.android.gms.ads.mediation.MediationBannerAdConfiguration
+import com.google.android.gms.ads.mediation.MediationConfiguration
+import com.google.android.gms.ads.mediation.MediationInterstitialAd
+import com.google.android.gms.ads.mediation.MediationInterstitialAdCallback
+import com.google.android.gms.ads.mediation.MediationInterstitialAdConfiguration
+import com.google.android.gms.ads.mediation.MediationNativeAdCallback
+import com.google.android.gms.ads.mediation.MediationNativeAdConfiguration
+import com.google.android.gms.ads.mediation.MediationRewardedAd
+import com.google.android.gms.ads.mediation.MediationRewardedAdCallback
+import com.google.android.gms.ads.mediation.MediationRewardedAdConfiguration
+import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper
+import com.yandex.mobile.ads.banner.BannerAdView
+import com.yandex.mobile.ads.common.MobileAds
+import com.yandex.mobile.ads.nativeads.NativeAdLoader
+
+internal class YandexAdapter @JvmOverloads constructor(
+ private val yandexAdRequestCreator: YandexAdRequestCreator = YandexAdRequestCreator(),
+ private val adRequestMapper: AdRequestMapper = AdRequestMapper(),
+ private val interstitialLoaderFactory: InterstitialLoaderFactory = InterstitialLoaderFactory(),
+ private val rewardedLoaderFactory: RewardedLoaderFactory = RewardedLoaderFactory(),
+ private val interstitialAdLoadListenerFactory: InterstitialAdLoadListenerFactory =
+ InterstitialAdLoadListenerFactory(),
+ private val rewardedAdLoadListenerFactory: RewardedAdLoadListenerFactory = RewardedAdLoadListenerFactory(),
+ private val adMobAdErrorCreator: AdMobAdErrorCreator = AdMobAdErrorCreator(),
+ private val yandexErrorConverter: YandexErrorConverter = YandexErrorConverter(),
+ private val adMobServerExtrasParserProvider: AdMobServerExtrasParserProvider = AdMobServerExtrasParserProvider(),
+ private val yandexVersionInfoProvider: YandexVersionInfoProvider = YandexVersionInfoProvider(),
+ private val yandexAdSizeProvider: YandexAdSizeProvider = YandexAdSizeProvider()
+) : Adapter() {
+
+ override fun getSDKVersionInfo() = yandexVersionInfoProvider.getSdkVersionInfo()
+
+ override fun getVersionInfo() = yandexVersionInfoProvider.adapterVersionInfo
+
+ override fun initialize(
+ context: Context,
+ initializationCompleteCallback: InitializationCompleteCallback,
+ list: MutableList
+ ) {
+ MobileAds.initialize(context) {
+ initializationCompleteCallback.onInitializationSucceeded()
+ }
+ }
+
+ override fun loadBannerAd(
+ mediationBannerAdConfiguration: MediationBannerAdConfiguration,
+ callback: MediationAdLoadCallback
+ ) {
+ try {
+ val serverExtrasParser = adMobServerExtrasParserProvider.getServerExtrasParser(
+ mediationBannerAdConfiguration.serverParameters,
+ CUSTOM_EVENT_SERVER_PARAMETER_FIELD
+ )
+ val adRequestWrapper = MediationAdRequestWrapper(mediationBannerAdConfiguration)
+ val adRequest = yandexAdRequestCreator.createAdRequest(adRequestWrapper)
+ val context = mediationBannerAdConfiguration.context
+
+ val adUnitId = serverExtrasParser.parseAdUnitId()
+ if (adUnitId.isNullOrEmpty() == false) {
+ val bannerAdView = BannerAdView(context)
+ val adViewWrapper = BannerAdViewWrapper(bannerAdView)
+
+ val adSize = yandexAdSizeProvider.getAdSize(
+ context, serverExtrasParser, mediationBannerAdConfiguration.adSize
+ )
+ val bannerAdEventListener = MediationAdEventListener(adViewWrapper, callback, adMobAdErrorCreator)
+ bannerAdView.apply {
+ adSize?.let { setAdSize(it) }
+ setAdUnitId(adUnitId)
+ setBannerAdEventListener(bannerAdEventListener)
+
+ loadAd(adRequest)
+ }
+ } else {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(ERROR_MESSAGE_INVALID_REQUEST)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ } catch (t: Throwable) {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(t.message)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ }
+
+ override fun loadNativeAd(
+ mediationNativeAdConfiguration: MediationNativeAdConfiguration,
+ callback: MediationAdLoadCallback
+ ) {
+ try {
+ val serverExtrasParser = adMobServerExtrasParserProvider.getServerExtrasParser(
+ mediationNativeAdConfiguration.serverParameters,
+ CUSTOM_EVENT_SERVER_PARAMETER_FIELD
+ )
+ val adRequestWrapper = MediationAdRequestWrapper(mediationNativeAdConfiguration)
+ val context = mediationNativeAdConfiguration.context
+
+ val adUnitId = serverExtrasParser.parseAdUnitId()
+ if (adUnitId.isNullOrEmpty() == false) {
+ val nativeAdLoader = NativeAdLoader(context)
+ val nativeAdLoadListener = YandexNativeAdLoadListener(
+ context,
+ callback,
+ mediationNativeAdConfiguration.mediationExtras
+ )
+
+ val configuration =
+ yandexAdRequestCreator.createNativeAdRequestConfiguration(adRequestWrapper, adUnitId)
+
+ nativeAdLoader.apply {
+ setNativeAdLoadListener(nativeAdLoadListener)
+ loadAd(configuration)
+ }
+ } else {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(ERROR_MESSAGE_INVALID_REQUEST)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ } catch (t: Throwable) {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(t.message)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ }
+
+ override fun loadInterstitialAd(
+ mediationInterstitialAdConfiguration: MediationInterstitialAdConfiguration,
+ callback: MediationAdLoadCallback
+ ) {
+ try {
+ val serverExtrasParser = adMobServerExtrasParserProvider.getServerExtrasParser(
+ mediationInterstitialAdConfiguration.serverParameters,
+ CUSTOM_EVENT_SERVER_PARAMETER_FIELD
+ )
+ val configuration = adRequestMapper.toAdRequestConfiguration(serverExtrasParser)
+
+ if (configuration != null) {
+ val context = mediationInterstitialAdConfiguration.context
+ val interstitialAdLoadListener = interstitialAdLoadListenerFactory.create(
+ callback, adMobAdErrorCreator
+ )
+
+ with(interstitialLoaderFactory.create(context)) {
+ setAdLoadListener(interstitialAdLoadListener)
+ loadAd(configuration)
+ }
+ } else {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(ERROR_MESSAGE_INVALID_REQUEST)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ } catch (t: Throwable) {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(t.message)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ }
+
+ override fun loadRewardedAd(
+ mediationRewardedAdConfiguration: MediationRewardedAdConfiguration,
+ callback: MediationAdLoadCallback
+ ) {
+ try {
+ val serverExtrasParser = adMobServerExtrasParserProvider.getServerExtrasParser(
+ mediationRewardedAdConfiguration.serverParameters,
+ CUSTOM_EVENT_SERVER_PARAMETER_FIELD
+ )
+ val configuration = adRequestMapper.toAdRequestConfiguration(serverExtrasParser)
+ if (configuration != null) {
+ val context = mediationRewardedAdConfiguration.context
+ val rewardedAdLoadListener = rewardedAdLoadListenerFactory.create(
+ callback, adMobAdErrorCreator
+ )
+
+ with(rewardedLoaderFactory.create(context)) {
+ setAdLoadListener(rewardedAdLoadListener)
+ loadAd(configuration)
+ }
+ } else {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(ERROR_MESSAGE_INVALID_REQUEST)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ } catch (t: Throwable) {
+ val adRequestError = yandexErrorConverter.convertToInvalidRequestError(t.message)
+ callback.onFailure(adMobAdErrorCreator.createLoadAdError(adRequestError))
+ }
+ }
+
+ companion object {
+
+ private const val CUSTOM_EVENT_SERVER_PARAMETER_FIELD = "parameter"
+ private const val ERROR_MESSAGE_INVALID_REQUEST = "Invalid request"
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/BannerAdViewWrapper.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/BannerAdViewWrapper.kt
new file mode 100644
index 000000000..fa74d2bb8
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/BannerAdViewWrapper.kt
@@ -0,0 +1,11 @@
+package com.google.ads.mediation.yandex.banner
+
+import android.view.View
+import com.google.android.gms.ads.mediation.MediationBannerAd
+import com.yandex.mobile.ads.banner.BannerAdView
+
+class BannerAdViewWrapper(private val bannerAdView: BannerAdView) : MediationBannerAd {
+ override fun getView(): View {
+ return bannerAdView.rootView
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/MediationAdEventListener.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/MediationAdEventListener.kt
new file mode 100644
index 000000000..62af76d5c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/MediationAdEventListener.kt
@@ -0,0 +1,41 @@
+package com.google.ads.mediation.yandex.banner
+
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.mediation.MediationAdLoadCallback
+import com.google.android.gms.ads.mediation.MediationBannerAd
+import com.google.android.gms.ads.mediation.MediationBannerAdCallback
+import com.yandex.mobile.ads.banner.BannerAdEventListener
+import com.yandex.mobile.ads.common.AdRequestError
+import com.yandex.mobile.ads.common.ImpressionData
+
+internal class MediationAdEventListener(
+ private val mediationBannerAd: MediationBannerAd,
+ private val mediationAdLoadCallback: MediationAdLoadCallback,
+ private val adMobAdErrorCreator: AdMobAdErrorCreator
+) : BannerAdEventListener {
+
+ private var bannerAdCallback: MediationBannerAdCallback? = null
+
+ override fun onImpression(impressionData: ImpressionData?) = Unit
+
+ override fun onAdLoaded() {
+ bannerAdCallback = mediationAdLoadCallback.onSuccess(mediationBannerAd)
+ }
+
+ override fun onAdFailedToLoad(adRequestError: AdRequestError) {
+ val adError = adMobAdErrorCreator.createLoadAdError(adRequestError)
+ mediationAdLoadCallback.onFailure(adError)
+ }
+
+ override fun onAdClicked() {
+ bannerAdCallback?.reportAdClicked()
+ }
+
+ override fun onLeftApplication() {
+ bannerAdCallback?.onAdLeftApplication()
+ }
+
+ override fun onReturnedToApplication() {
+ bannerAdCallback?.onAdClosed()
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/YandexAdSizeProvider.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/YandexAdSizeProvider.kt
new file mode 100644
index 000000000..e386d9bd0
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/banner/YandexAdSizeProvider.kt
@@ -0,0 +1,29 @@
+package com.google.ads.mediation.yandex.banner
+
+import android.content.Context
+import com.google.ads.mediation.yandex.base.AdMobServerExtrasParser
+import com.yandex.mobile.ads.banner.BannerAdSize
+import com.google.android.gms.ads.AdSize as GoogleAdSize
+
+internal class YandexAdSizeProvider {
+
+ fun getAdSize(
+ context: Context,
+ serverExtrasParser: AdMobServerExtrasParser,
+ adMobAdSize: GoogleAdSize?
+ ): BannerAdSize? {
+ var adSize = serverExtrasParser.parseAdSize(context)
+
+ if (adSize == null) {
+ adSize = getAdSizeFromAdMobAdSize(context, adMobAdSize)
+ }
+
+ return adSize
+ }
+
+ private fun getAdSizeFromAdMobAdSize(context: Context, adMobAdSize: GoogleAdSize?): BannerAdSize? {
+ return adMobAdSize?.let {
+ BannerAdSize.fixedSize(context, adMobAdSize.width, adMobAdSize.height)
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdErrorCreator.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdErrorCreator.kt
new file mode 100644
index 000000000..e353c3da9
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdErrorCreator.kt
@@ -0,0 +1,51 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.AdRequest
+import com.yandex.mobile.ads.common.AdError
+import com.yandex.mobile.ads.common.AdRequestError
+import com.google.android.gms.ads.AdError as AdMobError
+
+class AdMobAdErrorCreator {
+
+ private val yandexErrorConverter: YandexErrorConverter = YandexErrorConverter()
+
+ fun createLoadAdError(code: Int): AdMobError {
+ return AdMobError(code, FAILED_TO_LOAD_AD_MESSAGE, YANDEX_MOBILE_ADS_DOMAIN)
+ }
+
+ fun createLoadAdError(adRequestError: AdRequestError?): AdMobError {
+ return if (adRequestError != null) {
+ val code = yandexErrorConverter.convertToAdMobErrorCode(adRequestError)
+ AdMobError(code, adRequestError.description, YANDEX_MOBILE_ADS_DOMAIN)
+ } else {
+ AdMobError(
+ AdRequest.ERROR_CODE_INVALID_REQUEST,
+ FAILED_TO_LOAD_AD_MESSAGE,
+ YANDEX_MOBILE_ADS_DOMAIN,
+ null
+ )
+ }
+ }
+
+ fun createRequiresActivityError() = AdMobError(
+ yandexErrorConverter.convertToAdMobErrorCode(null),
+ REQUIRES_ACTIVITY_MESSAGE,
+ YANDEX_MOBILE_ADS_DOMAIN
+ )
+
+ fun convertToAdMobError(adError: AdError): AdMobError {
+ return AdMobError(
+ yandexErrorConverter.convertToAdMobErrorCode(null),
+ adError.description,
+ YANDEX_MOBILE_ADS_DOMAIN
+ )
+ }
+
+ companion object {
+
+ private const val REQUIRES_ACTIVITY_MESSAGE =
+ "Yandex Mobile Ads SDK requires an Activity context to show an ad."
+ private const val FAILED_TO_LOAD_AD_MESSAGE = "Failed to load ad"
+ private const val YANDEX_MOBILE_ADS_DOMAIN = "com.yandex.mobile.ads"
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdRequestParametersProvider.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdRequestParametersProvider.kt
new file mode 100644
index 000000000..865d108fb
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobAdRequestParametersProvider.kt
@@ -0,0 +1,41 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.MobileAds
+import com.google.ads.mediation.yandex.BuildConfig
+
+internal class AdMobAdRequestParametersProvider {
+
+ private val adapterVersion: String
+ get() = BuildConfig.ADAPTER_VERSION
+
+ fun getAdRequestParameters(): Map {
+ val adRequestParameters: MutableMap = HashMap()
+ adRequestParameters[ADAPTER_NETWORK_NAME_KEY] = ADAPTER_NETWORK_NAME
+ appendVersionParameters(adRequestParameters)
+
+ return adRequestParameters
+ }
+
+ private fun getAdMobSdkVersion(): String? {
+ return try {
+ MobileAds.getVersion().toString()
+ } catch (ignored: Throwable) {
+ null
+ }
+ }
+
+ private fun appendVersionParameters(adRequestParameters: MutableMap) {
+ val adMobSdkVersion = getAdMobSdkVersion()
+ if (adMobSdkVersion != null) {
+ adRequestParameters[ADAPTER_NETWORK_SDK_VERSION_KEY] = adMobSdkVersion
+ }
+ adRequestParameters[ADAPTER_VERSION_KEY] = adapterVersion
+ }
+
+ companion object {
+ private const val ADAPTER_VERSION_KEY = "adapter_version"
+ private const val ADAPTER_NETWORK_NAME_KEY = "adapter_network_name"
+ private const val ADAPTER_NETWORK_SDK_VERSION_KEY = "adapter_network_sdk_version"
+ private const val ADAPTER_NETWORK_NAME = "admob"
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParser.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParser.kt
new file mode 100644
index 000000000..f5c025bdc
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParser.kt
@@ -0,0 +1,53 @@
+package com.google.ads.mediation.yandex.base
+
+import android.content.Context
+import com.yandex.mobile.ads.banner.BannerAdSize
+import org.json.JSONObject
+
+class AdMobServerExtrasParser(private val serverExtras: JSONObject) {
+
+ fun parseAdUnitId(): String? {
+ var adUnitId = serverExtras.optString(AD_UNIT_ID)
+ if (adUnitId.isNullOrEmpty()) {
+ adUnitId = serverExtras.optString(BLOCK_ID)
+ }
+
+ return adUnitId
+ }
+
+ fun parseShouldOpenLinksInApp(): Boolean {
+ return serverExtras.optBoolean(OPEN_LINKS_IN_APP)
+ }
+
+ fun parseAdSize(context: Context): BannerAdSize? {
+ val serverAdWidth = parseInteger(AD_WIDTH_KEY)
+ val serverAdHeight = parseInteger(AD_HEIGHT_KEY)
+ return if (serverAdWidth != null && serverAdHeight != null) {
+ BannerAdSize.fixedSize(context, serverAdWidth, serverAdHeight)
+ } else {
+ null
+ }
+ }
+
+ private fun parseInteger(key: String): Int? {
+ val numberExtra = serverExtras.optString(key)
+ var number: Int? = null
+
+ try {
+ if (numberExtra != null) {
+ number = numberExtra.toInt()
+ }
+ } catch (ignored: NumberFormatException) {
+ }
+
+ return number
+ }
+
+ companion object {
+ private const val BLOCK_ID = "blockID"
+ private const val AD_UNIT_ID = "adUnitId"
+ private const val AD_WIDTH_KEY = "adWidth"
+ private const val AD_HEIGHT_KEY = "adHeight"
+ private const val OPEN_LINKS_IN_APP = "openLinksInApp"
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParserProvider.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParserProvider.kt
new file mode 100644
index 000000000..ad881b704
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdMobServerExtrasParserProvider.kt
@@ -0,0 +1,26 @@
+package com.google.ads.mediation.yandex.base
+
+import android.os.Bundle
+import org.json.JSONException
+import org.json.JSONObject
+
+class AdMobServerExtrasParserProvider {
+
+ @Throws(JSONException::class)
+ fun getServerExtrasParser(serverParameter: String?): AdMobServerExtrasParser {
+ if (serverParameter == null) {
+ throw JSONException("Server parameter must be not null")
+ }
+ val serverExtras = JSONObject(serverParameter)
+ return AdMobServerExtrasParser(serverExtras)
+ }
+
+ @Throws(JSONException::class)
+ fun getServerExtrasParser(
+ serverParameters: Bundle,
+ parametersKey: String?
+ ): AdMobServerExtrasParser {
+ val serverParameter = serverParameters.getString(parametersKey)
+ return getServerExtrasParser(serverParameter)
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdRequestMapper.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdRequestMapper.kt
new file mode 100644
index 000000000..1323c0351
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/AdRequestMapper.kt
@@ -0,0 +1,19 @@
+package com.google.ads.mediation.yandex.base
+
+import com.yandex.mobile.ads.common.AdRequestConfiguration
+
+internal class AdRequestMapper(
+ private val adRequestParametersProvider: AdMobAdRequestParametersProvider = AdMobAdRequestParametersProvider()
+) {
+
+ fun toAdRequestConfiguration(parser: AdMobServerExtrasParser): AdRequestConfiguration? {
+ val adUnitId = parser.parseAdUnitId()
+ ?.takeIf { it.isNotBlank() }
+ ?: return null
+
+ val params = adRequestParametersProvider.getAdRequestParameters()
+ return AdRequestConfiguration.Builder(adUnitId)
+ .setParameters(params)
+ .build()
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/MediationAdRequestWrapper.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/MediationAdRequestWrapper.kt
new file mode 100644
index 000000000..ff014cf17
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/MediationAdRequestWrapper.kt
@@ -0,0 +1,13 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.mediation.MediationAdConfiguration
+
+class MediationAdRequestWrapper(
+ private val mediationBannerAdConfiguration: MediationAdConfiguration
+) {
+ val keywords: Set?
+ get() = mediationBannerAdConfiguration.mediationExtras.keySet()
+
+ val taggedForChildDirectedTreatment: Int
+ get() = mediationBannerAdConfiguration.taggedForChildDirectedTreatment()
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexAdRequestCreator.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexAdRequestCreator.kt
new file mode 100644
index 000000000..361d3f1f0
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexAdRequestCreator.kt
@@ -0,0 +1,62 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.RequestConfiguration
+import com.yandex.mobile.ads.common.AdRequest
+import com.yandex.mobile.ads.common.MobileAds
+import com.yandex.mobile.ads.nativeads.NativeAdRequestConfiguration
+
+class YandexAdRequestCreator {
+
+ private val adRequestParametersProvider: AdMobAdRequestParametersProvider = AdMobAdRequestParametersProvider()
+
+ fun createAdRequest(mediationAdRequest: MediationAdRequestWrapper): AdRequest {
+ val adRequestParameters = adRequestParametersProvider.getAdRequestParameters()
+ val adRequestBuilder = AdRequest.Builder()
+ adRequestBuilder.setParameters(adRequestParameters)
+
+ setAgeRestrictedUser(mediationAdRequest)
+
+ val mediationKeywords = mediationAdRequest.keywords
+ if (mediationKeywords != null) {
+ val keywords = ArrayList(mediationKeywords)
+ adRequestBuilder.setContextTags(keywords)
+ }
+
+ return adRequestBuilder.build()
+ }
+
+ fun createAdRequest(): AdRequest {
+ val adRequestParameters = adRequestParametersProvider.getAdRequestParameters()
+ val adRequestBuilder = AdRequest.Builder()
+ adRequestBuilder.setParameters(adRequestParameters)
+
+ return adRequestBuilder.build()
+ }
+
+ fun createNativeAdRequestConfiguration(
+ adRequestWrapper: MediationAdRequestWrapper,
+ adUnitId: String
+ ): NativeAdRequestConfiguration {
+ val adRequestParameters = adRequestParametersProvider.getAdRequestParameters()
+ val adRequestConfigurationBuilder = NativeAdRequestConfiguration.Builder(adUnitId)
+ adRequestConfigurationBuilder.setParameters(adRequestParameters)
+
+ val mediationKeywords = adRequestWrapper.keywords
+ if (mediationKeywords != null) {
+ val keywords = ArrayList(mediationKeywords)
+ adRequestConfigurationBuilder.setContextTags(keywords)
+ }
+
+ return adRequestConfigurationBuilder.build()
+ }
+
+ private fun setAgeRestrictedUser(adRequestWrapper: MediationAdRequestWrapper) {
+ val tagForChildDirectedTreatment = adRequestWrapper.taggedForChildDirectedTreatment
+
+ if (tagForChildDirectedTreatment == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE) {
+ MobileAds.setAgeRestrictedUser(true)
+ } else if (tagForChildDirectedTreatment == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE) {
+ MobileAds.setAgeRestrictedUser(false)
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexErrorConverter.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexErrorConverter.kt
new file mode 100644
index 000000000..db6d9ab1c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexErrorConverter.kt
@@ -0,0 +1,28 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.AdRequest
+import com.yandex.mobile.ads.common.AdRequestError
+
+class YandexErrorConverter {
+
+ fun convertToAdMobErrorCode(adRequestError: AdRequestError?): Int {
+
+ return when (adRequestError?.code) {
+
+ AdRequestError.Code.INTERNAL_ERROR,
+ AdRequestError.Code.SYSTEM_ERROR -> AdRequest.ERROR_CODE_INTERNAL_ERROR
+
+ AdRequestError.Code.INVALID_REQUEST -> AdRequest.ERROR_CODE_INVALID_REQUEST
+
+ AdRequestError.Code.NETWORK_ERROR -> AdRequest.ERROR_CODE_NETWORK_ERROR
+
+ AdRequestError.Code.NO_FILL -> AdRequest.ERROR_CODE_NO_FILL
+
+ else -> AdRequest.ERROR_CODE_INTERNAL_ERROR
+ }
+ }
+
+ fun convertToInvalidRequestError(message: String?): AdRequestError {
+ return AdRequestError(AdRequestError.Code.INVALID_REQUEST, message)
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexVersionInfoProvider.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexVersionInfoProvider.kt
new file mode 100644
index 000000000..338f24a37
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/base/YandexVersionInfoProvider.kt
@@ -0,0 +1,48 @@
+package com.google.ads.mediation.yandex.base
+
+import com.google.android.gms.ads.VersionInfo
+import com.google.ads.mediation.yandex.BuildConfig;
+import com.yandex.mobile.ads.common.MobileAds
+
+class YandexVersionInfoProvider {
+
+ val adapterVersion: String
+ get() = BuildConfig.ADAPTER_VERSION
+
+ val adapterVersionInfo: VersionInfo
+ get() = createVersionInfo(adapterVersion)
+
+ fun getSdkVersionInfo(): VersionInfo {
+ val sdkVersionString = MobileAds.getLibraryVersion()
+ val normalizedSdkVersionString = sdkVersionString ?: ""
+ return createVersionInfo(normalizedSdkVersionString)
+ }
+
+ private fun createVersionInfo(version: String): VersionInfo {
+ val splitVersion = version.split(VERSION_SPLIT_REGEX).toTypedArray()
+
+ val numbers = splitVersion.map { parseInt(it) }
+
+ val versionInfo: VersionInfo = if (numbers.size >= SEMANTIC_VERSION_LENGTH) {
+ VersionInfo(numbers[0], numbers[1], numbers[2])
+ } else {
+ VersionInfo(0, 0, 0)
+ }
+
+ return versionInfo
+ }
+
+ private fun parseInt(value: String): Int {
+ return try {
+ value.toInt()
+ } catch (e: NumberFormatException) {
+ DEFAULT_PARSE_VALUE
+ }
+ }
+
+ companion object {
+ private const val SEMANTIC_VERSION_LENGTH = 3
+ private const val DEFAULT_PARSE_VALUE = 0
+ private const val VERSION_SPLIT_REGEX = "."
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialAdLoadListenerFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialAdLoadListenerFactory.kt
new file mode 100644
index 000000000..0192688af
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialAdLoadListenerFactory.kt
@@ -0,0 +1,44 @@
+package com.google.ads.mediation.yandex.interstitial
+
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.mediation.MediationAdLoadCallback
+import com.google.android.gms.ads.mediation.MediationInterstitialAd
+import com.google.android.gms.ads.mediation.MediationInterstitialAdCallback
+import com.yandex.mobile.ads.common.AdRequestError
+import com.yandex.mobile.ads.interstitial.InterstitialAd
+import com.yandex.mobile.ads.interstitial.InterstitialAdLoadListener
+
+internal class InterstitialAdLoadListenerFactory {
+
+ fun create(
+ callback: MediationAdLoadCallback,
+ adMobAdErrorCreator: AdMobAdErrorCreator,
+ mediationInterstitialAdFactory: MediationInterstitialAdFactory = MediationInterstitialAdFactory()
+ ) = object : InterstitialAdLoadListener {
+
+ var interstitialAdCallback: MediationInterstitialAdCallback? = null
+
+ override fun onAdLoaded(loadedAd: InterstitialAd) {
+ val mediationInterstitialAd = mediationInterstitialAdFactory.create(
+ loadedAd, ::onContextIsNotActivityError
+ )
+ interstitialAdCallback = callback.onSuccess(mediationInterstitialAd).also { interstitialAdCallback ->
+ val mediationInterstitialAdEventListener = MediationInterstitialAdEventListener(
+ interstitialAdCallback,
+ adMobAdErrorCreator
+ )
+ loadedAd.setAdEventListener(mediationInterstitialAdEventListener)
+ }
+ }
+
+ override fun onAdFailedToLoad(error: AdRequestError) {
+ val adError = adMobAdErrorCreator.createLoadAdError(error)
+ callback.onFailure(adError)
+ }
+
+ private fun onContextIsNotActivityError() {
+ val error = adMobAdErrorCreator.createRequiresActivityError()
+ interstitialAdCallback?.onAdFailedToShow(error)
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialLoaderFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialLoaderFactory.kt
new file mode 100644
index 000000000..a83051686
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/InterstitialLoaderFactory.kt
@@ -0,0 +1,8 @@
+package com.google.ads.mediation.yandex.interstitial
+
+import android.content.Context
+import com.yandex.mobile.ads.interstitial.InterstitialAdLoader
+
+internal class InterstitialLoaderFactory {
+ fun create(context: Context) = InterstitialAdLoader(context)
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdEventListener.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdEventListener.kt
new file mode 100644
index 000000000..1f8b3fd92
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdEventListener.kt
@@ -0,0 +1,33 @@
+package com.google.ads.mediation.yandex.interstitial
+
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.mediation.MediationInterstitialAdCallback
+import com.yandex.mobile.ads.common.AdError
+import com.yandex.mobile.ads.common.ImpressionData
+import com.yandex.mobile.ads.interstitial.InterstitialAdEventListener
+
+internal class MediationInterstitialAdEventListener(
+ private val interstitialAdCallback: MediationInterstitialAdCallback,
+ private val errorConverter: AdMobAdErrorCreator
+) : InterstitialAdEventListener {
+
+ override fun onAdClicked() {
+ interstitialAdCallback.reportAdClicked()
+ }
+
+ override fun onAdImpression(impressionData: ImpressionData?) {
+ interstitialAdCallback.reportAdImpression()
+ }
+
+ override fun onAdDismissed() {
+ interstitialAdCallback.onAdClosed()
+ }
+
+ override fun onAdShown() {
+ interstitialAdCallback.onAdOpened()
+ }
+
+ override fun onAdFailedToShow(adError: AdError) {
+ interstitialAdCallback.onAdFailedToShow(errorConverter.convertToAdMobError(adError))
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdFactory.kt
new file mode 100644
index 000000000..17381dac4
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/interstitial/MediationInterstitialAdFactory.kt
@@ -0,0 +1,17 @@
+package com.google.ads.mediation.yandex.interstitial
+
+import android.app.Activity
+import com.google.android.gms.ads.mediation.MediationInterstitialAd
+import com.yandex.mobile.ads.interstitial.InterstitialAd
+
+internal class MediationInterstitialAdFactory {
+
+ fun create(
+ loadedAd: InterstitialAd,
+ onContextIsNotActivity: () -> Unit
+ ) = MediationInterstitialAd { context ->
+ if (context is Activity) {
+ loadedAd.show(context)
+ } else onContextIsNotActivity()
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/UriGenerator.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/UriGenerator.kt
new file mode 100644
index 000000000..cb8d584c0
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/UriGenerator.kt
@@ -0,0 +1,14 @@
+package com.google.ads.mediation.yandex.nativeads
+
+import android.net.Uri
+
+internal class UriGenerator {
+
+ fun createImageUri(any: Any): Uri? {
+ return Uri.parse(IMAGE_URI_PREFIX + any.hashCode())
+ }
+
+ companion object {
+ private const val IMAGE_URI_PREFIX = "admob.image.url."
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdAsset.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdAsset.kt
new file mode 100644
index 000000000..0f0aeb96c
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdAsset.kt
@@ -0,0 +1,12 @@
+package com.google.ads.mediation.yandex.nativeads
+
+object YandexNativeAdAsset {
+ const val AGE = "age"
+ const val DOMAIN = "domain"
+ const val FAVICON = "favicon"
+ const val FEEDBACK = "feedback"
+ const val RATING = "rating"
+ const val REVIEW_COUNT = "review_count"
+ const val SPONSORED = "sponsored"
+ const val WARNING = "warning"
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdEventListener.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdEventListener.kt
new file mode 100644
index 000000000..887919f42
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdEventListener.kt
@@ -0,0 +1,27 @@
+package com.google.ads.mediation.yandex.nativeads
+
+import com.google.android.gms.ads.mediation.MediationNativeAdCallback
+import com.yandex.mobile.ads.common.ImpressionData
+import com.yandex.mobile.ads.nativeads.NativeAdEventListener
+
+internal class YandexNativeAdEventListener(
+ private val adMobListener: MediationNativeAdCallback
+) : NativeAdEventListener {
+
+ override fun onReturnedToApplication() {
+ adMobListener.onAdClosed()
+ }
+
+ override fun onAdClicked() {
+ adMobListener.reportAdClicked()
+ }
+
+ override fun onLeftApplication() {
+ adMobListener.onAdOpened()
+ adMobListener.onAdLeftApplication()
+ }
+
+ override fun onImpression(impressionData: ImpressionData?) {
+ adMobListener.reportAdImpression()
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImage.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImage.kt
new file mode 100644
index 000000000..b3fe0722a
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImage.kt
@@ -0,0 +1,17 @@
+package com.google.ads.mediation.yandex.nativeads
+
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import com.google.android.gms.ads.formats.NativeAd
+
+internal class YandexNativeAdImage(
+ private val drawable: Drawable,
+ private val uri: Uri
+) : NativeAd.Image() {
+
+ override fun getDrawable(): Drawable = drawable
+
+ override fun getUri(): Uri = uri
+
+ override fun getScale(): Double = 1.0
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImageFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImageFactory.kt
new file mode 100644
index 000000000..b394e71a9
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdImageFactory.kt
@@ -0,0 +1,29 @@
+package com.google.ads.mediation.yandex.nativeads
+
+import android.content.Context
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import com.yandex.mobile.ads.nativeads.NativeAdImage
+
+internal class YandexNativeAdImageFactory {
+
+ private val uriGenerator: UriGenerator = UriGenerator()
+
+ fun createYandexNativeAdImage(
+ context: Context,
+ imageData: NativeAdImage?
+ ): YandexNativeAdImage? {
+ var nativeAdImage: YandexNativeAdImage? = null
+
+ if (imageData != null) {
+ val resources = context.resources
+ val bitmap = imageData.bitmap
+ val imageDrawable: Drawable = BitmapDrawable(resources, bitmap)
+ uriGenerator.createImageUri(imageData)?.let {
+ nativeAdImage = YandexNativeAdImage(imageDrawable, it)
+ }
+ }
+
+ return nativeAdImage
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdLoadListener.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdLoadListener.kt
new file mode 100644
index 000000000..fffba7ac6
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/YandexNativeAdLoadListener.kt
@@ -0,0 +1,57 @@
+package com.google.ads.mediation.yandex.nativeads
+
+import android.content.Context
+import android.os.Bundle
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.AdRequest
+import com.google.android.gms.ads.mediation.MediationAdLoadCallback
+import com.google.android.gms.ads.mediation.MediationNativeAdCallback
+import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper
+import com.yandex.mobile.ads.common.AdRequestError
+import com.yandex.mobile.ads.nativeads.NativeAd
+import com.yandex.mobile.ads.nativeads.NativeAdLoadListener
+import com.yandex.mobile.ads.nativeads.YandexNativeAdMappersFactory
+import java.lang.ref.WeakReference
+
+internal class YandexNativeAdLoadListener @JvmOverloads constructor(
+ context: Context,
+ private val callback: MediationAdLoadCallback,
+ private val extras: Bundle?,
+ private val adMappersFactory: YandexNativeAdMappersFactory = YandexNativeAdMappersFactory(),
+ private val adMobAdErrorCreator: AdMobAdErrorCreator = AdMobAdErrorCreator()
+) : NativeAdLoadListener {
+
+ private val contextReference: WeakReference = WeakReference(context)
+
+ private var admobNativeListener: MediationNativeAdCallback? = null
+
+ private var nativeAd: NativeAd? = null
+
+ override fun onAdFailedToLoad(error: AdRequestError) {
+ val adError = adMobAdErrorCreator.createLoadAdError(error)
+ callback.onFailure(adError)
+ }
+
+ override fun onAdLoaded(nativeAd: NativeAd) {
+ finishWithAdMapper(nativeAd)
+ }
+
+ private fun finishWithAdMapper(nativeAd: NativeAd) {
+ val context = contextReference.get()
+ if (context != null) {
+ val nativeAdMapper = adMappersFactory.createAdMapper(context, nativeAd, extras)
+ admobNativeListener = callback.onSuccess(nativeAdMapper)
+ configureNativeAd(nativeAd)
+ } else {
+ val adError = adMobAdErrorCreator.createLoadAdError(AdRequest.ERROR_CODE_INTERNAL_ERROR)
+ callback.onFailure(adError)
+ }
+ }
+
+ private fun configureNativeAd(nativeAd: NativeAd) {
+ admobNativeListener?.let {
+ nativeAd.setNativeAdEventListener(YandexNativeAdEventListener(it))
+ }
+ this.nativeAd = nativeAd
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/ViewUtils.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/ViewUtils.kt
new file mode 100644
index 000000000..8045a4cbc
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/ViewUtils.kt
@@ -0,0 +1,18 @@
+package com.google.ads.mediation.yandex.nativeads.view
+
+import android.view.View
+
+internal object ViewUtils {
+
+ @JvmStatic
+ fun castView(
+ view: View?,
+ expectedViewClass: Class
+ ): T? {
+ return if (expectedViewClass.isInstance(view)) {
+ expectedViewClass.cast(view)
+ } else {
+ null
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexAdAssetViewsProviderCreator.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexAdAssetViewsProviderCreator.kt
new file mode 100644
index 000000000..e66f9e195
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexAdAssetViewsProviderCreator.kt
@@ -0,0 +1,58 @@
+package com.google.ads.mediation.yandex.nativeads.view
+
+import android.os.Bundle
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import com.google.ads.mediation.yandex.nativeads.YandexNativeAdAsset
+import com.google.ads.mediation.yandex.nativeads.view.ViewUtils.castView
+import com.google.android.gms.ads.nativead.NativeAdView
+
+internal class YandexAdAssetViewsProviderCreator(
+ extras: Bundle,
+ private val viewsFinder: YandexNativeAdViewsFinder = YandexNativeAdViewsFinder(extras),
+ private val providerBuilder: YandexNativeAssetViewsProvider.Builder =
+ YandexNativeAssetViewsProvider.Builder()
+) {
+
+ fun createProvider(nativeAdView: NativeAdView): YandexNativeAssetViewsProvider {
+ val bodyView = castView(nativeAdView.bodyView, TextView::class.java)
+ val callToActionView = castView(nativeAdView.callToActionView, TextView::class.java)
+ val domainView = castView(nativeAdView.storeView, TextView::class.java)
+ val iconView = castView(nativeAdView.iconView, ImageView::class.java)
+ val imageView = castView(nativeAdView.imageView, ImageView::class.java)
+ val priceView = castView(nativeAdView.priceView, TextView::class.java)
+ val sponsoredView = castView(nativeAdView.advertiserView, TextView::class.java)
+ val titleView = castView(nativeAdView.headlineView, TextView::class.java)
+ var builder = createBuilderWithYandexSupportedViews(nativeAdView)
+
+ builder = builder.withBodyView(bodyView)
+ .withCallToActionView(callToActionView)
+ .withDomainView(domainView)
+ .withIconView(iconView)
+ .withImageView(imageView)
+ .withPriceView(priceView)
+ .withSponsoredView(sponsoredView)
+ .withTitleView(titleView)
+
+ return builder.build()
+ }
+
+ private fun createBuilderWithYandexSupportedViews(
+ nativeAdView: View
+ ): YandexNativeAssetViewsProvider.Builder {
+ val ageView = viewsFinder.findViewByExtraKey(nativeAdView, YandexNativeAdAsset.AGE)
+ val faviconView = viewsFinder.findViewByExtraKey(nativeAdView, YandexNativeAdAsset.FAVICON)
+ val feedbackView = viewsFinder.findViewByExtraKey(nativeAdView, YandexNativeAdAsset.FEEDBACK)
+ val reviewCountView = viewsFinder.findViewByExtraKey(nativeAdView, YandexNativeAdAsset.REVIEW_COUNT)
+ val warningView = viewsFinder.findViewByExtraKey(nativeAdView, YandexNativeAdAsset.WARNING)
+
+ return providerBuilder
+ .withAgeView(castView(ageView, TextView::class.java))
+ .withFaviconView(castView(faviconView, ImageView::class.java))
+ .withFeedbackView(castView(feedbackView, ImageView::class.java))
+ .withRatingView(viewsFinder.findRatingView(nativeAdView))
+ .withReviewCountView(castView(reviewCountView, TextView::class.java))
+ .withWarningView(castView(warningView, TextView::class.java))
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAdViewsFinder.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAdViewsFinder.kt
new file mode 100644
index 000000000..10ae50cff
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAdViewsFinder.kt
@@ -0,0 +1,30 @@
+package com.google.ads.mediation.yandex.nativeads.view
+
+import android.os.Bundle
+import android.view.View
+import com.google.ads.mediation.yandex.nativeads.YandexNativeAdAsset
+import com.yandex.mobile.ads.nativeads.Rating
+
+internal class YandexNativeAdViewsFinder(private val extras: Bundle) {
+
+ fun findViewByExtraKey(
+ nativeAdView: View,
+ extraKey: String
+ ): View? {
+ return if (extras.containsKey(extraKey)) {
+ nativeAdView.findViewById(extras.getInt(extraKey))
+ } else {
+ null
+ }
+ }
+
+ fun findRatingView(nativeAdView: View): T? where T : View?, T : Rating? {
+ try {
+ val view = findViewByExtraKey(nativeAdView, YandexNativeAdAsset.RATING)
+ return view as? Rating as? T
+ } catch (ignored: Exception) {
+ }
+
+ return null
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAssetViewsProvider.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAssetViewsProvider.kt
new file mode 100644
index 000000000..55305941a
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/nativeads/view/YandexNativeAssetViewsProvider.kt
@@ -0,0 +1,160 @@
+package com.google.ads.mediation.yandex.nativeads.view
+
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import com.yandex.mobile.ads.nativeads.Rating
+
+internal class YandexNativeAssetViewsProvider private constructor(builder: Builder) {
+
+ val ageView: TextView? = builder.ageView
+
+ val bodyView: TextView? = builder.bodyView
+
+ val callToActionView: TextView? = builder.callToActionView
+
+ val domainView: TextView? = builder.domainView
+
+ val faviconView: ImageView? = builder.faviconView
+
+ val feedbackView: ImageView? = builder.feedbackView
+
+ val imageView: ImageView? = builder.imageView
+
+ val iconView: ImageView? = builder.iconView
+
+ val priceView: TextView? = builder.priceView
+
+ private val ratingView: View? = builder.ratingView
+
+ val reviewCountView: TextView? = builder.reviewCountView
+
+ val sponsoredView: TextView? = builder.sponsoredView
+
+ val titleView: TextView? = builder.titleView
+
+ val warningView: TextView? = builder.warningView
+
+ fun getRatingView(): T? where T : View?, T : Rating? {
+ return ratingView as T?
+ }
+
+ class Builder {
+
+ var ageView: TextView? = null
+ private set
+
+ var bodyView: TextView? = null
+ private set
+
+ var callToActionView: TextView? = null
+ private set
+
+ var domainView: TextView? = null
+ private set
+
+ var faviconView: ImageView? = null
+ private set
+
+ var feedbackView: ImageView? = null
+ private set
+
+ var imageView: ImageView? = null
+ private set
+
+ var iconView: ImageView? = null
+ private set
+
+ var priceView: TextView? = null
+ private set
+
+ var ratingView: View? = null
+ private set
+
+ var reviewCountView: TextView? = null
+ private set
+
+ var sponsoredView: TextView? = null
+ private set
+
+ var titleView: TextView? = null
+ private set
+
+ var warningView: TextView? = null
+ private set
+
+ fun build(): YandexNativeAssetViewsProvider {
+ return YandexNativeAssetViewsProvider(this)
+ }
+
+ fun withAgeView(ageView: TextView?): Builder {
+ this.ageView = ageView
+ return this
+ }
+
+ fun withBodyView(bodyView: TextView?): Builder {
+ this.bodyView = bodyView
+ return this
+ }
+
+ fun withCallToActionView(callToActionView: TextView?): Builder {
+ this.callToActionView = callToActionView
+ return this
+ }
+
+ fun withDomainView(domainView: TextView?): Builder {
+ this.domainView = domainView
+ return this
+ }
+
+ fun withFaviconView(faviconView: ImageView?): Builder {
+ this.faviconView = faviconView
+ return this
+ }
+
+ fun withFeedbackView(feedbackView: ImageView?): Builder {
+ this.feedbackView = feedbackView
+ return this
+ }
+
+ fun withIconView(iconView: ImageView?): Builder {
+ this.iconView = iconView
+ return this
+ }
+
+ fun withImageView(imageView: ImageView?): Builder {
+ this.imageView = imageView
+ return this
+ }
+
+ fun withPriceView(priceView: TextView?): Builder {
+ this.priceView = priceView
+ return this
+ }
+
+ fun withRatingView(ratingView: T?): Builder where T : View?, T : Rating? {
+ this.ratingView = ratingView
+ return this
+ }
+
+ fun withReviewCountView(reviewCountView: TextView?): Builder {
+ this.reviewCountView = reviewCountView
+ return this
+ }
+
+ fun withSponsoredView(sponsoredView: TextView?): Builder {
+ this.sponsoredView = sponsoredView
+ return this
+ }
+
+ fun withTitleView(titleView: TextView?): Builder {
+ this.titleView = titleView
+ return this
+ }
+
+ fun withWarningView(warningView: TextView?): Builder {
+ this.warningView = warningView
+ return this
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/AdMobReward.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/AdMobReward.kt
new file mode 100644
index 000000000..b19d9c534
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/AdMobReward.kt
@@ -0,0 +1,15 @@
+package com.google.ads.mediation.yandex.rewarded
+
+import com.google.android.gms.ads.rewarded.RewardItem
+import com.yandex.mobile.ads.rewarded.Reward
+
+internal class AdMobReward(private val reward: Reward) : RewardItem {
+
+ override fun getType(): String {
+ return reward.type
+ }
+
+ override fun getAmount(): Int {
+ return reward.amount
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdEventListener.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdEventListener.kt
new file mode 100644
index 000000000..1177f6613
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdEventListener.kt
@@ -0,0 +1,42 @@
+package com.google.ads.mediation.yandex.rewarded
+
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.mediation.MediationRewardedAdCallback
+import com.yandex.mobile.ads.common.AdError
+import com.yandex.mobile.ads.common.ImpressionData
+import com.yandex.mobile.ads.rewarded.Reward
+import com.yandex.mobile.ads.rewarded.RewardedAdEventListener
+
+internal class MediationRewardedAdEventListener(
+ private val rewardedAdCallback: MediationRewardedAdCallback,
+ private val errorConverter: AdMobAdErrorCreator
+) : RewardedAdEventListener {
+
+ override fun onAdClicked() {
+ rewardedAdCallback.reportAdClicked()
+ }
+
+ override fun onAdFailedToShow(adError: AdError) {
+ rewardedAdCallback.onAdFailedToShow(errorConverter.convertToAdMobError(adError))
+ }
+
+ override fun onAdImpression(impressionData: ImpressionData?) {
+ rewardedAdCallback.reportAdImpression()
+ }
+
+ override fun onAdDismissed() {
+ rewardedAdCallback.onAdClosed()
+ }
+
+ override fun onAdShown() {
+ rewardedAdCallback.apply {
+ onAdOpened()
+ onVideoStart()
+ }
+ }
+
+ override fun onRewarded(reward: Reward) {
+ val rewardItem = AdMobReward(reward)
+ rewardedAdCallback.onUserEarnedReward(rewardItem)
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdFactory.kt
new file mode 100644
index 000000000..dd2044d42
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/MediationRewardedAdFactory.kt
@@ -0,0 +1,17 @@
+package com.google.ads.mediation.yandex.rewarded
+
+import android.app.Activity
+import com.google.android.gms.ads.mediation.MediationRewardedAd
+import com.yandex.mobile.ads.rewarded.RewardedAd
+
+internal class MediationRewardedAdFactory {
+
+ fun create(
+ loadedAd: RewardedAd,
+ onContextIsNotActivity: () -> Unit
+ ) = MediationRewardedAd { context ->
+ if (context is Activity) {
+ loadedAd.show(context)
+ } else onContextIsNotActivity()
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedAdLoadListenerFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedAdLoadListenerFactory.kt
new file mode 100644
index 000000000..c8e4a4c2d
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedAdLoadListenerFactory.kt
@@ -0,0 +1,44 @@
+package com.google.ads.mediation.yandex.rewarded
+
+import com.google.ads.mediation.yandex.base.AdMobAdErrorCreator
+import com.google.android.gms.ads.mediation.MediationAdLoadCallback
+import com.google.android.gms.ads.mediation.MediationRewardedAd
+import com.google.android.gms.ads.mediation.MediationRewardedAdCallback
+import com.yandex.mobile.ads.common.AdRequestError
+import com.yandex.mobile.ads.rewarded.RewardedAd
+import com.yandex.mobile.ads.rewarded.RewardedAdLoadListener
+
+internal class RewardedAdLoadListenerFactory {
+
+ fun create(
+ callback: MediationAdLoadCallback,
+ adMobAdErrorCreator: AdMobAdErrorCreator,
+ mediationRewardedAdFactory: MediationRewardedAdFactory = MediationRewardedAdFactory()
+ ) = object : RewardedAdLoadListener {
+
+ var rewardedAdCallback: MediationRewardedAdCallback? = null
+
+ override fun onAdLoaded(loadedAd: RewardedAd) {
+ val mediationRewardedAd = mediationRewardedAdFactory.create(
+ loadedAd, ::onContextIsNotActivityError
+ )
+ rewardedAdCallback = callback.onSuccess(mediationRewardedAd).also { rewardedAdCallback ->
+ val mediationRewardedAdEventListener = MediationRewardedAdEventListener(
+ rewardedAdCallback,
+ adMobAdErrorCreator
+ )
+ loadedAd.setAdEventListener(mediationRewardedAdEventListener)
+ }
+ }
+
+ override fun onAdFailedToLoad(error: AdRequestError) {
+ val adError = adMobAdErrorCreator.createLoadAdError(error)
+ callback.onFailure(adError)
+ }
+
+ private fun onContextIsNotActivityError() {
+ val error = adMobAdErrorCreator.createRequiresActivityError()
+ rewardedAdCallback?.onAdFailedToShow(error)
+ }
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedLoaderFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedLoaderFactory.kt
new file mode 100644
index 000000000..2a2211e93
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/google/ads/mediation/yandex/rewarded/RewardedLoaderFactory.kt
@@ -0,0 +1,8 @@
+package com.google.ads.mediation.yandex.rewarded
+
+import android.content.Context
+import com.yandex.mobile.ads.rewarded.RewardedAdLoader
+
+internal class RewardedLoaderFactory {
+ fun create(context: Context) = RewardedAdLoader(context)
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/MediaViewFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/MediaViewFactory.kt
new file mode 100644
index 000000000..1843cf596
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/MediaViewFactory.kt
@@ -0,0 +1,7 @@
+package com.yandex.mobile.ads.nativeads
+
+import android.content.Context
+
+internal class MediaViewFactory {
+ fun create(context: Context) = MediaView(context)
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/NativeAdViewBinderBuilderFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/NativeAdViewBinderBuilderFactory.kt
new file mode 100644
index 000000000..242c58e0d
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/NativeAdViewBinderBuilderFactory.kt
@@ -0,0 +1,7 @@
+package com.yandex.mobile.ads.nativeads
+
+import android.view.View
+
+internal class NativeAdViewBinderBuilderFactory {
+ fun create(view: View) = NativeAdViewBinder.Builder(view)
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapper.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapper.kt
new file mode 100644
index 000000000..1eeee4936
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapper.kt
@@ -0,0 +1,66 @@
+package com.yandex.mobile.ads.nativeads
+
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import com.google.ads.mediation.yandex.nativeads.view.YandexAdAssetViewsProviderCreator
+import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper
+import com.google.android.gms.ads.nativead.NativeAdView
+
+internal class YandexNativeAdMapper(
+ private val nativeAd: NativeAd,
+ extras: Bundle,
+ private val nativeAdViewBinderBuilderFactory: NativeAdViewBinderBuilderFactory = NativeAdViewBinderBuilderFactory(),
+ private val assetViewsProviderCreator: YandexAdAssetViewsProviderCreator = YandexAdAssetViewsProviderCreator(extras)
+) : UnifiedNativeAdMapper() {
+
+ private var mediaView: MediaView? = null
+
+ override fun trackViews(
+ view: View,
+ clickableAssetViews: Map,
+ nonclickableAssetViews: Map
+ ) {
+ super.trackViews(view, clickableAssetViews, nonclickableAssetViews)
+
+ if (view is NativeAdView) {
+ try {
+ val provider = assetViewsProviderCreator.createProvider(view)
+
+ val binder = nativeAdViewBinderBuilderFactory.create(view)
+ .setAgeView(provider.ageView)
+ .setBodyView(provider.bodyView)
+ .setCallToActionView(provider.callToActionView)
+ .setDomainView(provider.domainView)
+ .setFaviconView(provider.faviconView)
+ .setFeedbackView(provider.feedbackView)
+ .setIconView(provider.iconView)
+ .setMediaView(mediaView)
+ .setPriceView(provider.priceView)
+ .setRatingView(provider.getRatingView())
+ .setReviewCountView(provider.reviewCountView)
+ .setSponsoredView(provider.sponsoredView)
+ .setTitleView(provider.titleView)
+ .setWarningView(provider.warningView)
+ .build()
+
+ nativeAd.bindNativeAd(binder)
+ } catch (e: Exception) {
+ Log.w(TAG, "Error while binding native ad. $e")
+ }
+ } else {
+ Log.w(TAG, "Invalid view type")
+ }
+ }
+
+ override fun setMediaView(view: View) {
+ super.setMediaView(view)
+ if (view is MediaView) {
+ mediaView = view
+ }
+ }
+
+ companion object {
+ private const val TAG = "Yandex AdMob Adapter"
+ }
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapperFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapperFactory.kt
new file mode 100644
index 000000000..54ad39770
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMapperFactory.kt
@@ -0,0 +1,7 @@
+package com.yandex.mobile.ads.nativeads
+
+import android.os.Bundle
+
+internal class YandexNativeAdMapperFactory {
+ fun create(nativeAd: NativeAd, extras: Bundle) = YandexNativeAdMapper(nativeAd, extras)
+}
diff --git a/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMappersFactory.kt b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMappersFactory.kt
new file mode 100644
index 000000000..2d9193264
--- /dev/null
+++ b/ThirdPartyAdapters/yandex/yandex/src/main/java/com/yandex/mobile/ads/nativeads/YandexNativeAdMappersFactory.kt
@@ -0,0 +1,113 @@
+package com.yandex.mobile.ads.nativeads
+
+import android.content.Context
+import android.os.Bundle
+import com.google.ads.mediation.yandex.nativeads.YandexNativeAdAsset
+import com.google.ads.mediation.yandex.nativeads.YandexNativeAdImageFactory
+import com.google.android.gms.ads.formats.NativeAd.Image
+
+internal class YandexNativeAdMappersFactory(
+ private val adMapperFactory: YandexNativeAdMapperFactory = YandexNativeAdMapperFactory(),
+ private val nativeAdImageFactory: YandexNativeAdImageFactory = YandexNativeAdImageFactory(),
+ private val mediaViewFactory: MediaViewFactory = MediaViewFactory()
+) {
+
+ fun createAdMapper(
+ context: Context,
+ nativeAd: NativeAd,
+ extras: Bundle?
+ ): YandexNativeAdMapper {
+ val networkExtras = extras ?: Bundle()
+ val mapper = adMapperFactory.create(nativeAd, networkExtras)
+
+ mapper.overrideClickHandling = OVERRIDE_CLICK_TRACKING
+ mapper.overrideImpressionRecording = OVERRIDE_IMPRESSION_RECORDING
+
+ val assets = nativeAd.adAssets
+
+ assets.sponsored?.let {
+ mapper.advertiser = it
+ }
+
+ assets.body?.let {
+ mapper.body = it
+ }
+
+ assets.callToAction?.let {
+ mapper.callToAction = it
+ }
+
+ assets.title?.let {
+ mapper.headline = it
+ }
+
+ assets.price?.let {
+ mapper.price = it
+ }
+
+ assets.domain?.let {
+ mapper.store = it
+ }
+
+ nativeAdImageFactory.createYandexNativeAdImage(context, assets.icon)?.let {
+ mapper.icon = it
+ }
+
+ mapper.images = createNativeAdImages(context, assets.image)
+
+ assets.rating?.let {
+ mapper.starRating = it.toDouble()
+ }
+
+ val media = assets.media
+ val hasMediaContent = media != null
+
+ mapper.setHasVideoContent(hasMediaContent)
+
+ if (hasMediaContent) {
+ media?.let {
+ mapper.mediaContentAspectRatio = media.aspectRatio
+ }
+ }
+
+ val mediaView = mediaViewFactory.create(context)
+ mapper.setMediaView(mediaView)
+
+ val assetExtras = createAssetExtras(assets)
+ mapper.extras = assetExtras
+
+ return mapper
+ }
+
+ private fun createAssetExtras(assets: NativeAdAssets): Bundle {
+ val assetExtras = Bundle()
+
+ with(assetExtras) {
+ putString(YandexNativeAdAsset.AGE, assets.age)
+ putString(YandexNativeAdAsset.DOMAIN, assets.domain)
+ putString(YandexNativeAdAsset.REVIEW_COUNT, assets.reviewCount)
+ putString(YandexNativeAdAsset.SPONSORED, assets.sponsored)
+ putString(YandexNativeAdAsset.WARNING, assets.warning)
+ }
+
+ return assetExtras
+ }
+
+ private fun createNativeAdImages(
+ context: Context,
+ nativeAdImage: NativeAdImage?
+ ): List {
+ val images: MutableList = ArrayList()
+
+ if (nativeAdImage != null) {
+ images.add(nativeAdImageFactory.createYandexNativeAdImage(context, nativeAdImage))
+ }
+
+ return images
+ }
+
+ companion object {
+ private const val OVERRIDE_CLICK_TRACKING = true
+ private const val OVERRIDE_IMPRESSION_RECORDING = true
+ }
+}