Skip to content
Open
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ buildscript {
}

plugins {
id "org.sonarqube" version "3.5.0.2730"
id "org.sonarqube" version "4.3.0.3225"
id "org.jlleitschuh.gradle.ktlint" version "11.2.0"
}

Expand Down
143 changes: 103 additions & 40 deletions src/main/kotlin/com/mparticle/kits/SingularKit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ import com.mparticle.commerce.Product
import com.mparticle.consent.ConsentState
import com.mparticle.internal.Logger
import com.mparticle.internal.MPUtility
import com.mparticle.kits.KitIntegration.*
import com.mparticle.kits.KitIntegration.ActivityListener
import com.mparticle.kits.KitIntegration.ApplicationStateListener
import com.mparticle.kits.KitIntegration.AttributeListener
import com.mparticle.kits.KitIntegration.CommerceListener
import com.mparticle.kits.KitIntegration.EventListener
import com.mparticle.kits.KitIntegration.PushListener
import com.mparticle.kits.KitIntegration.UserAttributeListener
import com.singular.sdk.Singular
import com.singular.sdk.SingularConfig
import com.singular.sdk.internal.SingularLog
Expand All @@ -26,6 +32,8 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
PushListener, CommerceListener, ApplicationStateListener, UserAttributeListener,
AttributeListener {
private val logger = SingularLog.getLogger(Singular::class.java.simpleName)
private var isInitialized = false
private var deviceToken: String? = null

//endregion
//region Kit Integration Implementation
Expand All @@ -36,16 +44,13 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
// Returning the reporting message to state that the method was successful and
// Preventing from the mParticle Kit to retry to activate to method.
val messages: MutableList<ReportingMessage> = ArrayList()
if (Singular.init(context, buildSingularConfig(settings))) {
singularSettings = settings
messages.add(
ReportingMessage(
this,
ReportingMessage.MessageType.APP_STATE_TRANSITION,
System.currentTimeMillis(), null
)
messages.add(
ReportingMessage(
this,
ReportingMessage.MessageType.APP_STATE_TRANSITION,
System.currentTimeMillis(), null
)
}
)
return messages
}

Expand Down Expand Up @@ -120,8 +125,10 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
}

//region Unimplemented (Empty Methods)
override fun onActivityCreated(activity: Activity, bundle: Bundle?): List<ReportingMessage> =
emptyList()
override fun onActivityCreated(activity: Activity, bundle: Bundle?): List<ReportingMessage> {
initializeSingular()
return emptyList()
}

override fun onActivityStarted(activity: Activity): List<ReportingMessage> = emptyList()

Expand All @@ -140,21 +147,23 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
//region Event Listener Implementation
override fun logEvent(mpEvent: MPEvent): List<ReportingMessage>? {
val messages: MutableList<ReportingMessage> = ArrayList()
val eventName = mpEvent.eventName
val eventInfo = mpEvent.customAttributes
executeIfSingularInitialized({
val eventName = mpEvent.eventName
val eventInfo = mpEvent.customAttributes

// Logging the event with the Singular API
val eventStatus: Boolean = if (!eventInfo.isNullOrEmpty()) {
Singular.eventJSON(eventName, JSONObject(eventInfo))
} else {
Singular.event(eventName)
}
// Logging the event with the Singular API
val eventStatus: Boolean = if (!eventInfo.isNullOrEmpty()) {
Singular.eventJSON(eventName, JSONObject(eventInfo))
} else {
Singular.event(eventName)
}

// If the Singular event logging was successful, return the message to the mParticle Kit
// So it won't retry the event
if (eventStatus) {
messages.add(ReportingMessage.fromEvent(this, mpEvent))
}
// If the Singular event logging was successful, return the message to the mParticle Kit
// So it won't retry the event
if (eventStatus) {
messages.add(ReportingMessage.fromEvent(this, mpEvent))
}
}, forceInitSingular = true, "logEvent")
return messages
}

Expand All @@ -178,12 +187,48 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
//region Push Listener Implementation
override fun onPushRegistration(deviceToken: String, senderId: String): Boolean {
// Saving the registration token to determine when the user uninstalls the app.
if (MPUtility.isFirebaseAvailable()) {
Singular.setFCMDeviceToken(deviceToken)
}
this.deviceToken = deviceToken
executeIfSingularInitialized({
if (MPUtility.isFirebaseAvailable()) {
Singular.setFCMDeviceToken(deviceToken)
}
}, forceInitSingular = false, "onPushRegistration")
return true
}

private fun executeIfSingularInitialized(
operation: () -> Unit,
forceInitSingular: Boolean = false,
operationName: String
) {
if (isInitialized) {
operation.invoke()
Logger.debug("$operationName executed")
} else {
if (forceInitSingular) {
initializeSingular()
executeIfSingularInitialized(operation, false, operationName)
} else {
Logger.debug("$operationName can't be executed, Singular not initialized")
}
}
}

private fun initializeSingular() {
if (!isInitialized) {
if (Singular.init(context, buildSingularConfig(settings))) {
currentUser?.id?.toString()?.let { Singular.setCustomUserId(it) }
isInitialized = true
singularSettings = settings
deviceToken?.let { deviceToken ->
if (MPUtility.isFirebaseAvailable()) {
Singular.setFCMDeviceToken(deviceToken)
}
}
}
}
}

//region Unimplemented (Empty Methods)
override fun willHandlePushMessage(intent: Intent): Boolean = false

Expand All @@ -193,11 +238,15 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
//endregion
//region Commerce Listener Implementation
override fun logEvent(commerceEvent: CommerceEvent): List<ReportingMessage> {
return if (commerceEvent.productAction == Product.PURCHASE) {
handlePurchaseEvents(commerceEvent)
} else {
handleNonPurchaseEvents(commerceEvent)
}
var list = emptyList<ReportingMessage>()
executeIfSingularInitialized(operation = {
if (commerceEvent.productAction == Product.PURCHASE) {
list = handlePurchaseEvents(commerceEvent)
} else {
list = handleNonPurchaseEvents(commerceEvent)
}
}, forceInitSingular = true, "logEvent")
return list
}

private fun handlePurchaseEvents(commerceEvent: CommerceEvent): List<ReportingMessage> {
Expand Down Expand Up @@ -264,7 +313,11 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
}
}
if (map.isNotEmpty()) {
Singular.eventJSON("UserAttribute", (map as Map<*, *>?)?.let { JSONObject(it) })
executeIfSingularInitialized(
{
Singular.eventJSON("UserAttribute", (map as Map<*, *>?)?.let { JSONObject(it) })
}, forceInitSingular = false, "setUserAttribute"
)
}
}

Expand Down Expand Up @@ -312,34 +365,44 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
filteredMParticleUser: FilteredMParticleUser
) {

consentState.ccpaConsentState?.let { Singular.limitDataSharing(it.isConsented) }
executeIfSingularInitialized({
consentState.ccpaConsentState?.let { Singular.limitDataSharing(it.isConsented) }
}, forceInitSingular = false, "onConsentStateUpdated")

}

override fun setAllUserAttributes(map: Map<String, String>, map1: Map<String, List<String>>) {}
override fun removeUserAttribute(s: String) {}
override fun setUserIdentity(identityType: IdentityType, s: String) {
if (identityType == IdentityType.CustomerId) {
Singular.setCustomUserId(s)
executeIfSingularInitialized({
Singular.setCustomUserId(s)
}, forceInitSingular = false, "setUserIdentity")
}
}

override fun removeUserIdentity(identityType: IdentityType) {
if (identityType == IdentityType.CustomerId) {
Singular.unsetCustomUserId()
executeIfSingularInitialized({
Singular.unsetCustomUserId()
isInitialized = false
}, forceInitSingular = false, "removeUserIdentity")
}
}

override fun logout(): List<ReportingMessage> {
Singular.unsetCustomUserId()
val messageList: MutableList<ReportingMessage> = ArrayList()
messageList.add(ReportingMessage.logoutMessage(this))
executeIfSingularInitialized({
Singular.unsetCustomUserId()
isInitialized = false
messageList.add(ReportingMessage.logoutMessage(this))
}, forceInitSingular = false, "logout")
return messageList
}

override fun onApplicationForeground() {
// Handling deeplinks when the application resumes from background
Singular.init(context, buildSingularConfig(singularSettings))
initializeSingular()
}

override fun onApplicationBackground() {} //endregion
Expand Down