diff --git a/kits/branch/branch-5/src/main/kotlin/com/mparticle/kits/BranchMetricsKit.kt b/kits/branch/branch-5/src/main/kotlin/com/mparticle/kits/BranchMetricsKit.kt index 9c863b57f..e5dc61802 100644 --- a/kits/branch/branch-5/src/main/kotlin/com/mparticle/kits/BranchMetricsKit.kt +++ b/kits/branch/branch-5/src/main/kotlin/com/mparticle/kits/BranchMetricsKit.kt @@ -49,6 +49,7 @@ class BranchMetricsKit : private var isMpidIdentityType = false var identityType: IdentityType? = IdentityType.CustomerId private var mSendScreenEvents = false + private var sendSessionId = false private var branchUtil: BranchUtil? = null override fun getInstance(): Branch? = branch @@ -74,6 +75,7 @@ class BranchMetricsKit : mSendScreenEvents = sendScreenEvents != null && sendScreenEvents.equals("true", ignoreCase = true) + sendSessionId = settings[SEND_SESSION_ID].equals("true", ignoreCase = true) setIdentityType(settings) return emptyList() } @@ -120,7 +122,10 @@ class BranchMetricsKit : ): List = emptyList() override fun logEvent(event: MPEvent): List { - branchUtil?.createBranchEventFromMPEvent(event)?.logEvent(context) + branchUtil + ?.createBranchEventFromMPEvent(event) + ?.withSessionId(currentSessionId, event.customAttributeStrings) + ?.logEvent(context) val messages = LinkedList() messages.add(ReportingMessage.fromEvent(this, event)) return messages @@ -134,7 +139,10 @@ class BranchMetricsKit : ): List = emptyList() override fun logEvent(commerceEvent: CommerceEvent): List { - branchUtil?.createBranchEventFromMPCommerceEvent(commerceEvent)?.logEvent(context) + branchUtil + ?.createBranchEventFromMPCommerceEvent(commerceEvent) + ?.withSessionId(currentSessionId, commerceEvent.customAttributeStrings) + ?.logEvent(context) val messages: MutableList = LinkedList() messages.add(ReportingMessage.fromEvent(this, commerceEvent)) return messages @@ -151,7 +159,7 @@ class BranchMetricsKit : eventAttributes = HashMap() } branchUtil?.updateBranchEventWithCustomData(logScreenEvent, eventAttributes) - logScreenEvent.logEvent(context) + logScreenEvent.withSessionId(currentSessionId, eventAttributes).logEvent(context) val messages = LinkedList() messages.add( @@ -168,6 +176,9 @@ class BranchMetricsKit : } } + private val currentSessionId: Long? + get() = if (sendSessionId) MParticle.getInstance()?.currentSession?.sessionID else null + private val branch: Branch? get() = settings[branchAppKey]?.let { Branch.getInstance() } @@ -315,9 +326,25 @@ class BranchMetricsKit : override fun onApplicationBackground() {} + /** + * Adds the mParticle session ID to the event's custom data. A customer attribute with the same + * key wins, and nothing is added without a session ID. + */ + internal fun BranchEvent.withSessionId( + sessionId: Long?, + attributes: Map?, + ): BranchEvent = + apply { + if (sessionId != null && sessionId != 0L && attributes?.containsKey(SESSION_ID_KEY) != true) { + addCustomDataProperty(SESSION_ID_KEY, sessionId.toString()) + } + } + companion object { private const val FORWARD_SCREEN_VIEWS = "forwardScreenViews" private const val USER_IDENTIFICATION_TYPE = "userIdentificationType" + private const val SEND_SESSION_ID = "sendSessionId" + internal const val SESSION_ID_KEY = "mp_session_id" const val NAME = "Branch Metrics" } } diff --git a/kits/branch/branch-5/src/test/kotlin/com/mparticle/kits/BranchKitTests.kt b/kits/branch/branch-5/src/test/kotlin/com/mparticle/kits/BranchKitTests.kt index dc92f808d..68ccf4c9f 100644 --- a/kits/branch/branch-5/src/test/kotlin/com/mparticle/kits/BranchKitTests.kt +++ b/kits/branch/branch-5/src/test/kotlin/com/mparticle/kits/BranchKitTests.kt @@ -2,6 +2,7 @@ package com.mparticle.kits import android.content.Context import com.mparticle.MParticleOptions +import io.branch.referral.util.BranchEvent import org.junit.Assert import org.junit.Test import org.mockito.Mockito @@ -50,4 +51,59 @@ class BranchKitTests { } Assert.fail("$className not found as a known integration.") } + + /** + * Verifies the session ID is added to the Branch event's custom data. + */ + @Test + fun testWithSessionIdAddsSessionId() { + val branchEvent = Mockito.mock(BranchEvent::class.java) + + with(BranchMetricsKit()) { branchEvent.withSessionId(-7046029254386353131L, mapOf("color" to "blue")) } + + Mockito + .verify(branchEvent) + .addCustomDataProperty(BranchMetricsKit.SESSION_ID_KEY, "-7046029254386353131") + } + + /** + * Verifies a customer attribute with the session ID key is not overwritten. + */ + @Test + fun testWithSessionIdKeepsCustomerValue() { + val branchEvent = Mockito.mock(BranchEvent::class.java) + + with(BranchMetricsKit()) { + branchEvent.withSessionId( + -7046029254386353131L, + mapOf(BranchMetricsKit.SESSION_ID_KEY to "customer-value"), + ) + } + + Mockito.verifyZeroInteractions(branchEvent) + } + + /** + * Verifies nothing is added when there is no current session. + */ + @Test + fun testWithSessionIdSkipsWithoutSession() { + val branchEvent = Mockito.mock(BranchEvent::class.java) + + with(BranchMetricsKit()) { branchEvent.withSessionId(null, null) } + + Mockito.verifyZeroInteractions(branchEvent) + } + + /** + * Verifies nothing is added when the session has no UUID, which the SDK reports as an ID of 0. + */ + @Test + fun testWithSessionIdSkipsZeroId() { + val branchEvent = Mockito.mock(BranchEvent::class.java) + + with(BranchMetricsKit()) { branchEvent.withSessionId(0L, null) } + + Mockito.verifyZeroInteractions(branchEvent) + } }