Skip to content

Commit

Permalink
Merge pull request #40 from THEOplayer/feature/THEO-10603-sgai-conviva
Browse files Browse the repository at this point in the history
Feature/theo 10603 sgai conviva
  • Loading branch information
Jeroen-Veltmans authored Dec 11, 2024
2 parents b2af35c + 851e9fc commit 62c23d3
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ import com.conviva.sdk.ConvivaAdAnalytics
import com.conviva.sdk.ConvivaExperienceAnalytics
import com.conviva.sdk.ConvivaSdkConstants
import com.conviva.sdk.ConvivaVideoAnalytics
import com.theoplayer.android.api.ads.Ad
import com.theoplayer.android.api.ads.AdBreak
import com.theoplayer.android.api.ads.GoogleImaAd
import com.theoplayer.android.api.ads.ima.GoogleImaAdEvent
import com.theoplayer.android.api.ads.ima.GoogleImaAdEventType
import com.theoplayer.android.api.event.EventDispatcher
import com.theoplayer.android.api.event.EventListener
import com.theoplayer.android.api.event.ads.AdBeginEvent
import com.theoplayer.android.api.event.ads.AdBreakBeginEvent
import com.theoplayer.android.api.event.ads.AdBreakEndEvent
import com.theoplayer.android.api.event.ads.AdEndEvent
import com.theoplayer.android.api.event.ads.AdErrorEvent
import com.theoplayer.android.api.event.ads.AdEvent
import com.theoplayer.android.api.event.ads.AdIntegrationKind
import com.theoplayer.android.api.event.ads.AdSkipEvent
import com.theoplayer.android.api.event.ads.AdsEventTypes
import com.theoplayer.android.api.event.player.*
import com.theoplayer.android.api.player.Player
import com.theoplayer.android.connector.analytics.conviva.BuildConfig
Expand All @@ -21,8 +30,9 @@ import com.theoplayer.android.connector.analytics.conviva.utils.calculateAdTypeA
import com.theoplayer.android.connector.analytics.conviva.utils.calculateCurrentAdBreakInfo
import com.theoplayer.android.connector.analytics.conviva.utils.collectAdMetadata
import com.theoplayer.android.connector.analytics.conviva.utils.collectPlayerInfo
import com.theoplayer.android.connector.analytics.conviva.utils.updateAdMetadataForGoogleIma

fun isAdLinear(ad: GoogleImaAd?): Boolean {
fun isAdLinear(ad: Ad?): Boolean {
return ad?.type == "linear"
}

Expand All @@ -37,19 +47,25 @@ class AdReporter(
private val adEventsExtension: EventDispatcher<AdEvent<*>>?
) : ConvivaExperienceAnalytics.ICallback {
private var currentAdBreak: AdBreak? = null
private var currentAd: GoogleImaAd? = null
private var currentAd: Ad? = null
private var adBreakCounter = 0

private val onPlay: EventListener<PlayEvent>
private val onPlaying: EventListener<PlayingEvent>
private val onPause: EventListener<PauseEvent>

private val onAdStarted: EventListener<GoogleImaAdEvent>
private val onAdCompleted: EventListener<GoogleImaAdEvent>
private val onAdSkip: EventListener<GoogleImaAdEvent>
private val onAdBuffering: EventListener<GoogleImaAdEvent>
private val onAdError: EventListener<GoogleImaAdEvent>
private val onContentResume: EventListener<GoogleImaAdEvent>
private val onImaAdStarted: EventListener<GoogleImaAdEvent>
private val onImaAdCompleted: EventListener<GoogleImaAdEvent>
private val onImaAdSkip: EventListener<GoogleImaAdEvent>
private val onImaAdBuffering: EventListener<GoogleImaAdEvent>
private val onImaAdError: EventListener<GoogleImaAdEvent>
private val onImaContentResume: EventListener<GoogleImaAdEvent>

private val onAdBegin: EventListener<AdBeginEvent>
private val onAdEnd: EventListener<AdEndEvent>
private val onAdBreakEnd: EventListener<AdBreakEndEvent>
private val onAdSkip: EventListener<AdSkipEvent>
private val onAdError: EventListener<AdErrorEvent>

init {
convivaAdAnalytics.setCallback(this)
Expand Down Expand Up @@ -91,27 +107,19 @@ class AdReporter(
}
}

onAdStarted = EventListener<GoogleImaAdEvent> { event ->
onImaAdStarted = EventListener<GoogleImaAdEvent> { event ->
handleAdBegin(event.ad)
}

onAdCompleted = EventListener<GoogleImaAdEvent> { event ->
onImaAdCompleted = EventListener<GoogleImaAdEvent> { event ->
handleAdEnd(event.ad)
}

onAdSkip = EventListener<GoogleImaAdEvent> {
if (currentAdBreak != null) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdMetric - PlayerState.STOPPED")
}
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.PLAYER_STATE,
ConvivaSdkConstants.PlayerState.STOPPED
)
}
onImaAdSkip = EventListener<GoogleImaAdEvent> {
handleAdSkip()
}

onAdBuffering = EventListener<GoogleImaAdEvent> {
onImaAdBuffering = EventListener<GoogleImaAdEvent> {
if (currentAdBreak != null) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdMetric - PlayerState.BUFFERING")
Expand All @@ -123,17 +131,34 @@ class AdReporter(
}
}

onAdError = EventListener<GoogleImaAdEvent> {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdFailed")
}
convivaAdAnalytics.reportAdFailed("Ad Request Failed")
onImaAdError = EventListener<GoogleImaAdEvent> {
handleAdError()
}

onImaContentResume = EventListener<GoogleImaAdEvent> {
handleAdBreakEnd()
}

onAdBegin = EventListener<AdBeginEvent> { event ->
handleAdBegin(event.ad)
}

onAdEnd = EventListener<AdEndEvent> { event ->
handleAdEnd(event.ad)
}

onContentResume = EventListener<GoogleImaAdEvent> {
onAdBreakEnd = EventListener<AdBreakEndEvent> {
handleAdBreakEnd()
}

onAdSkip = EventListener<AdSkipEvent> {
handleAdSkip()
}

onAdError = EventListener<AdErrorEvent> {
handleAdError()
}

addEventListeners()
}

Expand All @@ -159,14 +184,20 @@ class AdReporter(
player.addEventListener(PlayerEventTypes.PAUSE, onPause)

(listOf(player.ads, adEventsExtension)).forEach { ads ->
ads?.addEventListener(GoogleImaAdEventType.STARTED, onAdStarted)
ads?.addEventListener(GoogleImaAdEventType.COMPLETED, onAdCompleted)
ads?.addEventListener(GoogleImaAdEventType.SKIPPED, onAdSkip)
ads?.addEventListener(GoogleImaAdEventType.AD_BUFFERING, onAdBuffering)
ads?.addEventListener(GoogleImaAdEventType.AD_ERROR, onAdError)
ads?.addEventListener(AdsEventTypes.AD_BEGIN, onAdBegin)
ads?.addEventListener(AdsEventTypes.AD_END, onAdEnd)
ads?.addEventListener(AdsEventTypes.AD_BREAK_END, onAdBreakEnd)
ads?.addEventListener(AdsEventTypes.AD_SKIP, onAdSkip)
ads?.addEventListener(AdsEventTypes.AD_ERROR, onAdError)

ads?.addEventListener(GoogleImaAdEventType.STARTED, onImaAdStarted)
ads?.addEventListener(GoogleImaAdEventType.COMPLETED, onImaAdCompleted)
ads?.addEventListener(GoogleImaAdEventType.SKIPPED, onImaAdSkip)
ads?.addEventListener(GoogleImaAdEventType.AD_BUFFERING, onImaAdBuffering)
ads?.addEventListener(GoogleImaAdEventType.AD_ERROR, onImaAdError)
ads?.addEventListener(
GoogleImaAdEventType.CONTENT_RESUME_REQUESTED,
onContentResume
onImaContentResume
)
}
}
Expand All @@ -177,14 +208,20 @@ class AdReporter(
player.removeEventListener(PlayerEventTypes.PAUSE, onPause)

(listOf(player.ads, adEventsExtension)).forEach { ads ->
ads?.removeEventListener(GoogleImaAdEventType.STARTED, onAdStarted)
ads?.removeEventListener(GoogleImaAdEventType.COMPLETED, onAdCompleted)
ads?.removeEventListener(GoogleImaAdEventType.SKIPPED, onAdSkip)
ads?.removeEventListener(GoogleImaAdEventType.AD_BUFFERING, onAdBuffering)
ads?.removeEventListener(GoogleImaAdEventType.AD_ERROR, onAdError)
ads?.addEventListener(AdsEventTypes.AD_BEGIN, onAdBegin)
ads?.addEventListener(AdsEventTypes.AD_END, onAdEnd)
ads?.addEventListener(AdsEventTypes.AD_BREAK_END, onAdBreakEnd)
ads?.addEventListener(AdsEventTypes.AD_SKIP, onAdSkip)
ads?.addEventListener(AdsEventTypes.AD_ERROR, onAdError)

ads?.removeEventListener(GoogleImaAdEventType.STARTED, onImaAdStarted)
ads?.removeEventListener(GoogleImaAdEventType.COMPLETED, onImaAdCompleted)
ads?.removeEventListener(GoogleImaAdEventType.SKIPPED, onImaAdSkip)
ads?.removeEventListener(GoogleImaAdEventType.AD_BUFFERING, onImaAdBuffering)
ads?.removeEventListener(GoogleImaAdEventType.AD_ERROR, onImaAdError)
ads?.removeEventListener(
GoogleImaAdEventType.CONTENT_RESUME_REQUESTED,
onContentResume
onImaContentResume
)
}
}
Expand All @@ -205,7 +242,7 @@ class AdReporter(
adBreakCounter++
convivaVideoAnalytics.reportAdBreakStarted(
ConvivaSdkConstants.AdPlayer.CONTENT,
calculateAdType(player),
calculateAdType(adBreak),
calculateCurrentAdBreakInfo(adBreak, adBreakCounter)
)
} else {
Expand All @@ -215,8 +252,8 @@ class AdReporter(
}
}

private fun handleAdBegin(ad: GoogleImaAd?) {
if (currentAdBreak == null && ad?.imaAd != null) {
private fun handleAdBegin(ad: Ad?) {
if (currentAdBreak == null && ad != null) {
handleAdBreakBegin(ad.adBreak, isAdLinear(ad))
}
if (ad != null && isAdLinear(ad)) {
Expand All @@ -226,11 +263,17 @@ class AdReporter(
// - `c3.csid`: the content’s sessionID;
// - `contentAssetName`: the content's assetName.
val contentAssetName = convivaHandler.contentAssetName
val adMetadata = collectAdMetadata(ad) + mapOf(
val adTechnology = calculateAdTypeAsString(ad)
var adMetadata = collectAdMetadata(ad) + mapOf(
"c3.csid" to convivaVideoAnalytics.sessionId.toString(),
"contentAssetName" to contentAssetName,
"c3.ad.technology" to calculateAdTypeAsString(player),
"c3.ad.technology" to adTechnology,
)
if (ad is GoogleImaAd) {
// Update with Google IMA specific information
adMetadata = updateAdMetadataForGoogleIma(ad, adMetadata)
}

if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdStarted - $adMetadata")
}
Expand All @@ -242,15 +285,22 @@ class AdReporter(
player.videoWidth,
player.videoHeight
)
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.BITRATE,
player.videoWidth,
ad.imaAd.vastMediaBitrate
)
if (ad is GoogleImaAd) {
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.BITRATE,
player.videoWidth,
ad.imaAd.vastMediaBitrate
)
} else {
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.BITRATE,
player.videoWidth
)
}

// Report playing state in case of SSAI, as the player will not send an additional
// `playing` event.
if (calculateAdType(player) == ConvivaSdkConstants.AdType.SERVER_SIDE) {
if (calculateAdType(ad) == ConvivaSdkConstants.AdType.SERVER_SIDE) {
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.PLAYER_STATE,
ConvivaSdkConstants.PlayerState.PLAYING
Expand All @@ -263,7 +313,7 @@ class AdReporter(
}
}

private fun handleAdEnd(ad: GoogleImaAd?) {
private fun handleAdEnd(ad: Ad?) {
if (ad != null && isAdLinear(ad)) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdEnded")
Expand Down Expand Up @@ -292,6 +342,25 @@ class AdReporter(
currentAdBreak = null
}

private fun handleAdSkip() {
if (currentAdBreak != null) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdMetric - PlayerState.STOPPED")
}
convivaAdAnalytics.reportAdMetric(
ConvivaSdkConstants.PLAYBACK.PLAYER_STATE,
ConvivaSdkConstants.PlayerState.STOPPED
)
}
}

private fun handleAdError() {
if (BuildConfig.DEBUG) {
Log.d(TAG, "reportAdFailed")
}
convivaAdAnalytics.reportAdFailed("Ad Request Failed")
}

fun reset() {
// Optionally report end of current Ad
if (currentAd != null) {
Expand Down
Loading

0 comments on commit 62c23d3

Please sign in to comment.