Skip to content

Commit dab52e2

Browse files
authored
[QA] Avoid collecting normal frames (#3782)
* avoid keeping normal frames in memory when collecting slow/frozen frames * renamed SpanFrameMetricsCollector.getTotalFrameCount method to getSlowFrozenFrameCount * confirm no delay in UI test when there are no slow/frozen frames collected
1 parent a183163 commit dab52e2

File tree

5 files changed

+30
-50
lines changed

5 files changed

+30
-50
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
### Fixes
1111

12+
- Avoid collecting normal frames ([#3782](https://github.com/getsentry/sentry-java/pull/3782))
1213
- Ensure android initialization process continues even if options configuration block throws an exception ([#3887](https://github.com/getsentry/sentry-java/pull/3887))
1314
- Do not report parsing ANR error when there are no threads ([#3888](https://github.com/getsentry/sentry-java/pull/3888))
1415
- This should significantly reduce the number of events with message "Sentry Android SDK failed to parse system thread dump..." reported

sentry-android-core/src/main/java/io/sentry/android/core/SentryFrameMetrics.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
@ApiStatus.Internal
77
final class SentryFrameMetrics {
88

9-
private int normalFrameCount;
109
private int slowFrameCount;
1110
private int frozenFrameCount;
1211

@@ -18,15 +17,11 @@ final class SentryFrameMetrics {
1817
public SentryFrameMetrics() {}
1918

2019
public SentryFrameMetrics(
21-
final int normalFrameCount,
2220
final int slowFrameCount,
2321
final long slowFrameDelayNanos,
2422
final int frozenFrameCount,
2523
final long frozenFrameDelayNanos,
2624
final long totalDurationNanos) {
27-
28-
this.normalFrameCount = normalFrameCount;
29-
3025
this.slowFrameCount = slowFrameCount;
3126
this.slowFrameDelayNanos = slowFrameDelayNanos;
3227

@@ -47,15 +42,9 @@ public void addFrame(
4742
} else if (isSlow) {
4843
slowFrameDelayNanos += delayNanos;
4944
slowFrameCount += 1;
50-
} else {
51-
normalFrameCount += 1;
5245
}
5346
}
5447

55-
public int getNormalFrameCount() {
56-
return normalFrameCount;
57-
}
58-
5948
public int getSlowFrameCount() {
6049
return slowFrameCount;
6150
}
@@ -72,17 +61,16 @@ public long getFrozenFrameDelayNanos() {
7261
return frozenFrameDelayNanos;
7362
}
7463

75-
public int getTotalFrameCount() {
76-
return normalFrameCount + slowFrameCount + frozenFrameCount;
64+
/** Returns the sum of the slow and frozen frames. */
65+
public int getSlowFrozenFrameCount() {
66+
return slowFrameCount + frozenFrameCount;
7767
}
7868

7969
public long getTotalDurationNanos() {
8070
return totalDurationNanos;
8171
}
8272

8373
public void clear() {
84-
normalFrameCount = 0;
85-
8674
slowFrameCount = 0;
8775
slowFrameDelayNanos = 0;
8876

@@ -95,7 +83,6 @@ public void clear() {
9583
@NotNull
9684
public SentryFrameMetrics duplicate() {
9785
return new SentryFrameMetrics(
98-
normalFrameCount,
9986
slowFrameCount,
10087
slowFrameDelayNanos,
10188
frozenFrameCount,
@@ -110,7 +97,6 @@ public SentryFrameMetrics duplicate() {
11097
@NotNull
11198
public SentryFrameMetrics diffTo(final @NotNull SentryFrameMetrics other) {
11299
return new SentryFrameMetrics(
113-
normalFrameCount - other.normalFrameCount,
114100
slowFrameCount - other.slowFrameCount,
115101
slowFrameDelayNanos - other.slowFrameDelayNanos,
116102
frozenFrameCount - other.frozenFrameCount,
@@ -123,8 +109,7 @@ public SentryFrameMetrics diffTo(final @NotNull SentryFrameMetrics other) {
123109
* to 0
124110
*/
125111
public boolean containsValidData() {
126-
return normalFrameCount >= 0
127-
&& slowFrameCount >= 0
112+
return slowFrameCount >= 0
128113
&& slowFrameDelayNanos >= 0
129114
&& frozenFrameCount >= 0
130115
&& frozenFrameDelayNanos >= 0

sentry-android-core/src/main/java/io/sentry/android/core/SpanFrameMetricsCollector.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private void captureFrameMetrics(@NotNull final ISpan span) {
192192
}
193193
}
194194

195-
int totalFrameCount = frameMetrics.getTotalFrameCount();
195+
int totalFrameCount = frameMetrics.getSlowFrozenFrameCount();
196196

197197
final long nextScheduledFrameNanos = frameMetricsCollector.getLastKnownFrameStartTimeNanos();
198198
// nextScheduledFrameNanos might be -1 if no frames have been scheduled for drawing yet
@@ -254,15 +254,17 @@ public void onFrameMetricCollected(
254254
(long) ((double) ONE_SECOND_NANOS / (double) refreshRate);
255255
lastKnownFrameDurationNanos = expectedFrameDurationNanos;
256256

257-
frames.add(
258-
new Frame(
259-
frameStartNanos,
260-
frameEndNanos,
261-
durationNanos,
262-
delayNanos,
263-
isSlow,
264-
isFrozen,
265-
expectedFrameDurationNanos));
257+
if (isSlow || isFrozen) {
258+
frames.add(
259+
new Frame(
260+
frameStartNanos,
261+
frameEndNanos,
262+
durationNanos,
263+
delayNanos,
264+
isSlow,
265+
isFrozen,
266+
expectedFrameDurationNanos));
267+
}
266268
}
267269

268270
private static int interpolateFrameCount(
@@ -277,7 +279,7 @@ private static int interpolateFrameCount(
277279
final long frameMetricsDurationNanos = frameMetrics.getTotalDurationNanos();
278280
final long nonRenderedDuration = spanDurationNanos - frameMetricsDurationNanos;
279281
if (nonRenderedDuration > 0) {
280-
return (int) (nonRenderedDuration / frameDurationNanos);
282+
return (int) Math.ceil((double) nonRenderedDuration / frameDurationNanos);
281283
}
282284
return 0;
283285
}

sentry-android-core/src/test/java/io/sentry/android/core/SentryFrameMetricsTest.kt

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ import kotlin.test.assertFalse
66
import kotlin.test.assertTrue
77

88
class SentryFrameMetricsTest {
9-
@Test
10-
fun addFastFrame() {
11-
val frameMetrics = SentryFrameMetrics()
12-
frameMetrics.addFrame(10, 0, false, false)
13-
assertEquals(1, frameMetrics.normalFrameCount)
14-
15-
frameMetrics.addFrame(10, 0, false, false)
16-
assertEquals(2, frameMetrics.normalFrameCount)
17-
}
189

1910
@Test
2011
fun addSlowFrame() {
@@ -43,10 +34,12 @@ class SentryFrameMetricsTest {
4334
@Test
4435
fun totalFrameCount() {
4536
val frameMetrics = SentryFrameMetrics()
37+
// Normal frames are ignored
4638
frameMetrics.addFrame(10, 0, false, false)
39+
// Slow and frozen frames are considered
4740
frameMetrics.addFrame(116, 100, true, false)
4841
frameMetrics.addFrame(1016, 1000, true, true)
49-
assertEquals(3, frameMetrics.totalFrameCount)
42+
assertEquals(2, frameMetrics.slowFrozenFrameCount)
5043
}
5144

5245
@Test
@@ -57,12 +50,11 @@ class SentryFrameMetricsTest {
5750
frameMetrics.addFrame(1016, 1000, true, true)
5851

5952
val dup = frameMetrics.duplicate()
60-
assertEquals(1, dup.normalFrameCount)
6153
assertEquals(1, dup.slowFrameCount)
6254
assertEquals(100, dup.slowFrameDelayNanos)
6355
assertEquals(1, dup.frozenFrameCount)
6456
assertEquals(1000, dup.frozenFrameDelayNanos)
65-
assertEquals(3, dup.totalFrameCount)
57+
assertEquals(2, dup.slowFrozenFrameCount)
6658
}
6759

6860
@Test
@@ -89,7 +81,7 @@ class SentryFrameMetricsTest {
8981
assertEquals(1, diff.frozenFrameCount)
9082
assertEquals(1000, diff.frozenFrameDelayNanos)
9183

92-
assertEquals(2, diff.totalFrameCount)
84+
assertEquals(2, diff.slowFrozenFrameCount)
9385
}
9486

9587
@Test
@@ -102,12 +94,11 @@ class SentryFrameMetricsTest {
10294

10395
frameMetrics.clear()
10496

105-
assertEquals(0, frameMetrics.normalFrameCount)
10697
assertEquals(0, frameMetrics.slowFrameCount)
10798
assertEquals(0, frameMetrics.slowFrameDelayNanos)
10899
assertEquals(0, frameMetrics.frozenFrameCount)
109100
assertEquals(0, frameMetrics.frozenFrameDelayNanos)
110-
assertEquals(0, frameMetrics.totalFrameCount)
101+
assertEquals(0, frameMetrics.slowFrozenFrameCount)
111102
}
112103

113104
@Test

sentry-android-core/src/test/java/io/sentry/android/core/SpanFrameMetricsCollectorTest.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class SpanFrameMetricsCollectorTest {
192192
sut.onFrameMetricCollected(0, 10, 10, 0, false, false, 60.0f)
193193
sut.onFrameMetricCollected(16, 48, 32, 16, true, false, 60.0f)
194194
sut.onFrameMetricCollected(60, 92, 32, 16, true, false, 60.0f)
195-
sut.onFrameMetricCollected(100, 800, 800, 784, true, true, 60.0f)
195+
sut.onFrameMetricCollected(100, 800, 700, 784, true, true, 60.0f)
196196

197197
// then a second span starts
198198
fixture.timeNanos = 800
@@ -337,10 +337,11 @@ class SpanFrameMetricsCollectorTest {
337337
fixture.timeNanos = TimeUnit.SECONDS.toNanos(2)
338338
sut.onSpanFinished(span)
339339

340-
// then still 60 frames should be reported (1 second at 60fps)
341-
verify(span).setData("frames.total", 60)
340+
// then still 61 frames should be reported (1 second at 60fps with approximation)
341+
verify(span).setData("frames.total", 61)
342342
verify(span).setData("frames.slow", 0)
343343
verify(span).setData("frames.frozen", 0)
344+
verify(span).setData("frames.delay", 0.0)
344345
}
345346

346347
@Test
@@ -364,9 +365,9 @@ class SpanFrameMetricsCollectorTest {
364365
sut.onSpanFinished(span)
365366

366367
// then
367-
// still 60 fps should be reported for 1 seconds
368+
// still 61 fps should be reported for 1 seconds (with approximation)
368369
// and one frame with frame delay should be reported (1s - 16ms)
369-
verify(span).setData("frames.total", 61)
370+
verify(span).setData("frames.total", 62)
370371
verify(span).setData("frames.slow", 0)
371372
verify(span).setData("frames.frozen", 1)
372373
verify(span).setData(eq("frames.delay"), AdditionalMatchers.eq(0.983333334, 0.01))

0 commit comments

Comments
 (0)