Skip to content
Draft
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
11 changes: 11 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ android {
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments["clearPackageData"] = "true"
// Optional coding-agent identifier (e.g. `-Pmapbox.agent=claude-code`), forwarded at runtime
// to Common's MapboxAgentContext so outbound requests can be tagged for agent-driven traffic
// measurement. Defaults to an empty string, which is treated as "no agent" and is a no-op.
val mapboxAgentId = if (project.hasProperty("mapbox.agent")) {
(project.property("mapbox.agent") as String)
.replace("\\", "\\\\")
.replace("\"", "\\\"")
} else {
""
}
buildConfigField("String", "MAPBOX_AGENT", String.format("\"%s\"", mapboxAgentId))
ndk {
val abi: String =
if (System.getenv("ANDROID_ABI") != null) System.getenv("ANDROID_ABI") else ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.mapbox.maps.testapp

/**
* Forwards [agentId] via [setAgentId] when it is non-empty.
*
* [agentId] is expected to come from [BuildConfig.MAPBOX_AGENT], which is populated at build
* time from the optional `-Pmapbox.agent=<id>` Gradle property (see `app/build.gradle.kts`).
* When that property is not supplied on the command line, [BuildConfig.MAPBOX_AGENT] defaults to
* an empty string and this function is a no-op, so normal (non-test) builds are unaffected.
*
* The forwarding logic itself is kept free of any Mapbox Common SDK dependency so that it can be
* unit tested in isolation; callers supply [setAgentId] to perform the actual forwarding, e.g.:
*
* ```
* forwardAgentIdIfPresent(BuildConfig.MAPBOX_AGENT) { agentId ->
* MapboxAgentContextFactory.getInstance().setMapboxAgentId(agentId)
* }
* ```
*/
internal fun forwardAgentIdIfPresent(agentId: String, setAgentId: (String) -> Unit) {
if (agentId.isNotEmpty()) {
setAgentId(agentId)
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/com/mapbox/maps/testapp/MapboxApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import android.os.StrictMode
import com.mapbox.android.core.permissions.PermissionsManager
import com.mapbox.annotation.MapboxExperimental
import com.mapbox.common.MapboxAgentContextFactory
import com.mapbox.common.MapboxTracing
import com.mapbox.common.geofencing.GeofencingError
import com.mapbox.common.geofencing.GeofencingEvent
Expand Down Expand Up @@ -66,11 +67,28 @@ class MapboxApplication : Application() {
// Enable all traces. Useful when capturing Perfetto traces
MapboxTracing.enableAll()
initializeStrictMode()
forwardMapboxAgentId()
if (ENABLE_BACKGROUND_GEOFENCING) {
registerGeofencingObserver()
}
}

/**
* Forwards the compile-time Mapbox agent id (see `-Pmapbox.agent=<id>` and
* [BuildConfig.MAPBOX_AGENT]) into Common's process-wide `MapboxAgentContext`, so that
* outbound Mapbox requests made during this process' lifetime (e.g. during a
* `connectedAndroidTest` run) carry an `agent/<id>` tag on the User-Agent header.
*
* This is a no-op whenever [BuildConfig.MAPBOX_AGENT] is empty, which is the default when the
* `mapbox.agent` Gradle property is not supplied, so regular `assembleRelease` / non-test
* builds of this app are unaffected.
*/
private fun forwardMapboxAgentId() {
forwardAgentIdIfPresent(BuildConfig.MAPBOX_AGENT) { agentId ->
MapboxAgentContextFactory.getInstance().setMapboxAgentId(agentId)
}
}

private fun initializeStrictMode() {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.mapbox.maps.testapp

import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test

class AgentTelemetryForwardingTest {

@Test
fun `does not forward when agent id is empty`() {
var forwardedAgentId: String? = null
forwardAgentIdIfPresent("") { forwardedAgentId = it }
assertNull(
"Setter should not be invoked when BuildConfig.MAPBOX_AGENT is empty (the default when " +
"`-Pmapbox.agent` is not supplied)",
forwardedAgentId
)
}

@Test
fun `forwards agent id when non-empty`() {
var forwardedAgentId: String? = null
forwardAgentIdIfPresent("claude-code") { forwardedAgentId = it }
assertEquals("claude-code", forwardedAgentId)
}

@Test
fun `forwards agent id exactly once`() {
var invocationCount = 0
forwardAgentIdIfPresent("codex") { invocationCount++ }
assertEquals(1, invocationCount)
}
}
Loading