From 5652b693f22c50c0484cdb1f0ea3b80ebf4a816f Mon Sep 17 00:00:00 2001 From: Mobile Ads Developer Relations Date: Wed, 27 May 2026 11:02:31 -0700 Subject: [PATCH] Maps `AgeRestrictedTreatment` to InMobi's COPPA API. PiperOrigin-RevId: 922233292 --- ThirdPartyAdapters/inmobi/CHANGELOG.md | 3 ++ ThirdPartyAdapters/inmobi/build.gradle | 2 +- ThirdPartyAdapters/inmobi/inmobi/build.gradle | 8 +-- .../mediation/inmobi/InMobiAdapterUtils.java | 4 +- .../mediation/inmobi/InMobiExtrasBuilder.java | 6 ++- .../inmobi/InMobiAdapterUtilsTest.kt | 37 +++++++++++++- .../inmobi/InMobiExtrasBuilderTest.kt | 49 +++++++++++++++++-- 7 files changed, 95 insertions(+), 14 deletions(-) diff --git a/ThirdPartyAdapters/inmobi/CHANGELOG.md b/ThirdPartyAdapters/inmobi/CHANGELOG.md index 37a9caeda..838df555a 100644 --- a/ThirdPartyAdapters/inmobi/CHANGELOG.md +++ b/ThirdPartyAdapters/inmobi/CHANGELOG.md @@ -1,5 +1,8 @@ ## InMobi Android Mediation Adapter Changelog +#### Next Version +- Maps `AgeRestrictedTreatment` to InMobi's COPPA API. + #### Version 11.3.0.0 - Verified compatibility with InMobi Kotlin SDK version 11.3.0. diff --git a/ThirdPartyAdapters/inmobi/build.gradle b/ThirdPartyAdapters/inmobi/build.gradle index 9f3c231fe..a8e6f7d7a 100644 --- a/ThirdPartyAdapters/inmobi/build.gradle +++ b/ThirdPartyAdapters/inmobi/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlinVersion = '2.1.10' + kotlinVersion = '2.3.0' } repositories { google() diff --git a/ThirdPartyAdapters/inmobi/inmobi/build.gradle b/ThirdPartyAdapters/inmobi/inmobi/build.gradle index 9a8d50f16..e956e6c6a 100644 --- a/ThirdPartyAdapters/inmobi/inmobi/build.gradle +++ b/ThirdPartyAdapters/inmobi/inmobi/build.gradle @@ -120,9 +120,9 @@ dependencies { // Mobile Ads SDK // Check for a 'useNextGenGma' flag to use the next generation GMA SDK. if (project.hasProperty('useNextGenGma')) { - implementation 'com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.0.1' + implementation 'com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.1.0' } else { - implementation 'com.google.android.gms:play-services-ads:25.2.0' + implementation 'com.google.android.gms:play-services-ads:25.3.0' } // inMobi SDK @@ -133,14 +133,14 @@ dependencies { // Unit tests testImplementation 'junit:junit:4.13.2' - testImplementation 'org.jetbrains.kotlin:kotlin-stdlib:2.1.10' + testImplementation 'org.jetbrains.kotlin:kotlin-stdlib:2.3.0' testImplementation 'com.google.truth:truth:1.1.5' testImplementation 'androidx.test:core:1.6.1' testImplementation 'org.mockito:mockito-core:5.5.0' testImplementation 'org.robolectric:robolectric:4.9' testImplementation 'androidx.test.ext:junit:1.2.1' testImplementation 'org.mockito.kotlin:mockito-kotlin:5.1.0' - testImplementation 'org.jetbrains.kotlin:kotlin-test:2.1.10' + testImplementation 'org.jetbrains.kotlin:kotlin-test:2.3.0' } /** diff --git a/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiAdapterUtils.java b/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiAdapterUtils.java index 16cd0ca97..ad257f905 100644 --- a/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiAdapterUtils.java +++ b/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiAdapterUtils.java @@ -26,6 +26,7 @@ import androidx.annotation.VisibleForTesting; import com.google.android.gms.ads.AdError; import com.google.android.gms.ads.AdSize; +import com.google.android.gms.ads.AgeRestrictedTreatment; import com.google.android.gms.ads.MobileAds; import com.google.android.gms.ads.RequestConfiguration; import com.inmobi.ads.InMobiAdRequestStatus; @@ -145,7 +146,8 @@ static void setIsAgeRestricted(InMobiSdkWrapper inMobiSdkWrapper) { if (requestConfiguration.getTagForChildDirectedTreatment() == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE || requestConfiguration.getTagForUnderAgeOfConsent() - == RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_TRUE) { + == RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_TRUE + || requestConfiguration.getAgeRestrictedTreatment() == AgeRestrictedTreatment.CHILD) { inMobiSdkWrapper.setIsAgeRestricted(true); } else if (requestConfiguration.getTagForChildDirectedTreatment() == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE diff --git a/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiExtrasBuilder.java b/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiExtrasBuilder.java index 497924a57..d91b36f02 100644 --- a/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiExtrasBuilder.java +++ b/ThirdPartyAdapters/inmobi/inmobi/src/main/java/com/google/ads/mediation/inmobi/InMobiExtrasBuilder.java @@ -5,10 +5,10 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.google.android.gms.ads.AgeRestrictedTreatment; import com.google.android.gms.ads.MobileAds; import com.google.android.gms.ads.RequestConfiguration; import com.inmobi.compliance.InMobiPrivacyCompliance; - import java.util.HashMap; public class InMobiExtrasBuilder { @@ -45,7 +45,9 @@ public static InMobiExtras build(@NonNull Context context, @Nullable Bundle medi // If the COPPA value isn't specified by the publisher, InMobi SDK expects the default value to // be `0`. if (MobileAds.getRequestConfiguration().getTagForChildDirectedTreatment() - == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE) { + == RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE + || MobileAds.getRequestConfiguration().getAgeRestrictedTreatment() + == AgeRestrictedTreatment.CHILD) { map.put(COPPA, "1"); } else { map.put(COPPA, "0"); diff --git a/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiAdapterUtilsTest.kt b/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiAdapterUtilsTest.kt index 34667ed04..050af1bb7 100644 --- a/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiAdapterUtilsTest.kt +++ b/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiAdapterUtilsTest.kt @@ -2,6 +2,7 @@ package com.google.ads.mediation.inmobi import android.os.Bundle import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.android.gms.ads.AgeRestrictedTreatment import com.google.android.gms.ads.MobileAds import com.google.android.gms.ads.RequestConfiguration import com.google.common.truth.Truth.assertThat @@ -113,6 +114,35 @@ class InMobiAdapterUtilsTest { setCOPPAAndUnderAgeOnMobileAdsRequestConfiguration( RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED, RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED, + AgeRestrictedTreatment.UNSPECIFIED, + ) + + InMobiAdapterUtils.setIsAgeRestricted(inMobiSdkWrapper) + + verify(inMobiSdkWrapper, never()).setIsAgeRestricted(any()) + } + + @Test + fun setIsAgeRestricted_whenAgeRestrictedTreatmentChild_setsAgeRestrictedTrueOnInMobiSDK() { + val inMobiSdkWrapper = mock() + setCOPPAAndUnderAgeOnMobileAdsRequestConfiguration( + RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED, + RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED, + AgeRestrictedTreatment.CHILD, + ) + + InMobiAdapterUtils.setIsAgeRestricted(inMobiSdkWrapper) + + verify(inMobiSdkWrapper).setIsAgeRestricted(true) + } + + @Test + fun setIsAgeRestricted_whenAgeRestrictedTreatmentTeen_setIsAgeRestrictedIsNeverInvoked() { + val inMobiSdkWrapper = mock() + setCOPPAAndUnderAgeOnMobileAdsRequestConfiguration( + RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED, + RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED, + AgeRestrictedTreatment.TEEN, ) InMobiAdapterUtils.setIsAgeRestricted(inMobiSdkWrapper) @@ -270,12 +300,17 @@ class InMobiAdapterUtilsTest { assertThat(adError).isNull() } - private fun setCOPPAAndUnderAgeOnMobileAdsRequestConfiguration(coppa: Int, underAgeConsent: Int) { + private fun setCOPPAAndUnderAgeOnMobileAdsRequestConfiguration( + coppa: Int, + underAgeConsent: Int, + ageRestrictedTreatment: AgeRestrictedTreatment = AgeRestrictedTreatment.UNSPECIFIED, + ) { val requestConfiguration = MobileAds.getRequestConfiguration() .toBuilder() .setTagForChildDirectedTreatment(coppa) .setTagForUnderAgeOfConsent(underAgeConsent) + .setAgeRestrictedTreatment(ageRestrictedTreatment) .build() MobileAds.setRequestConfiguration(requestConfiguration) } diff --git a/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiExtrasBuilderTest.kt b/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiExtrasBuilderTest.kt index d62ce1edf..db01108ef 100644 --- a/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiExtrasBuilderTest.kt +++ b/ThirdPartyAdapters/inmobi/inmobi/src/test/kotlin/com/google/ads/mediation/inmobi/InMobiExtrasBuilderTest.kt @@ -3,6 +3,7 @@ package com.google.ads.mediation.inmobi import android.content.Context import android.os.Bundle import androidx.test.core.app.ApplicationProvider +import com.google.android.gms.ads.AgeRestrictedTreatment import com.google.android.gms.ads.MobileAds import com.google.android.gms.ads.RequestConfiguration import com.google.common.truth.Truth.assertThat @@ -13,7 +14,7 @@ import org.robolectric.ParameterizedRobolectricTestRunner @RunWith(ParameterizedRobolectricTestRunner::class) class InMobiExtrasBuilderTest( private val mediationExtras: Map?, - private val protocol: String + private val protocol: String, ) { private val context = ApplicationProvider.getApplicationContext() @@ -56,6 +57,44 @@ class InMobiExtrasBuilderTest( assertThat(inMobiExtras.parameterMap[InMobiAdapterUtils.COPPA]).isEqualTo("1") } + @Test + fun buildInMobiExtras_whenAgeRestrictedTreatmentChild_returnsInMobiExtrasWithCoppaTrue() { + val requestConfiguration = + MobileAds.getRequestConfiguration() + .toBuilder() + .setTagForChildDirectedTreatment( + RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED + ) + .setAgeRestrictedTreatment(AgeRestrictedTreatment.CHILD) + .build() + MobileAds.setRequestConfiguration(requestConfiguration) + + val inMobiExtras = InMobiExtrasBuilder.build(context, mapToBundle(mediationExtras), protocol) + + assertThat(inMobiExtras).isNotNull() + assertThat(inMobiExtras.parameterMap).isNotEmpty() + assertThat(inMobiExtras.parameterMap[InMobiAdapterUtils.COPPA]).isEqualTo("1") + } + + @Test + fun buildInMobiExtras_whenAgeRestrictedTreatmentTeen_returnsInMobiExtrasWithCoppaFalse() { + val requestConfiguration = + MobileAds.getRequestConfiguration() + .toBuilder() + .setTagForChildDirectedTreatment( + RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED + ) + .setAgeRestrictedTreatment(AgeRestrictedTreatment.TEEN) + .build() + MobileAds.setRequestConfiguration(requestConfiguration) + + val inMobiExtras = InMobiExtrasBuilder.build(context, mapToBundle(mediationExtras), protocol) + + assertThat(inMobiExtras).isNotNull() + assertThat(inMobiExtras.parameterMap).isNotEmpty() + assertThat(inMobiExtras.parameterMap[InMobiAdapterUtils.COPPA]).isEqualTo("0") + } + @Test fun buildInMobiExtras_whenCoppaNotSet_returnsInMobiExtrasWithCoppaFalse() { // when coppa value is not specified... @@ -118,7 +157,7 @@ class InMobiExtrasBuilderTest( private fun verifyInMobiExtrasParameterMap( mediationExtras: Map?, - inMobiExtras: InMobiExtras + inMobiExtras: InMobiExtras, ) { if (!mediationExtras.isNullOrEmpty()) { assertThat(inMobiExtras.parameterMap).containsAtLeastEntriesIn(mediationExtras) @@ -132,14 +171,14 @@ class InMobiExtrasBuilderTest( listOf( arrayOf( mapOf(InMobiNetworkKeys.AGE to "25", InMobiNetworkKeys.AREA_CODE to "12345"), - InMobiAdapterUtils.PROTOCOL_RTB + InMobiAdapterUtils.PROTOCOL_RTB, ), arrayOf( mapOf(InMobiNetworkKeys.CITY to "MTV", InMobiNetworkKeys.LANGUAGE to "Japanese"), - InMobiAdapterUtils.PROTOCOL_WATERFALL + InMobiAdapterUtils.PROTOCOL_WATERFALL, ), arrayOf(null, InMobiAdapterUtils.PROTOCOL_WATERFALL), - arrayOf(null, InMobiAdapterUtils.PROTOCOL_RTB) + arrayOf(null, InMobiAdapterUtils.PROTOCOL_RTB), ) } }