From c027e3f545adf6ba43a3aea902be5cc516c49aaa Mon Sep 17 00:00:00 2001 From: Vehovec Date: Tue, 21 May 2024 15:53:40 +0200 Subject: [PATCH 01/30] Update to the latest gradle and AGP versions --- ConvivaExampleApp/build.gradle | 3 ++- ConvivaTestApp/build.gradle | 2 +- build.gradle | 4 ++-- conviva/build.gradle | 5 ++++- gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ConvivaExampleApp/build.gradle b/ConvivaExampleApp/build.gradle index 4fb65eb..340ec77 100644 --- a/ConvivaExampleApp/build.gradle +++ b/ConvivaExampleApp/build.gradle @@ -1,7 +1,8 @@ apply plugin: 'com.android.application' android { - compileSdkVersion rootProject.compileSdkVersion + compileSdk rootProject.compileSdkVersion + defaultConfig { applicationId "com.bitmovin.analytics.convivaanalyticsexample" minSdkVersion rootProject.minSdkVersion diff --git a/ConvivaTestApp/build.gradle b/ConvivaTestApp/build.gradle index 6de412a..11e49d3 100644 --- a/ConvivaTestApp/build.gradle +++ b/ConvivaTestApp/build.gradle @@ -4,7 +4,7 @@ plugins { } android { - compileSdkVersion rootProject.compileSdkVersion + compileSdk rootProject.compileSdkVersion buildToolsVersion "30.0.3" defaultConfig { diff --git a/build.gradle b/build.gradle index 9933c45..a31780f 100644 --- a/build.gradle +++ b/build.gradle @@ -8,8 +8,8 @@ buildscript { } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.android.tools.build:gradle:7.4.2' - classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.24.2" + classpath 'com.android.tools.build:gradle:8.2.2' + classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.33.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/conviva/build.gradle b/conviva/build.gradle index 276a10b..c7b7ec6 100644 --- a/conviva/build.gradle +++ b/conviva/build.gradle @@ -7,7 +7,7 @@ def packageName = 'com.bitmovin.analytics' def libraryVersion = '2.2.0' android { - compileSdkVersion rootProject.compileSdkVersion + compileSdk rootProject.compileSdkVersion defaultConfig { minSdkVersion rootProject.minSdkVersion @@ -27,6 +27,9 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + buildFeatures { + buildConfig true + } namespace 'com.bitmovin.analytics.conviva' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 83ce604..7f8f151 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Oct 12 15:36:49 CEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 3e4652fc148022c3b4d2b9d545effb6b8ef1545a Mon Sep 17 00:00:00 2001 From: Vehovec Date: Tue, 21 May 2024 16:17:57 +0200 Subject: [PATCH 02/30] Update dependencies --- ConvivaTestApp/build.gradle | 3 +-- build.gradle | 6 +++--- dependencies.gradle | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ConvivaTestApp/build.gradle b/ConvivaTestApp/build.gradle index 11e49d3..37c44a9 100644 --- a/ConvivaTestApp/build.gradle +++ b/ConvivaTestApp/build.gradle @@ -5,7 +5,6 @@ plugins { android { compileSdk rootProject.compileSdkVersion - buildToolsVersion "30.0.3" defaultConfig { applicationId "com.bitmovin.analytics.conviva.testapp" @@ -38,7 +37,7 @@ android { } dependencies { - implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.appcompat:appcompat:1.6.1' implementation bitmovinPlayerDependencies.bitmovinPlayer implementation "com.google.ads.interactivemedia.v3:interactivemedia:$googleImaSdk" // only needed if ads are used: diff --git a/build.gradle b/build.gradle index a31780f..5ff8826 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.7.0" + ext.kotlin_version = "1.9.23" repositories { mavenCentral() google() @@ -18,8 +18,8 @@ buildscript { ext { minSdkVersion = 16 - targetSdkVersion = 33 - compileSdkVersion = 33 + targetSdkVersion = 34 + compileSdkVersion = 34 } // Load dependencies diff --git a/dependencies.gradle b/dependencies.gradle index 15051ac..f557806 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,6 +1,6 @@ ext { - bitmovinPlayerVersion = '3.39.0' - googleImaSdk = '3.29.0' + bitmovinPlayerVersion = '3.69.0' + googleImaSdk = '3.31.0' googlePlayAdsIdentifier = '18.0.1' bitmovinPlayerDependencies = [ @@ -14,4 +14,4 @@ ext { androidx_espresso_core: 'androidx.test.espresso:espresso-core:3.5.1', mockk: 'io.mockk:mockk-android:1.12.0' ] -} \ No newline at end of file +} From acc0a51d0df9eb5165e98673de43e2676d80eec5 Mon Sep 17 00:00:00 2001 From: Vehovec Date: Tue, 21 May 2024 16:18:35 +0200 Subject: [PATCH 03/30] Update dependencies + use the new publishing functions --- conviva/build.gradle | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/conviva/build.gradle b/conviva/build.gradle index c7b7ec6..a1c8812 100644 --- a/conviva/build.gradle +++ b/conviva/build.gradle @@ -7,6 +7,7 @@ def packageName = 'com.bitmovin.analytics' def libraryVersion = '2.2.0' android { + namespace 'com.bitmovin.analytics.conviva' compileSdk rootProject.compileSdkVersion defaultConfig { @@ -30,29 +31,34 @@ android { buildFeatures { buildConfig true } - namespace 'com.bitmovin.analytics.conviva' + publishing { + singleVariant("release") { + withSourcesJar() + } + } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.appcompat:appcompat:1.6.1' testImplementation testingDependencies.junit androidTestImplementation testingDependencies.androidx_junit androidTestImplementation testingDependencies.androidx_espresso_core - api 'com.conviva.sdk:conviva-core-sdk:4.0.35' + api 'com.conviva.sdk:conviva-core-sdk:4.0.37' implementation bitmovinPlayerDependencies.bitmovinPlayer - implementation 'org.apache.commons:commons-text:1.7' + implementation 'org.apache.commons:commons-text:1.10.0' } publishing { publications { - aar(MavenPublication) { + release(MavenPublication) { groupId packageName version = libraryVersion artifactId project.getName() - // Tell maven to prepare the generated "*.aar" file for publishing - artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") + afterEvaluate { + from components.release + } pom.withXml { def dependenciesNode = asNode().appendNode('dependencies') From d9eddfbd38f8cd853bc1c5db8182d07bd1fe8b32 Mon Sep 17 00:00:00 2001 From: Vehovec Date: Tue, 21 May 2024 16:59:04 +0200 Subject: [PATCH 04/30] Fix publishing --- conviva/build.gradle | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/conviva/build.gradle b/conviva/build.gradle index a1c8812..4870d20 100644 --- a/conviva/build.gradle +++ b/conviva/build.gradle @@ -59,22 +59,6 @@ publishing { afterEvaluate { from components.release } - - pom.withXml { - def dependenciesNode = asNode().appendNode('dependencies') - - //Defining configuration names from which dependencies will be taken (debugCompile or releaseCompile and compile) - def configurationNames = ['api'] - - configurationNames.each { configurationName -> - configurations[configurationName].allDependencies.each { - def dependencyNode = dependenciesNode.appendNode('dependency') - dependencyNode.appendNode('groupId', it.group) - dependencyNode.appendNode('artifactId', it.name) - dependencyNode.appendNode('version', it.version) - } - } - } } } } @@ -90,7 +74,7 @@ artifactory { } defaults { // Tell the Artifactory Plugin which artifacts should be published to Artifactory. - publications('aar') + publications('release') publishArtifacts = true // Properties to be attached to the published artifacts. From a4c667a3c7fdde0d73188dbe3feb5a525f54727a Mon Sep 17 00:00:00 2001 From: Vehovec Date: Wed, 22 May 2024 17:03:21 +0200 Subject: [PATCH 05/30] Fix source.getConfig cannot be null --- .../analytics/conviva/BitmovinPlayerHelper.java | 7 +++++-- .../conviva/ConvivaAnalyticsIntegration.java | 12 ++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java index 9dd8c4e..494113a 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java @@ -1,5 +1,6 @@ package com.bitmovin.analytics.conviva; +import androidx.annotation.Nullable; import com.bitmovin.player.api.Player; class BitmovinPlayerHelper { @@ -13,16 +14,18 @@ String getSdkVersionString() { return Player.getSdkVersion(); } + @Nullable String getStreamType() { - if (player.getSource() == null || player.getSource().getConfig() == null) { + if (player.getSource() == null) { return null; } else { return player.getSource().getConfig().getType().name(); } } + @Nullable String getStreamUrl() { - if (player.getSource() == null || player.getSource().getConfig() == null) { + if (player.getSource() == null) { return null; } else { return player.getSource().getConfig().getUrl(); 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 037b044..ff4e364 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -114,9 +114,7 @@ public void sendCustomPlaybackEvent(String name, Map attributes) * If no source was loaded this method will throw an error. */ public void initializeSession() throws ConvivaAnalyticsException { - if ((bitmovinPlayer.getSource() == null || - bitmovinPlayer.getSource().getConfig() == null - || bitmovinPlayer.getSource().getConfig().getTitle() == null) + if ((bitmovinPlayer.getSource() == null || bitmovinPlayer.getSource().getConfig().getTitle() == null) && this.contentMetadataBuilder.getAssetName() == null) { throw new ConvivaAnalyticsException( "AssetName is missing. Load player source (with Title) first or set assetName via updateContentMetadata" @@ -300,13 +298,7 @@ private void createContentMetadata() { SourceConfig sourceConfig = source.getConfig(); String overriddenAssetName = metadataOverrides != null ? metadataOverrides.getAssetName() : null; - if (sourceConfig != null) { - contentMetadataBuilder.setAssetName(overriddenAssetName != null ? overriddenAssetName : sourceConfig.getTitle()); - } else { - if(overriddenAssetName != null) { - contentMetadataBuilder.setAssetName(overriddenAssetName); - } - } + contentMetadataBuilder.setAssetName(overriddenAssetName != null ? overriddenAssetName : sourceConfig.getTitle()); } this.buildDynamicContentMetadata(); } From 1ca2350f01f288b8698d5c0cc87d1b6f4687e078 Mon Sep 17 00:00:00 2001 From: Vehovec Date: Wed, 22 May 2024 17:37:00 +0200 Subject: [PATCH 06/30] Add changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a9ff38..bb56053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- Updated Bitmovin Player to `3.69.0` +- Updated IMA SDK to `3.31.0` +- Updated Kotlin to `1.9.23` +- Updated conviva-core to `4.0.37` +- Updated Gradle wrapper to `8.2` and AGP to `8.2.2` +- Updated compile and target SDK version to `34` ## 2.3.0 - 2024-05-21 ### Added From af789ba8256684d325e741230006910689aae02f Mon Sep 17 00:00:00 2001 From: Vehovec Date: Thu, 23 May 2024 11:21:08 +0200 Subject: [PATCH 07/30] Remove unused libraries and fix the generated POM file --- conviva/build.gradle | 8 +++----- .../bitmovin/analytics/conviva/BitmovinPlayerHelper.java | 3 --- .../analytics/conviva/ContentMetadataBuilder.java | 2 -- .../java/com/bitmovin/analytics/conviva/ObjectUtils.java | 7 +++++++ 4 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 conviva/src/main/java/com/bitmovin/analytics/conviva/ObjectUtils.java diff --git a/conviva/build.gradle b/conviva/build.gradle index 9b351c1..039a540 100644 --- a/conviva/build.gradle +++ b/conviva/build.gradle @@ -39,14 +39,12 @@ android { } dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'androidx.appcompat:appcompat:1.6.1' + api 'com.conviva.sdk:conviva-core-sdk:4.0.37' + implementation bitmovinPlayerDependencies.bitmovinPlayer + testImplementation testingDependencies.junit androidTestImplementation testingDependencies.androidx_junit androidTestImplementation testingDependencies.androidx_espresso_core - api 'com.conviva.sdk:conviva-core-sdk:4.0.37' - implementation bitmovinPlayerDependencies.bitmovinPlayer - implementation 'org.apache.commons:commons-text:1.10.0' } publishing { diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java index 494113a..78ead59 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java @@ -1,6 +1,5 @@ package com.bitmovin.analytics.conviva; -import androidx.annotation.Nullable; import com.bitmovin.player.api.Player; class BitmovinPlayerHelper { @@ -14,7 +13,6 @@ String getSdkVersionString() { return Player.getSdkVersion(); } - @Nullable String getStreamType() { if (player.getSource() == null) { return null; @@ -23,7 +21,6 @@ String getStreamType() { } } - @Nullable String getStreamUrl() { if (player.getSource() == null) { return null; diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java index e4d4b6c..513a0c4 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java @@ -2,8 +2,6 @@ import android.util.Log; import com.conviva.sdk.ConvivaSdkConstants; -import org.apache.commons.lang3.ObjectUtils; - import java.util.HashMap; import java.util.Map; diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ObjectUtils.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ObjectUtils.java new file mode 100644 index 0000000..4bebd47 --- /dev/null +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ObjectUtils.java @@ -0,0 +1,7 @@ +package com.bitmovin.analytics.conviva; + +/*package*/ class ObjectUtils { + public static T defaultIfNull(T object, T defaultValue) { + return object != null ? object : defaultValue; + } +} From 62ea57584ef713bcca630724935842da252855b7 Mon Sep 17 00:00:00 2001 From: Vehovec Date: Thu, 23 May 2024 11:34:47 +0200 Subject: [PATCH 08/30] Add pom file changelog entry --- CHANGELOG.md | 3 +++ README.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb56053..4936c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Updated Gradle wrapper to `8.2` and AGP to `8.2.2` - Updated compile and target SDK version to `34` +### Fixed +- The pom file now also includes the `com.bitmovin.player` dependency which was missing before + ## 2.3.0 - 2024-05-21 ### Added - New `TimeChanged` callback for reporting Playhead to conviva playback metric. Calculates Live and Vod playback for report. diff --git a/README.md b/README.md index fdd4f4e..82f8409 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ allprojects { And these lines to your main project ``` dependencies { - implementation 'com.conviva.sdk:conviva-core-sdk:4.0.35' // <-- conviva sdk + implementation 'com.conviva.sdk:conviva-core-sdk:4.0.37' // <-- conviva sdk implementation 'com.bitmovin.analytics:conviva:2.3.0' } ``` From 76d337d24598a84a4ad48cf63c5a8784e1c10c7d Mon Sep 17 00:00:00 2001 From: Vehovec Date: Thu, 23 May 2024 14:00:31 +0200 Subject: [PATCH 09/30] Improve changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4936c43..68522eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Updated Kotlin to `1.9.23` - Updated conviva-core to `4.0.37` - Updated Gradle wrapper to `8.2` and AGP to `8.2.2` -- Updated compile and target SDK version to `34` +- Increased minimum required `compileSdk` version to `34` +- Increased `compileSdk` and `targetSdkVersion` to `34` ### Fixed - The pom file now also includes the `com.bitmovin.player` dependency which was missing before From 3474c884ab485c0ec4afae759ba743ba013836c6 Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 13:20:13 +0200 Subject: [PATCH 10/30] Resolve lint warnings --- .../analytics/conviva/testapp/TestBase.kt | 103 +++++--- .../conviva/BitmovinPlayerHelper.java | 2 +- .../conviva/ContentMetadataBuilder.java | 9 +- .../conviva/ConvivaAnalyticsIntegration.java | 237 +++++++----------- 4 files changed, 162 insertions(+), 189 deletions(-) diff --git a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/TestBase.kt b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/TestBase.kt index d426cb6..3ff04c8 100644 --- a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/TestBase.kt +++ b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/TestBase.kt @@ -32,11 +32,22 @@ open class TestBase { ) as HashMap val CUSTOM_ERROR_MESSAGE = "CUSTOM_ERROR_MESSAGE" - val DEFAULT_DASH_VOD_SOURCE = Source.create(SourceConfig("https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd", SourceType.Dash)) + val DEFAULT_DASH_VOD_SOURCE = Source.create( + SourceConfig( + "https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd", + SourceType.Dash + ) + ) val DEFAULT_DASH_VOD_SOURCE_DURATION = 210 - val DEFAULT_DASH_LIVE_SOURCE = Source.create(SourceConfig("https://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd", SourceType.Dash)) + val DEFAULT_DASH_LIVE_SOURCE = Source.create( + SourceConfig( + "https://livesim.dashif.org/livesim/testpic_2s/Manifest.mpd", + SourceType.Dash + ) + ) val DEFAULT_DASH_LIVE_SOURCE_DURATION = 0 - val INVALID_DASH_VOD_SOURCE = Source.create(SourceConfig("https://bitmovin.com", SourceType.Dash)) + val INVALID_DASH_VOD_SOURCE = + Source.create(SourceConfig("https://bitmovin.com", SourceType.Dash)) val PLAYER_TYPE = "Bitmovin Player Android" val TIMEOUT = 4000 @@ -72,22 +83,25 @@ open class TestBase { mockConvivaAnalyticsObject() } - fun tearDownMocks () { + fun tearDownMocks() { videoAnalyticsMock?.let { unmockkObject(it) } } - fun createConvivaAnalyticsObject(activity: MainActivity) : ConvivaAnalyticsIntegration { + fun createConvivaAnalyticsObject(activity: MainActivity): ConvivaAnalyticsIntegration { // Setup mocks and create ConvivaAnalytics using mock objects ConvivaAnalytics.init(activity.applicationContext, "test") setupMocks(activity.applicationContext) - return spyk(ConvivaAnalyticsIntegration( + return spyk( + ConvivaAnalyticsIntegration( activity.bitmovinPlayer, "test", activity.applicationContext, - convivaConfig, videoAnalyticsMock)) + convivaConfig, videoAnalyticsMock + ) + ) } - fun defaultMetadataOverrides() : MetadataOverrides { + fun defaultMetadataOverrides(): MetadataOverrides { val metadata = MetadataOverrides() metadata.applicationName = "Bitmovin Android Conviva test app" metadata.viewerId = "awesomeViewerId" @@ -100,7 +114,7 @@ open class TestBase { streamType: ConvivaSdkConstants.StreamType? = null, duration: Int? = null, customTags: Map? = null - ) : MetadataOverrides { + ): MetadataOverrides { val metadata = MetadataOverrides() metadata.applicationName = "Bitmovin Android Conviva test app" metadata.viewerId = "awesomeViewerId" @@ -125,7 +139,7 @@ open class TestBase { duration: Int, overrideMetadata: MetadataOverrides, overrideCustom: Boolean = false - ) : MutableMap { + ): MutableMap { val contentInfo = mutableMapOf() contentInfo[ConvivaSdkConstants.PLAYER_NAME] = overrideMetadata.applicationName contentInfo[ConvivaSdkConstants.VIEWER_ID] = overrideMetadata.viewerId @@ -133,43 +147,50 @@ open class TestBase { contentInfo[ConvivaSdkConstants.ENCODED_FRAMERATE] = -1 contentInfo[ConvivaSdkConstants.IS_OFFLINE_PLAYBACK] = false if (overrideCustom) { - contentInfo[ConvivaSdkConstants.STREAM_URL] = overrideMetadata.streamUrl ?: source.config.url + contentInfo[ConvivaSdkConstants.STREAM_URL] = + overrideMetadata.streamUrl ?: source.config.url val streamTypeLocal = overrideMetadata.streamType ?: streamType - contentInfo[ConvivaSdkConstants.IS_LIVE] = streamTypeLocal == ConvivaSdkConstants.StreamType.LIVE; + contentInfo[ConvivaSdkConstants.IS_LIVE] = + streamTypeLocal == ConvivaSdkConstants.StreamType.LIVE; contentInfo[ConvivaSdkConstants.DURATION] = overrideMetadata.duration ?: duration overrideMetadata.custom.forEach { (s: String, s2: String) -> contentInfo[s] = s2 } - contentInfo["streamType"] = overrideMetadata.custom["streamType"] ?: source.config.type.toString() - contentInfo["integrationVersion"] = overrideMetadata.custom["integrationVersion"] ?: com.bitmovin.analytics.conviva.BuildConfig.VERSION_NAME + contentInfo["streamType"] = + overrideMetadata.custom["streamType"] ?: source.config.type.toString() + contentInfo["integrationVersion"] = overrideMetadata.custom["integrationVersion"] + ?: com.bitmovin.analytics.conviva.BuildConfig.VERSION_NAME } else { contentInfo[ConvivaSdkConstants.STREAM_URL] = source.config.url - contentInfo[ConvivaSdkConstants.IS_LIVE] = streamType == ConvivaSdkConstants.StreamType.LIVE + contentInfo[ConvivaSdkConstants.IS_LIVE] = + streamType == ConvivaSdkConstants.StreamType.LIVE contentInfo[ConvivaSdkConstants.DURATION] = duration contentInfo["streamType"] = source.config.type.toString() - contentInfo["integrationVersion"] = com.bitmovin.analytics.conviva.BuildConfig.VERSION_NAME + contentInfo["integrationVersion"] = + com.bitmovin.analytics.conviva.BuildConfig.VERSION_NAME } return contentInfo } // TODO: All references to ContentMetadata are obsolete and we should be using Map instead - fun MockKMatcherScope.metadataEq(expectedMetadata: MetadataOverrides) = match { - it.assetName == expectedMetadata.assetName && - it.applicationName == expectedMetadata.applicationName && - it.viewerId == expectedMetadata.viewerId && - it.streamType == expectedMetadata.streamType && - it.streamUrl == expectedMetadata.streamUrl && - it.duration == expectedMetadata.duration && - it.encodedFrameRate == expectedMetadata.encodedFrameRate && - it.custom.equals(expectedMetadata.custom) - } + fun MockKMatcherScope.metadataEq(expectedMetadata: MetadataOverrides) = + match { + it.assetName == expectedMetadata.assetName && + it.applicationName == expectedMetadata.applicationName && + it.viewerId == expectedMetadata.viewerId && + it.streamType == expectedMetadata.streamType && + it.streamUrl == expectedMetadata.streamUrl && + it.duration == expectedMetadata.duration && + it.encodedFrameRate == expectedMetadata.encodedFrameRate && + it.custom.equals(expectedMetadata.custom) + } fun setupPlayerActivityForTest( autoPlay: Boolean, metadataOverrides: MetadataOverrides, adTag: String = "" - ) : ActivityScenario { + ): ActivityScenario { val launchIntent = Intent( ApplicationProvider.getApplicationContext(), MainActivity::class.java @@ -207,13 +228,17 @@ open class TestBase { } // Implicit session tests do not actually initialize the session until play starts, in the new SDK - fun verifySessionInitialization(activityScenario: ActivityScenario, metadata: MetadataOverrides?, implicit: Boolean = false) { + fun verifySessionInitialization( + activityScenario: ActivityScenario, + metadata: MetadataOverrides?, + implicit: Boolean = false + ) { activityScenario.onActivity { _: MainActivity -> verifyOrder { - if(metadata != null) { + if (metadata != null) { convivaAnalyticsIntegration?.updateContentMetadata(metadata) } - if(!implicit) { + if (!implicit) { convivaAnalyticsIntegration?.initializeSession() if (metadata != null) { @@ -240,7 +265,10 @@ open class TestBase { fun verifyPlaying(activityScenario: ActivityScenario) { activityScenario.onActivity { activity: MainActivity -> verify { - videoAnalyticsMock?.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.PLAYING); + videoAnalyticsMock?.reportPlaybackMetric( + ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, + ConvivaSdkConstants.PlayerState.PLAYING + ); } } } @@ -268,18 +296,23 @@ open class TestBase { metadata.assetName = rawMetadata[ConvivaSdkConstants.ASSET_NAME] as String? metadata.applicationName = rawMetadata[ConvivaSdkConstants.PLAYER_NAME] as String? metadata.viewerId = rawMetadata[ConvivaSdkConstants.VIEWER_ID] as String? - metadata.streamType = if (rawMetadata[ConvivaSdkConstants.IS_LIVE] as Boolean) ConvivaSdkConstants.StreamType.LIVE else ConvivaSdkConstants.StreamType.VOD + metadata.streamType = + if (rawMetadata[ConvivaSdkConstants.IS_LIVE] as Boolean) ConvivaSdkConstants.StreamType.LIVE else ConvivaSdkConstants.StreamType.VOD metadata.streamUrl = rawMetadata[ConvivaSdkConstants.STREAM_URL] as String? metadata.duration = rawMetadata[ConvivaSdkConstants.DURATION] as Int? - metadata.encodedFrameRate = rawMetadata[ConvivaSdkConstants.ENCODED_FRAMERATE] as Int? + metadata.encodedFrameRate = + rawMetadata[ConvivaSdkConstants.ENCODED_FRAMERATE] as Int? - convivaAnalyticsIntegration?.updateContentMetadata(metadataEq ( metadata )) + convivaAnalyticsIntegration?.updateContentMetadata(metadataEq(metadata)) } verify(atLeast = 1) { - videoAnalyticsMock?.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.PLAYING); + videoAnalyticsMock?.reportPlaybackMetric( + ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, + ConvivaSdkConstants.PlayerState.PLAYING + ); } } } diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java index 78ead59..c1c4b6e 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java @@ -3,7 +3,7 @@ import com.bitmovin.player.api.Player; class BitmovinPlayerHelper { - private Player player; + private final Player player; BitmovinPlayerHelper(Player player) { this.player = player; diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java index 513a0c4..6b1b77a 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java @@ -17,7 +17,7 @@ class ContentMetadataBuilder { private boolean playbackStarted; ContentMetadataBuilder() { - contentInfo = new HashMap(); + contentInfo = new HashMap<>(); metadata = new MetadataOverrides(); metadataOverrides = new MetadataOverrides(); } @@ -25,7 +25,6 @@ class ContentMetadataBuilder { /** * This method is used for custom content metadata updates during / before a session. * - * @param metadataOverrides */ public void setOverrides(MetadataOverrides metadataOverrides) { if (playbackStarted) { @@ -62,7 +61,7 @@ public Map build() { Integer duration = ObjectUtils.defaultIfNull( metadataOverrides.getDuration(), metadata.getDuration()); - Integer convivaDuration = duration != null ? duration : -1; + int convivaDuration = duration != null ? duration : -1; if (convivaDuration > 0) { contentInfo.put(ConvivaSdkConstants.DURATION, convivaDuration); } @@ -121,7 +120,7 @@ public Map getCustom() { // merge internal and override metadata key-value pairs // with override values having higher precedence Map customInternals = metadata.getCustom(); - Map customs = customInternals != null ? customInternals : new HashMap(); + Map customs = customInternals != null ? customInternals : new HashMap<>(); Map customOverrides = metadataOverrides.getCustom(); if (customOverrides != null) { customs.putAll(customOverrides); @@ -165,6 +164,6 @@ public void reset() { metadataOverrides = new MetadataOverrides(); metadata = new MetadataOverrides(); playbackStarted = false; - contentInfo = new HashMap(); + contentInfo = new HashMap<>(); } } 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 ff4e364..acfca1e 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -23,14 +23,13 @@ public class ConvivaAnalyticsIntegration { private static final String TAG = "ConvivaAnalyticsInt"; - private Player bitmovinPlayer; - private ContentMetadataBuilder contentMetadataBuilder = new ContentMetadataBuilder(); - private ConvivaConfig config; - private ConvivaVideoAnalytics convivaVideoAnalytics; + private final Player bitmovinPlayer; + private final ContentMetadataBuilder contentMetadataBuilder = new ContentMetadataBuilder(); + private final ConvivaVideoAnalytics convivaVideoAnalytics; private MetadataOverrides metadataOverrides; // Wrapper to extract bitmovinPlayer helper methods - private BitmovinPlayerHelper playerHelper; + private final BitmovinPlayerHelper playerHelper; // Helper private Boolean adStarted = false; @@ -57,9 +56,8 @@ public ConvivaAnalyticsIntegration(Player player, ) { this.bitmovinPlayer = player; this.playerHelper = new BitmovinPlayerHelper(player); - this.config = config; if(config.getGatewayUrl() != null || config.isDebugLoggingEnabled()) { - Map settings = new HashMap(); + Map settings = new HashMap<>(); if (config.getGatewayUrl() != null) { settings.put(ConvivaSdkConstants.GATEWAY_URL, config.getGatewayUrl()); } @@ -86,7 +84,7 @@ public ConvivaAnalyticsIntegration(Player player, // region public methods public void sendCustomApplicationEvent(String name) { - sendCustomApplicationEvent(name, new HashMap()); + sendCustomApplicationEvent(name, new HashMap<>()); } public void sendCustomApplicationEvent(String name, Map attributes) { @@ -95,7 +93,7 @@ public void sendCustomApplicationEvent(String name, Map attribut } public void sendCustomPlaybackEvent(String name) { - sendCustomPlaybackEvent(name, new HashMap()); + sendCustomPlaybackEvent(name, new HashMap<>()); } public void sendCustomPlaybackEvent(String name, Map attributes) { @@ -245,7 +243,7 @@ private void ensureConvivaSessionIsCreatedAndInitialized() { } private void customEvent(Event event) { - customEvent(event, new HashMap()); + customEvent(event, new HashMap<>()); } private void customEvent(Event event, Map attributes) { @@ -256,7 +254,7 @@ private void customEvent(Event event, Map attributes) { // region Session handling private void setupPlayerStateManager() { convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.STOPPED); - Map playerInfo = new HashMap(); + Map playerInfo = new HashMap<>(); playerInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME,"Bitmovin Player Android"); playerInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); convivaVideoAnalytics.setPlayerInfo(playerInfo); @@ -426,21 +424,15 @@ private void trackAdEnd() { // endregion // region Listeners - private final EventListener onSourceUnloadedListener = new EventListener() { - @Override - public void onEvent(SourceEvent.Unloaded event) { - // The default SDK error handling is that it triggers the onSourceUnloaded before the onError event. - // To track errors on Conviva we need to delay the onSourceUnloaded to ensure the onError event is - // called first. - // TODO: remove this once the event order is fixed on the Android SDK. - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - Log.d(TAG, "[Player Event] SourceUnloaded"); - internalEndSession(); - } - }, 100); - } + private final EventListener onSourceUnloadedListener = event -> { + // The default SDK error handling is that it triggers the onSourceUnloaded before the onError event. + // To track errors on Conviva we need to delay the onSourceUnloaded to ensure the onError event is + // called first. + // TODO: remove this once the event order is fixed on the Android SDK. + new Handler().postDelayed(() -> { + Log.d(TAG, "[Player Event] SourceUnloaded"); + internalEndSession(); + }, 100); }; private final EventListener onPlayerErrorListener = new EventListener() { @@ -481,77 +473,53 @@ public void onEvent(SourceEvent.Warning warningEvent) { } }; - private final EventListener onMutedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Muted event) { - Log.d(TAG, "[Player Event] Muted"); - customEvent(event); - } + private final EventListener onMutedListener = event -> { + Log.d(TAG, "[Player Event] Muted"); + customEvent(event); }; - private final EventListener onUnmutedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Unmuted event) { - Log.d(TAG, "[Player Event] Unmuted"); - customEvent(event); - } + private final EventListener onUnmutedListener = event -> { + Log.d(TAG, "[Player Event] Unmuted"); + customEvent(event); }; // region Playback state events - private final EventListener onPlayListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Play playEvent) { - Log.d(TAG, "[Player Event] Play"); - ensureConvivaSessionIsCreatedAndInitialized(); - updateSession(); - } + private final EventListener onPlayListener = playEvent -> { + Log.d(TAG, "[Player Event] Play"); + ensureConvivaSessionIsCreatedAndInitialized(); + updateSession(); }; - private final EventListener onPlayingListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Playing playingEvent) { - Log.d(TAG, "[Player Event] Playing"); - contentMetadataBuilder.setPlaybackStarted(true); - transitionState(ConvivaSdkConstants.PlayerState.PLAYING); - } + private final EventListener onPlayingListener = playingEvent -> { + Log.d(TAG, "[Player Event] Playing"); + contentMetadataBuilder.setPlaybackStarted(true); + transitionState(ConvivaSdkConstants.PlayerState.PLAYING); }; - private EventListener onPausedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Paused pausedEvent) { - // The default SDK handling is that it triggers the onPaused before the - // onError event in case of no internet connectivity. (No onPaused should be triggered) - // To ensure that no playback state change will be reported we need to delay the - // onPaused event. - // TODO: remove this once the event order is fixed on the Android SDK. - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - Log.d(TAG, "[Player Event] Paused"); - transitionState(ConvivaSdkConstants.PlayerState.PAUSED); - } - }, 100); - } + private final EventListener onPausedListener = pausedEvent -> { + // The default SDK handling is that it triggers the onPaused before the + // onError event in case of no internet connectivity. (No onPaused should be triggered) + // To ensure that no playback state change will be reported we need to delay the + // onPaused event. + // TODO: remove this once the event order is fixed on the Android SDK. + new Handler().postDelayed(() -> { + Log.d(TAG, "[Player Event] Paused"); + transitionState(ConvivaSdkConstants.PlayerState.PAUSED); + }, 100); }; - private final EventListener onPlaybackFinishedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.PlaybackFinished playbackFinishedEvent) { - Log.d(TAG, "[Player Event] PlaybackFinished"); - transitionState(ConvivaSdkConstants.PlayerState.STOPPED); - internalEndSession(); - } + private final EventListener onPlaybackFinishedListener = playbackFinishedEvent -> { + Log.d(TAG, "[Player Event] PlaybackFinished"); + transitionState(ConvivaSdkConstants.PlayerState.STOPPED); + internalEndSession(); }; - private EventListener onStallStartedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.StallStarted stallStartedEvent) { - Log.d(TAG, "[Player Event] StallStarted"); - transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); - } + private final EventListener onStallStartedListener = stallStartedEvent -> { + Log.d(TAG, "[Player Event] StallStarted"); + transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); }; - private EventListener onStallEndedListener = new EventListener() { + private final EventListener onStallEndedListener = new EventListener() { @Override public void onEvent(PlayerEvent.StallEnded stallEndedEvent) { // The default SDK error handling is that it triggers the onStallEnded before the @@ -559,57 +527,42 @@ public void onEvent(PlayerEvent.StallEnded stallEndedEvent) { // To track errors on Conviva we need to delay the onStallEnded to ensure no // playback state change will be reported. // TODO: remove this once the event order is fixed on the Android SDK. - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - Log.d(TAG, "[Player Event] StallEnded"); - ConvivaSdkConstants.PlayerState state = ConvivaSdkConstants.PlayerState.PLAYING; - if (bitmovinPlayer.isPaused()) { - state = ConvivaSdkConstants.PlayerState.PAUSED; - } - transitionState(state); + new Handler().postDelayed(() -> { + Log.d(TAG, "[Player Event] StallEnded"); + ConvivaSdkConstants.PlayerState state = ConvivaSdkConstants.PlayerState.PLAYING; + if (bitmovinPlayer.isPaused()) { + state = ConvivaSdkConstants.PlayerState.PAUSED; } + transitionState(state); }, 100); } }; // endregion // region Seek and Timeshift events - private EventListener onSeekListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Seek seekEvent) { - Log.d(TAG, "[Player Event] Seek"); - setSeekStart((int) seekEvent.getTo().getTime() * 1000); - // Conviva expect notification of buffering events on seek (typically there is always buffering) - transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); - } + private final EventListener onSeekListener = seekEvent -> { + Log.d(TAG, "[Player Event] Seek"); + setSeekStart((int) seekEvent.getTo().getTime() * 1000); + // Conviva expect notification of buffering events on seek (typically there is always buffering) + transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); }; - private EventListener onSeekedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.Seeked seekedEvent) { - Log.d(TAG, "[Player Event] Seeked"); - setSeekEnd(); - } + private final EventListener onSeekedListener = seekedEvent -> { + Log.d(TAG, "[Player Event] Seeked"); + setSeekEnd(); }; - private EventListener onTimeShiftListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.TimeShift timeShiftEvent) { - Log.d(TAG, "[Player Event] TimeShift"); - // According to conviva it is valid to pass -1 for seeking in live streams - setSeekStart(-1); - // Conviva expect notification of buffering events on timeshift (typically there is always buffering) - transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); - } + private final EventListener onTimeShiftListener = timeShiftEvent -> { + Log.d(TAG, "[Player Event] TimeShift"); + // According to conviva it is valid to pass -1 for seeking in live streams + setSeekStart(-1); + // Conviva expect notification of buffering events on timeshift (typically there is always buffering) + transitionState(ConvivaSdkConstants.PlayerState.BUFFERING); }; - private EventListener onTimeShiftedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.TimeShifted timeShiftedEvent) { - Log.d(TAG, "[Player Event] TimeShifted"); - setSeekEnd(); - } + private final EventListener onTimeShiftedListener = timeShiftedEvent -> { + Log.d(TAG, "[Player Event] TimeShifted"); + setSeekEnd(); }; private void setSeekStart(int seekTarget) { @@ -631,7 +584,7 @@ public void setSeekEnd() { // endregion // region Ad events - private EventListener onAdStartedListener = new EventListener() { + private final EventListener onAdStartedListener = new EventListener() { @Override public void onEvent(PlayerEvent.AdStarted adStartedEvent) { Log.d(TAG, "[Player Event] AdStarted"); @@ -640,42 +593,30 @@ public void onEvent(PlayerEvent.AdStarted adStartedEvent) { } }; - private EventListener onAdFinishedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.AdFinished adFinishedEvent) { - Log.d(TAG, "[Player Event] AdFinished"); - trackAdEnd(); - } + private final EventListener onAdFinishedListener = adFinishedEvent -> { + Log.d(TAG, "[Player Event] AdFinished"); + trackAdEnd(); }; - private EventListener onAdSkippedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.AdSkipped adSkippedEvent) { - Log.d(TAG, "[Player Event] AdSkipped"); - customEvent(adSkippedEvent); - trackAdEnd(); - } + private final EventListener onAdSkippedListener = adSkippedEvent -> { + Log.d(TAG, "[Player Event] AdSkipped"); + customEvent(adSkippedEvent); + trackAdEnd(); }; - private EventListener onAdErrorListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.AdError adErrorEvent) { - Log.d(TAG, "[Player Event] AdError"); - customEvent(adErrorEvent); - trackAdEnd(); - } + private final EventListener onAdErrorListener = adErrorEvent -> { + Log.d(TAG, "[Player Event] AdError"); + customEvent(adErrorEvent); + trackAdEnd(); }; // endregion - private EventListener onVideoPlaybackQualityChangedListener = new EventListener() { - @Override - public void onEvent(PlayerEvent.VideoPlaybackQualityChanged videoPlaybackQualityChangedEvent) { - Log.d(TAG, "[Player Event] VideoPlaybackQualityChanged"); - updateSession(); - } + private final EventListener onVideoPlaybackQualityChangedListener = videoPlaybackQualityChangedEvent -> { + Log.d(TAG, "[Player Event] VideoPlaybackQualityChanged"); + updateSession(); }; - private EventListener onTimeChangedListener = new EventListener() { + private final EventListener onTimeChangedListener = new EventListener() { @Override public void onEvent(PlayerEvent.TimeChanged timeChangedEvent) { if (bitmovinPlayer.isLive()) { From ce7ad08690dc8be3428153a76fed8dd701e5ee79 Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 13:31:27 +0200 Subject: [PATCH 11/30] Replace deprecated API usage --- .../analytics/convivaanalyticsexample/MainActivity.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java b/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java index 28b0616..f3d761d 100644 --- a/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java +++ b/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java @@ -9,11 +9,12 @@ import android.widget.LinearLayout; import android.widget.Switch; -import com.bitmovin.analytics.conviva.ConvivaAnalyticsIntegration;; +import com.bitmovin.analytics.conviva.ConvivaAnalyticsIntegration; import com.bitmovin.analytics.conviva.ConvivaConfig; import com.bitmovin.analytics.conviva.MetadataOverrides; import com.bitmovin.player.api.Player; import com.bitmovin.player.PlayerView; +import com.bitmovin.player.api.PlayerBuilder; import com.bitmovin.player.api.source.SourceConfig; import com.bitmovin.player.api.PlayerConfig; import com.bitmovin.player.api.advertising.AdItem; @@ -63,7 +64,10 @@ protected void onCreate(Bundle savedInstanceState) { } protected void setupBitmovinPlayer() { - this.bitmovinPlayer = Player.create(this, buildPlayerConfiguration()); + this.bitmovinPlayer = new PlayerBuilder(this) + .setPlayerConfig(buildPlayerConfiguration()) + .disableAnalytics() + .build(); this.bitmovinPlayerView = new PlayerView(this, this.bitmovinPlayer); LinearLayout playerUIView = this.findViewById(R.id.bitmovinPlayerUIView); From 3ba749653b85139528fcc435841c9fe2c0a706bd Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 13:35:25 +0200 Subject: [PATCH 12/30] Formatting --- .../conviva/ContentMetadataBuilder.java | 3 +- .../conviva/ConvivaAnalyticsIntegration.java | 50 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java index 6b1b77a..1ce5f3d 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ContentMetadataBuilder.java @@ -1,7 +1,9 @@ package com.bitmovin.analytics.conviva; import android.util.Log; + import com.conviva.sdk.ConvivaSdkConstants; + import java.util.HashMap; import java.util.Map; @@ -24,7 +26,6 @@ class ContentMetadataBuilder { /** * This method is used for custom content metadata updates during / before a session. - * */ public void setOverrides(MetadataOverrides metadataOverrides) { if (playbackStarted) { 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 acfca1e..f42b0d8 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -53,10 +53,10 @@ public ConvivaAnalyticsIntegration(Player player, Context context, ConvivaConfig config, ConvivaVideoAnalytics videoAnalytics - ) { + ) { this.bitmovinPlayer = player; this.playerHelper = new BitmovinPlayerHelper(player); - if(config.getGatewayUrl() != null || config.isDebugLoggingEnabled()) { + if (config.getGatewayUrl() != null || config.isDebugLoggingEnabled()) { Map settings = new HashMap<>(); if (config.getGatewayUrl() != null) { settings.put(ConvivaSdkConstants.GATEWAY_URL, config.getGatewayUrl()); @@ -64,16 +64,16 @@ public ConvivaAnalyticsIntegration(Player player, if (config.isDebugLoggingEnabled()) { settings.put(ConvivaSdkConstants.LOG_LEVEL, ConvivaSdkConstants.LogLevel.DEBUG); } - if(videoAnalytics == null) { + if (videoAnalytics == null) { ConvivaAnalytics.init(context, customerKey, settings); } } else { - if(videoAnalytics == null) { + if (videoAnalytics == null) { ConvivaAnalytics.init(context, customerKey); } } - if(videoAnalytics != null) { + if (videoAnalytics != null) { convivaVideoAnalytics = videoAnalytics; } else { convivaVideoAnalytics = ConvivaAnalytics.buildVideoAnalytics(context); @@ -166,7 +166,7 @@ public void release(Boolean releaseConvivaSdk) { * Sends a custom deficiency event during playback to Conviva's Player Insight. If no session is active it will NOT * create one. * - * @param message Message which will be send to conviva + * @param message Message which will be send to conviva * @param severity One of FATAL or WARNING */ public void reportPlaybackDeficiency(String message, ConvivaSdkConstants.ErrorSeverity severity) { @@ -177,8 +177,8 @@ public void reportPlaybackDeficiency(String message, ConvivaSdkConstants.ErrorSe * Sends a custom deficiency event during playback to Conviva's Player Insight. If no session is active it will NOT * create one. * - * @param message Message which will be send to conviva - * @param severity One of FATAL or WARNING + * @param message Message which will be send to conviva + * @param severity One of FATAL or WARNING * @param endSession Boolean flag if session should be closed after reporting the deficiency */ public void reportPlaybackDeficiency(String message, ConvivaSdkConstants.ErrorSeverity severity, Boolean endSession) { @@ -227,7 +227,7 @@ public void reportAppForegrounded() { */ public void reportAppBackgrounded() { Log.d(TAG, "appBackgrounded"); - if(!isBackgrounded) { + if (!isBackgrounded) { ConvivaAnalytics.reportAppBackgrounded(); isBackgrounded = true; } @@ -255,13 +255,13 @@ private void customEvent(Event event, Map attributes) { private void setupPlayerStateManager() { convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.STOPPED); Map playerInfo = new HashMap<>(); - playerInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME,"Bitmovin Player Android"); + playerInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin Player Android"); playerInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); convivaVideoAnalytics.setPlayerInfo(playerInfo); } private void internalInitializeSession() { - if(isSessionActive) { + if (isSessionActive) { return; } Log.d(TAG, "internalInitializeSession"); @@ -280,12 +280,12 @@ private void updateSession() { VideoQuality videoQuality = bitmovinPlayer.getPlaybackVideoData(); if (videoQuality != null) { int bitrate = videoQuality.getBitrate() / 1000; // in kbps - convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.RESOLUTION, videoQuality.getHeight(), videoQuality.getWidth()); - convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.BITRATE, bitrate); - convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.RENDERED_FRAMERATE, Math.round(videoQuality.getFrameRate())); + convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.RESOLUTION, videoQuality.getHeight(), videoQuality.getWidth()); + convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.BITRATE, bitrate); + convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.RENDERED_FRAMERATE, Math.round(videoQuality.getFrameRate())); } - if(isSessionActive) { + if (isSessionActive) { convivaVideoAnalytics.setContentInfo(contentMetadataBuilder.build()); } } @@ -322,7 +322,7 @@ private void buildDynamicContentMetadata() { private void internalEndSession() { contentMetadataBuilder.reset(); - if(!isSessionActive) { + if (!isSessionActive) { return; } convivaVideoAnalytics.reportPlaybackEnded(); @@ -425,14 +425,14 @@ private void trackAdEnd() { // region Listeners private final EventListener onSourceUnloadedListener = event -> { - // The default SDK error handling is that it triggers the onSourceUnloaded before the onError event. - // To track errors on Conviva we need to delay the onSourceUnloaded to ensure the onError event is - // called first. - // TODO: remove this once the event order is fixed on the Android SDK. - new Handler().postDelayed(() -> { - Log.d(TAG, "[Player Event] SourceUnloaded"); - internalEndSession(); - }, 100); + // The default SDK error handling is that it triggers the onSourceUnloaded before the onError event. + // To track errors on Conviva we need to delay the onSourceUnloaded to ensure the onError event is + // called first. + // TODO: remove this once the event order is fixed on the Android SDK. + new Handler().postDelayed(() -> { + Log.d(TAG, "[Player Event] SourceUnloaded"); + internalEndSession(); + }, 100); }; private final EventListener onPlayerErrorListener = new EventListener() { @@ -568,7 +568,7 @@ public void onEvent(PlayerEvent.StallEnded stallEndedEvent) { private void setSeekStart(int seekTarget) { Log.d(TAG, "Sending seek start event"); convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.SEEK_STARTED, seekTarget); - }; + } public void setSeekEnd() { Log.d(TAG, "Sending seek end event"); From 44a1766ee7c00e2621af9ce8eb20e7677e75e94d Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 13:45:51 +0200 Subject: [PATCH 13/30] Introduce ConvivaAdAnalytics instance --- .../conviva/ConvivaAnalyticsIntegration.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) 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 f42b0d8..731315b 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -12,6 +12,7 @@ import com.bitmovin.player.api.media.video.quality.VideoQuality; import com.bitmovin.player.api.source.Source; import com.bitmovin.player.api.source.SourceConfig; +import com.conviva.sdk.ConvivaAdAnalytics; import com.conviva.sdk.ConvivaAnalytics; import com.conviva.sdk.ConvivaSdkConstants; import com.conviva.sdk.ConvivaVideoAnalytics; @@ -26,6 +27,7 @@ public class ConvivaAnalyticsIntegration { private final Player bitmovinPlayer; private final ContentMetadataBuilder contentMetadataBuilder = new ContentMetadataBuilder(); private final ConvivaVideoAnalytics convivaVideoAnalytics; + private final ConvivaAdAnalytics convivaAdAnalytics; private MetadataOverrides metadataOverrides; // Wrapper to extract bitmovinPlayer helper methods @@ -53,30 +55,39 @@ public ConvivaAnalyticsIntegration(Player player, Context context, ConvivaConfig config, ConvivaVideoAnalytics videoAnalytics + ) { + this(player, customerKey, context, config, videoAnalytics, null); + } + + public ConvivaAnalyticsIntegration(Player player, + String customerKey, + Context context, + ConvivaConfig config, + ConvivaVideoAnalytics videoAnalytics, + ConvivaAdAnalytics adAnalytics ) { this.bitmovinPlayer = player; this.playerHelper = new BitmovinPlayerHelper(player); + Map settings = new HashMap<>(); if (config.getGatewayUrl() != null || config.isDebugLoggingEnabled()) { - Map settings = new HashMap<>(); if (config.getGatewayUrl() != null) { settings.put(ConvivaSdkConstants.GATEWAY_URL, config.getGatewayUrl()); } if (config.isDebugLoggingEnabled()) { settings.put(ConvivaSdkConstants.LOG_LEVEL, ConvivaSdkConstants.LogLevel.DEBUG); } - if (videoAnalytics == null) { - ConvivaAnalytics.init(context, customerKey, settings); - } - } else { - if (videoAnalytics == null) { - ConvivaAnalytics.init(context, customerKey); - } } - if (videoAnalytics != null) { + if (videoAnalytics == null) { + ConvivaAnalytics.init(context, customerKey, settings); + convivaVideoAnalytics = ConvivaAnalytics.buildVideoAnalytics(context); + } else { convivaVideoAnalytics = videoAnalytics; + } + if (adAnalytics == null) { + convivaAdAnalytics = ConvivaAnalytics.buildAdAnalytics(context, convivaVideoAnalytics); } else { - convivaVideoAnalytics = ConvivaAnalytics.buildVideoAnalytics(context); + convivaAdAnalytics = adAnalytics; } attachBitmovinEventListeners(); @@ -155,6 +166,7 @@ public void release() { } public void release(Boolean releaseConvivaSdk) { + convivaAdAnalytics.release(); convivaVideoAnalytics.release(); detachBitmovinEventListeners(); if (releaseConvivaSdk) { From b73e139f7131f09e5f69c0e7b913db7cf10ec782 Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 14:15:33 +0200 Subject: [PATCH 14/30] Migrate ad lifecycle reporting to conviva ad analytics --- .../conviva/ConvivaAnalyticsIntegration.java | 68 +++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) 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 731315b..8c9db6d 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -34,7 +34,6 @@ public class ConvivaAnalyticsIntegration { private final BitmovinPlayerHelper playerHelper; // Helper - private Boolean adStarted = false; private Boolean isSessionActive = false; private Boolean isBumper = false; private Boolean isBackgrounded = false; @@ -370,6 +369,8 @@ private void attachBitmovinEventListeners() { bitmovinPlayer.on(PlayerEvent.TimeShifted.class, onTimeShiftedListener); // Ad events + bitmovinPlayer.on(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); + bitmovinPlayer.on(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); bitmovinPlayer.on(PlayerEvent.AdStarted.class, onAdStartedListener); bitmovinPlayer.on(PlayerEvent.AdFinished.class, onAdFinishedListener); bitmovinPlayer.on(PlayerEvent.AdSkipped.class, onAdSkippedListener); @@ -421,20 +422,6 @@ private synchronized void transitionState(ConvivaSdkConstants.PlayerState state) convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, state); } - // region Helper - - private void trackAdEnd() { - if (!adStarted) { - // Do not track adEnd if no ad is was shown (possible if an error occurred) - return; - } - adStarted = false; - - Log.d(TAG, "Report ad break ended"); - convivaVideoAnalytics.reportAdBreakEnded(); - } - // endregion - // region Listeners private final EventListener onSourceUnloadedListener = event -> { // The default SDK error handling is that it triggers the onSourceUnloaded before the onError event. @@ -596,31 +583,56 @@ public void setSeekEnd() { // endregion // region Ad events + + private final EventListener onAdBreakStarted = new EventListener() { + @Override + public void onEvent(PlayerEvent.AdBreakStarted adBreakStarted) { + Log.d(TAG, "[Player Event] AdBreakStarted"); + convivaVideoAnalytics.reportAdBreakStarted(ConvivaSdkConstants.AdPlayer.CONTENT, ConvivaSdkConstants.AdType.CLIENT_SIDE); + } + }; + + private final EventListener onAdBreakFinished = new EventListener() { + @Override + public void onEvent(PlayerEvent.AdBreakFinished adBreakFinished) { + Log.d(TAG, "[Player Event] AdBreakFinished"); + convivaVideoAnalytics.reportAdBreakEnded(); + } + }; + private final EventListener onAdStartedListener = new EventListener() { @Override public void onEvent(PlayerEvent.AdStarted adStartedEvent) { Log.d(TAG, "[Player Event] AdStarted"); - adStarted = true; - convivaVideoAnalytics.reportAdBreakStarted(ConvivaSdkConstants.AdPlayer.CONTENT, ConvivaSdkConstants.AdType.CLIENT_SIDE); + convivaAdAnalytics.reportAdLoaded(); + convivaAdAnalytics.reportAdStarted(); } }; - private final EventListener onAdFinishedListener = adFinishedEvent -> { - Log.d(TAG, "[Player Event] AdFinished"); - trackAdEnd(); + private final EventListener onAdFinishedListener = new EventListener() { + @Override + public void onEvent(PlayerEvent.AdFinished adFinished) { + Log.d(TAG, "[Player Event] AdFinished"); + convivaAdAnalytics.reportAdEnded(); + } }; - private final EventListener onAdSkippedListener = adSkippedEvent -> { - Log.d(TAG, "[Player Event] AdSkipped"); - customEvent(adSkippedEvent); - trackAdEnd(); + private final EventListener onAdSkippedListener = new EventListener() { + @Override + public void onEvent(PlayerEvent.AdSkipped adSkipped) { + Log.d(TAG, "[Player Event] AdSkipped"); + convivaAdAnalytics.reportAdSkipped(); + } }; - private final EventListener onAdErrorListener = adErrorEvent -> { - Log.d(TAG, "[Player Event] AdError"); - customEvent(adErrorEvent); - trackAdEnd(); + private final EventListener onAdErrorListener = new EventListener() { + @Override + public void onEvent(PlayerEvent.AdError adError) { + Log.d(TAG, "[Player Event] AdError"); + convivaAdAnalytics.reportAdFailed(adError.getMessage()); + } }; + // endregion private final EventListener onVideoPlaybackQualityChangedListener = videoPlaybackQualityChangedEvent -> { From 9f1e09e4e62f8d9af355ebc87af986fa57e00e42 Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 14:22:53 +0200 Subject: [PATCH 15/30] Add changelog entries --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68522eb..1107136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Ad analytics for ad event reporting + ### Changed - Updated Bitmovin Player to `3.69.0` - Updated IMA SDK to `3.31.0` @@ -13,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Updated Gradle wrapper to `8.2` and AGP to `8.2.2` - Increased minimum required `compileSdk` version to `34` - Increased `compileSdk` and `targetSdkVersion` to `34` +- Ad break started and ended is now reported in `PlayerEvent.AdBreakStarted` and `PlayerEvent.AdBreakFinished` + +### Removed +- Custom event for `AdSkipped` and `AdError`. Replaced by Conviva build in tracking ### Fixed - The pom file now also includes the `com.bitmovin.player` dependency which was missing before From 5358dadc3c6e9b012f5a66cc94e20ac12e144573 Mon Sep 17 00:00:00 2001 From: Matthias Tamegger Date: Mon, 27 May 2024 14:46:35 +0200 Subject: [PATCH 16/30] wip --- .../conviva/ConvivaAnalyticsIntegration.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) 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 8c9db6d..bc73d08 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -5,6 +5,8 @@ import android.util.Log; import com.bitmovin.player.api.Player; +import com.bitmovin.player.api.advertising.Ad; +import com.bitmovin.player.api.advertising.vast.VastAdData; import com.bitmovin.player.api.event.Event; import com.bitmovin.player.api.event.EventListener; import com.bitmovin.player.api.event.PlayerEvent; @@ -269,6 +271,7 @@ private void setupPlayerStateManager() { playerInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin Player Android"); playerInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); convivaVideoAnalytics.setPlayerInfo(playerInfo); + convivaAdAnalytics.setAdPlayerInfo(playerInfo); } private void internalInitializeSession() { @@ -604,11 +607,36 @@ public void onEvent(PlayerEvent.AdBreakFinished adBreakFinished) { @Override public void onEvent(PlayerEvent.AdStarted adStartedEvent) { Log.d(TAG, "[Player Event] AdStarted"); - convivaAdAnalytics.reportAdLoaded(); - convivaAdAnalytics.reportAdStarted(); + Map adInfo = null; + if (adStartedEvent.getAd() != null) { + adInfo = adToAdInfo(adStartedEvent.getAd()); + } + convivaAdAnalytics.reportAdLoaded(adInfo); + convivaAdAnalytics.reportAdStarted(adInfo); + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.PLAYING); } }; + private Map adToAdInfo(Ad ad) { + Map adInfo = new HashMap<>(); + adInfo.put("c3.ad.technology", "Client Side"); + + if (ad.getMediaFileUrl() != null) { + adInfo.put(ConvivaSdkConstants.STREAM_URL, ad.getMediaFileUrl()); + } + if (ad.getId() != null) { + adInfo.put("c3.ad.id", ad.getId()); + } + + if (ad.getData() instanceof VastAdData) { + VastAdData vastAdData = (VastAdData) ad.getData(); + if (vastAdData.getAdTitle() != null) { + adInfo.put(ConvivaSdkConstants.ASSET_NAME, vastAdData.getAdTitle()); + } + } + return adInfo; + } + private final EventListener onAdFinishedListener = new EventListener() { @Override public void onEvent(PlayerEvent.AdFinished adFinished) { From 97b9218c4959debaa1fe75198bbaf26e72fcfa3e Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Sun, 2 Jun 2024 13:25:15 +0200 Subject: [PATCH 17/30] Unsubscribe from ad break evens --- .../bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java | 2 ++ 1 file changed, 2 insertions(+) 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 bc73d08..5673975 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -410,6 +410,8 @@ private void detachBitmovinEventListeners() { bitmovinPlayer.off(PlayerEvent.TimeShifted.class, onTimeShiftedListener); // Ad events + bitmovinPlayer.off(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); + bitmovinPlayer.off(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); bitmovinPlayer.off(PlayerEvent.AdStarted.class, onAdStartedListener); bitmovinPlayer.off(PlayerEvent.AdFinished.class, onAdFinishedListener); bitmovinPlayer.off(PlayerEvent.AdSkipped.class, onAdSkippedListener); From 7ae183e5245d06129810feda650aacfb33499f43 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Sun, 2 Jun 2024 13:27:42 +0200 Subject: [PATCH 18/30] Ensure Conviva analytics session is initialized for pre-roll ads --- .../analytics/conviva/ConvivaAnalyticsIntegration.java | 3 +++ 1 file changed, 3 insertions(+) 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 5673975..c770f21 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -593,6 +593,9 @@ public void setSeekEnd() { @Override public void onEvent(PlayerEvent.AdBreakStarted adBreakStarted) { Log.d(TAG, "[Player Event] AdBreakStarted"); + // For pre-roll ads there is no `PlayerEvent.Play` before the `PlayerEvent.AdBreakStarted` + // which means we need to make sure the session is correctly initialized. + ensureConvivaSessionIsCreatedAndInitialized(); convivaVideoAnalytics.reportAdBreakStarted(ConvivaSdkConstants.AdPlayer.CONTENT, ConvivaSdkConstants.AdType.CLIENT_SIDE); } }; From 256bccfa2f38967880e178428d836f7869dcd940 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Mon, 3 Jun 2024 13:25:14 +0200 Subject: [PATCH 19/30] Update Bitmovin Player version to `3.71.0` --- CHANGELOG.md | 2 +- dependencies.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1107136..08f5618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Ad analytics for ad event reporting ### Changed -- Updated Bitmovin Player to `3.69.0` +- Updated Bitmovin Player to `3.71.0` - Updated IMA SDK to `3.31.0` - Updated Kotlin to `1.9.23` - Updated conviva-core to `4.0.37` diff --git a/dependencies.gradle b/dependencies.gradle index f557806..71cd90c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,5 +1,5 @@ ext { - bitmovinPlayerVersion = '3.69.0' + bitmovinPlayerVersion = '3.71.0' googleImaSdk = '3.31.0' googlePlayAdsIdentifier = '18.0.1' From 57c23ec3cd9c1ce7bc67f349f392a29a87d941af Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Mon, 3 Jun 2024 15:37:48 +0200 Subject: [PATCH 20/30] Set additional ad metadata --- .../conviva/ConvivaAnalyticsIntegration.java | 85 +++++++++++++++---- 1 file changed, 70 insertions(+), 15 deletions(-) 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 c770f21..ac525c9 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -6,6 +6,8 @@ import com.bitmovin.player.api.Player; import com.bitmovin.player.api.advertising.Ad; +import com.bitmovin.player.api.advertising.AdSourceType; +import com.bitmovin.player.api.advertising.vast.AdSystem; import com.bitmovin.player.api.advertising.vast.VastAdData; import com.bitmovin.player.api.event.Event; import com.bitmovin.player.api.event.EventListener; @@ -20,6 +22,7 @@ import com.conviva.sdk.ConvivaVideoAnalytics; import java.util.HashMap; +import java.util.List; import java.util.Map; public class ConvivaAnalyticsIntegration { @@ -612,36 +615,88 @@ public void onEvent(PlayerEvent.AdBreakFinished adBreakFinished) { @Override public void onEvent(PlayerEvent.AdStarted adStartedEvent) { Log.d(TAG, "[Player Event] AdStarted"); - Map adInfo = null; - if (adStartedEvent.getAd() != null) { - adInfo = adToAdInfo(adStartedEvent.getAd()); - } + Map adInfo = adStartedToAdInfo(adStartedEvent); convivaAdAnalytics.reportAdLoaded(adInfo); convivaAdAnalytics.reportAdStarted(adInfo); convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.PLAYING); } }; - private Map adToAdInfo(Ad ad) { + private Map adStartedToAdInfo(PlayerEvent.AdStarted adStartedEvent) { Map adInfo = new HashMap<>(); - adInfo.put("c3.ad.technology", "Client Side"); - if (ad.getMediaFileUrl() != null) { - adInfo.put(ConvivaSdkConstants.STREAM_URL, ad.getMediaFileUrl()); - } - if (ad.getId() != null) { - adInfo.put("c3.ad.id", ad.getId()); + adInfo.put("c3.ad.id", "NA"); + adInfo.put("c3.ad.system", "NA"); + adInfo.put("c3.ad.mediaFileApiFramework", "NA"); + adInfo.put("c3.ad.firstAdSystem", "NA"); + adInfo.put("c3.ad.firstAdId", "NA"); + adInfo.put("c3.ad.firstCreativeId", "NA"); + + adInfo.put("c3.ad.technology", "Client Side"); + if (adStartedEvent.getClientType() == AdSourceType.Ima) { + adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Google IMA SDK"); + //tags.put(ConvivaSdkConstants.FRAMEWORK_VERSION, "3.31.0");// todo better way to provide version? + } else { + adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin"); + adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); } + adInfo.put("c3.ad.position", getAdPosition(adStartedEvent.getTimeOffset())); + adInfo.put(ConvivaSdkConstants.DURATION, adStartedEvent.getDuration()); + adInfo.put(ConvivaSdkConstants.IS_LIVE, convivaVideoAnalytics.getMetadataInfo().get(ConvivaSdkConstants.IS_LIVE)); - if (ad.getData() instanceof VastAdData) { - VastAdData vastAdData = (VastAdData) ad.getData(); - if (vastAdData.getAdTitle() != null) { - adInfo.put(ConvivaSdkConstants.ASSET_NAME, vastAdData.getAdTitle()); + Ad ad = adStartedEvent.getAd(); + if (ad != null) { + if (ad.getMediaFileUrl() != null) { + adInfo.put(ConvivaSdkConstants.STREAM_URL, ad.getMediaFileUrl()); + } + if (ad.getId() != null) { + adInfo.put("c3.ad.id", ad.getId()); + } + + if (ad.getData() instanceof VastAdData) { + setVastAdMetadata((VastAdData) ad.getData(), adInfo); } } return adInfo; } + private static void setVastAdMetadata(VastAdData vastAdData, Map adInfo) { + if (vastAdData.getAdTitle() != null) { + adInfo.put(ConvivaSdkConstants.ASSET_NAME, vastAdData.getAdTitle()); + } + if (vastAdData.getCreative() != null && vastAdData.getCreative().getId() != null) { + adInfo.put("c3.ad.creativeId", vastAdData.getCreative().getId()); + } + if (vastAdData.getAdDescription() != null) { + adInfo.put("c3.ad.description", vastAdData.getAdDescription()); + } + if (vastAdData.getAdSystem() != null) { + adInfo.put("c3.ad.system", vastAdData.getAdSystem().getName()); + } + List wrapperAdSystems = vastAdData.getWrapperAdSystems(); + if (!wrapperAdSystems.isEmpty()) { + adInfo.put("c3.ad.firstAdSystem", wrapperAdSystems.get(wrapperAdSystems.size() - 1).getName()); + } + String[] wrapperAdIds = vastAdData.getWrapperAdIds(); + if (wrapperAdIds.length != 0) { + adInfo.put("c3.ad.firstAdId", wrapperAdIds[wrapperAdIds.length - 1]); + } + List wrapperCreativeIds = vastAdData.getWrapperCreativeIds(); + if (!wrapperCreativeIds.isEmpty()) { + adInfo.put("c3.ad.firstCreativeId", wrapperCreativeIds.get(wrapperCreativeIds.size() - 1)); + } + } + + private ConvivaSdkConstants.AdPosition getAdPosition(double timeOffset) { + ConvivaSdkConstants.AdPosition adPosition = ConvivaSdkConstants.AdPosition.MIDROLL; + if (timeOffset == 0.0) { + adPosition = ConvivaSdkConstants.AdPosition.PREROLL; + } else if (timeOffset == bitmovinPlayer.getDuration()) { + adPosition = ConvivaSdkConstants.AdPosition.POSTROLL; + } + return adPosition; + } + private final EventListener onAdFinishedListener = new EventListener() { @Override public void onEvent(PlayerEvent.AdFinished adFinished) { From 03207bda71cda0f6f5e7adf2292eb268c6770f5d Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Tue, 4 Jun 2024 05:49:47 +0200 Subject: [PATCH 21/30] Report Google IMA SDK as `NA` if not known --- .../bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ac525c9..65d419c 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -635,7 +635,7 @@ private Map adStartedToAdInfo(PlayerEvent.AdStarted adStartedEve adInfo.put("c3.ad.technology", "Client Side"); if (adStartedEvent.getClientType() == AdSourceType.Ima) { adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Google IMA SDK"); - //tags.put(ConvivaSdkConstants.FRAMEWORK_VERSION, "3.31.0");// todo better way to provide version? + adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, "NA"); } else { adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin"); adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); From 389cbb1b9a781aa57ee66f6188d8dda61130acb4 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Tue, 4 Jun 2024 06:23:27 +0200 Subject: [PATCH 22/30] Add VMAP pre-roll advertising test --- .../conviva/testapp/AdvertisingTests.kt | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/AdvertisingTests.kt diff --git a/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/AdvertisingTests.kt b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/AdvertisingTests.kt new file mode 100644 index 0000000..1d92632 --- /dev/null +++ b/ConvivaTestApp/src/androidTest/java/com/bitmovin/analytics/conviva/testapp/AdvertisingTests.kt @@ -0,0 +1,133 @@ +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.player.api.PlaybackConfig +import com.bitmovin.player.api.Player +import com.bitmovin.player.api.PlayerConfig +import com.bitmovin.player.api.advertising.AdItem +import com.bitmovin.player.api.advertising.AdSource +import com.bitmovin.player.api.advertising.AdSourceType +import com.bitmovin.player.api.advertising.AdvertisingConfig +import com.bitmovin.player.api.analytics.AnalyticsPlayerConfig +import com.bitmovin.player.api.event.Event +import com.bitmovin.player.api.event.EventEmitter +import com.bitmovin.player.api.event.PlayerEvent +import com.bitmovin.player.api.event.on +import com.bitmovin.player.api.source.SourceConfig +import com.bitmovin.player.api.source.SourceType +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +private const val BITMOVIN_PLAYER_LICENSE_KEY = "YOUR_LICENSE_KEY" +private const val CONVIVA_CUSTOMER_KEY = "YOUR-CUSTOMER-KEY" +private const val CONVIVA_GATEWAY_URL = "YOUR-GATEWAY-URL" + +private const val VMAP_PREROLL_SINGLE_TAG = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpreonly&cmsid=496&vid=short_onecue&correlator=" +private val ART_OF_MOTION_DASH = SourceConfig( + url = "https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd", + type = SourceType.Dash, + title = "Art of Motion Test Stream", +) + +/** + * 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 AdvertisingTests { + /** + * Plays the first 5 seconds of a stream with a VMAP ad that includes a single pre-roll with a + * attached [ConvivaAnalyticsIntegration]. + * Ad playback is paused and resumed to test for according events. + */ + @Test + fun reports_ad_analytics_for_IMA_pre_roll_ad() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + val mainHandler = Handler(context.mainLooper) + val player = mainHandler.postWaiting { + val player = Player( + context, + PlayerConfig( + key = BITMOVIN_PLAYER_LICENSE_KEY, + advertisingConfig = AdvertisingConfig( + AdItem(AdSource(AdSourceType.Ima, VMAP_PREROLL_SINGLE_TAG)), + ), + playbackConfig = PlaybackConfig( + isAutoplayEnabled = true, + ), + ), + analyticsConfig = AnalyticsPlayerConfig.Disabled, + ) + val convivaAnalyticsIntegration = ConvivaAnalyticsIntegration( + player, + CONVIVA_CUSTOMER_KEY, + context, + ConvivaConfig().apply { + isDebugLoggingEnabled = true + gatewayUrl = CONVIVA_GATEWAY_URL + }, + ) + + convivaAnalyticsIntegration.updateContentMetadata( + MetadataOverrides() + .apply { + applicationName = "Bitmovin Android Conviva integration example app" + viewerId = "testViewerId" + } + ) + player + } + + mainHandler.postWaiting { player.load(ART_OF_MOTION_DASH) } + player.expectEvent { it.time > 5.0 } + + // pause player for a second and resume playback + mainHandler.postWaiting { player.pause() } + runBlocking { delay(1000) } + mainHandler.postWaiting { player.play() } + + // wait for the ad break to finish and play main content for five more seconds + player.expectEvent() + player.expectEvent { it.time > 5.0 } + + mainHandler.postWaiting { player.destroy() } + runBlocking { delay(1000) } + } +} + +/** + * Subscribes to an [Event] on the [Player] and suspends until the event is emitted. + * Optionally a [condition] can be provided to filter the emitted events. + */ +private inline fun EventEmitter.expectEvent( + crossinline condition: (T) -> Boolean = { true } +) = runBlocking { + 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. + */ +private inline fun Handler.postWaiting(crossinline block: () -> T) = runBlocking { + suspendCoroutine { continuation -> + post { continuation.resume(block()) } + } +} From 6fa9cf3be40d27ff99fd658e65fbfcc81ca087bb Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Mon, 3 Jun 2024 16:31:27 +0200 Subject: [PATCH 23/30] Report ad playback metrics --- .../conviva/ConvivaAnalyticsIntegration.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) 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 ac525c9..72acc45 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -6,6 +6,7 @@ import com.bitmovin.player.api.Player; import com.bitmovin.player.api.advertising.Ad; +import com.bitmovin.player.api.advertising.AdData; import com.bitmovin.player.api.advertising.AdSourceType; import com.bitmovin.player.api.advertising.vast.AdSystem; import com.bitmovin.player.api.advertising.vast.VastAdData; @@ -18,6 +19,7 @@ import com.bitmovin.player.api.source.SourceConfig; import com.conviva.sdk.ConvivaAdAnalytics; import com.conviva.sdk.ConvivaAnalytics; +import com.conviva.sdk.ConvivaExperienceAnalytics; import com.conviva.sdk.ConvivaSdkConstants; import com.conviva.sdk.ConvivaVideoAnalytics; @@ -95,6 +97,22 @@ public ConvivaAnalyticsIntegration(Player player, } attachBitmovinEventListeners(); + setUpAdAnalyticsCallback(); + } + + private void setUpAdAnalyticsCallback() { + convivaAdAnalytics.setCallback(new ConvivaExperienceAnalytics.ICallback() { + @Override + public void update() { + if (bitmovinPlayer.isAd()) { + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAY_HEAD_TIME, ((long) (bitmovinPlayer.getCurrentTime() * 1000))); + } + } + + @Override + public void update(String s) { + } + }); } // region public methods @@ -428,6 +446,10 @@ private void detachBitmovinEventListeners() { private synchronized void transitionState(ConvivaSdkConstants.PlayerState state) { Log.d(TAG, "Transitioning to :" + state.name()); convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, state); + if (bitmovinPlayer.isAd()) { + Log.d(TAG, "Transitioning ad state to: " + state.name()); + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, state); + } } // region Listeners @@ -619,6 +641,16 @@ public void onEvent(PlayerEvent.AdStarted adStartedEvent) { convivaAdAnalytics.reportAdLoaded(adInfo); convivaAdAnalytics.reportAdStarted(adInfo); convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.PLAYING); + Ad ad = adStartedEvent.getAd(); + if (ad != null) { + if (ad.getWidth() != 0 && ad.getHeight() != 0) { + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.RESOLUTION, ad.getWidth(), ad.getHeight()); + } + AdData adData = ad.getData(); + if (adData != null && adData.getBitrate() != null) { + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.BITRATE, adData.getBitrate()); + } + } } }; From 14c8c424f698641c45a48752150b417df449cb2a Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Tue, 4 Jun 2024 07:05:09 +0200 Subject: [PATCH 24/30] Allow setting Google IMA SDK version for CSAI tracking in `MetadataOverrides`. --- .../convivaanalyticsexample/MainActivity.java | 2 ++ .../conviva/ConvivaAnalyticsIntegration.java | 5 ++++- .../analytics/conviva/MetadataOverrides.java | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java b/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java index f3d761d..1e39ce9 100644 --- a/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java +++ b/ConvivaExampleApp/src/main/java/com/bitmovin/analytics/convivaanalyticsexample/MainActivity.java @@ -103,6 +103,8 @@ protected void setupBitmovinPlayer() { customTags.put("custom_tag", "Episode"); metadata.setCustom(customTags); + metadata.setImaSdkVersion("3.31.0"); + convivaAnalyticsIntegration.updateContentMetadata(metadata); // load source using the created source configuration 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 65d419c..36ec339 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -635,7 +635,10 @@ private Map adStartedToAdInfo(PlayerEvent.AdStarted adStartedEve adInfo.put("c3.ad.technology", "Client Side"); if (adStartedEvent.getClientType() == AdSourceType.Ima) { adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Google IMA SDK"); - adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, "NA"); + adInfo.put( + ConvivaSdkConstants.FRAMEWORK_VERSION, + metadataOverrides.getImaSdkVersion() != null ? metadataOverrides.getImaSdkVersion() : "NA" + ); } else { adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin"); adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/MetadataOverrides.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/MetadataOverrides.java index e60cf78..c0ab7e6 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/MetadataOverrides.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/MetadataOverrides.java @@ -20,6 +20,7 @@ public class MetadataOverrides { private Integer encodedFrameRate; private String defaultResource; private String streamUrl; + private String imaSdkVersion; public String getAssetName() { return assetName; @@ -104,4 +105,16 @@ public String getStreamUrl() { public void setStreamUrl(String streamUrl) { this.streamUrl = streamUrl; } + + public String getImaSdkVersion() { + return imaSdkVersion; + } + + /** + * Set the IMA SDK version to be tracked with client side ads of type + * {@link com.bitmovin.player.api.advertising.AdSourceType#Ima}. + */ + public void setImaSdkVersion(String imaSdkVersion) { + this.imaSdkVersion = imaSdkVersion; + } } From e8ad6464dbd4f495af6c6487646afabddc74cd35 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Tue, 4 Jun 2024 12:50:50 +0200 Subject: [PATCH 25/30] Increase minSdkVersion to 19 --- CHANGELOG.md | 1 + build.gradle | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f5618..7c0d03d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Increased minimum required `compileSdk` version to `34` - Increased `compileSdk` and `targetSdkVersion` to `34` - Ad break started and ended is now reported in `PlayerEvent.AdBreakStarted` and `PlayerEvent.AdBreakFinished` +- Increased the `minSdkVersion` to 19 ### Removed - Custom event for `AdSkipped` and `AdError`. Replaced by Conviva build in tracking diff --git a/build.gradle b/build.gradle index 5ff8826..3022578 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ buildscript { } ext { - minSdkVersion = 16 + minSdkVersion = 19 targetSdkVersion = 34 compileSdkVersion = 34 } From 91b515e0eb613c586a6fad589d0bbd8801350d2a Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Tue, 4 Jun 2024 15:30:28 +0200 Subject: [PATCH 26/30] Add minimal CI --- .github/workflows/ci.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..8dab044 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,21 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +jobs: + build: + name: Build + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + architecture: ${{ inputs.architecture }} + - run: ./gradlew assemble From db1be29a3c9fcdaea502fb1831c002286e27994f Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Wed, 5 Jun 2024 08:20:45 +0200 Subject: [PATCH 27/30] Update .github/workflows/ci.yaml Co-authored-by: Matthias Tamegger <5555332+matamegger@users.noreply.github.com> --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8dab044..0c55404 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,4 +18,4 @@ jobs: distribution: 'zulu' java-version: '17' architecture: ${{ inputs.architecture }} - - run: ./gradlew assemble + - run: ./gradlew build From f6aaa8f501771d9b91af7f014e88fb089b4e2b86 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Wed, 5 Jun 2024 08:43:23 +0200 Subject: [PATCH 28/30] Update .github/workflows/ci.yaml Co-authored-by: Matthias Tamegger <5555332+matamegger@users.noreply.github.com> --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0c55404..586496e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,5 +17,4 @@ jobs: with: distribution: 'zulu' java-version: '17' - architecture: ${{ inputs.architecture }} - run: ./gradlew build From fd8ef21a26055b837664a29d9d379a736f79fe9b Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Thu, 6 Jun 2024 12:39:15 +0200 Subject: [PATCH 29/30] Update version --- conviva/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conviva/build.gradle b/conviva/build.gradle index 039a540..a8e4722 100644 --- a/conviva/build.gradle +++ b/conviva/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'maven-publish' apply from: "../bitmovinpropertiesloader.gradle" def packageName = 'com.bitmovin.analytics' -def libraryVersion = '2.3.0' +def libraryVersion = '2.4.0' android { namespace 'com.bitmovin.analytics.conviva' From f4c4db12c8f5db6ae1bf14158da25b4d66a0f838 Mon Sep 17 00:00:00 2001 From: Lukas Knoch-Girstmair Date: Thu, 6 Jun 2024 12:40:16 +0200 Subject: [PATCH 30/30] Update changelog --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c0d03d..fe07348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,20 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [Unreleased] +## 2.4.0 - 2024-06-06 ### Added - Ad analytics for ad event reporting ### Changed - Updated Bitmovin Player to `3.71.0` - Updated IMA SDK to `3.31.0` -- Updated Kotlin to `1.9.23` - Updated conviva-core to `4.0.37` -- Updated Gradle wrapper to `8.2` and AGP to `8.2.2` -- Increased minimum required `compileSdk` version to `34` +- Increased minimum required `compileSdk` version to `34` - Increased `compileSdk` and `targetSdkVersion` to `34` +- Increased `minSdkVersion` to `19` - Ad break started and ended is now reported in `PlayerEvent.AdBreakStarted` and `PlayerEvent.AdBreakFinished` -- Increased the `minSdkVersion` to 19 +- Updated Kotlin to `1.9.23` +- Updated Gradle wrapper to `8.2` and AGP to `8.2.2` ### Removed - Custom event for `AdSkipped` and `AdError`. Replaced by Conviva build in tracking