diff --git a/CHANGELOG.md b/CHANGELOG.md index 4132107..0fe67bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Potential integration error shown in Touchstone if the player emits a warning outside of an active Conviva session + +### Changed +- Updated Bitmovin Player to `3.81.0` ## 2.6.0 - 2024-08-28 ### Added diff --git a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/WarningTests.kt b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/WarningTests.kt new file mode 100644 index 0000000..47cbb69 --- /dev/null +++ b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/WarningTests.kt @@ -0,0 +1,84 @@ +package com.bitmovin.analytics.conviva.testapp + +import android.os.Handler +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.bitmovin.analytics.conviva.ConvivaAnalyticsIntegration +import com.bitmovin.analytics.conviva.ConvivaConfig +import com.bitmovin.analytics.conviva.MetadataOverrides +import com.bitmovin.analytics.conviva.testapp.framework.BITMOVIN_PLAYER_LICENSE_KEY +import com.bitmovin.analytics.conviva.testapp.framework.CONVIVA_CUSTOMER_KEY +import com.bitmovin.analytics.conviva.testapp.framework.CONVIVA_GATEWAY_URL +import com.bitmovin.analytics.conviva.testapp.framework.Sources +import com.bitmovin.analytics.conviva.testapp.framework.callAndExpectEvent +import com.bitmovin.analytics.conviva.testapp.framework.expectEvent +import com.bitmovin.analytics.conviva.testapp.framework.postWaiting +import com.bitmovin.player.api.PlaybackConfig +import com.bitmovin.player.api.Player +import com.bitmovin.player.api.PlayerConfig +import com.bitmovin.player.api.analytics.AnalyticsPlayerConfig +import com.bitmovin.player.api.event.PlayerEvent +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith + +/** + * This test class does not verify any specific behavior, but rather can be used to validate the + * integration against the [Conviva Touchstone integration test tool](https://touchstone.conviva.com/). + */ +@RunWith(AndroidJUnit4::class) +class WarningTests { + /** + * Triggers a warning outside of the active conviva session. No integration error must be + * shown in Touchstone. + */ + @Test + fun warning_outside_of_active_conviva_session_does_not_cause_integration_error() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + val mainHandler = Handler(context.mainLooper) + val player = mainHandler.postWaiting { + Player( + context, + PlayerConfig( + key = BITMOVIN_PLAYER_LICENSE_KEY, + playbackConfig = PlaybackConfig( + isAutoplayEnabled = true, + ), + ), + analyticsConfig = AnalyticsPlayerConfig.Disabled, + ) + } + mainHandler.postWaiting { + val conviva = ConvivaAnalyticsIntegration( + player, + CONVIVA_CUSTOMER_KEY, + context, + ConvivaConfig().apply { + isDebugLoggingEnabled = true + gatewayUrl = CONVIVA_GATEWAY_URL + }, + ) + conviva.updateContentMetadata( + MetadataOverrides().apply { + applicationName = "Bitmovin Android Conviva integration test app" + viewerId = "testViewerId" + assetName = "warning_outside_of_active_conviva_session_does_not_cause_integration_error" + } + ) + } + + mainHandler.postWaiting { + player.load(Sources.Dash.basic) + } + player.expectEvent { it.time > 10.0 } + mainHandler.postWaiting { + player.unload() // Unloading the player ends the active conviva session + } + runBlocking { delay(500) } // Give conviva some time to end the session + player.callAndExpectEvent(block = { + player.play() // Calling "play" outside of an active playback session triggers a warning + }) + runBlocking { delay(500) } // Give Conviva some time to report the event + } +} diff --git a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/framework/TestingFramework.kt b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/framework/TestingFramework.kt index c27a51f..feffb62 100644 --- a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/framework/TestingFramework.kt +++ b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/framework/TestingFramework.kt @@ -5,6 +5,7 @@ import com.bitmovin.player.api.Player import com.bitmovin.player.api.event.Event import com.bitmovin.player.api.event.EventEmitter import com.bitmovin.player.api.event.on +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -33,6 +34,26 @@ inline fun EventEmitter.expectEvent( } } +/** + * Same as [expectEvent] except that [block] is executed once the event listener is attached. + */ +inline fun EventEmitter.callAndExpectEvent( + crossinline block: suspend () -> Unit = {}, + crossinline condition: (T) -> Boolean = { true } +) = runBlocking { + launch { block() } + suspendCoroutine { continuation -> + lateinit var action: ((T) -> Unit) + action = { + if (condition(it)) { + off(action) + continuation.resume(Unit) + } + } + on(action) + } +} + /** * Posts a [block] of code to the main thread and suspends until it is executed. */ diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java index 9f55687..c72c81c 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -588,6 +588,10 @@ private void handleError(String message) { private final EventListener onPlayerWarningListener = new EventListener() { @Override public void onEvent(PlayerEvent.Warning warningEvent) { + if (!isSessionActive) { + Log.d(TAG, "[Player Event] Warning outside of active conviva session. Ignoring."); + return; + } Log.d(TAG, "[Player Event] Warning"); String message = String.format("%s - %s", warningEvent.getCode(), warningEvent.getMessage()); convivaVideoAnalytics.reportPlaybackError(message, ConvivaSdkConstants.ErrorSeverity.WARNING); @@ -597,6 +601,10 @@ public void onEvent(PlayerEvent.Warning warningEvent) { private final EventListener onSourceWarningListener = new EventListener() { @Override public void onEvent(SourceEvent.Warning warningEvent) { + if (!isSessionActive) { + Log.d(TAG, "[Source Event] Warning outside of active conviva session. Ignoring."); + return; + } Log.d(TAG, "[Source Event] Warning"); String message = String.format("%s - %s", warningEvent.getCode(), warningEvent.getMessage()); convivaVideoAnalytics.reportPlaybackError(message, ConvivaSdkConstants.ErrorSeverity.WARNING); diff --git a/dependencies.gradle b/dependencies.gradle index 14e1308..b2371e3 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,5 +1,5 @@ ext { - bitmovinPlayerVersion = '3.78.2' + bitmovinPlayerVersion = '3.81.0' googleImaSdk = '3.31.0' googlePlayAdsIdentifier = '18.0.1'