Skip to content

Commit c1af868

Browse files
author
Memfault Inc.
committed
Memfault BORT SDK 4.19.0 (Build 2345299)
1 parent 0fce7f9 commit c1af868

File tree

51 files changed

+1031
-274
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1031
-274
lines changed

CHANGELOG.md

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# Memfault Bort Changelog
22

3+
## v4.19.0 - August 13, 2024
4+
5+
### :rocket: New Features
6+
7+
- Added support for automatically collecting the phone's IMEI number as a
8+
metric: `phone.imei`.
9+
- Updates the Stable Hours algorithm. By default, only ANRs, non-WTF app
10+
crashes, kernel panics, and tombstones count as "crashes" for the purposes of
11+
the algorithm. It is now also possible to exclude these crashes from the
12+
algorithm if desired (please reach out to customer support for more
13+
information).
14+
15+
### :chart_with_upwards_trend: Improvements
16+
17+
- Fixed a bug in the battery per-hour charge and discharge calculations where
18+
the wrong denominator was being used.
19+
- Fixed a bug in the SDK where heartbeats after reboots could fail to process.
20+
- Fixed a bug in the SDK where batterystats collection could fail
21+
inconsistently.
22+
- Added the device serial and override to the diagnostics content provider.
23+
- Disables metrics handling in more places if Bort is also disabled.
24+
25+
### :house: Internal
26+
27+
- Added more internal metrics to detect how often the Bort app restarts.
28+
- Cleaned up spurious Bort logs.
29+
- Fixed bug when tracking Bort's own battery usage.
30+
331
## v4.18.0 - July 1, 2024
432

533
### :rocket: New Features
@@ -993,7 +1021,7 @@ documentation.
9931021
provided, the `dumpstate.memfault.requestid` system property is set to the
9941022
value provided. Additionally, a BroadcastReceiver can be specified to which
9951023
the status of the bug report request will be reported by Bort. See
996-
https://mflt.io/android-bort-sdk for details.
1024+
<https://mflt.io/android-bort-sdk> for details.
9971025
> NOTE: in order to use this feature, the AOSP system image has to be updated
9981026
> (merely updating MemfaultBort.apk is not sufficient, because this feature
9991027
> also involved a change in the MemfaultDumpstateRunner system component).
@@ -1025,13 +1053,13 @@ documentation.
10251053
- Have you ever wondered how the metrics in your device timelines are trending
10261054
across your whole fleet? With the 3.0.0 version of Bort, now you can view
10271055
visualizations of these metrics aggregated across all your devices! See
1028-
https://mflt.io/fleet-wide-metrics for details.
1056+
<https://mflt.io/fleet-wide-metrics> for details.
10291057
- The aforementioned "experimental" data source is now ready for prime time! It
10301058
can be used to collect traces and metrics, with additional data sources coming
1031-
in future SDK releases. See https://mflt.io/memfault-caliper for details.
1059+
in future SDK releases. See <https://mflt.io/memfault-caliper> for details.
10321060
- Reboot events were added in an earlier version of the SDK but didn't make it
10331061
into the changelog. Let's call that a 3.0 feature too! See
1034-
https://mflt.io/android-reboot-reasons to learn more.
1062+
<https://mflt.io/android-reboot-reasons> to learn more.
10351063

10361064
## v2.9.1 - December 3, 2020
10371065

@@ -1317,7 +1345,7 @@ documentation.
13171345
it, add an intent filter with the launcher category to an activity in the
13181346
`AndroidManifest`.
13191347

1320-
```
1348+
```xml
13211349
<intent-filter>
13221350
<action android:name="android.intent.action.MAIN" />
13231351
<category android:name="android.intent.category.LAUNCHER" />

MemfaultDumpster/ContinuousLogcat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ void ContinuousLogcat::run() {
217217
// don't block when the buffer ends (equivalent to logcat -d), this does not prevent blocking in wrapping scenarios
218218
int log_mode = ANDROID_LOG_NONBLOCK;
219219

220-
// if we are not doing an inmmediate dump, use wrapping behavior
220+
// if we are not doing an immediate dump, use wrapping behavior
221221
if (!dump_after_intr) {
222222
log_mode |= ANDROID_LOG_WRAP;
223223
}

MemfaultPackages/bort-ota-lib/src/main/java/com/memfault/bort/ota/lib/PeriodicSoftwareUpdateWorker.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.memfault.bort.shared.runAndTrackExceptions
1717
import dagger.assisted.Assisted
1818
import dagger.assisted.AssistedInject
1919
import java.util.concurrent.TimeUnit
20+
import kotlin.time.toJavaDuration
2021

2122
/**
2223
* A periodic worker that triggers an update check.
@@ -54,7 +55,7 @@ class PeriodicSoftwareUpdateWorker @AssistedInject constructor(
5455
JitterDelayProvider(
5556
jitterDelayConfiguration = { JitterDelayProvider.ApplyJitter.APPLY },
5657
devMode = DEV_MODE_DISABLED,
57-
).randomJitterDelay(),
58+
).randomJitterDelay().toJavaDuration(),
5859
)
5960
}.build()
6061

MemfaultPackages/bort-shared/src/main/java/com/memfault/bort/settings/FetchedSettings.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ data class FetchedSettings(
270270
@Serializable(with = DurationAsMillisecondsLong::class)
271271
val metricsCollectionInterval: BoxedDuration,
272272

273+
@SerialName("metrics.operational_crashes_exclusions")
274+
val metricsOperationalCrashesExclusions: List<String> = listOf(),
275+
273276
@SerialName("metrics.data_source_enabled")
274277
val metricsDataSourceEnabled: Boolean,
275278

@@ -294,6 +297,9 @@ data class FetchedSettings(
294297
@SerialName("network.collection_transmit_threshold_kb")
295298
val networkCollectionTransmitThresholdKb: Long = 1_000L,
296299

300+
@SerialName("metrics.record_imei")
301+
val metricsRecordImei: Boolean = false,
302+
297303
@SerialName("metrics.reporter_collection_interval_ms")
298304
@Serializable(with = DurationAsMillisecondsLong::class)
299305
val metricsReporterCollectionInterval: BoxedDuration = 10.minutes.boxed(),

MemfaultPackages/bort-shared/src/main/java/com/memfault/bort/shared/JitterDelayProvider.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package com.memfault.bort.shared
22

33
import com.memfault.bort.DevMode
44
import com.memfault.bort.shared.JitterDelayProvider.ApplyJitter.APPLY
5-
import java.time.Duration
6-
import java.time.Duration.ZERO
75
import javax.inject.Inject
86
import kotlin.random.Random
7+
import kotlin.time.Duration
8+
import kotlin.time.Duration.Companion.milliseconds
9+
import kotlin.time.Duration.Companion.minutes
910

1011
/**
1112
* Generate a random jittery delay for server calls.
@@ -14,13 +15,11 @@ class JitterDelayProvider @Inject constructor(
1415
private val jitterDelayConfiguration: JitterDelayConfiguration,
1516
private val devMode: DevMode,
1617
) {
17-
// Uses Java's Duration type: Kotlin's Duration is an inline class which causes a crash when a return value is
18-
// accessed from another module.
19-
fun randomJitterDelay(maxDelay: Duration = MAX_JITTER_DELAY): Duration =
18+
fun randomJitterDelay(maxDelay: Duration = DEFAULT_JITTER_DELAY): Duration =
2019
if (!devMode.isEnabled() && jitterDelayConfiguration.applyJitter() == APPLY) {
21-
Duration.ofMillis(Random.nextLong(0, maxDelay.toMillis()))
20+
Random.nextLong(0, maxDelay.inWholeMilliseconds).milliseconds
2221
} else {
23-
ZERO
22+
Duration.ZERO
2423
}
2524

2625
enum class ApplyJitter {
@@ -29,7 +28,7 @@ class JitterDelayProvider @Inject constructor(
2928
}
3029

3130
companion object {
32-
private const val MAX_JITTER_DELAY_MINUTES: Long = 15
33-
private val MAX_JITTER_DELAY = Duration.ofMinutes(MAX_JITTER_DELAY_MINUTES)
31+
private const val DEFAULT_JITTER_DELAY_MINUTES: Long = 15
32+
private val DEFAULT_JITTER_DELAY = DEFAULT_JITTER_DELAY_MINUTES.minutes
3433
}
3534
}

MemfaultPackages/bort/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
<uses-permission
2929
android:name="android.permission.WRITE_SECURE_SETTINGS"
3030
tools:ignore="ProtectedPermissions" />
31+
<!-- Read IMEI -->
32+
<uses-permission
33+
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
34+
tools:ignore="ProtectedPermissions" />
3135

3236
<permission
3337
android:name="com.memfault.bort.permission.CONTROL"

MemfaultPackages/bort/src/main/java/com/memfault/bort/clientserver/MarBatchingTask.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import kotlin.time.Duration
5151
import kotlin.time.Duration.Companion.ZERO
5252
import kotlin.time.Duration.Companion.minutes
5353
import kotlin.time.toJavaDuration
54-
import kotlin.time.toKotlinDuration
5554

5655
/**
5756
* Can be either periodic or one-time.
@@ -193,10 +192,10 @@ class PeriodicMarUploadRequester @Inject constructor(
193192
) : PeriodicWorkRequester() {
194193
override suspend fun startPeriodic(justBooted: Boolean, settingsChanged: Boolean) {
195194
// Jitter is based on the mar batching period.
196-
val maxJitterDelay = httpApiSettings.batchedMarUploadPeriod.toJavaDuration()
195+
val maxJitterDelay = httpApiSettings.batchedMarUploadPeriod
197196
val jitter: Duration
198197
val bootDelay = if (justBooted) 5.minutes else ZERO
199-
jitter = bootDelay + jitterDelayProvider.randomJitterDelay(maxDelay = maxJitterDelay).toKotlinDuration()
198+
jitter = bootDelay + jitterDelayProvider.randomJitterDelay(maxDelay = maxJitterDelay)
200199
MarBatchingTask.schedulePeriodicMarBatching(
201200
context = application,
202201
period = httpApiSettings.batchedMarUploadPeriod,

MemfaultPackages/bort/src/main/java/com/memfault/bort/diagnostics/BortDiagnosticsProvider.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import android.database.DatabaseUtils
77
import android.database.MatrixCursor
88
import android.net.Uri
99
import com.memfault.bort.DevMode
10+
import com.memfault.bort.DeviceInfoProvider
11+
import com.memfault.bort.OverrideSerial
1012
import com.memfault.bort.ProjectKeySyspropName
1113
import com.memfault.bort.requester.PeriodicWorkRequester.PeriodicWorkManager
1214
import com.memfault.bort.settings.AllowProjectKeyChange
@@ -35,6 +37,8 @@ class BortDiagnosticsProvider : ContentProvider() {
3537
fun bortErrors(): BortErrors
3638
fun periodicWorkManager(): PeriodicWorkManager
3739
fun bortJobReporter(): BortJobReporter
40+
fun deviceInfoProvider(): DeviceInfoProvider
41+
fun overrideSerial(): OverrideSerial
3842
}
3943

4044
val entryPoint: DiagnosticsProviderEntryPoint by lazy {
@@ -72,6 +76,8 @@ class BortDiagnosticsProvider : ContentProvider() {
7276
cursor.addRow(arrayOf("bort_error", it.toString()))
7377
}
7478
addJobStatus(cursor)
79+
cursor.addRow(arrayOf("device_serial", entryPoint.deviceInfoProvider().getDeviceInfo().deviceSerial))
80+
cursor.addRow(arrayOf("override_serial", entryPoint.overrideSerial().overriddenSerial))
7581
}
7682
Logger.d("Bort Diagnostics:")
7783
Logger.d(DatabaseUtils.dumpCursorToString(cursor))

MemfaultPackages/bort/src/main/java/com/memfault/bort/dropbox/AnrUploadingEntryProcessorDelegate.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.memfault.bort.dropbox
22

33
import android.os.DropBoxManager
44
import com.memfault.bort.parsers.AnrParser
5+
import com.memfault.bort.settings.OperationalCrashesExclusions
56
import com.memfault.bort.shared.Logger
67
import com.memfault.bort.tokenbucket.Anr
78
import com.memfault.bort.tokenbucket.TokenBucketStore
@@ -10,6 +11,7 @@ import javax.inject.Inject
1011

1112
class AnrUploadingEntryProcessorDelegate @Inject constructor(
1213
@Anr private val tokenBucketStore: TokenBucketStore,
14+
private val operationalCrashesExclusions: OperationalCrashesExclusions,
1315
) : UploadingEntryProcessorDelegate {
1416
override val tags = listOf(
1517
"data_app_anr",
@@ -31,5 +33,6 @@ class AnrUploadingEntryProcessorDelegate @Inject constructor(
3133
EntryInfo(entry.tag)
3234
}
3335

34-
override fun isCrash(tag: String): Boolean = true
36+
override fun isCrash(entry: DropBoxManager.Entry, entryFile: File): Boolean =
37+
entry.tag !in operationalCrashesExclusions()
3538
}

MemfaultPackages/bort/src/main/java/com/memfault/bort/dropbox/JavaExceptionUploadingEntryProcessorDelegate.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.memfault.bort.dropbox
22

33
import android.os.DropBoxManager
44
import com.memfault.bort.parsers.JavaExceptionParser
5+
import com.memfault.bort.settings.OperationalCrashesExclusions
56
import com.memfault.bort.tokenbucket.JavaException
67
import com.memfault.bort.tokenbucket.TokenBucketStore
78
import com.memfault.bort.tokenbucket.Wtf
@@ -14,6 +15,7 @@ class JavaExceptionUploadingEntryProcessorDelegate @Inject constructor(
1415
@JavaException private val javaExceptionTokenBucketStore: TokenBucketStore,
1516
@Wtf private val wtfTokenBucketStore: TokenBucketStore,
1617
@WtfTotal private val wtfTotalTokenBucketStore: TokenBucketStore,
18+
private val operationalCrashesExclusions: OperationalCrashesExclusions,
1719
) : UploadingEntryProcessorDelegate {
1820
override val tags = listOf(
1921
"data_app_crash",
@@ -52,7 +54,13 @@ class JavaExceptionUploadingEntryProcessorDelegate @Inject constructor(
5254
EntryInfo(entry.tag)
5355
}
5456

55-
override fun isCrash(tag: String): Boolean = !isWtf(tag)
57+
override fun isCrash(entry: DropBoxManager.Entry, entryFile: File): Boolean {
58+
if (entry.tag in operationalCrashesExclusions()) {
59+
return false
60+
}
61+
62+
return !isWtf(entry.tag)
63+
}
5664

5765
companion object {
5866
private fun isWtf(tag: String): Boolean = tag.endsWith("wtf")

0 commit comments

Comments
 (0)