#!/usr/bin/env bash # find-ads.sh — Search decompiled source for advertising SDK usage set -euo pipefail usage() { cat < [OPTIONS] Search decompiled Java/Kotlin source for advertising SDK usage. Arguments: Path to the decompiled sources directory Options: --admob Search only for AdMob/Google Mobile Ads --unity Search only for Unity Ads --ironsource Search only for IronSource/LevelPlay --applovin Search only for AppLovin/MAX --facebook Search only for Meta Audience Network --vungle Search only for Vungle/Liftoff --inmobi Search only for InMobi --chartboost Search only for Chartboost --pangle Search only for Pangle/TikTok --mintegral Search only for Mintegral --formats Search only for cross-SDK ad format patterns --mediation Search only for mediation adapter patterns --consent Search only for consent/privacy framework patterns --manifest Search only for AndroidManifest.xml ad markers --entrypoints Search only for ad SDK calls in app code (excludes library packages) --all Search all patterns (default) -h, --help Show this help message Output: Results are printed as file:line:match for easy navigation. EOF exit 0 } SOURCE_DIR="" SEARCH_ADMOB=false SEARCH_UNITY=false SEARCH_IRONSOURCE=false SEARCH_APPLOVIN=false SEARCH_FACEBOOK=false SEARCH_VUNGLE=false SEARCH_INMOBI=false SEARCH_CHARTBOOST=false SEARCH_PANGLE=false SEARCH_MINTEGRAL=false SEARCH_FORMATS=false SEARCH_MEDIATION=false SEARCH_CONSENT=false SEARCH_MANIFEST=false SEARCH_ENTRYPOINTS=false SEARCH_ALL=true while [[ $# -gt 0 ]]; do case "$1" in --admob) SEARCH_ADMOB=true; SEARCH_ALL=false; shift ;; --unity) SEARCH_UNITY=true; SEARCH_ALL=false; shift ;; --ironsource) SEARCH_IRONSOURCE=true; SEARCH_ALL=false; shift ;; --applovin) SEARCH_APPLOVIN=true; SEARCH_ALL=false; shift ;; --facebook) SEARCH_FACEBOOK=true; SEARCH_ALL=false; shift ;; --vungle) SEARCH_VUNGLE=true; SEARCH_ALL=false; shift ;; --inmobi) SEARCH_INMOBI=true; SEARCH_ALL=false; shift ;; --chartboost) SEARCH_CHARTBOOST=true; SEARCH_ALL=false; shift ;; --pangle) SEARCH_PANGLE=true; SEARCH_ALL=false; shift ;; --mintegral) SEARCH_MINTEGRAL=true; SEARCH_ALL=false; shift ;; --formats) SEARCH_FORMATS=true; SEARCH_ALL=false; shift ;; --mediation) SEARCH_MEDIATION=true; SEARCH_ALL=false; shift ;; --consent) SEARCH_CONSENT=true; SEARCH_ALL=false; shift ;; --manifest) SEARCH_MANIFEST=true; SEARCH_ALL=false; shift ;; --entrypoints) SEARCH_ENTRYPOINTS=true; SEARCH_ALL=false; shift ;; --all) SEARCH_ALL=true; shift ;; -h|--help) usage ;; -*) echo "Error: Unknown option $1" >&2; usage ;; *) SOURCE_DIR="$1"; shift ;; esac done if [[ -z "$SOURCE_DIR" ]]; then echo "Error: No source directory specified." >&2 usage fi if [[ ! -d "$SOURCE_DIR" ]]; then echo "Error: Directory not found: $SOURCE_DIR" >&2 exit 1 fi GREP_OPTS="-rn --include=*.java --include=*.kt" section() { echo echo "==== $1 ====" echo } run_grep() { local pattern="$1" # shellcheck disable=SC2086 grep $GREP_OPTS -E "$pattern" "$SOURCE_DIR" 2>/dev/null || true } run_grep_xml() { local pattern="$1" grep -rn --include="*.xml" -E "$pattern" "$SOURCE_DIR" 2>/dev/null || true } # --- AdMob / Google Mobile Ads --- if [[ "$SEARCH_ALL" == true || "$SEARCH_ADMOB" == true ]]; then section "AdMob — Initialization" run_grep '(MobileAds\.initialize\s*\(|MobileAds\.setRequestConfiguration|com\.google\.android\.gms\.ads)' section "AdMob — Banner" run_grep '(AdView\s|AdSize\.|\.loadAd\s*\(|AdRequest\.Builder|com\.google\.android\.gms\.ads\.AdView)' section "AdMob — Interstitial" run_grep '(InterstitialAd\.load\s*\(|InterstitialAdLoadCallback|FullScreenContentCallback|com\.google\.android\.gms\.ads\.interstitial)' section "AdMob — Rewarded" run_grep '(RewardedAd\.load\s*\(|RewardedAdLoadCallback|OnUserEarnedRewardListener|RewardedInterstitialAd\.load)' section "AdMob — Native" run_grep '(AdLoader\.Builder|NativeAd\.|NativeAdView|UnifiedNativeAd|NativeAdOptions|com\.google\.android\.gms\.ads\.nativead)' section "AdMob — App Open" run_grep '(AppOpenAd\.load\s*\(|AppOpenAd\.AppOpenAdLoadCallback|AppOpenAdManager)' section "AdMob — Ad Unit IDs" run_grep '(ca-app-pub-|/[0-9]+/[0-9]+|adUnitId|setAdUnitId\s*\()' fi # --- Unity Ads --- if [[ "$SEARCH_ALL" == true || "$SEARCH_UNITY" == true ]]; then section "Unity Ads — Initialization" run_grep '(UnityAds\.initialize\s*\(|UnityAds\.isInitialized|IUnityAdsInitializationListener|com\.unity3d\.ads)' section "Unity Ads — Load & Show" run_grep '(UnityAds\.load\s*\(|UnityAds\.show\s*\(|IUnityAdsLoadListener|IUnityAdsShowListener)' section "Unity Ads — Banner" run_grep '(BannerView\s*\(|UnityBannerSize|com\.unity3d\.services\.banners)' fi # --- IronSource / LevelPlay --- if [[ "$SEARCH_ALL" == true || "$SEARCH_IRONSOURCE" == true ]]; then section "IronSource — Initialization" run_grep '(IronSource\.init\s*\(|IronSource\.setUserId|IronSourceConfig|com\.ironsource\.mediationsdk)' section "IronSource — Interstitial" run_grep '(IronSource\.loadInterstitial|IronSource\.showInterstitial|IronSource\.isInterstitialReady|InterstitialListener)' section "IronSource — Rewarded Video" run_grep '(IronSource\.showRewardedVideo|IronSource\.isRewardedVideoAvailable|RewardedVideoListener)' section "IronSource — Banner" run_grep '(IronSource\.loadBanner|IronSource\.destroyBanner|IronSourceBannerLayout|BannerListener)' section "IronSource — LevelPlay" run_grep '(LevelPlay|LevelPlayAdError|LevelPlayBannerAdView|LevelPlayInterstitialAd|LevelPlayRewardedAd)' fi # --- AppLovin / MAX --- if [[ "$SEARCH_ALL" == true || "$SEARCH_APPLOVIN" == true ]]; then section "AppLovin — Initialization" run_grep '(AppLovinSdk\.getInstance|AppLovinSdk\.initializeSdk|AppLovinSdkSettings|com\.applovin\.sdk)' section "AppLovin MAX — Banner" run_grep '(MaxAdView\s|MaxAdViewAdListener|maxAdView\.loadAd|maxAdView\.startAutoRefresh)' section "AppLovin MAX — Interstitial" run_grep '(MaxInterstitialAd\s*\(|MaxAdListener|interstitialAd\.loadAd|interstitialAd\.showAd)' section "AppLovin MAX — Rewarded" run_grep '(MaxRewardedAd\.getInstance|MaxRewardedAdListener|rewardedAd\.loadAd|rewardedAd\.showAd)' section "AppLovin MAX — Native" run_grep '(MaxNativeAdLoader|MaxNativeAdView|MaxNativeAdListener)' fi # --- Facebook / Meta Audience Network --- if [[ "$SEARCH_ALL" == true || "$SEARCH_FACEBOOK" == true ]]; then section "Meta Audience Network — Initialization" run_grep '(AudienceNetworkAds\.initialize|AudienceNetworkAds\.buildInitSettings|com\.facebook\.ads)' section "Meta AN — Banner" run_grep '(com\.facebook\.ads\.AdView|com\.facebook\.ads\.AdSize|\.loadAd\s*\(.*AdView)' section "Meta AN — Interstitial" run_grep '(com\.facebook\.ads\.InterstitialAd|InterstitialAdListener|InterstitialAdExtendedListener)' section "Meta AN — Rewarded" run_grep '(RewardedVideoAd\s*\(|RewardedVideoAdListener|RewardedVideoAdExtendedListener|com\.facebook\.ads\.RewardedVideoAd)' section "Meta AN — Native" run_grep '(NativeAd\s*\(|NativeBannerAd|NativeAdListener|com\.facebook\.ads\.NativeAd|NativeAdLayout)' fi # --- Vungle / Liftoff --- if [[ "$SEARCH_ALL" == true || "$SEARCH_VUNGLE" == true ]]; then section "Vungle — Initialization & Ads" run_grep '(Vungle\.init\s*\(|VungleInitListener|Vungle\.loadAd\s*\(|Vungle\.playAd\s*\(|Vungle\.isInitialized|com\.vungle\.warren)' run_grep '(VungleBanner|VungleInterstitial|VungleRewarded|VungleNativeAd|com\.vungle\.ads)' fi # --- InMobi --- if [[ "$SEARCH_ALL" == true || "$SEARCH_INMOBI" == true ]]; then section "InMobi — Initialization & Ads" run_grep '(InMobiSdk\.init\s*\(|InMobiBanner|InMobiInterstitial|InMobiNative|com\.inmobi\.sdk|com\.inmobi\.ads)' fi # --- Chartboost --- if [[ "$SEARCH_ALL" == true || "$SEARCH_CHARTBOOST" == true ]]; then section "Chartboost — Initialization & Ads" run_grep '(Chartboost\.startWithAppId|Chartboost\.showInterstitial|Chartboost\.showRewardedVideo|Chartboost\.cacheInterstitial|com\.chartboost\.sdk)' fi # --- Pangle / TikTok --- if [[ "$SEARCH_ALL" == true || "$SEARCH_PANGLE" == true ]]; then section "Pangle — Initialization & Ads" run_grep '(TTAdSdk\.init\s*\(|TTAdConfig\.Builder|TTAdNative|TTFullScreenVideoAd|TTRewardVideoAd|TTBannerAd|com\.bytedance\.sdk\.openadsdk)' run_grep '(PAGSdk\.init\s*\(|PAGConfig\.Builder|PAGBannerAd|PAGInterstitialAd|PAGRewardedAd|com\.pgl\.sys)' fi # --- Mintegral --- if [[ "$SEARCH_ALL" == true || "$SEARCH_MINTEGRAL" == true ]]; then section "Mintegral — Initialization & Ads" run_grep '(MBridgeSDKFactory\.getMBridgeSDK|MBBannerView|MBInterstitialVideoHandler|MBRewardVideoHandler|MBNewInterstitialHandler|com\.mbridge\.msdk)' fi # --- Cross-SDK Ad Format Patterns --- if [[ "$SEARCH_ALL" == true || "$SEARCH_FORMATS" == true ]]; then section "Cross-SDK — All Banner Patterns" run_grep '(BannerView|AdView|BannerAd|IronSourceBannerLayout|MaxAdView|MBBannerView|PAGBannerAd|TTBannerAd|InMobiBanner|VungleBanner)' section "Cross-SDK — All Interstitial Patterns" run_grep '(InterstitialAd|showInterstitial|loadInterstitial|MaxInterstitialAd|MBInterstitialVideoHandler|PAGInterstitialAd|TTFullScreenVideoAd|InMobiInterstitial|VungleInterstitial)' section "Cross-SDK — All Rewarded Patterns" run_grep '(RewardedAd|RewardedVideo|showRewardedVideo|MaxRewardedAd|MBRewardVideoHandler|PAGRewardedAd|TTRewardVideoAd|VungleRewarded|OnUserEarnedRewardListener)' section "Cross-SDK — All Native Patterns" run_grep '(NativeAd|NativeAdView|NativeAdLoader|NativeBannerAd|MaxNativeAdLoader|InMobiNative|VungleNativeAd|NativeAdLayout)' section "Cross-SDK — Ad Unit / Placement IDs" run_grep '(adUnitId|setAdUnitId|placementId|setPlacementId|PLACEMENT_ID|AD_UNIT_ID|ca-app-pub-|BANNER_ID|INTERSTITIAL_ID|REWARDED_ID)' fi # --- Mediation Adapters --- if [[ "$SEARCH_ALL" == true || "$SEARCH_MEDIATION" == true ]]; then section "Mediation — Google AdMob Mediation Adapters" run_grep '(com\.google\.ads\.mediation|MediationAdapter|MediationBannerAdapter|MediationInterstitialAdapter|MediationRewardedAd)' section "Mediation — IronSource Mediation Adapters" run_grep '(com\.ironsource\.adapters|IronSourceAdapter|ISBannerAdapter|ISInterstitialAdapter|ISRewardedVideoAdapter)' section "Mediation — AppLovin MAX Mediation Adapters" run_grep '(com\.applovin\.mediation\.adapters|MediationAdapterBase|MaxAdapter|MaxMediatedNetworkInfo)' section "Mediation — Waterfall & Bidding Configuration" run_grep '(waterfall|bidding|headerBidding|realTimeBidding|setWaterfall|mediationConfig|adNetworkId|networkName)' fi # --- Consent / Privacy Frameworks --- if [[ "$SEARCH_ALL" == true || "$SEARCH_CONSENT" == true ]]; then section "Consent — Google UMP / Funding Choices" run_grep '(ConsentInformation|ConsentRequestParameters|ConsentForm\.load|UserMessagingPlatform|com\.google\.android\.ump)' section "Consent — IAB TCF v2" run_grep '(IABTCF_|TCString|GDPR_APPLIES|GDPR_CONSENT|gdprApplies|tcfPolicyVersion|tcString)' section "Consent — COPPA / Child-Directed" run_grep '(tagForChildDirectedTreatment|COPPA|TAG_FOR_CHILD_DIRECTED|setTagForUnderAgeOfConsent|maxAdContentRating)' section "Consent — SDK-specific Opt-out" run_grep '(setHasUserConsent|setDoNotSell|setCCPADoNotSell|setGDPRConsent|gdprForgetMe|setDataProcessingOptions|setNonPersonalizedOnly)' fi # --- AndroidManifest.xml Markers --- if [[ "$SEARCH_ALL" == true || "$SEARCH_MANIFEST" == true ]]; then section "AndroidManifest — Ad Activities & Services" run_grep_xml '(com\.google\.android\.gms\.ads|AdActivity|com\.unity3d\.ads|com\.ironsource|com\.applovin|com\.facebook\.ads|com\.vungle|com\.inmobi|com\.chartboost|com\.bytedance)' section "AndroidManifest — Ad Permissions" run_grep_xml '(AD_ID|com\.google\.android\.gms\.permission\.AD_ID|BIND_GET_INSTALL_REFERRER_SERVICE)' section "AndroidManifest — Ad Meta-data" run_grep_xml '(com\.google\.android\.gms\.ads\.APPLICATION_ID|com\.google\.android\.gms\.ads\.AD_MANAGER_APP|applovin\.sdk\.key|com\.facebook\.sdk\.ApplicationId|unity\.ads\.gameId)' fi # --- Entry Points: Ad SDK calls from app code only --- if [[ "$SEARCH_ALL" == true || "$SEARCH_ENTRYPOINTS" == true ]]; then section "Entry Points — Ad SDK calls from app code (library packages excluded)" # Build --exclude-dir arguments for known library packages EXCLUDE_DIRS=( --exclude-dir="com/google" --exclude-dir="com/unity3d" --exclude-dir="com/ironsource" --exclude-dir="com/applovin" --exclude-dir="com/facebook" --exclude-dir="com/vungle" --exclude-dir="com/inmobi" --exclude-dir="com/chartboost" --exclude-dir="com/bytedance" --exclude-dir="com/pgl" --exclude-dir="com/mbridge" --exclude-dir="com/mintegral" --exclude-dir="com/adcolony" --exclude-dir="com/tapjoy" --exclude-dir="com/fyber" --exclude-dir="com/amazon/device/ads" --exclude-dir="io/vungle" ) ENTRYPOINT_PATTERN='(MobileAds\.initialize|MobileAds\.setRequestConfiguration|InterstitialAd\.load|RewardedAd\.load|RewardedInterstitialAd\.load|AppOpenAd\.load|AdView\.loadAd|AdLoader\.Builder|UnityAds\.initialize|UnityAds\.load|UnityAds\.show|IronSource\.init|IronSource\.loadInterstitial|IronSource\.showInterstitial|IronSource\.showRewardedVideo|IronSource\.loadBanner|AppLovinSdk\.getInstance|AppLovinSdk\.initializeSdk|MaxInterstitialAd|MaxRewardedAd|MaxAdView|AudienceNetworkAds\.initialize|Vungle\.init|Vungle\.loadAd|Vungle\.playAd|InMobiSdk\.init|Chartboost\.startWithAppId|TTAdSdk\.init|PAGSdk\.init|MBridgeSDKFactory\.getMBridgeSDK|LevelPlayInterstitialAd|LevelPlayRewardedAd|LevelPlayBannerAdView)' # shellcheck disable=SC2086 grep -rn --include="*.java" --include="*.kt" "${EXCLUDE_DIRS[@]}" -E "$ENTRYPOINT_PATTERN" "$SOURCE_DIR" 2>/dev/null || true echo echo "NOTE: Only calls from app code are shown above. Library-internal calls are excluded." echo "If no results appear, ad SDKs may only be invoked internally via mediation adapters." fi echo echo "=== Search complete ==="