Skip to content
Draft
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
131811f
run pigeon
bparrishMines Aug 11, 2025
dc9ed24
add missing apis
bparrishMines Aug 11, 2025
406e507
tests
bparrishMines Aug 11, 2025
07122c9
fix tests sort of
bparrishMines Aug 11, 2025
9acd11c
try fix tests maybe
bparrishMines Aug 11, 2025
038f303
fix version bump
bparrishMines Aug 12, 2025
bf56d72
fix tests
bparrishMines Aug 13, 2025
2f37abc
update adevent to
bparrishMines Aug 13, 2025
db23655
changelog update
bparrishMines Aug 13, 2025
84a9fba
Merge branch 'main' of github.com:flutter/packages into ima_ad_ios
bparrishMines Aug 13, 2025
dff3de9
fix pigeon code
bparrishMines Aug 13, 2025
660aa72
support a string value
bparrishMines Aug 14, 2025
3af4706
fix tests
bparrishMines Aug 14, 2025
5929f30
Merge branch 'main' of github.com:flutter/packages into ima_ad_ios
bparrishMines Aug 14, 2025
b00649e
comment the code
bparrishMines Aug 14, 2025
52d7635
Merge branch 'main' of github.com:flutter/packages into ima_ad_ios
bparrishMines Aug 18, 2025
7f77c09
version bump
bparrishMines Aug 18, 2025
473357a
improve ad proxy code
bparrishMines Aug 19, 2025
37ce423
Merge branch 'main' of github.com:flutter/packages into ima_ad_ios
bparrishMines Aug 19, 2025
711064b
start of implementation
bparrishMines Aug 19, 2025
88541d8
platform implementations
bparrishMines Sep 7, 2025
3f2bc4a
Merge branch 'main' of github.com:flutter/packages into ima_ad_event_ad
bparrishMines Sep 7, 2025
5839848
app facing interface implementation
bparrishMines Sep 7, 2025
457ffe5
fix tests
bparrishMines Sep 7, 2025
701e8e7
version bump
bparrishMines Sep 7, 2025
6bff03f
make resource value nullable
bparrishMines Sep 7, 2025
7f30199
analyze error
bparrishMines Sep 9, 2025
634dbf5
Merge branch 'main' of github.com:flutter/packages into ima_ad_event_ad
bparrishMines Sep 9, 2025
575eebd
update docs and add null checks
bparrishMines Sep 11, 2025
8567b5a
add test for android ads
bparrishMines Sep 12, 2025
ccc3ad1
tests for ios
bparrishMines Sep 12, 2025
4e93744
actually add ios tests
bparrishMines Sep 12, 2025
bc89942
include ad for test
bparrishMines Sep 12, 2025
f2bccf7
Merge branch 'main' of github.com:flutter/packages into ima_ad_event_ad
bparrishMines Sep 12, 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.6+8

* Adds support for accessing data for an ad. See `AdEvent.ad`.

## 0.2.6+7

* Updates Android `PlatformAdDisplayContainer` implementation to support preloading ads.
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.6+7"
const val pluginVersion = "0.2.6+8"
}

override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5860,7 +5860,7 @@ abstract class PigeonApiCompanionAd(
/** The URL for the static resource of this companion. */
abstract fun resourceValue(
pigeon_instance: com.google.ads.interactivemedia.v3.api.CompanionAd
): String
): String?

/**
* The width of the companion in pixels.
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.6+7"
static let pluginVersion = "0.2.6+8"

func pigeonDefaultConstructor(
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export 'src/ad.dart';
export 'src/ad_display_container.dart';
export 'src/ads_loader.dart';
export 'src/ads_manager_delegate.dart';
Expand All @@ -19,7 +20,6 @@ export 'src/platform_interface/platform_interface.dart'
AdErrorCode,
AdErrorEvent,
AdErrorType,
AdEvent,
AdEventType,
AdUIElement,
AdsLoadErrorData,
Expand Down
199 changes: 199 additions & 0 deletions packages/interactive_media_ads/lib/src/ad.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// 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 'platform_interface/platform_interface.dart';

/// Data object representing a single ad.
class Ad {
/// Constructs an [Ad] from a specific platform implementation.
Ad.fromPlatform(this.platform);

/// Implementation of [PlatformAd] for the current platform.
final PlatformAd platform;

/// The ad ID as specified in the VAST response.
String get adId => platform.adId;

/// The pod metadata object.
AdPodInfo get adPodInfo => AdPodInfo.fromPlatform(platform.adPodInfo);

/// The ad system as specified in the VAST response.
String get adSystem => platform.adSystem;

/// The IDs of the ads' creatives, starting with the first wrapper ad.
List<String> get wrapperCreativeIds => platform.wrapperCreativeIds;

/// The wrapper ad IDs as specified in the VAST response.
List<String> get wrapperIds => platform.wrapperIds;

/// The wrapper ad systems as specified in the VAST response.
List<String> get wrapperSystems => platform.wrapperSystems;

/// The advertiser name as defined by the serving party.
String get advertiserName => platform.advertiserName;

/// The companions for the current ad while using DAI.
///
/// Returns an empty list in any other scenario.
List<CompanionAd> get companionAds => List<CompanionAd>.unmodifiable(
platform.companionAds.map(CompanionAd.fromPlatform),
);

/// The content type of the currently selected creative, or null if no
/// creative is selected or the content type is unavailable.
String? get contentType => platform.contentType;

/// The ISCI (Industry Standard Commercial Identifier) code for an ad.
String get creativeAdId => platform.creativeAdId;

/// The ID of the selected creative for the ad,
String get creativeId => platform.creativeId;

/// The first deal ID present in the wrapper chain for the current ad,
/// starting from the top.
String get dealId => platform.dealId;

/// The description of this ad from the VAST response.
String? get description => platform.description;

/// The duration of the ad.
Duration? get duration => platform.duration;

/// The height of the selected creative if non-linear, else returns 0.
int get height => platform.height;

/// The playback time before the ad becomes skippable.
///
/// The value is null for non-skippable ads, or if the value is unavailable.
Duration? get skipTimeOffset => platform.skipTimeOffset;

/// The URL associated with the survey for the given ad.
String? get surveyUrl => platform.surveyUrl;

/// The title of this ad from the VAST response.
String? get title => platform.title;

/// The custom parameters associated with the ad at the time of ad
/// trafficking.
String get traffickingParameters => platform.traffickingParameters;

/// The set of ad UI elements rendered by the IMA SDK for this ad.
Set<AdUIElement> get uiElements => platform.uiElements;

/// The list of all universal ad IDs for this ad.
List<UniversalAdId> get universalAdIds => List<UniversalAdId>.unmodifiable(
platform.universalAdIds.map(UniversalAdId.fromPlatform),
);

/// The VAST bitrate in Kbps of the selected creative.
int get vastMediaBitrate => platform.vastMediaBitrate;

/// The VAST media height in pixels of the selected creative.
int get vastMediaHeight => platform.vastMediaHeight;

/// The VAST media width in pixels of the selected creative.
int get vastMediaWidth => platform.vastMediaWidth;

/// The width of the selected creative if non-linear, else returns 0.
int get width => platform.width;

/// Indicates whether the ad’s current mode of operation is linear or
/// non-linear.
bool get isLinear => platform.isLinear;

/// Indicates whether the ad can be skipped by the user.
bool get isSkippable => platform.isSkippable;
}

/// Simple data object containing podding metadata.
class AdPodInfo {
/// Constructs an [AdPodInfo] from a specific platform implementation.
AdPodInfo.fromPlatform(this.platform);

/// Implementation of [PlatformAdPodInfo] for the current platform.
final PlatformAdPodInfo platform;

/// The position of the ad within the pod.
///
/// The value returned is one-based, for example, 1 of 2, 2 of 2, etc. If the
/// ad is not part of a pod, this will return 1.
int get adPosition => platform.adPosition;

/// The maximum duration of the pod.
///
/// For unknown duration, null.
Duration? get maxDuration => platform.maxDuration;

/// Returns the index of the ad pod.
///
/// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…,
/// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of
/// a pod, or this pod is not part of a playlist.
///
/// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0.
/// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X.
/// Defaults to 0 if this ad is not part of a pod, or this pod is not part of
/// a playlist.
///
/// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the
/// break ID. Returns -2 if pod index cannot be determined (internal error).
int get podIndex => platform.podIndex;

/// The content time offset at which the current ad pod was scheduled.
///
/// For preroll pod, 0 is returned. For midrolls, the scheduled time is
/// returned. For postroll, -1 is returned. Defaults to 0 if this ad is not
/// part of a pod, or the pod is not part of an ad playlist.
Duration get timeOffset => platform.timeOffset;

/// Total number of ads in the pod this ad belongs to, including bumpers.
///
/// Will be 1 for standalone ads.
int get totalAds => platform.totalAds;

/// Specifies whether the ad is a bumper.
///
/// Bumpers are short videos used to open and close ad breaks.
bool get isBumper => platform.isBumper;
}

/// An object that holds data corresponding to the companion Ad.
class CompanionAd {
/// Constructs a [CompanionAd] from a specific platform implementation.
CompanionAd.fromPlatform(this.platform);

/// Implementation of [PlatformCompanionAd] for the current platform.
final PlatformCompanionAd platform;

/// The API needed to execute this ad, or null if unavailable.
String? get apiFramework => platform.apiFramework;

/// The height of the companion in pixels.
int? get height => platform.height;

/// The URL for the static resource of this companion.
String? get resourceValue => platform.resourceValue;

/// The width of the companion in pixels.
int? get width => platform.width;
}

/// Simple data object containing universal ad ID information.
class UniversalAdId {
/// Constructs an [UniversalAdId] from a specific platform implementation.
UniversalAdId.fromPlatform(this.platform);

/// Implementation of [PlatformUniversalAdId] for the current platform.
final PlatformUniversalAdId platform;

/// The universal ad ID value.
///
/// This will be null if it isn’t defined by the ad.
String? get adIDValue => platform.adIDValue;

/// The universal ad ID registry with which the value is registered.
///
/// This will be null if it isn’t defined by the ad.
String? get adIDRegistry => platform.adIDRegistry;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'ad.dart';
import 'platform_interface/platform_interface.dart';

/// Delegate for ad events or errors that occur during ad or stream
Expand Down Expand Up @@ -37,7 +38,9 @@ class AdsManagerDelegate {
void Function(AdErrorEvent event)? onAdErrorEvent,
}) : this.fromPlatformCreationParams(
PlatformAdsManagerDelegateCreationParams(
onAdEvent: onAdEvent,
onAdEvent:
(PlatformAdEvent event) =>
onAdEvent?.call(AdEvent._fromPlatform(event)),
onAdErrorEvent: onAdErrorEvent,
),
);
Expand Down Expand Up @@ -80,10 +83,28 @@ class AdsManagerDelegate {
final PlatformAdsManagerDelegate platform;

/// Invoked when there is an [AdEvent].
void Function(AdEvent event)? get onAdEvent => platform.params.onAdEvent;
void Function(AdEvent event)? get onAdEvent =>
(AdEvent event) => platform.params.onAdEvent?.call(event.platform);

/// Invoked when there was an error playing the ad. Log the error and resume
/// playing content.
void Function(AdErrorEvent event)? get onAdErrorEvent =>
platform.params.onAdErrorEvent;
}

/// Simple data class used to transport ad playback information.
class AdEvent {
AdEvent._fromPlatform(this.platform);

/// Implementation of [PlatformAdEvent] for the current platform.
final PlatformAdEvent platform;

/// The type of event that occurred.
AdEventType get type => platform.type;

/// The ad with which this event is associated.
Ad? get ad => platform.ad != null ? Ad.fromPlatform(platform.ad!) : null;

/// A map containing any extra ad data for the event, if needed.
Map<String, String> get adData => platform.adData;
}
Loading