@@ -51,8 +51,8 @@ class VPNService : android.net.VpnService() {
51
51
override fun onTick (millisUntilFinished : Long ) {
52
52
// We want to skip the first onTick, which is called as the timer is started.
53
53
// (The Start ping is sent then, so there is no need for a Timer ping.)
54
- var wasTimerJustStarted = (millisUntilFinished == mBackgroundPingTimerMSec)
55
- if (! wasTimerJustStarted && isUsingShortTimerSessionPing && shouldRecordTimerAndEndMetrics ) {
54
+ var wasTimerJustStarted = (millisUntilFinished >= ( mBackgroundPingTimerMSec - 1000 ) )
55
+ if (! wasTimerJustStarted && isUsingShortTimerSessionPing && isSuperDooperMetricsActive ) {
56
56
Log .i(tag, " Sending daemon_timer ping (on short timer debug schedule)" )
57
57
Pings .daemonsession.submit(
58
58
Pings .daemonsessionReasonCodes.daemonTimer,
@@ -61,8 +61,7 @@ class VPNService : android.net.VpnService() {
61
61
}
62
62
override fun onFinish () {
63
63
Log .i(tag, " Sending daemon_timer ping" )
64
- if (shouldRecordTimerAndEndMetrics) {
65
- recordDataTransferMetrics()
64
+ if (isSuperDooperMetricsActive) {
66
65
Pings .daemonsession.submit(
67
66
Pings .daemonsessionReasonCodes.daemonTimer,
68
67
)
@@ -84,11 +83,6 @@ class VPNService : android.net.VpnService() {
84
83
return (this .mConfig?.optInt(" reason" ) ? : 0 ) == 1
85
84
}
86
85
87
- private val shouldRecordTimerAndEndMetrics: Boolean
88
- get() {
89
- return isSuperDooperMetricsActive && ! isAppChangingServers
90
- }
91
-
92
86
private val isUsingShortTimerSessionPing: Boolean
93
87
get() {
94
88
return this .mConfig?.optBoolean(" isUsingShortTimerSessionPing" , false ) ? : false
@@ -325,6 +319,12 @@ class VPNService : android.net.VpnService() {
325
319
// now.
326
320
if (currentTunnelHandle != - 1 ) {
327
321
Log .i(tag, " Currently have a connection, close old handle" )
322
+ // Record data transfer metrics, as we're switching servers/configs and this data will get reset
323
+ // Data metrics must be recorded prior to wgTurnOff, or we can't get data from the config
324
+ if (isSuperDooperMetricsActive) {
325
+ recordDataTransferMetrics()
326
+ }
327
+
328
328
wgTurnOff(currentTunnelHandle)
329
329
}
330
330
currentTunnelHandle = wgTurnOn(" mvpn0" , tun.detachFd(), wgConfig)
@@ -338,12 +338,14 @@ class VPNService : android.net.VpnService() {
338
338
protect(wgGetSocketV6(currentTunnelHandle))
339
339
340
340
mConfig = json
341
- // shouldRecordStartTelemetry must be calculated after mConfig is set (on prior line)
342
341
// We don't want to record start metrics in several situations:
343
- // - If Super Dooper feature is not active. (Covered by shouldRecordTimerAndEndMetrics)
344
- // - If this is an app-caused server switch. (Covered by shouldRecordTimerAndEndMetrics)
345
- // - If this is a daemon-caused server switch. (Covered by isDaemonChangingServers)
346
- val shouldRecordStartTelemetry = shouldRecordTimerAndEndMetrics && ! isDaemonChangingServers
342
+ // - If Super Dooper feature is not active.
343
+ // - If this is an app-caused server switch.
344
+ // - If this is a daemon-caused server switch.
345
+ // This must be calculated after mConfig is set (on line above)
346
+ val isChangingServers = isDaemonChangingServers || isAppChangingServers
347
+ val shouldSkipStartTelemetry = ! isSuperDooperMetricsActive || isChangingServers
348
+ Log .i(tag, " Is changing server: " + shouldSkipStartTelemetry)
347
349
348
350
// Store the config in case the service gets
349
351
// asked boot vpn from the OS
@@ -363,13 +365,17 @@ class VPNService : android.net.VpnService() {
363
365
} else {
364
366
fallbackIpv4 = json.getJSONArray(" servers" ).getJSONObject(0 ).getString(" ipv4AddrIn" )
365
367
}
366
- mConnectionHealth.start(
367
- jServer.getString(" ipv4AddrIn" ),
368
- jServer.getString(" ipv4Gateway" ),
369
- json.getString(" dns" ),
370
- fallbackIpv4,
371
- shouldRecordStartTelemetry,
372
- )
368
+
369
+ // If changing server, connection health is still running
370
+ if (! isChangingServers) {
371
+ mConnectionHealth.start(
372
+ jServer.getString(" ipv4AddrIn" ),
373
+ jServer.getString(" ipv4Gateway" ),
374
+ json.getString(" dns" ),
375
+ fallbackIpv4,
376
+ isSuperDooperMetricsActive,
377
+ )
378
+ }
373
379
374
380
// For `isGleanDebugTagActive` and `isSuperDooperMetricsActive` to work,
375
381
// this must be after the mConfig is set to the latest data.
@@ -378,7 +384,8 @@ class VPNService : android.net.VpnService() {
378
384
Log .i(tag, " Setting Glean debug tag for daemon." )
379
385
Glean .setDebugViewTag(gleanTag)
380
386
}
381
- if (shouldRecordStartTelemetry) {
387
+ if (! shouldSkipStartTelemetry) {
388
+ Log .v(tag, " Recording start telmetry" )
382
389
val installationIdString = json.getString(" installationId" )
383
390
installationIdString?.let {
384
391
try {
@@ -401,7 +408,10 @@ class VPNService : android.net.VpnService() {
401
408
Pings .daemonsession.submit(
402
409
Pings .daemonsessionReasonCodes.daemonStart,
403
410
)
411
+ } else {
412
+ Log .v(tag, " Skipping recording of start telemetry" )
404
413
}
414
+ mMetricsTimer.cancel() // if this is a server switch, time is already running and must be reset
405
415
mMetricsTimer.start()
406
416
}
407
417
@@ -455,8 +465,10 @@ class VPNService : android.net.VpnService() {
455
465
456
466
fun turnOff () {
457
467
Log .v(tag, " Try to disable tunnel" )
458
- if (shouldRecordTimerAndEndMetrics) {
459
- // Data metrics must be recorded prior to wgTurnOff, or we can't get data from the cocnfig
468
+ // turnOff is not called when switching locations, doing a silent server switch from app, or doing a silent server switch from daemon...
469
+ // Thus we always want to record end-of-session metrics here, and send the ping below.
470
+ if (isSuperDooperMetricsActive) {
471
+ // Data metrics must be recorded prior to wgTurnOff, or we can't get data from the config
460
472
recordDataTransferMetrics()
461
473
}
462
474
@@ -471,7 +483,8 @@ class VPNService : android.net.VpnService() {
471
483
// Clear the notification message, so the content
472
484
// is not "disconnected" in case we connect from a non-client.
473
485
CannedNotification (mConfig)?.let { mNotificationHandler.hide(it) }
474
- if (shouldRecordTimerAndEndMetrics) {
486
+ if (isSuperDooperMetricsActive) {
487
+ Log .v(tag, " Sending ending metrics" )
475
488
Session .daemonSessionEnd.set()
476
489
Pings .daemonsession.submit(
477
490
Pings .daemonsessionReasonCodes.daemonEnd,
@@ -483,6 +496,8 @@ class VPNService : android.net.VpnService() {
483
496
// "flush" reason, which should contain this UUID and no other
484
497
// metrics.
485
498
Session .daemonSessionId.generateAndSet()
499
+ } else {
500
+ Log .v(tag, " Skipping ending metrics" )
486
501
}
487
502
mMetricsTimer.cancel()
488
503
}
@@ -648,6 +663,7 @@ class VPNService : android.net.VpnService() {
648
663
}
649
664
650
665
private fun recordDataTransferMetrics () {
666
+ Log .v(tag, " Recording data metrics" )
651
667
val rxBytes = getConfigValue(" rx_bytes" )?.toLong()
652
668
val txBytes = getConfigValue(" tx_bytes" )?.toLong()
653
669
if (rxBytes != null && txBytes != null ) {
0 commit comments