From 76b99a6e575b175b4e9e62a304521c62fa334da8 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 1 Jul 2026 09:09:38 -0500 Subject: [PATCH 1/3] Fix Java-generic name-clash in AdLoadCallback subclasses (issue #1491) The base `AdLoadCallback` in play-services-ads-lite declares `onAdLoaded(AdT)` which erases to `onAdLoaded(Object)` in bytecode. The binding generator therefore exposes only `virtual OnAdLoaded(Java.Lang.Object)` on every concrete subclass (`AdManagerInterstitialAdLoadCallback`, `InterstitialAdLoadCallback`, `RewardedAdLoadCallback`, `RewardedInterstitialAdLoadCallback`, `AppOpenAd.AppOpenAdLoadCallback`). When a user override that in C#, the generated Java ACW stub emits `public void onAdLoaded(java.lang.Object p0)`, which javac rejects with error: name clash: onAdLoaded(Object) in MyCallback and onAdLoaded(AdManagerInterstitialAd) in AdLoadCallback have the same erasure, yet neither overrides the other because after generic substitution the parent's method is the specialized one. Add a specialized `onAdLoaded(SpecificAd)` method on each concrete subclass via so the binding exposes a properly-typed `virtual OnAdLoaded(SpecificAd)` with a specialized JNI registration. Users can now override the specialized overload, and the resulting ACW stub emits the specialized Java signature that correctly overrides the parent -- matching how Google's docs show the callback being subclassed in Java. Fixes #1491. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../PublicAPI/PublicAPI.Unshipped.txt | 5 ++ .../Transforms/Metadata.xml | 56 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/source/com.google.android.gms/play-services-ads-lite/PublicAPI/PublicAPI.Unshipped.txt b/source/com.google.android.gms/play-services-ads-lite/PublicAPI/PublicAPI.Unshipped.txt index 7fff905de..c2fcbf797 100644 --- a/source/com.google.android.gms/play-services-ads-lite/PublicAPI/PublicAPI.Unshipped.txt +++ b/source/com.google.android.gms/play-services-ads-lite/PublicAPI/PublicAPI.Unshipped.txt @@ -1336,6 +1336,7 @@ virtual Android.Gms.Ads.AdLoader.IsLoading.get -> bool virtual Android.Gms.Ads.AdLoader.LoadAd(Android.Gms.Ads.AdManager.AdManagerAdRequest! adManagerAdRequest) -> void virtual Android.Gms.Ads.AdLoader.LoadAd(Android.Gms.Ads.AdRequest! adRequest) -> void virtual Android.Gms.Ads.AdLoader.LoadAds(Android.Gms.Ads.AdRequest! adRequest, int maxNumberOfAds) -> void +virtual Android.Gms.Ads.AdManager.AdManagerInterstitialAdLoadCallback.OnAdLoaded(Android.Gms.Ads.AdManager.AdManagerInterstitialAd! p0) -> void virtual Android.Gms.Ads.AdRequest.AdString.get -> string? virtual Android.Gms.Ads.AdRequest.Builder.Build() -> Android.Gms.Ads.AdRequest! virtual Android.Gms.Ads.AdRequest.ContentUrl.get -> string! @@ -1346,6 +1347,7 @@ virtual Android.Gms.Ads.AdRequest.IsTestDevice(Android.Content.Context! context) virtual Android.Gms.Ads.AdRequest.Keywords.get -> System.Collections.Generic.ICollection! virtual Android.Gms.Ads.AdRequest.NeighboringContentUrls.get -> System.Collections.Generic.IList! virtual Android.Gms.Ads.AdRequest.RequestAgent.get -> string! +virtual Android.Gms.Ads.AppOpen.AppOpenAd.AppOpenAdLoadCallback.OnAdLoaded(Android.Gms.Ads.AppOpen.AppOpenAd! p0) -> void virtual Android.Gms.Ads.BaseAdView.AdListener.get -> Android.Gms.Ads.AdListener! virtual Android.Gms.Ads.BaseAdView.AdListener.set -> void virtual Android.Gms.Ads.BaseAdView.AdSize.get -> Android.Gms.Ads.AdSize? @@ -1369,6 +1371,7 @@ virtual Android.Gms.Ads.FullScreenContentCallback.OnAdDismissedFullScreenContent virtual Android.Gms.Ads.FullScreenContentCallback.OnAdFailedToShowFullScreenContent(Android.Gms.Ads.AdError! p0) -> void virtual Android.Gms.Ads.FullScreenContentCallback.OnAdImpression() -> void virtual Android.Gms.Ads.FullScreenContentCallback.OnAdShowedFullScreenContent() -> void +virtual Android.Gms.Ads.Interstitial.InterstitialAdLoadCallback.OnAdLoaded(Android.Gms.Ads.Interstitial.InterstitialAd! p0) -> void virtual Android.Gms.Ads.Mediation.Adapter.LoadAppOpenAd(Android.Gms.Ads.Mediation.MediationAppOpenAdConfiguration! p0, Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void virtual Android.Gms.Ads.Mediation.Adapter.LoadBannerAd(Android.Gms.Ads.Mediation.MediationBannerAdConfiguration! p0, Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void virtual Android.Gms.Ads.Mediation.Adapter.LoadInterstitialAd(Android.Gms.Ads.Mediation.MediationInterstitialAdConfiguration! p0, Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void @@ -1454,8 +1457,10 @@ virtual Android.Gms.Ads.RequestConfiguration.TagForChildDirectedTreatment.get -> virtual Android.Gms.Ads.RequestConfiguration.TagForUnderAgeOfConsent.get -> int virtual Android.Gms.Ads.RequestConfiguration.TestDeviceIds.get -> System.Collections.Generic.IList! virtual Android.Gms.Ads.RequestConfiguration.ToBuilder() -> Android.Gms.Ads.RequestConfiguration.Builder! +virtual Android.Gms.Ads.Rewarded.RewardedAdLoadCallback.OnAdLoaded(Android.Gms.Ads.Rewarded.RewardedAd! p0) -> void virtual Android.Gms.Ads.Rewarded.ServerSideVerificationOptions.CustomData.get -> string! virtual Android.Gms.Ads.Rewarded.ServerSideVerificationOptions.UserId.get -> string! +virtual Android.Gms.Ads.RewardedInterstitial.RewardedInterstitialAdLoadCallback.OnAdLoaded(Android.Gms.Ads.RewardedInterstitial.RewardedInterstitialAd! p0) -> void virtual Android.Gms.Ads.VersionInfo.MajorVersion.get -> int virtual Android.Gms.Ads.VersionInfo.MicroVersion.get -> int virtual Android.Gms.Ads.VersionInfo.MinorVersion.get -> int diff --git a/source/com.google.android.gms/play-services-ads-lite/Transforms/Metadata.xml b/source/com.google.android.gms/play-services-ads-lite/Transforms/Metadata.xml index 03887c9b4..605bd6895 100644 --- a/source/com.google.android.gms/play-services-ads-lite/Transforms/Metadata.xml +++ b/source/com.google.android.gms/play-services-ads-lite/Transforms/Metadata.xml @@ -127,6 +127,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Wed, 1 Jul 2026 10:03:00 -0500 Subject: [PATCH 2/3] Bump Xamarin.GooglePlayServices.Ads.Lite to 124.0.0.7 Ship the AdLoadCallback binding fix from the previous commit (fixes #1491) as a new NuGet revision. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 0d4e5d0c4..5a2b538c2 100644 --- a/config.json +++ b/config.json @@ -2764,7 +2764,7 @@ "groupId": "com.google.android.gms", "artifactId": "play-services-ads-lite", "version": "24.0.0", - "nugetVersion": "124.0.0.6", + "nugetVersion": "124.0.0.7", "nugetId": "Xamarin.GooglePlayServices.Ads.Lite", "frozen": true, "extraDependencies": "androidx.lifecycle.lifecycle-livedata-core,androidx.lifecycle.lifecycle-runtime", From 66c0f361231f77ef865538b87a57b6824f7aa1cf Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 1 Jul 2026 10:31:19 -0500 Subject: [PATCH 3/3] Extend AdLoadCallback fix to play-services-ads-api (issue #1491) The customer's project uses the Google.Android.Gms.Ads.* namespace, which comes from Xamarin.GooglePlayServices.Ads.Api (transitively via Xamarin.GooglePlayServices.Ads), not Xamarin.GooglePlayServices.Ads.Lite. Apply the same metadata fix to the -api binding so that the five concrete AdLoadCallback subclasses expose a specialized OnAdLoaded(SpecificAd) overload, avoiding the javac name-clash on ACW generation when users override the callback. Also bump Xamarin.GooglePlayServices.Ads and Xamarin.GooglePlayServices.Ads.Api by 0.0.0.1 so consumers pick up the fix. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- config.json | 4 +- .../PublicAPI/PublicAPI.Unshipped.txt | 16 +++++ .../Transforms/Metadata.xml | 59 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 5a2b538c2..01f12f455 100644 --- a/config.json +++ b/config.json @@ -2730,7 +2730,7 @@ "groupId": "com.google.android.gms", "artifactId": "play-services-ads", "version": "25.4.0", - "nugetVersion": "125.4.0.1", + "nugetVersion": "125.4.0.2", "nugetId": "Xamarin.GooglePlayServices.Ads", "allowPrereleaseDependencies": true, "extraDependencies": "androidx.lifecycle.lifecycle-livedata-core,androidx.lifecycle.lifecycle-runtime", @@ -2740,7 +2740,7 @@ "groupId": "com.google.android.gms", "artifactId": "play-services-ads-api", "version": "25.4.0", - "nugetVersion": "125.4.0.1", + "nugetVersion": "125.4.0.2", "nugetId": "Xamarin.GooglePlayServices.Ads.Api", "type": "xbd" }, diff --git a/source/com.google.android.gms/play-services-ads-api/PublicAPI/PublicAPI.Unshipped.txt b/source/com.google.android.gms/play-services-ads-api/PublicAPI/PublicAPI.Unshipped.txt index 492baca9f..09976a055 100644 --- a/source/com.google.android.gms/play-services-ads-api/PublicAPI/PublicAPI.Unshipped.txt +++ b/source/com.google.android.gms/play-services-ads-api/PublicAPI/PublicAPI.Unshipped.txt @@ -227,6 +227,17 @@ Google.Android.Gms.Ads.Initialization.IOnInitializationCompleteListener.OnInitia Google.Android.Gms.Ads.Initialization.InitializationCompleteEventArgs Google.Android.Gms.Ads.Initialization.InitializationCompleteEventArgs.InitializationCompleteEventArgs(Google.Android.Gms.Ads.Initialization.IInitializationStatus! p0) -> void Google.Android.Gms.Ads.Initialization.InitializationCompleteEventArgs.P0.get -> Google.Android.Gms.Ads.Initialization.IInitializationStatus! +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpDeepLinkServiceWrapper +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpDeepLinkServiceWrapper.EndSession(Android.Gms.Dynamic.IObjectWrapper! p0, string! p1) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpDeepLinkServiceWrapper.Open(Android.Gms.Dynamic.IObjectWrapper! p0, string! p1, string! p2, Android.OS.Bundle! p3, bool p4, Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpServiceCallback! p5) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpDeepLinkServiceWrapper.Prewarm(Android.Gms.Dynamic.IObjectWrapper! p0, System.Collections.Generic.IList! p1, Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpPrewarmServiceCallback! p2) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpPrewarmServiceCallback +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpPrewarmServiceCallback.OnError(Android.OS.Bundle! p0) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpPrewarmServiceCallback.OnPrewarmCompleted(Android.OS.Bundle! p0) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpServiceCallback +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpServiceCallback.OnDismissed(Android.OS.Bundle! p0) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpServiceCallback.OnError(Android.OS.Bundle! p0) -> void +Google.Android.Gms.Ads.Internal.Client.Hsdp.IHsdpServiceCallback.OnShown(Android.OS.Bundle! p0) -> void Google.Android.Gms.Ads.Internal.Offline.Buffering.OfflineNotificationPoster Google.Android.Gms.Ads.Internal.Offline.Buffering.OfflineNotificationPoster.OfflineNotificationPoster(Android.Content.Context! context, AndroidX.Work.WorkerParameters! params) -> void Google.Android.Gms.Ads.Internal.Offline.Buffering.OfflineNotificationPoster.OfflineNotificationPoster(nint javaReference, Android.Runtime.JniHandleOwnership transfer) -> void @@ -1375,6 +1386,7 @@ virtual Google.Android.Gms.Ads.AdLoader.IsLoading.get -> bool virtual Google.Android.Gms.Ads.AdLoader.LoadAd(Google.Android.Gms.Ads.AdManager.AdManagerAdRequest! adManagerAdRequest) -> void virtual Google.Android.Gms.Ads.AdLoader.LoadAd(Google.Android.Gms.Ads.AdRequest! adRequest) -> void virtual Google.Android.Gms.Ads.AdLoader.LoadAds(Google.Android.Gms.Ads.AdRequest! adRequest, int maxNumberOfAds) -> void +virtual Google.Android.Gms.Ads.AdManager.AdManagerInterstitialAdLoadCallback.OnAdLoaded(Google.Android.Gms.Ads.AdManager.AdManagerInterstitialAd! p0) -> void virtual Google.Android.Gms.Ads.AdRequest.AdString.get -> string? virtual Google.Android.Gms.Ads.AdRequest.Builder.Build() -> Google.Android.Gms.Ads.AdRequest! virtual Google.Android.Gms.Ads.AdRequest.Builder.Self() -> Google.Android.Gms.Ads.AdRequest.Builder! @@ -1387,6 +1399,7 @@ virtual Google.Android.Gms.Ads.AdRequest.Keywords.get -> System.Collections.Gene virtual Google.Android.Gms.Ads.AdRequest.NeighboringContentUrls.get -> System.Collections.Generic.IList! virtual Google.Android.Gms.Ads.AdRequest.PlacementId.get -> long virtual Google.Android.Gms.Ads.AdRequest.RequestAgent.get -> string! +virtual Google.Android.Gms.Ads.AppOpen.AppOpenAd.AppOpenAdLoadCallback.OnAdLoaded(Google.Android.Gms.Ads.AppOpen.AppOpenAd! p0) -> void virtual Google.Android.Gms.Ads.BaseAdView.AdListener.get -> Google.Android.Gms.Ads.AdListener! virtual Google.Android.Gms.Ads.BaseAdView.AdListener.set -> void virtual Google.Android.Gms.Ads.BaseAdView.AdSize.get -> Google.Android.Gms.Ads.AdSize? @@ -1412,6 +1425,7 @@ virtual Google.Android.Gms.Ads.FullScreenContentCallback.OnAdDismissedFullScreen virtual Google.Android.Gms.Ads.FullScreenContentCallback.OnAdFailedToShowFullScreenContent(Google.Android.Gms.Ads.AdError! p0) -> void virtual Google.Android.Gms.Ads.FullScreenContentCallback.OnAdImpression() -> void virtual Google.Android.Gms.Ads.FullScreenContentCallback.OnAdShowedFullScreenContent() -> void +virtual Google.Android.Gms.Ads.Interstitial.InterstitialAdLoadCallback.OnAdLoaded(Google.Android.Gms.Ads.Interstitial.InterstitialAd! p0) -> void virtual Google.Android.Gms.Ads.Mediation.Adapter.LoadAppOpenAd(Google.Android.Gms.Ads.Mediation.MediationAppOpenAdConfiguration! p0, Google.Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void virtual Google.Android.Gms.Ads.Mediation.Adapter.LoadBannerAd(Google.Android.Gms.Ads.Mediation.MediationBannerAdConfiguration! p0, Google.Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void virtual Google.Android.Gms.Ads.Mediation.Adapter.LoadInterstitialAd(Google.Android.Gms.Ads.Mediation.MediationInterstitialAdConfiguration! p0, Google.Android.Gms.Ads.Mediation.IMediationAdLoadCallback! callback) -> void @@ -1503,8 +1517,10 @@ virtual Google.Android.Gms.Ads.RequestConfiguration.TagForChildDirectedTreatment virtual Google.Android.Gms.Ads.RequestConfiguration.TagForUnderAgeOfConsent.get -> int virtual Google.Android.Gms.Ads.RequestConfiguration.TestDeviceIds.get -> System.Collections.Generic.IList! virtual Google.Android.Gms.Ads.RequestConfiguration.ToBuilder() -> Google.Android.Gms.Ads.RequestConfiguration.Builder! +virtual Google.Android.Gms.Ads.Rewarded.RewardedAdLoadCallback.OnAdLoaded(Google.Android.Gms.Ads.Rewarded.RewardedAd! p0) -> void virtual Google.Android.Gms.Ads.Rewarded.ServerSideVerificationOptions.CustomData.get -> string! virtual Google.Android.Gms.Ads.Rewarded.ServerSideVerificationOptions.UserId.get -> string! +virtual Google.Android.Gms.Ads.RewardedInterstitial.RewardedInterstitialAdLoadCallback.OnAdLoaded(Google.Android.Gms.Ads.RewardedInterstitial.RewardedInterstitialAd! p0) -> void virtual Google.Android.Gms.Ads.VersionInfo.MajorVersion.get -> int virtual Google.Android.Gms.Ads.VersionInfo.MicroVersion.get -> int virtual Google.Android.Gms.Ads.VersionInfo.MinorVersion.get -> int diff --git a/source/com.google.android.gms/play-services-ads-api/Transforms/Metadata.xml b/source/com.google.android.gms/play-services-ads-api/Transforms/Metadata.xml index 0da4a77ab..ee98a5e35 100644 --- a/source/com.google.android.gms/play-services-ads-api/Transforms/Metadata.xml +++ b/source/com.google.android.gms/play-services-ads-api/Transforms/Metadata.xml @@ -125,4 +125,63 @@ OnAdFailedToLoadWithErrorCode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +