Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
bc3cd9b
fix crash for legacy AdLoader fallback for old mobile Ads sdk apps (#…
jonathanklee Jun 8, 2026
96afe59
AdMob: Add ChimeraCreator Impl (#3536)
DaVinci9196 Jun 8, 2026
4c4247e
Introduce new play-services-ads-api package
mar-v-in Jun 8, 2026
fc737ad
Ads: Fix some API details
mar-v-in Jun 8, 2026
212de1e
Phenotype: NotebookLM displays the "Video Overview" feature. (#3419)
DaVinci9196 Jun 8, 2026
50562bc
FACS: Show Google Contacts toggle in Maps settings (#3429)
DaVinci9196 Jun 8, 2026
0b94e87
Phenotype: Enable Gemini temporary chat and more menus (#3447)
DaVinci9196 Jun 8, 2026
daed3a6
ProviderInstaller: Update defaultTlsProtocol (#3467)
DaVinci9196 Jun 8, 2026
3a5d4ab
Fix: GoogleIdTokenCredential ClassCastException (#3452)
DaVinci9196 Jun 8, 2026
3382510
Maps: Fixed unable to enable Privacy Mode. (#3490)
DaVinci9196 Jun 8, 2026
fd71e36
Vending: Add deep link handler (#3415)
DaVinci9196 Jun 8, 2026
0b62625
Fido: Log CTAP status code with description (#3472)
p1gp1g Jun 8, 2026
730b917
Fixed an issue where tapping the location sharing settings redirected…
DaVinci9196 Jun 8, 2026
c4967b0
fix: return SUCCESS with empty result when no BlockStore data exists …
jonathanklee Jun 8, 2026
b98a8a4
Reject isBillingSupported requests with apiVersion above 28 (#3440)
DaVinci9196 Jun 8, 2026
877b438
Allow activity controls via web view (#3365)
DaVinci9196 Jun 8, 2026
ad3c413
Google package: Add YTCreate signature information (#3373)
DaVinci9196 Jun 8, 2026
147a188
Phenotype: Display NotebookLM in Gemini AttachmentMenuConfig (#3386)
DaVinci9196 Jun 8, 2026
6f711bb
Phenotype: Displays the Practice feature. (#3381)
DaVinci9196 Jun 8, 2026
046c00b
Phenotype: Fixed the issue of no Gemini entry point in Google Message…
DaVinci9196 Jun 8, 2026
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
46 changes: 46 additions & 0 deletions play-services-ads-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'signing'

android {
namespace "com.google.android.gms.ads"

compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"

buildFeatures {
aidl = true
}

defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

apply from: '../gradle/publish-android.gradle'

description = 'microG implementation of play-services-ads-api'

dependencies {
// Dependencies from play-services-ads-api:25.3.0
api 'androidx.browser:browser:1.8.0'
api 'androidx.core:core:1.10.1'
api 'androidx.datastore:datastore:1.0.0'
api 'androidx.work:work-runtime:2.7.0'
//api 'com.google.android.ump:user-messaging-platform:4.0.0'
api project(':play-services-basement')
//api project(':play-services-measurement-sdk-api')
annotationProcessor project(':safe-parcel-processor')
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

dependencies {
api project(':play-services-ads-lite')
api project(':play-services-ads-api')
implementation project(':play-services-base-core')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.os.IBinder
import android.os.Parcel
import android.util.Log
import androidx.annotation.Keep
import com.google.android.gms.ads.internal.client.IAdLoaderBuilder
import com.google.android.gms.ads.internal.client.IAdLoaderBuilderCreator
import com.google.android.gms.ads.internal.mediation.client.IAdapterCreator
import com.google.android.gms.dynamic.IObjectWrapper
Expand All @@ -16,10 +17,10 @@ import org.microg.gms.utils.warnOnTransactionIssues
private const val TAG = "AdLoaderBuilder"

@Keep
class AdLoaderBuilderCreatorImpl : IAdLoaderBuilderCreator.Stub() {
override fun newAdLoaderBuilder(context: IObjectWrapper?, adUnitId: String, adapterCreator: IAdapterCreator?, clientVersion: Int): IBinder? {
open class AdLoaderBuilderCreatorImpl : IAdLoaderBuilderCreator.Stub() {
override fun newAdLoaderBuilder(context: IObjectWrapper?, adUnitId: String, adapterCreator: IAdapterCreator?, clientVersion: Int): IAdLoaderBuilder? {
Log.d(TAG, "newAdLoaderBuilder: adUnitId=$adUnitId clientVersion=$clientVersion")
return null
return LegacyAdLoaderBuilder()
}

override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import android.content.Context
import android.os.IBinder
import android.os.Parcel
import android.util.Log
import androidx.annotation.Keep
import com.google.android.gms.ads.internal.client.AdSizeParcel
import com.google.android.gms.ads.internal.client.IAdManager
import com.google.android.gms.ads.internal.client.IAdManagerCreator
import com.google.android.gms.ads.internal.mediation.client.IAdapterCreator
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper
import org.microg.gms.utils.warnOnTransactionIssues

private const val TAG = "AdManagerCreator"

@Keep
open class AdManagerCreatorImpl : IAdManagerCreator.Stub() {
override fun newAdManager(context: IObjectWrapper?, adSize: AdSizeParcel?, adUnitId: String?, adapterCreator: IAdapterCreator?, clientVersion: Int): IAdManager {
Log.d(TAG, "newAdManager: adUnitId=$adUnitId clientVersion=$clientVersion")
return LegacyAdManager(ObjectWrapper.unwrap(context) as? Context)
}

override fun newAdManagerByType(context: IObjectWrapper?, adSize: AdSizeParcel?, adUnitId: String?, adapterCreator: IAdapterCreator?, clientVersion: Int, type: Int): IAdManager {
Log.d(TAG, "newAdManagerByType: adUnitId=$adUnitId clientVersion=$clientVersion type=$type")
return LegacyAdManager(ObjectWrapper.unwrap(context) as? Context)
}

override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import androidx.annotation.Keep

/**
* Dynamite entry point for the native-ad (AdLoader) path.
*
* The AdMob SDK loads this class from the ads dynamite module by its fully-qualified name, so it must
* exist under this exact FQCN and implement `IAdLoaderBuilderCreator`. Behaviour is identical to
* [AdLoaderBuilderCreatorImpl], which is kept under its own name for SDKs that request the un-prefixed
* class.
*/
@Keep
class ChimeraAdLoaderBuilderCreatorImpl : AdLoaderBuilderCreatorImpl()
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import androidx.annotation.Keep

/**
* Dynamite entry point for the banner/interstitial (AdManager) path.
*
* The AdMob SDK loads this class from the ads dynamite module by its fully-qualified name, so it must
* exist under this exact FQCN and implement `IAdManagerCreator`. Behaviour is identical to
* [AdManagerCreatorImpl], which is kept under its own name for SDKs that request the un-prefixed class.
*/
@Keep
class ChimeraAdManagerCreatorImpl : AdManagerCreatorImpl()
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import androidx.annotation.Keep

/**
* Dynamite entry point for the Mobile Ads initialization / settings path.
*
* The AdMob SDK loads this class from the ads dynamite module by its fully-qualified name, so it must
* exist under this exact FQCN and implement `IMobileAdsSettingManagerCreator`. This is the entry point
* that gates ad initialization. Behaviour is identical to [MobileAdsSettingManagerCreatorImpl], which is
* kept under its own name for SDKs that request the un-prefixed class.
*/
@Keep
class ChimeraMobileAdsSettingManagerCreatorImpl : MobileAdsSettingManagerCreatorImpl()
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import android.util.Log
import com.google.android.gms.ads.formats.AdManagerAdViewOptions
import com.google.android.gms.ads.formats.PublisherAdViewOptions
import com.google.android.gms.ads.internal.AdRequestParcel
import com.google.android.gms.ads.internal.client.AdSizeParcel
import com.google.android.gms.ads.internal.client.IAdListener
import com.google.android.gms.ads.internal.client.IAdLoader
import com.google.android.gms.ads.internal.client.IAdLoaderBuilder
import com.google.android.gms.ads.internal.client.ICorrelationIdProvider
import com.google.android.gms.ads.internal.formats.NativeAdOptionsParcel
import com.google.android.gms.ads.internal.formats.client.IOnAppInstallAdLoadedListener
import com.google.android.gms.ads.internal.formats.client.IOnContentAdLoadedListener
import com.google.android.gms.ads.internal.formats.client.IOnCustomClickListener
import com.google.android.gms.ads.internal.formats.client.IOnCustomTemplateAdLoadedListener
import com.google.android.gms.ads.internal.formats.client.IOnPublisherAdViewLoadedListener
import com.google.android.gms.ads.internal.formats.client.IOnUnifiedNativeAdLoadedListener
import com.google.android.gms.ads.internal.instream.InstreamAdConfigurationParcel
import com.google.android.gms.ads.internal.instream.client.IInstreamAdLoadCallback

private const val TAG = "LegacyAdLoader"

internal class LegacyAdLoaderBuilder : IAdLoaderBuilder.Stub() {
override fun build(): IAdLoader = LegacyAdLoader
override fun withAdListener(listener: IAdListener?) = Unit
override fun withAppInstallAdLoadedListener(listener: IOnAppInstallAdLoadedListener?) = Unit
override fun withContentAdLoadedListener(listener: IOnContentAdLoadedListener?) = Unit
override fun forCustomFormatAd(templateId: String?, onCustomFormatAdLoadedListener: IOnCustomTemplateAdLoadedListener?, onCustomClickListener: IOnCustomClickListener?) = Unit
override fun withNativeAdOptions(options: NativeAdOptionsParcel?) = Unit
override fun withCorrelationIdProvider(provider: ICorrelationIdProvider?) = Unit
override fun forAdView(onPublisherAdViewLoadedListener: IOnPublisherAdViewLoadedListener?, adSize: AdSizeParcel?) = Unit
override fun withPublisherAdViewOptions(options: PublisherAdViewOptions?) = Unit
override fun forNativeAd(listener: IOnUnifiedNativeAdLoadedListener?) = Unit
override fun forInstreamAd(config: InstreamAdConfigurationParcel?) = Unit
override fun setInstreamAdLoadCallback(callback: IInstreamAdLoadCallback?) = Unit
override fun withAdManagerAdViewOptions(options: AdManagerAdViewOptions?) = Unit
}

private object LegacyAdLoader : IAdLoader.Stub() {
override fun load(request: AdRequestParcel?) {
Log.w(TAG, "load")
}
override fun getMediationAdapterClassName(): String? = null
override fun isLoading(): Boolean = false
override fun getAdManagerAdapterClassName(): String? = null
override fun loadAds(request: AdRequestParcel?, count: Int) {
Log.w(TAG, "loadAds")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.ads

import android.content.Context
import android.util.Log
import android.widget.FrameLayout
import com.google.android.gms.ads.internal.AdRequestParcel
import com.google.android.gms.ads.internal.client.AdSizeParcel
import com.google.android.gms.ads.internal.client.IAdClickListener
import com.google.android.gms.ads.internal.client.IAdListener
import com.google.android.gms.ads.internal.client.IAdLoadCallback
import com.google.android.gms.ads.internal.client.IAdManager
import com.google.android.gms.ads.internal.client.IAppEventListener
import com.google.android.gms.ads.internal.client.IFullScreenContentCallback
import com.google.android.gms.ads.internal.client.IOnPaidEventListener
import com.google.android.gms.ads.internal.client.IVideoController
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper

private const val TAG = "LegacyAdManager"

/**
* Minimal [IAdManager] returned by [AdManagerCreatorImpl] for the banner/interstitial path.
*
* It is a non-null ad manager so the AdMob SDK keeps using microG's remote result. No ad is served:
* [getView] returns an empty container, [loadAd] reports "no fill", and the listeners/getters are
* accepted but inert.
*/
internal class LegacyAdManager(private val context: Context?) : IAdManager.Stub() {
private val adView: FrameLayout? by lazy { context?.let { FrameLayout(it) } }

override fun getView(): IObjectWrapper = ObjectWrapper.wrap(adView)
override fun destroy() = Unit
override fun loadAd(request: AdRequestParcel?): Boolean {
Log.w(TAG, "loadAd")
return false
}
override fun pause() = Unit
override fun resume() = Unit
override fun setAdListener(listener: IAdListener?) = Unit
override fun setAppEventListener(listener: IAppEventListener?) = Unit
override fun getAdSize(): AdSizeParcel? = null
override fun setAdSize(adSize: AdSizeParcel?) = Unit
override fun setAdClickListener(listener: IAdClickListener?) = Unit
override fun setManualImpressionFlag(flag: Int) = Unit
override fun getVideoController(): IVideoController? = null
override fun setManualImpressionsEnabled(enabled: Boolean) = Unit
override fun setOnPaidEventListener(listener: IOnPaidEventListener?) = Unit
override fun loadAdWithCallback(request: AdRequestParcel?, callback: IAdLoadCallback?) = Unit
override fun showInterstitial(activityWrapper: IObjectWrapper?) = Unit
override fun setFullScreenContentCallback(callback: IFullScreenContentCallback?) = Unit
override fun setStartTimestampMillis(timestampMillis: Long) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.os.IBinder
import android.os.Parcel
import android.util.Log
import androidx.annotation.Keep
import com.google.android.gms.ads.internal.client.IMobileAdsSettingManager
import com.google.android.gms.ads.internal.client.IMobileAdsSettingManagerCreator
import com.google.android.gms.dynamic.IObjectWrapper
import com.google.android.gms.dynamic.ObjectWrapper
Expand All @@ -18,8 +19,8 @@ import org.microg.gms.utils.warnOnTransactionIssues
private const val TAG = "AdsSettingManager"

@Keep
class MobileAdsSettingManagerCreatorImpl : IMobileAdsSettingManagerCreator.Stub() {
override fun getMobileAdsSettingManager(context: IObjectWrapper?, clientVersion: Int): IBinder {
open class MobileAdsSettingManagerCreatorImpl : IMobileAdsSettingManagerCreator.Stub() {
override fun getMobileAdsSettingManager(context: IObjectWrapper?, clientVersion: Int): IMobileAdsSettingManager {
Log.d(TAG, "getMobileAdsSettingManager($clientVersion)")
return MobileAdsSettingManagerImpl(ObjectWrapper.unwrap(context) as Context)
}
Expand Down
53 changes: 53 additions & 0 deletions play-services-ads-api/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ SPDX-FileCopyrightText: 2026 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID" />
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" />
<uses-permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS" />
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED"
tools:node="remove" />

<queries>
<!-- Website links -->
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<!-- Custom tabs -->
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
<!-- MRAID -->
<intent>
<action android:name="android.intent.action.INSERT" />
<data android:mimeType="vnd.android.cursor.dir/event" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<intent>
<action android:name="android.intent.action.DIAL" />
<data android:path="tel:" />
</intent>
</queries>

<application>
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
android:value="true" />
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
android:value="true" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package com.google.android.gms.ads.formats;

parcelable AdManagerAdViewOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package com.google.android.gms.ads.formats;

parcelable PublisherAdViewOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package com.google.android.gms.ads.internal.client;

parcelable AdSizeParcel;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2026 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/

package com.google.android.gms.ads.internal.client;

parcelable AdValueParcel;
Loading
Loading