Skip to content

[interactive_media_ads] Adds support to set general SDK settings #9648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4b126be
start of settings
bparrishMines Jul 2, 2025
bb4550e
add test stubs
bparrishMines Jul 2, 2025
c4fc99a
some android impl work
bparrishMines Jul 3, 2025
62edcca
Merge branch 'main' of github.com:flutter/packages into ima_settings
bparrishMines Jul 9, 2025
e0c10a2
ios impl
bparrishMines Jul 9, 2025
171d050
add app facing class
bparrishMines Jul 9, 2025
66c6ec8
make class immuatable and return settings
bparrishMines Jul 9, 2025
6ffe107
add better docs
bparrishMines Jul 9, 2025
a38e789
formatting and updating android
bparrishMines Jul 9, 2025
d94cb5b
fix app facing test
bparrishMines Jul 9, 2025
6b9c519
Merge branch 'main' of github.com:flutter/packages into ima_settings
bparrishMines Jul 14, 2025
b6235d6
update pigeon
bparrishMines Jul 17, 2025
032d8e7
fix android adsloader test
bparrishMines Jul 17, 2025
b2c2a60
revert changes to android ads loader test
bparrishMines Jul 17, 2025
7b17129
fix android tests
bparrishMines Jul 18, 2025
de045bf
fix ios loader tests
bparrishMines Jul 18, 2025
2798ecf
android ima settings test
bparrishMines Jul 18, 2025
c0b52fd
add ios settings
bparrishMines Jul 18, 2025
cc03997
Merge branch 'main' of github.com:flutter/packages into ima_settings
bparrishMines Jul 18, 2025
6ad5d1a
ima settings test for app-facing
bparrishMines Jul 18, 2025
8792a50
version bump
bparrishMines Jul 18, 2025
bfa41ee
remove html brackets
bparrishMines Jul 18, 2025
9962724
gemini code assist review
bparrishMines Jul 18, 2025
377d7f5
update android to take nonnull values
bparrishMines Jul 18, 2025
215b38a
make android nonnull
bparrishMines Jul 18, 2025
09f7205
update ima settings tests
bparrishMines Jul 18, 2025
eb8bdb5
fix formatting
bparrishMines Jul 18, 2025
7ecb8c1
formatting
bparrishMines Jul 18, 2025
85d6f62
improve settings docs
bparrishMines Jul 21, 2025
4bd107b
Merge branch 'main' of github.com:flutter/packages into ima_settings
bparrishMines Jul 21, 2025
dac72ba
erge branch 'main' of github.com:flutter/packages into ima_settings
bparrishMines Jul 24, 2025
ed438ae
use await
bparrishMines Jul 24, 2025
427e307
use create instead of init
bparrishMines Jul 24, 2025
3f08cfc
remove g
bparrishMines Jul 24, 2025
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
4 changes: 4 additions & 0 deletions packages/interactive_media_ads/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.2.5

* Adds support to set general SDK settings. See `ImaSettings` and `AdsLoader.settings`.

## 0.2.4+2

* Bumps gradle from 8.9.0 to 8.11.1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) :
*
* This must match the version in pubspec.yaml.
*/
const val pluginVersion = "0.2.4+2"
const val pluginVersion = "0.2.5"
}

override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v25.5.0), do not edit directly.
// Autogenerated from Pigeon (v26.0.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest {
/// The current version of the `interactive_media_ads` plugin.
///
/// This must match the version in pubspec.yaml.
static let pluginVersion = "0.2.4+2"
static let pluginVersion = "0.2.5"

func pigeonDefaultConstructor(
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v25.5.0), do not edit directly.
// Autogenerated from Pigeon (v26.0.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon

import Foundation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export 'src/android/android_interactive_media_ads.dart'
show AndroidInteractiveMediaAds;
export 'src/companion_ad_slot.dart';
export 'src/content_progress_provider.dart';
export 'src/ima_settings.dart';
export 'src/ios/ios_interactive_media_ads.dart' show IOSInteractiveMediaAds;
export 'src/platform_interface/platform_interface.dart'
show
Expand Down
7 changes: 7 additions & 0 deletions packages/interactive_media_ads/lib/src/ads_loader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'ad_display_container.dart';
import 'ads_manager_delegate.dart';
import 'ads_rendering_settings.dart';
import 'ads_request.dart';
import 'ima_settings.dart';
import 'platform_interface/platform_interface.dart';

/// Allows publishers to request ads from ad servers or a dynamic ad insertion
Expand Down Expand Up @@ -42,9 +43,11 @@ class AdsLoader {
required AdDisplayContainer container,
required void Function(OnAdsLoadedData data) onAdsLoaded,
required void Function(AdsLoadErrorData data) onAdsLoadError,
ImaSettings? settings,
}) : this.fromPlatformCreationParams(
PlatformAdsLoaderCreationParams(
container: container.platform,
settings: settings?.platform ?? ImaSettings().platform,
onAdsLoaded: (PlatformOnAdsLoadedData data) {
onAdsLoaded(OnAdsLoadedData._(platform: data));
},
Expand Down Expand Up @@ -89,6 +92,10 @@ class AdsLoader {
/// Implementation of [PlatformAdsLoader] for the current platform.
final PlatformAdsLoader platform;

/// Defines general SDK settings.
ImaSettings get settings =>
ImaSettings.fromPlatform(platform.params.settings);

/// Signals to the SDK that the content has completed.
Future<void> contentComplete() {
return platform.contentComplete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../platform_interface/platform_interface.dart';
import 'android_ad_display_container.dart';
import 'android_ads_manager.dart';
import 'android_content_progress_provider.dart';
import 'android_ima_settings.dart';
import 'enum_converter_utils.dart';
import 'interactive_media_ads.g.dart' as ima;
import 'interactive_media_ads_proxy.dart';
Expand All @@ -19,6 +20,7 @@ final class AndroidAdsLoaderCreationParams
extends PlatformAdsLoaderCreationParams {
/// Constructs a [AndroidAdsLoaderCreationParams].
const AndroidAdsLoaderCreationParams({
required super.settings,
required super.container,
required super.onAdsLoaded,
required super.onAdsLoadError,
Expand All @@ -33,6 +35,7 @@ final class AndroidAdsLoaderCreationParams
@visibleForTesting InteractiveMediaAdsProxy? proxy,
}) {
return AndroidAdsLoaderCreationParams(
settings: params.settings,
container: params.container,
onAdsLoaded: params.onAdsLoaded,
onAdsLoadError: params.onAdsLoadError,
Expand Down Expand Up @@ -97,11 +100,13 @@ base class AndroidAdsLoader extends PlatformAdsLoader {
}

Future<ima.AdsLoader> _createAdsLoader() async {
final ima.ImaSdkSettings settings =
await _sdkFactory.createImaSdkSettings();
final AndroidImaSettings settings = switch (_androidParams.settings) {
final AndroidImaSettings androidSettings => androidSettings,
_ => AndroidImaSettings(_androidParams.settings.params),
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.


final ima.AdsLoader adsLoader = await _sdkFactory.createAdsLoader(
settings,
await settings.nativeSettingsFuture,
(params.container as AndroidAdDisplayContainer).adDisplayContainer!,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:meta/meta.dart';

import '../platform_interface/platform_ima_settings.dart';
import 'interactive_media_ads.g.dart';

/// Android implementation of [PlatformImaSettings].
final class AndroidImaSettings extends PlatformImaSettings {
/// Constructs an [AndroidImaSettings].
AndroidImaSettings(super.params) : super.implementation();

/// The native Android ImaSdkSettings.
///
/// Defines general SDK settings that are used when creating an `AdsLoader`.
@internal
late final Future<ImaSdkSettings> nativeSettingsFuture = _createSettings();

@override
Future<void> setAutoPlayAdBreaks(bool autoPlayAdBreaks) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setAutoPlayAdBreaks(autoPlayAdBreaks);
}
Comment on lines +24 to +27

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Many methods in this class follow the same pattern of awaiting nativeSettingsFuture and then calling a single method on the resulting settings object. This leads to some repetitive code.

To improve maintainability and reduce boilerplate, consider introducing a private helper method to encapsulate this pattern. For example:

Future<void> _withSettings(Future<void> Function(ImaSdkSettings) callback) async {
  final ImaSdkSettings settings = await nativeSettingsFuture;
  await callback(settings);
}

You could then refactor the methods like this:

@override
Future<void> setAutoPlayAdBreaks(bool autoPlayAdBreaks) {
  return _withSettings(
    (ImaSdkSettings settings) => settings.setAutoPlayAdBreaks(autoPlayAdBreaks),
  );
}


@override
Future<void> setDebugMode(bool enabled) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setDebugMode(enabled);
}

@override
Future<void> setFeatureFlags(Map<String, String> featureFlags) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setFeatureFlags(featureFlags);
}

@override
Future<void> setMaxRedirects(int maxRedirects) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setMaxRedirects(maxRedirects);
}

@override
Future<void> setPlayerType(String playerType) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setPlayerType(playerType);
}

@override
Future<void> setPlayerVersion(String playerVersion) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setPlayerVersion(playerVersion);
}

@override
Future<void> setPpid(String ppid) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setPpid(ppid);
}

@override
Future<void> setSessionID(String sessionID) async {
final ImaSdkSettings settings = await nativeSettingsFuture;
await settings.setSessionId(sessionID);
}

Future<ImaSdkSettings> _createSettings() async {
final ImaSdkSettings settings =
await ImaSdkFactory.instance.createImaSdkSettings();
if (params.language case final String language) {
await settings.setLanguage(language);
}
return settings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import '../platform_interface/platform_ads_manager_delegate.dart';
import '../platform_interface/platform_ads_rendering_settings.dart';
import '../platform_interface/platform_companion_ad_slot.dart';
import '../platform_interface/platform_content_progress_provider.dart';
import '../platform_interface/platform_ima_settings.dart';
import 'android_ad_display_container.dart';
import 'android_ads_loader.dart';
import 'android_ads_manager_delegate.dart';
import 'android_ads_rendering_settings.dart';
import 'android_companion_ad_slot.dart';
import 'android_content_progress_provider.dart';
import 'android_ima_settings.dart';

/// Android implementation of [InteractiveMediaAdsPlatform].
final class AndroidInteractiveMediaAds extends InteractiveMediaAdsPlatform {
Expand All @@ -24,28 +26,28 @@ final class AndroidInteractiveMediaAds extends InteractiveMediaAdsPlatform {
}

@override
PlatformAdDisplayContainer createPlatformAdDisplayContainer(
AndroidAdDisplayContainer createPlatformAdDisplayContainer(
PlatformAdDisplayContainerCreationParams params,
) {
return AndroidAdDisplayContainer(params);
}

@override
PlatformAdsLoader createPlatformAdsLoader(
AndroidAdsLoader createPlatformAdsLoader(
PlatformAdsLoaderCreationParams params,
) {
return AndroidAdsLoader(params);
}

@override
PlatformAdsManagerDelegate createPlatformAdsManagerDelegate(
AndroidAdsManagerDelegate createPlatformAdsManagerDelegate(
PlatformAdsManagerDelegateCreationParams params,
) {
return AndroidAdsManagerDelegate(params);
}

@override
PlatformContentProgressProvider createPlatformContentProgressProvider(
AndroidContentProgressProvider createPlatformContentProgressProvider(
PlatformContentProgressProviderCreationParams params,
) {
return AndroidContentProgressProvider(params);
Expand All @@ -64,4 +66,11 @@ final class AndroidInteractiveMediaAds extends InteractiveMediaAdsPlatform {
) {
return AndroidCompanionAdSlot(params);
}

@override
AndroidImaSettings createPlatformImaSettings(
PlatformImaSettingsCreationParams params,
) {
return AndroidImaSettings(params);
}
}
Loading