Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ThirdPartyAdapters/pangle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Pangle Android Mediation Adapter Changelog

#### Next Version
- Filter age-restricted requests for Pangle SDK when new `AgeRestrictedTreatment` is set to `CHILD`.

#### Version 8.0.0.5.0
- Verified compatibility with Pangle SDK version 8.0.0.5.

Expand Down
2 changes: 1 addition & 1 deletion ThirdPartyAdapters/pangle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

buildscript {
ext {
kotlinVersion = '2.1.10'
kotlinVersion = '2.3.0'
}
repositories {
google()
Expand Down
Empty file modified ThirdPartyAdapters/pangle/gradlew
100644 → 100755
Empty file.
6 changes: 3 additions & 3 deletions ThirdPartyAdapters/pangle/pangle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ dependencies {
implementation 'androidx.annotation:annotation:1.5.0'
// 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'
}

testImplementation 'androidx.core:core-ktx:1.8.0'
Expand All @@ -135,7 +135,7 @@ dependencies {
testImplementation "com.google.truth:truth:1.2.0"
testImplementation 'junit:junit:4.13.2'
testImplementation 'com.google.testparameterinjector:test-parameter-injector:1.18'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib:2.1.10'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib:2.3.0'
testImplementation 'org.mockito.kotlin:mockito-kotlin:5.1.0'
testImplementation 'org.robolectric:robolectric:4.14'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AgeRestrictedTreatment;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.RequestConfiguration;
import java.lang.annotation.Retention;
Expand Down Expand Up @@ -94,7 +95,8 @@ public static boolean isChildUser() {
return 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;
}

/** A private constructor since this is a utility class which should not be instantiated. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import com.google.ads.mediation.pangle.utils.mockPangleSdkInitializationSuccess
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdFormat
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.google.android.gms.ads.mediation.InitializationCompleteCallback
import com.google.android.gms.ads.mediation.MediationAdLoadCallback
import com.google.android.gms.ads.mediation.MediationAppOpenAd
Expand Down Expand Up @@ -104,6 +107,16 @@ class PangleMediationAdapterTest {
// Resetting the PA Consent Information to their default value.
PangleMediationAdapter.setPAConsent(PAGPAConsentType.PAG_PA_CONSENT_TYPE_CONSENT)

val requestConfiguration =
RequestConfiguration.Builder()
.setTagForChildDirectedTreatment(
RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED
)
.setTagForUnderAgeOfConsent(RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED)
.setAgeRestrictedTreatment(AgeRestrictedTreatment.UNSPECIFIED)
.build()
MobileAds.setRequestConfiguration(requestConfiguration)

pangleMediationAdapter =
PangleMediationAdapter(pangleInitializer, pangleSdkWrapper, pangleFactory)
}
Expand Down Expand Up @@ -161,6 +174,32 @@ class PangleMediationAdapterTest {
assertThat(error.domain).isEqualTo(PANGLE_SDK_ERROR_DOMAIN)
}

@Test
fun collectSignals_withAgeRestrictedTreatmentChild_callsOnFailure() {
val requestConfiguration =
RequestConfiguration.Builder()
.setTagForChildDirectedTreatment(
RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED
)
.setTagForUnderAgeOfConsent(RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED)
.setAgeRestrictedTreatment(AgeRestrictedTreatment.CHILD)
.build()
MobileAds.setRequestConfiguration(requestConfiguration)
val signalCallbacks: SignalCallbacks = mock()

pangleMediationAdapter.collectSignals(
RtbSignalData(context, emptyList(), bundleOf(), AdSize(1, 1)),
signalCallbacks,
)

val errorCaptor = argumentCaptor<AdError>()
verify(signalCallbacks).onFailure(errorCaptor.capture())
val error = errorCaptor.firstValue
assertThat(error.code).isEqualTo(PangleConstants.ERROR_CHILD_USER)
assertThat(error.domain).isEqualTo(PangleConstants.ERROR_DOMAIN)
assertThat(error.message).isEqualTo(PangleConstants.ERROR_MSG_CHILD_USER)
}

@Test
fun initialize_ifAppIdsAreMissing_callsFailureCallback() {
// Create server parameters without app ID.
Expand Down Expand Up @@ -220,6 +259,28 @@ class PangleMediationAdapterTest {
verify(initializationCompleteCallback).onInitializationFailed(PANGLE_INIT_FAILURE_MESSAGE)
}

@Test
fun initialize_withAgeRestrictedTreatmentChild_callsFailureCallback() {
val requestConfiguration =
RequestConfiguration.Builder()
.setTagForChildDirectedTreatment(
RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED
)
.setTagForUnderAgeOfConsent(RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED)
.setAgeRestrictedTreatment(AgeRestrictedTreatment.CHILD)
.build()
MobileAds.setRequestConfiguration(requestConfiguration)

pangleMediationAdapter.initialize(
context,
initializationCompleteCallback,
listOf(buildProperMediationConfig()),
)

verify(initializationCompleteCallback)
.onInitializationFailed(PangleConstants.ERROR_MSG_CHILD_USER)
}

@Test
fun getVersionInfo_ifAdapterVersionHasLessThanFourParts_returnsZeros() {
// "3.1.4" is invalid because adapter version should contain at least four parts delimited by
Expand Down Expand Up @@ -285,6 +346,28 @@ class PangleMediationAdapterTest {
verify(bannerAd).render(bannerAdConfig)
}

@Test
fun loadBannerAd_withAgeRestrictedTreatmentChild_callsOnFailure() {
val requestConfiguration =
RequestConfiguration.Builder()
.setTagForChildDirectedTreatment(
RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED
)
.setTagForUnderAgeOfConsent(RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED)
.setAgeRestrictedTreatment(AgeRestrictedTreatment.CHILD)
.build()
MobileAds.setRequestConfiguration(requestConfiguration)

pangleMediationAdapter.loadBannerAd(bannerAdConfig, bannerAdLoadCallback)

val errorCaptor = argumentCaptor<AdError>()
verify(bannerAdLoadCallback).onFailure(errorCaptor.capture())
val error = errorCaptor.firstValue
assertThat(error.code).isEqualTo(PangleConstants.ERROR_CHILD_USER)
assertThat(error.domain).isEqualTo(PangleConstants.ERROR_DOMAIN)
assertThat(error.message).isEqualTo(PangleConstants.ERROR_MSG_CHILD_USER)
}

@Test
fun loadInterstitialAd_rendersInterstitialAd() {
pangleMediationAdapter.loadInterstitialAd(interstitialAdConfig, interstitialAdLoadCallback)
Expand Down
Loading