Mediation

Migration from 4.X to 5.X

All code samples are provided in kotlin unless otherwise noted. The 5.X documentation is effective for v5.0.0. Refer to the main documentation for the most up-to-date information with the latest 5.X version.

New Features for the 5.X Series πŸ”—

Core SDK Required πŸ”—

The Chartboost Mediation 5.X series of SDKs introduces a new architecture centered around the Chartboost Core SDK. By moving the Mediation SDK’s consent duties to the Core SDK, the Mediation SDK is able to more rapidly keep pace with the evolving privacy and consent landscape.

Review the Core SDK integration guide for more information.

Mediation API πŸ”—

The public APIs have been audited so that there is better parity between all of the platforms.

  • The fixed and adapter banner APIs have been merged into a singular API.
  • The fullscreen ads API architecture has been updated to match that of the banner ads API.
  • The old Helium moniker has been rebranded with ChartboostMediation to be consistent with the product’s marketing terms.

Packages πŸ”—

Mediation 4.X Mediation 5.X
com.chartboost.heliumsdk com.chartboost.chartboostmediationsdk
com.chartboost.heliumsdk.ad com.chartboost.chartboostmediationsdk.ad
com.chartboost.heliumsdk.domain com.chartboost.chartboostmediationsdk.domain
com.chartboost.heliumsdk.network.model com.chartboost.chartboostmediationsdk.network.model

Classes πŸ”—

Mediation 4.X Mediation 5.X
HeliumImpressionData ChartboostMediationImpressionData
HeliumInitializationOptions ChartboostMediationPreinitializationOptions
HeliumSdk ChartboostMediation
HeliumBannerAd ChartboostMediationBannerAdView
HeliumBannerSize ChartboostMediationBannerSize

Interfaces πŸ”—

Mediation 4.X Mediation 5.X
HeliumIlrdObserver ChartboostMediationIlrdObserver
HeliumSdkListener Removed
HeliumBannerAdListener ChartboostMediationBannerAdViewListener

Integration πŸ”—

SDK Initialization πŸ”—

Starting with Mediation SDK 5.0.0, the Mediation SDK can only be initialized by Chartboost Core SDK. This architectural change was made so that Core can manage the initialization sequences of the current Mediation SDK and future SDKs on the horizon.

Review the Core SDK integration guide for more information.

  • repositories {
      maven {
        name "Chartboost Mediation’s maven repo"
        url "https://cboost.jfrog.io/artifactory/chartboost-mediation"
      }
    }
     
    dependencies {
       implementation 'com.chartboost:chartboost-mediation-sdk:4.0.0'
    }
    
  • repositories {
        maven {
          name "Chartboost Mediation's maven repo"
          url "https://cboost.jfrog.io/artifactory/chartboost-mediation"
        }
        maven {
          name "Chartboost Core's maven repo"
          url "https://cboost.jfrog.io/artifactory/chartboost-core"
        }
    }
     
    dependencies {
        implementation("com.chartboost:chartboost-core-sdk:1.0.0")
        implementation("com.chartboost:chartboost-mediation-sdk:5.0.0")
    }
    

Network Killswitch πŸ”—

Since Mediation SDK initialization is now handled by the Core SDK, the network killswitch feature has been moved to the static method ChartboostMediationSdk.setPreinitializationConfigurationn() that must be called before Core SDK initialization is initiated.

  • // Create a listener
     val heliumSdkListener = object : HeliumSdk.HeliumSdkListener { error -> {
        error?.let {
            Log.d(TAG, "Helium SDK failed to initialize. Reason: ${it.message}")
        } ?: run {
            // SDK Initialized with no errors. 
            Log.d(TAG, "Helium SDK Initialized successfully")
        }
    }
    
    // Put the partner id in this map for network kill switch
    val skippedPartnerIds = mutableSetOf<String>()
    // skippedPartnerIds.add("chartboost") // for example
    HeliumSdk.start(context, myHeliumAppId, myHeliumAppSignature,HeliumInitializationOptions(skippedPartnerIds), heliumSdkListener)
    
  • // Prepare a list of partners that should not be initialized
    ChartboostMediationSdk.setPreinitializationConfiguration(
       ChartboostMediationPreinitializationConfiguration(
           YOUR_LIST_OF_PARTNER_IDS_TO_SKIP
       ),
    )
    
    // Create a usercentrics module (or any other consent management platform module)
    val usercentrics = UsercentricsAdapter()
    
    // Create a module listener
    val listener = object : ModuleObserver {
        override fun onModuleInitializationCompleted(result: ModuleInitializationResult) {
            // Use this to action off of a specific module initialization
            val moduleId = result.moduleId
        }
    
    // Make sure you're in a coroutine
    CoroutineScope(Main).launch {
        // Initialize ChartboostCore. You do not need to do anything additional besides providing the Chartboost app ID to initialize mediation.
        ChartboostCore.initializeSdk(context, SdkConfiguration("[chartboost app id]", listOf(usercentrics)), listener)
    }
    

All privacy and consent related APIs have been removed from the Mediation 5.X SDK and will be handled by the Core SDK.

The Mediation SDK will continue to utilize the TCFv2 string as part of auction requests, and will forward consent changes to the partner adapters. For partners that utilize complex non-IAB compliant privacy and consent signals that cannot be extrapolated from Core SDK consent signals, last resort APIs will be exposed via that partner adapter’s AdapterConfiguration class and must be directly set on the adapter configuration.

For more information on supported Consent Mediation Platforms and their integration, review the Core SDK integration guide.

HyprMX πŸ”—

// Set consent status directly on the adapter configuration
HyprMXAdapterConfiguration.setConsentStatusOverride(context, CONSENT_GIVEN)

Pangle πŸ”—

// Set consent status directly on the adapter configuration
PangleAdapterConfiguration.setGdprConsentOverride(consent) // this is an int
PangleAdapterConfiguration.setDoNotSellOverride(doNotSell) // this is an int

UnityAds πŸ”—

// Set consent status directly on the adapter configuration
UnityAdsAdapterConfiguration.setGdprConsentOverride(context, true)
UnityAdsAdapterConfiguration.setPrivacyConsentOverride(context, true)

Vungle πŸ”—

// Set consent status directly on the adapter configuration
VungleAdapterConfiguration.setGdprStatusOverride(true)
VungleAdapterConfiguration.setCcpaStatusOverride(true)

Publisher Metadata πŸ”—

Publisher-specified data used to improve auction requests have been moved to the Core SDK, and will still be available to the Mediation 5.X auction requests.

Mediation 4.X Mediation 5.X
Helium.userIdentifier ChartboostCore.publisherMetadata.setPlayerIdentifier()
Helium.setGameEngineName(_, version:) ChartboostCore.publisherMetadata.setFramework(name:, version:)
Helium.setSubjectToCoppa() ChartboostCore.publisherMetadata.setIsUserUnderage()

Adaptive Banner Ads πŸ”—

The changes to the adaptive banner ads APIs revolved around naming convention parity.

  • // To load an adaptive 6x1 ad (with width 300dp)
    heliumBannerAd.load(placement, HeliumBannerSize.adaptive6x1(300))
        // You can pass in another size or the old non-adaptive sizes such as HeliumBannerSize.STANDARD
    
    // To listen for refreshes
    val listener: HeliumBannerAdListener = object : HeliumBannerAdListener {
        fun onAdViewAdded(placementName: String, child: View?) {
            // notified that a view is added.
        }
        // other callbacks didn't change
    }
    heliumBannerAd.heliumBannerAdListener = listener
    
  • // Make sure you're in a coroutine
    CoroutineScope(Main).launch { ...
    
    // Create a listener
    val listener = object : ChartboostMediationBannerAdViewListener {
            override fun onAdClicked(placement: String) {
                // Fired when the banner is clicked
            }
    
            override fun onAdImpressionRecorded(placement: String) {
                // Fired when a banner impression has occurred
            }
    
            override fun onAdViewAdded(
                placement: String,
                child: View?,
            ) {
                // Fired when a view has been added to the banner
            }
        }
    
    // Create an adaptive banner ad instance. Here is an example adaptive 6x1
    val banner = ChartboostMediationBannerAdView(
            context,
            "[placement]",
            ChartboostMediationBannerAdView.ChartboostMediationBannerSize.adaptive6x1(300),
            listener
        )
    
    // Load an adaptive banner ad. This variable has the load details.
    val adaptiveBannerResult = banner.load(ChartboostMediationBannerAdLoadRequest(
        "[placement]", 
        keywords,
        ChartboostMediationBannerAdView.ChartboostMediationBannerSize.adaptive6x1(300)
    )
    

Resizing adaptive banners πŸ”—

The changes to resizing adaptive banner ads APIs revolved around naming convention parity.

  • val density = context.resources.displayMetrics.density
    heliumBannerAd.layoutParams = ViewGroup.LayoutParams(
                        300 * density,
                        50 * density
                    )
    // If you want this to be automatic, just use WRAP_CONTENT for
    // both width and height.
    heliumBannerAd.layoutParams = ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT
                    )
    // You can change this anytime. The next ad will use these sizes.
    
    // To get the size of the currently showing creative, see:
    heliumBannerAd.getCreativeSizeDips()
    
  • val density = context.resources.displayMetrics.density
    ChartboostMediationBannerAdView.layoutParams = ViewGroup.LayoutParams(
                        300 * density,
                        50 * density
                    )
    // If you want this to be automatic, just use WRAP_CONTENT for
    // both width and height.
    ChartboostMediationBannerAdView.layoutParams = ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT
                    )
    // You can change this anytime. The next ad will use these sizes.
    
    // To get the size of the currently showing creative, see:
    ChartboostMediationBannerAdView.getCreativeSizeDips()
    

Fixed Banner Ads πŸ”—

The fixed banner APIs have been deprecated and removed. To create and load fixed banners in the 5.X series, use the new banner APIs with a fixed size.

  • /*
      The following Banner enum Sizes can be passed down:
      HeliumBannerAd.HeliumBannerSize.STANDARD
      HeliumBannerAd.HeliumBannerSize.MEDIUM
      HeliumBannerAd.HeliumBannerSize.LEADERBOARD
    */
    val bannerSize = HeliumBannerAd.HeliumBannerSize.STANDARD
    val heliumBannerAd = new HeliumBannerAd(context, placementName, bannerSize, bannerListener)
    
  • // Make sure you're in a coroutine
    CoroutineScope(Main).launch {
    ...
    
    // Create a listener
    val listener = object : ChartboostMediationBannerAdViewListener {
            override fun onAdClicked(placement: String) {
                // Fired when the banner is clicked
            }
    
            override fun onAdImpressionRecorded(placement: String) {
                // Fired when a banner impression has occurred
            }
    
            override fun onAdViewAdded(
                placement: String,
                child: View?,
            ) {
                // Fired when a view has been added to the banner
            }
        }
    
    // Create a standard banner ad instance
    val standardBanner = ChartboostMediationBannerAdView(
            context,
            "[placement]",
            ChartboostMediationBannerAdView.ChartboostMediationBannerSize.STANDARD,
            listener
        )
    // It is also possible to get it from the xml
    val standardBanner = activity.findViewById(R.id.standard_banner) as ChartboostMediationBannerAdView
    
    // Loading a standard banner. This variable has the load details.
    val bannerLoadResult = standardBanner.load(ChartboostMediationBannerAdLoadRequest(
        "[placement]", 
        keywords, 
        ChartboostMediationBannerAdView.ChartboostMediationBannerSize.STANDARD
    )
    
    // Create a medium rectangle banner ad instance
    val mediumRectagle = ChartboostMediationBannerAdView(
            context,
            "[placement]",
            ChartboostMediationBannerAdView.ChartboostMediationBannerSize.MEDIUM,
            listener
        )
    
    // Load a medium rectangle. This variable has the load details.
    val mediumRectangleLoadResult = mediumRectagle.load(ChartboostMediationBannerAdLoadRequest(
        "[placement]", 
        keywords, 
        ChartboostMediationBannerAdView.ChartboostMediationBannerSize.MEDIUM
    )
    
    // Create a leaderboard ad instance
    val leaderboard = ChartboostMediationBannerAdView(
            context,
            "[placement]",
            ChartboostMediationBannerAdView.ChartboostMediationBannerSize.LEADERBOARD,
            listener
        )
    
    // Load a leaderboard ad. This variable has the load details.
    val leaderboardResult = leaderboard.load(ChartboostMediationBannerAdLoadRequest(
        "[placement]", 
        keywords, 
        ChartboostMediationBannerAdView.ChartboostMediationBannerSize.LEADERBOARD
    )
    

Fullscreen Ads πŸ”—

The changes to the fullscreen ads APIs revolved around naming convention parity and architectural alignment with the banner ads APIs.

  • // Interstitial Ads
    val interstitialRequest =   
        ChartboostMediationAdLoadRequest(
            placementName = "YOUR_INTERSTITIAL_MEDIATION_PLACEMENT",
            keywords = // Construct your keywords
        )
    
    // Rewarded Ads
    val rewardedRequest =   
        ChartboostMediationAdLoadRequest(
            placementName = "YOUR_REWARDED_MEDIATION_PLACEMENT",
            keywords = // Construct your keywords
        )
    
    // Load the fullscreen ad
    val result =
        HeliumSdk.loadFullscreenAd(
            context,
            interstitialRequest, // or rewardedRequest
            chartboostMediationFullscreenAdListener,
        )
    
    // Handle the ad load result
    result.ad?.let { ad ->
        // Success. Show the ad.
        CoroutineScope(Main).launch {
            ad.show(context)
        }
    } ?: run {
        // Failure
    }
    
  • // Interstitial Ads
    val interstitialRequest =
       ChartboostMediationFullscreenAdLoadRequest(
           placement = "YOUR_INTERSTITIAL_MEDIATION_PLACEMENT",
           keywords = // Construct your keywords
       )
    
    // Rewarded Ads
    val rewardedRequest =
       ChartboostMediationFullscreenAdLoadRequest(
           placement = "YOUR_REWARDED_MEDIATION_PLACEMENT",
           keywords = // Construct your keywords
       )
    
    // Load the fullscreen ad
    val result =
       ChartboostMediationFullscreenAd.loadFullscreenAd(
           context,
           interstitialRequest, // or rewardedRequest
           chartboostMediationFullscreenAdListener,
       )
    
    // Handle the ad load result
    result.ad?.let { ad ->
        // Success. Show the ad.
        CoroutineScope(Main).launch {
            ad.show(activity)
        }
    } ?: run {
        // Failure
    }
    

Discarding Oversized Ads πŸ”—

The changes to the discarding oversized ads revolved around naming convention parity.

  • // To drop oversized ads
    HeliumSdk.setShouldDiscardOversizedAds(true)
    
    // To allow oversized ads
    HeliumSdk.setShouldDiscardOversizedAds(false)
    
  • // To drop oversized ads
    ChartboostMediation.setShouldDiscardOversizedAds(true)
    
    // To allow oversized ads
    ChartboostMediation.setShouldDiscardOversizedAds(false)
    

Clearing Loaded Ads πŸ”—

The changes to clearing loaded ads revolved around naming convention parity and architectural alignment with the banner ads APIs.

  • heliumInterstitialAd.clearLoaded()
    heliumRewardedAd.clearLoaded()
    
  • ChartboostMediationFullscreenAd.invalidate()
    ChartboostMediationBannerAdView.clearAd()
    

Releasing Ads πŸ”—

The changes to releasing ads revolved around naming convention parity and architectural alignment with the banner ads APIs.

  • override fun onDestroy() {
      ...
      // Release interstitial ad
      heliumInterstitialAd?.let {
          it.destroy();
          Log("destroyed an existing interstitial");
      }
      // Release rewarded ad
      heliumRewardedAd?.let {
          it.destroy();
          Log("destroyed an existing rewarded");
      }
      // Release banner ad
      heliumBannerAd?.let {
          it.destroy();
          Log("destroyed an existing banner");
      }
      ...
    }
    
  • override fun onDestroy() {
      ...
      // Release banner ad
      chartboostMediationBannerAdView?.let {
          it.destroy();
          Log("destroyed an existing banner");
      }
      ...
    }
    

Winning Bid Information πŸ”—

The keys used to retrieve information from the dictionary have been normalized to use underscores instead of hyphens.

Mediation 4.X Mediation 5.X
auction-id auction_id
partner-id partner_id
price price
line_item_id line_item_id
line_item_name line_item_name

Configure Mediation πŸ”—

Test Mode πŸ”—

The changes to test mode revolved around naming convention parity.

  • HeliumSdk.setTestMode(true)
    HeliumSdk.setTestMode(false)
    
  • ChartboostMediation.setTestMode(context, true)
    ChartboostMediation.setTestMode(context, false)
    

Privacy Methods πŸ”—

All privacy methods have been removed from 5.X and migrated to Chartboost Core SDK.

  • // COPPA
    HeliumSdk.setSubjectToCoppa(true)
    // or
    HeliumSdk.setSubjectToCoppa(false)
    
    //- By sending `setSubjectToCoppa(true)`, you indicate that you want your content treated as child-directed for purposes of COPPA. We will take steps to disable interest-based advertising for such ad requests.
    //- By sending `setSubjectToCoppa(false)`, you indicate that you don't want your content treated as child-directed for purposes of COPPA. You represent and warrant that your applications and services are not directed towards children and that you will not provide any information to Mediation from a user under the age of 13.
    
    // GDPR
    HeliumSdk.setSubjectToGDPR(true)
    // or
    HeliumSdk.setSubjectToGDPR(false)
    
    //- By sending `setSubjectToGDPR(true)`, you indicate that GDPR is applied to this user from your application.
    //- By sending `setSubjectToGDPR(false)`, you indicate that GDPR is not applied to this user from your application.
    
    // User Given Consent
    HeliumSdk.setUserHasGivenConsent(true)
    // or
    HeliumSdk.setUserHasGivenConsent(false)
    
    //- By sending `setUserHasGivenConsent(true)`, you indicate that this user from your application has given consent to share personal data for behavior-targeted advertising.
    //- By sending `setUserHasGivenConsent(false)`, you indicate that this user from your application has not given consent to use its personal data for behavior-targeted advertising, so only contextual advertising is allowed.
    
    // CCPA
    HeliumSdk.setCCPAConsent(true)
    // or
    HeliumSdk.setCCPAConsent(false)
    
    //- By sending `setCCPAConsent(true)`, you indicate that this user from your application has given consent to share personal data for behavior-targeted advertising under CCPA regulation.
    //- By sending `setCCPAConsent(false)`, you indicate that this user from your application has not given consent to allow sharing personal data for behavior-targeted advertising under CCPA regulation.
    

Keywords πŸ”—

The changes keywords revolved around naming convention parity and architectural alignment with the banner ads APIs.

  • // Set Keywords
    val interstitialAd = HeliumInterstitialAd(placementName, heliumInterstitialAdListener)
      
    val rewardedAd = HeliumRewardedAd(placementName, heliumRewardedAdListener)
      
    val bannerAd = HeliumBannerAd(context, placementName, bannerSize, heliumBannerAdListener)
      
    interstitialAd.keywords["i12_keyword1"] = "i12_value1"
      
    rewardedAd.keywords["rwd_keyword1"] = "rwd_value1"
      
    bannerAd.keywords["bnr_keyword1"] = "bnr_value1"
    
    
    // Remove Keywords
    interstitialAd.remove("i12_keyword1")
    rewardedAd.remove("rwd_keyword1")
    bannerAd.remove("bnr_keyword1")
    
  • // ChartboostMediationFullscreenAd
    // Adding Keywords to the Keywords object
    val keywords = Keywords().set("keyword1", "value1")
    
    // Removing Keywords.
    keywords.remove("keyword1")
    
    // Passing keywords to the fullscreen load request.
    val request = ChartboostMediationFullscreenAdLoadRequest(
        placement = "placement",
        keywords = keywords,
        emptyMap(),
    )
    
    val result =
        ChartboostMediationFullscreenAd.loadFullscreenAd(
            context,
            request,
            listener,
        )
    
    // Adding Keywords from the ad result.
    result.ad?.request?.keywords?.set()"keyword1", "value1"
    
    // Removing Keywords from the ad result.
    result.ad?.request?.keywords?.remove("keyword1")
    
    
    // Banners
    // Adding Keywords to the Keywords object.
    val keywords = Keywords().set("banner1", "value1")
    
    val bannerRequest = ChartboostMediationBannerAdLoadRequest(
        "placement",
        keywords,
        bannerSize,
    )
    
    // Adding Keywords to banner request.
    bannerRequest.keywords["banner2"] = "value2"
    
    // Removing Keywords
    val bannerAdView = ChartboostMediationBannerAdView(
        context,
        "placement",
        size,
        listener,
    )
    // Removing a keyword from the banner ad view
    bannerAdView.keywords.remove("key1")
    
    // It is also possible to remove the keyword from the banner load request
    val keywords = Keywords()
    keywords.add("key1")
    keywords.remove("key1")
    val loadRequest = ChartboostMediationBannerAdLoadRequest("placement", keywords, size)
    // Can then load the banner with the keywords
    bannerAdView.load(loadRequest)
    

Setting User Identifier πŸ”—

The user identifier property is now configured with the Chartboost Core SDK.

  • HeliumSdk.setUserIdentifier("user")
    
  • ChartboostCore.publisherMetadata.setPlayerIdentifier("player_id")
    

Setting Custom Data πŸ”—

The custom data is now set as a property with naming changes to align with the banner ads APIs.

  • val rewardedAd: HeliumRewardedAd = // create your HeliumRewardedAd
    
    // load ad
    
    val base64EncodedCustomData = "Y3VzdG9tIGRhdGE="
    rewarded.customData = base64EncodedCustomData
    // show ad
    

Implementation πŸ”—

The changes to implementation revolved around naming convention parity.

  • val ilrdObserver = object: HeliumIlrdObserver {
      override fun onImpression(impData: HeliumImpressionData) {
          // Placement name
          val placement = impData.placementId
          // JSON
          val json = impData.ilrdInfo
      }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
      ...
      // Subscribe to ILRD on app startup, e.g. in onCreate()
      HeliumSdk.subscribeIlrd(ilrdObserver)
      ...
    }
    
    override fun onDestroy() {
      ...
      // Unsubscribe from ILRD on app terminations, e.g. in onDestroy()
      HeliumSdk.unsubscribeIlrd(ilrdObserver)
      ...
    }
    
  • val chartboostMediationIlrdObserver = object: ChartboostMediationIlrdObserver {
      override fun onImpression(impData: ChartboostMediationImpressionData) {
          // Placement name
          val placement = impData.placementId
          // JSON
          val json = impData.ilrdInfo
      }
    }
    
    override fun onCreate(savedInstanceState: Bundle?) {
      ...
      // Subscribe to ILRD on app startup, e.g. in onCreate()
      ChartboostMediationSdk.subscribeIlrd(chartboostMediationIlrdObserver)
      ...
    }
    
    override fun onDestroy() {
      ...
      // Unsubscribe from ILRD on app terminations, e.g. in onDestroy()
      ChartboostMediationSdk.unsubscribeIlrd(chartboostMediationIlrdObserver)
      ...
    }
    

Listener Usage πŸ”—

The changes to the listener usage revolved around naming convention parity.

  • // HeliumFullscreenAdListener
    val heliumFullscreenAdListener = object : HeliumFullscreenAdListener
    
    // HeliumBannerAdListener
    val heliumBannerAdListener = object : HeliumBannerAdListener
    
  • // ChartboostMediationFullscreenAdListener
    val chartboostMediationFullscreenAdListener = object : ChartboostMediationFullscreenAdListener
    
    // ChartboostMediationBannerAdViewListener
    val chartboostMediationBannerAdViewListener = object : ChartboostMediationBannerAdViewListener
    

Error Codes πŸ”—

5.X will continue to use codes from 4.X with minor changes in the descriptions. Any new error codes introduced in 5.X will follow the same naming convention.

Proguard and R8 πŸ”—

All consent handling and Mediation initialization will be done by the core SDK. In addition, 5.x will use the Mediation branding.

  • // Chartboost Mediation SDK
    -keep class com.chartboost.heliumsdk.** { *; }
    
    // Chartboost Mediation Adapters
    -keep class com.chartboost.mediation.** { *; }
    
    // Keep kotlinx.serialization annotations
    -keepattributes *Annotation*
    
    // Keep the names of kotlinx.serialization classes
    -keep,includedescriptorclasses class kotlinx.serialization.** {
        *;
    }
    
    // Keep the names of classes with @Serializable annotation
    -keep,includedescriptorclasses @kotlinx.serialization.Serializable class * {
        *;
    }
    
    // Keep kotlinx.serialization internal implementation classes
    -keepclassmembers class kotlinx.serialization.internal.** {
        *;
    }
    
  • // Chartboost Mediation SDK
    -keep class com.chartboost.chartboostmediationsdk.** { *; }
    
    // Chartboost Core SDK
    -keep class com.chartboost.core.** { *; }
    
    // Chartboost Mediation Adapters
    -keep class com.chartboost.mediation.** { *; }
    
    // Keep kotlinx.serialization annotations
    -keepattributes *Annotation*
    
    // Keep the names of kotlinx.serialization classes
    -keep,includedescriptorclasses class kotlinx.serialization.** {
        *;
    }
    
    // Keep the names of classes with @Serializable annotation
    -keep,includedescriptorclasses @kotlinx.serialization.Serializable class * {
        *;
    }
    
    // Keep kotlinx.serialization internal implementation classes
    -keepclassmembers class kotlinx.serialization.internal.** {
        *;
    }