Skip to content

Commit

Permalink
Merge pull request #35 from at-internet/develop
Browse files Browse the repository at this point in the history
fix: avinsights heartbeats were miscalculated
  • Loading branch information
piano-analytics authored May 31, 2023
2 parents 180262a + fd0440c commit 493ce15
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 23 deletions.
4 changes: 2 additions & 2 deletions ATMobileAnalytics/Tracker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply plugin: 'jacoco'
apply from: './publish-mavencentral.gradle'

group = 'com.atinternet'
version = '2.21.2'
version = '2.21.3'

android {
compileSdkVersion 30
Expand Down Expand Up @@ -182,4 +182,4 @@ task jacocoTestReport(type: JacocoReport, dependsOn: "testReleaseUnitTest") {
xml.enabled true
html.enabled false
}
}
}
4 changes: 2 additions & 2 deletions ATMobileAnalytics/Tracker/publish-mavencentral.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publishing {
release(MavenPublication) {
groupId 'com.atinternet'
artifactId 'Tracker'
version '2.21.2'
version '2.21.3'

artifact(project.buildDir.absolutePath + "/outputs/aar/${project.getName()}-release.aar")
artifact androidSourcesJar
Expand Down Expand Up @@ -64,4 +64,4 @@ signing {

nexusStaging {
packageGroup = 'com.atinternet'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ class TechnicalContext {
static final Closure VTAG = new Closure() {
@Override
public String execute() {
return "2.21.2";
return "2.21.3";
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.atinternet.tracker.RequiredPropertiesDataObject;
import com.atinternet.tracker.Utility;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
Expand All @@ -31,6 +32,8 @@ public class Media extends RequiredPropertiesDataObject {

private String sessionId;
private String previousEvent = "";
private int previousHeartbeatDelay = 0;
private int previousBufferHeartbeatDelay = 0;
private int previousCursorPositionMillis = 0;
private int currentCursorPositionMillis = 0;
private long eventDurationMillis = 0;
Expand All @@ -53,6 +56,8 @@ public Media(Events events) {
heartbeatRunnable = new HeartbeatRunnable(this);
bufferHeartbeatRunnable = new BufferHeartbeatRunnable(this);
rebufferHeartbeatRunnable = new RebufferHeartbeatRunnable(this);

this.sessionId = UUID.randomUUID().toString();
}

public Media(Events events, int heartbeat, int bufferHeartbeat, String sessionId) {
Expand All @@ -73,7 +78,9 @@ public Media(Events events, SparseIntArray heartbeat, SparseIntArray bufferHeart
this(events);
setHeartbeat(createHeartbeatStages(MIN_HEARTBEAT_DURATION));
setBufferHeartbeat(createHeartbeatStages(MIN_BUFFER_HEARTBEAT_DURATION));
this.sessionId = TextUtils.isEmpty(sessionId) ? UUID.randomUUID().toString() : sessionId;
if (!TextUtils.isEmpty(sessionId)) {
this.sessionId = sessionId;
}
}

/***
Expand Down Expand Up @@ -201,8 +208,7 @@ public synchronized void setPlaybackSpeed(double playbackSpeed) {
heartbeat(-1, null);

if (autoHeartbeat) {
int diffMin = (int) ((Utility.currentTimeMillis() - startSessionTimeMillis) / 60_000);
heartbeatExecutor.schedule(heartbeatRunnable, heartbeatDurations.get(diffMin, MIN_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousHeartbeatDelay = updateHeartbeatRunnable(this.previousHeartbeatDelay, startSessionTimeMillis, MIN_HEARTBEAT_DURATION, heartbeatDurations, heartbeatRunnable);
}
this.playbackSpeed = playbackSpeed;
}
Expand Down Expand Up @@ -266,15 +272,13 @@ public synchronized void bufferStart(int cursorPosition, Map<String, Object> ext
if (isPlaybackActivated) {
if (autoBufferHeartbeat) {
bufferTimeMillis = bufferTimeMillis == 0 ? Utility.currentTimeMillis() : bufferTimeMillis;
int diffMin = (int) ((Utility.currentTimeMillis() - bufferTimeMillis) / 60_000);
heartbeatExecutor.schedule(rebufferHeartbeatRunnable, bufferHeartbeatDurations.get(diffMin, MIN_BUFFER_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousBufferHeartbeatDelay = updateHeartbeatRunnable(this.previousBufferHeartbeatDelay, bufferTimeMillis, MIN_BUFFER_HEARTBEAT_DURATION, bufferHeartbeatDurations, rebufferHeartbeatRunnable);
}
sendEvents(createEvent("av.rebuffer.start", true, extraProps));
} else {
if (autoBufferHeartbeat) {
bufferTimeMillis = bufferTimeMillis == 0 ? Utility.currentTimeMillis() : bufferTimeMillis;
int diffMin = (int) ((Utility.currentTimeMillis() - bufferTimeMillis) / 60_000);
heartbeatExecutor.schedule(bufferHeartbeatRunnable, bufferHeartbeatDurations.get(diffMin, MIN_BUFFER_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousBufferHeartbeatDelay = updateHeartbeatRunnable(this.previousBufferHeartbeatDelay, bufferTimeMillis, MIN_BUFFER_HEARTBEAT_DURATION, bufferHeartbeatDurations, bufferHeartbeatRunnable);
}
sendEvents(createEvent("av.buffer.start", true, extraProps));
}
Expand All @@ -298,8 +302,7 @@ public synchronized void playbackStart(int cursorPosition, Map<String, Object> e

stopHeartbeatService();
if (autoHeartbeat) {
int diffMin = (int) ((Utility.currentTimeMillis() - startSessionTimeMillis) / 60_000);
heartbeatExecutor.schedule(heartbeatRunnable, heartbeatDurations.get(diffMin, MIN_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousHeartbeatDelay = updateHeartbeatRunnable(this.previousHeartbeatDelay, startSessionTimeMillis, MIN_HEARTBEAT_DURATION, heartbeatDurations, heartbeatRunnable);
}

sendEvents(createEvent("av.start", true, extraProps));
Expand All @@ -322,8 +325,7 @@ public synchronized void playbackResumed(int cursorPosition, Map<String, Object>

stopHeartbeatService();
if (autoHeartbeat) {
int diffMin = (int) ((Utility.currentTimeMillis() - startSessionTimeMillis) / 60_000);
heartbeatExecutor.schedule(heartbeatRunnable, heartbeatDurations.get(diffMin, MIN_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousHeartbeatDelay = updateHeartbeatRunnable(this.previousHeartbeatDelay, startSessionTimeMillis, MIN_HEARTBEAT_DURATION, heartbeatDurations, heartbeatRunnable);
}

sendEvents(createEvent("av.resume", true, extraProps));
Expand Down Expand Up @@ -510,6 +512,13 @@ public void share(Map<String, Object> extraProps) {
sendEvents(createEvent("av.share", false, extraProps));
}

private int updateHeartbeatRunnable(int previousHeartbeatDelay, long startTimerMillis, int MIN_HEARTBEAT_DURATION, SparseIntArray heartbeatDurations, AVRunnable heartbeatRunnable) {
int minutesDelay = (int) ((currentTimeMillis() - startTimerMillis) / 60_000);
int heartbeatDelay = Math.max(heartbeatDurations.get(minutesDelay, previousHeartbeatDelay), MIN_HEARTBEAT_DURATION);
heartbeatExecutor.schedule(heartbeatRunnable, heartbeatDelay, TimeUnit.SECONDS);
return heartbeatDelay;
}

synchronized void processHeartbeat(int cursorPosition, boolean fromAuto, Map<String, Object> extraProps) {
startSessionTimeMillis = startSessionTimeMillis == 0 ? Utility.currentTimeMillis() : startSessionTimeMillis;

Expand All @@ -523,8 +532,7 @@ synchronized void processHeartbeat(int cursorPosition, boolean fromAuto, Map<Str
}

if (fromAuto) {
int diffMin = (int) ((Utility.currentTimeMillis() - startSessionTimeMillis) / 60_000);
heartbeatExecutor.schedule(heartbeatRunnable, heartbeatDurations.get(diffMin, MIN_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousHeartbeatDelay = updateHeartbeatRunnable(this.previousHeartbeatDelay, startSessionTimeMillis, MIN_HEARTBEAT_DURATION, heartbeatDurations, heartbeatRunnable);
}

sendEvents(createEvent("av.heartbeat", true, extraProps));
Expand All @@ -537,8 +545,7 @@ synchronized void processBufferHeartbeat(boolean fromAuto, Map<String, Object> e

if (fromAuto) {
bufferTimeMillis = bufferTimeMillis == 0 ? Utility.currentTimeMillis() : bufferTimeMillis;
int diffMin = (int) ((Utility.currentTimeMillis() - bufferTimeMillis) / 60_000);
heartbeatExecutor.schedule(bufferHeartbeatRunnable, bufferHeartbeatDurations.get(diffMin, MIN_BUFFER_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousBufferHeartbeatDelay = updateHeartbeatRunnable(this.previousBufferHeartbeatDelay, bufferTimeMillis, MIN_BUFFER_HEARTBEAT_DURATION, bufferHeartbeatDurations, bufferHeartbeatRunnable);
}
sendEvents(createEvent("av.buffer.heartbeat", true, extraProps));
}
Expand All @@ -552,8 +559,7 @@ synchronized void processRebufferHeartbeat(boolean fromAuto, Map<String, Object>

if (fromAuto) {
bufferTimeMillis = bufferTimeMillis == 0 ? Utility.currentTimeMillis() : bufferTimeMillis;
int diffMin = (int) ((Utility.currentTimeMillis() - bufferTimeMillis) / 60_000);
heartbeatExecutor.schedule(rebufferHeartbeatRunnable, bufferHeartbeatDurations.get(diffMin, MIN_BUFFER_HEARTBEAT_DURATION), TimeUnit.SECONDS);
this.previousBufferHeartbeatDelay = updateHeartbeatRunnable(this.previousBufferHeartbeatDelay, bufferTimeMillis, MIN_BUFFER_HEARTBEAT_DURATION, bufferHeartbeatDurations, rebufferHeartbeatRunnable);
}

sendEvents(createEvent("av.rebuffer.heartbeat", true, extraProps));
Expand Down Expand Up @@ -581,6 +587,29 @@ private synchronized void processSeek(String seekDirection, int oldCursorPositio
sendEvents(seekStart, createEvent("av." + seekDirection, true, extraProps));
}

private long currentTimeMillis() {
long timeMillis;
int year;
int retry = 3;
do {
retry--;
timeMillis = System.currentTimeMillis();

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timeMillis);
year = cal.get(Calendar.YEAR);
if (year < 2000) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} while (year < 2000 && retry > 0);

return timeMillis;
}

private synchronized Event createEvent(String name, boolean withOptions, Map<String, Object> extraProps) {
Map<String, Object> props = new HashMap<>(this.getProps());
if (withOptions) {
Expand Down Expand Up @@ -627,4 +656,4 @@ private void resetState() {
currentCursorPositionMillis = 0;
eventDurationMillis = 0;
}
}
}

0 comments on commit 493ce15

Please sign in to comment.