Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/optional auto end session #85

Merged
merged 4 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added
- Support for reporting the stack trace in case of error events, if provided by the player
- New `ConvivaAnalyticsIntegration.setAutoEndSession` to not end Conviva session automatically from certain player events if set to false (true by default).
stonko1994 marked this conversation as resolved.
Show resolved Hide resolved
- New `ConvivaAnalyticsIntegration.reportPlaybackStalled` to report a stalled event to Conviva

## 2.7.2 - 2024-10-28

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public Boolean getSessionActive() {
@Nullable
private AdBreak activeAdBreak;

private Boolean isAutoEndSession = true;

public ConvivaAnalyticsIntegration(String customerKey, Context context) {
this(
null,
Expand Down Expand Up @@ -167,6 +169,14 @@ public SsaiApi getSsai() {
return ssai;
}

public Boolean getAutoEndSession() {
return isAutoEndSession;
}

public void setAutoEndSession(Boolean autoEndingSession) {
isAutoEndSession = autoEndingSession;
}

public void sendCustomApplicationEvent(String name) {
sendCustomApplicationEvent(name, new HashMap<>());
}
Expand Down Expand Up @@ -252,6 +262,16 @@ public void release(Boolean releaseConvivaSdk) {
isSessionActive = false;
}

/**
* Sends a stalled event during playback to Conviva's Player Insight. If no session is active it will NOT
* create one.
*/
public void reportPlaybackStalled() {
stonko1994 marked this conversation as resolved.
Show resolved Hide resolved
if (isSessionActive) {
transitionState(ConvivaSdkConstants.PlayerState.BUFFERING);
}
}

/**
* Sends a custom deficiency event during playback to Conviva's Player Insight. If no session is active it will NOT
* create one.
Expand All @@ -260,7 +280,7 @@ public void release(Boolean releaseConvivaSdk) {
* @param severity One of FATAL or WARNING
*/
public void reportPlaybackDeficiency(String message, ConvivaSdkConstants.ErrorSeverity severity) {
reportPlaybackDeficiency(message, severity, true);
reportPlaybackDeficiency(message, severity, isAutoEndSession);
}

/**
Expand Down Expand Up @@ -573,7 +593,9 @@ private synchronized void transitionState(ConvivaSdkConstants.PlayerState state)
// TODO: remove this once the event order is fixed on the Android SDK.
new Handler().postDelayed(() -> {
Log.d(TAG, "[Player Event] SourceUnloaded");
internalEndSession();
if (isAutoEndSession) {
internalEndSession();
}
}, 100);
};

Expand All @@ -594,8 +616,7 @@ private void handleError(String message) {
if (ssai.isAdBreakActive()) {
convivaAdAnalytics.reportAdError(message, severity);
}
convivaVideoAnalytics.reportPlaybackError(message, severity);
internalEndSession();
reportPlaybackDeficiency(message, severity);
}

private final EventListener<PlayerEvent.Warning> onPlayerWarningListener = new EventListener<PlayerEvent.Warning>() {
Expand Down Expand Up @@ -661,12 +682,14 @@ public void onEvent(SourceEvent.Warning warningEvent) {
private final EventListener<PlayerEvent.PlaybackFinished> onPlaybackFinishedListener = playbackFinishedEvent -> {
Log.d(TAG, "[Player Event] PlaybackFinished");
transitionState(ConvivaSdkConstants.PlayerState.STOPPED);
internalEndSession();
if (isAutoEndSession) {
internalEndSession();
}
};

private final EventListener<PlayerEvent.StallStarted> onStallStartedListener = stallStartedEvent -> {
Log.d(TAG, "[Player Event] StallStarted");
transitionState(ConvivaSdkConstants.PlayerState.BUFFERING);
reportPlaybackStalled();
};

private final EventListener<PlayerEvent.StallEnded> onStallEndedListener = new EventListener<PlayerEvent.StallEnded>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class ConvivaAnalyticsIntegrationTest {
adAnalytics,
ssaiApi,
)
convivaAnalyticsIntegration.initializeSession()
clearMocks(videoAnalytics, answers = true)
}

@After
Expand Down Expand Up @@ -177,6 +179,8 @@ class ConvivaAnalyticsIntegrationTest {

@Test
fun `does not report a playback error when receiving a player warning event without active conviva session`() {
convivaAnalyticsIntegration.endSession()

player.listeners[PlayerEvent.Warning::class]?.forEach { onEvent ->
onEvent(PlayerEvent.Warning(PlayerWarningCode.General, "warning"))
}
Expand All @@ -185,12 +189,26 @@ class ConvivaAnalyticsIntegrationTest {

@Test
fun `does not report a playback error when receiving a source warning event without active conviva session`() {
convivaAnalyticsIntegration.endSession()

player.listeners[SourceEvent.Warning::class]?.forEach { onEvent ->
onEvent(SourceEvent.Warning(SourceWarningCode.General, "warning"))
}
verify(exactly = 0) { videoAnalytics.reportPlaybackError(any(), any()) }
}

@Test
fun `does not report a playback stalled without active conviva session`() {
convivaAnalyticsIntegration.reportPlaybackStalled()
verify(exactly = 1) { videoAnalytics.reportPlaybackMetric(any(), any()) }

convivaAnalyticsIntegration.endSession()
clearMocks(videoAnalytics, answers = true)

convivaAnalyticsIntegration.reportPlaybackStalled()
verify(exactly = 0) { videoAnalytics.reportPlaybackMetric(any(), any()) }
}

@Test
fun `reports CSAI ad position based on last ad break schedule time`() {
player.listeners[PlayerEvent.AdBreakStarted::class]?.forEach {
Expand Down