Skip to content

Commit

Permalink
[interactive_media_ads] Fixes bug where ad can replay during content …
Browse files Browse the repository at this point in the history
…playback (#7537)

As stated in the [VideoView](https://developer.android.com/reference/android/widget/VideoView): _"VideoView does not retain its full state when going into the background."_

This also seems to include the `onComplete` state. So even after the `onComplete` callback was triggered, the `onPrepared` callback would trigger if the the app is sent to the background and then the foreground.

This is fixed by setting the video URI to `null` once the ad is signaled to stop by the IMA SDK.

I also considered setting the value to `null` in the `onComplete/onError` callbacks, but I assume these callbacks will always trigger the `stopAd` callback from the SDK (this seems to be true when I tested it). Making the calls redundant.
  • Loading branch information
bparrishMines authored Aug 30, 2024
1 parent c9c0004 commit 1f9b89b
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 62 deletions.
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.1.2+6

* Fixes bug where the ad would play when the app returned to foreground during content playback.

## 0.1.2+5

* Adds internal wrapper for remaining methods of the Android native `AdsManager`.
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.1.2+5"
const val pluginVersion = "0.1.2+6"
}

override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class VideoViewProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) :
return instance
}

override fun setVideoUri(pigeon_instance: VideoView, uri: String) {
pigeon_instance.setVideoURI(Uri.parse(uri))
override fun setVideoUri(pigeon_instance: VideoView, uri: String?) {
pigeon_instance.setVideoURI(if (uri != null) Uri.parse(uri) else null)
}

override fun getCurrentPosition(pigeon_instance: VideoView): Long {
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.1.2+5"
static let pluginVersion = "0.1.2+6"

func pigeonDefaultConstructor(
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ base class AndroidAdDisplayContainer extends PlatformAdDisplayContainer {
final AndroidAdDisplayContainer? container = weakThis.target;
if (container != null) {
container._stopAdProgressTracking();
container._videoView.setVideoUri(null);
container._clearMediaPlayer();
container._loadedAdMediaInfo = null;
container._adDuration = null;
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 (v21.3.0), do not edit directly.
// Autogenerated from Pigeon (v22.1.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers

Expand Down Expand Up @@ -334,8 +334,7 @@ class _PigeonInternalInstanceManagerApi {

final BinaryMessenger? pigeonVar_binaryMessenger;

static const MessageCodec<Object?> pigeonChannelCodec =
StandardMessageCodec();
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

static void setUpMessageHandlers({
bool pigeon_clearHandlers = false,
Expand Down Expand Up @@ -644,7 +643,10 @@ class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is AdErrorCode) {
if (value is int) {
buffer.putUint8(4);
buffer.putInt64(value);
} else if (value is AdErrorCode) {
buffer.putUint8(129);
writeValue(buffer, value.index);
} else if (value is AdErrorType) {
Expand Down Expand Up @@ -3181,7 +3183,7 @@ class VideoView extends View {
}

/// Sets the URI of the video.
Future<void> setVideoUri(String uri) async {
Future<void> setVideoUri(String? uri) async {
final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
_pigeonVar_codecVideoView;
final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ abstract class VideoView extends View {
late final void Function(MediaPlayer player, int what, int extra) onError;
/// Sets the URI of the video.
void setVideoUri(String uri);
void setVideoUri(String? uri);
/// The current position of the playing video.
///
Expand Down
2 changes: 1 addition & 1 deletion packages/interactive_media_ads/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: interactive_media_ads
description: A Flutter plugin for using the Interactive Media Ads SDKs on Android and iOS.
repository: https://github.com/flutter/packages/tree/main/packages/interactive_media_ads
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+interactive_media_ads%22
version: 0.1.2+5 # This must match the version in
version: 0.1.2+6 # This must match the version in
# `android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt` and
# `ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,5 +514,50 @@ void main() {

verify(mockVideoView.setVideoUri(videoUrl));
});

test('stop ad sets video uri to null', () async {
late final void Function(
ima.VideoAdPlayer,
ima.AdMediaInfo,
) stopAdCallback;

final MockVideoView mockVideoView = MockVideoView();
final InteractiveMediaAdsProxy imaProxy = InteractiveMediaAdsProxy(
newFrameLayout: () => MockFrameLayout(),
newVideoView: ({
dynamic onError,
dynamic onPrepared,
dynamic onCompletion,
}) {
return mockVideoView;
},
createAdDisplayContainerImaSdkFactory: (_, __) async {
return MockAdDisplayContainer();
},
newVideoAdPlayer: ({
required dynamic addCallback,
required dynamic loadAd,
required dynamic pauseAd,
required dynamic playAd,
required dynamic release,
required dynamic removeCallback,
required void Function(ima.VideoAdPlayer, ima.AdMediaInfo) stopAd,
}) {
stopAdCallback = stopAd;
return MockVideoAdPlayer();
},
);

AndroidAdDisplayContainer(
AndroidAdDisplayContainerCreationParams(
onContainerAdded: (_) {},
imaProxy: imaProxy,
),
);

stopAdCallback(MockVideoAdPlayer(), MockAdMediaInfo());

verify(mockVideoView.setVideoUri(null));
});
});
}

0 comments on commit 1f9b89b

Please sign in to comment.